当前位置: 首页 > news >正文

cmake学习--add_subdirectory

add_subdirectory引入的是构建规则,不是目标文件

当你执行add_subdirectory时,CMake 会:

  1. 读取子目录中的CMakeLists.txt

  2. 解析其中的构建指令(如add_library,add_executable

  3. 记录这些目标和依赖关系到 CMake 的构建数据库中

此时并没有编译任何文件,也没有生成目标文件(.o/.obj)或可执行文件。

完整流程示例

# 顶层 CMakeLists.txt cmake_minimum_required(VERSION 3.10) project(Demo) add_subdirectory(lib) # ① 只是注册构建规则 add_executable(main main.cpp) target_link_libraries(main mylib) # ② 建立依赖关系

下级的lib的cmakelist:

# lib/CMakeLists.txt add_library(mylib util.cpp) # ③ 注册库的构建规则

各阶段发生的事情:

阶段命令实际行为
配置阶段(cmake ..)add_subdirectory(lib)读取lib/CMakeLists.txt,记录"需要构建mylib这个库"
配置阶段target_link_libraries(main mylib)记录"main需要链接mylib"
生成阶段(cmake ..)-生成 Makefile/Ninja 文件,包含完整构建规则
构建阶段(make)make main才真正编译util.cpp生成util.o,然后链接成libmylib.a,最终由main链接libmylib.a

关键理解

# 配置阶段:只读 CMakeLists.txt,不编译 $ cmake .. -- Configuring done # add_subdirectory 在这里生效 -- Generating done # 此时查看 build 目录,还没有 .o 或 .a 文件 $ ls lib/ CMakeFiles/ CMakeLists.txt # 只有 CMake 的缓存文件
$ make Scanning dependencies of target mylib [ 25%] Building CXX object lib/CMakeFiles/mylib.dir/util.cpp.o [ 50%] Linking CXX static library libmylib.a # ← 中间产物:静态库mylib Scanning dependencies of target main [ 75%] Building CXX object CMakeFiles/main.dir/main.cpp.o [100%] Linking CXX executable main

引入的具体内容

add_subdirectory引入的是CMake 目标(Target)定义

cmake

add_subdirectory(lib) # 之后,你可以使用子目录中定义的目标名称 target_link_libraries(main mylib) # mylib 是"目标名称" target_include_directories(main PRIVATE lib) # 甚至可以使用目录路径

这些目标包含:

  • 源文件列表(如util.cpp

  • 编译选项(target_compile_options

  • 链接库依赖

  • 包含路径(target_include_directories

  • 自定义命令等

类比理解

可以把add_subdirectory理解为:

  • 不是“把做好的饭菜端过来”

  • 而是“把菜谱加入菜单”,告诉厨师(编译器)如何做这道菜

  • 实际烹饪(编译)发生在makecmake --build

与预编译库的对比

# 方式1:add_subdirectory(有源码) add_subdirectory(lib) # 引入构建规则 # 构建时才会编译 util.cpp -> libmylib.a # 方式2:使用预编译库(已有 libmylib.a) add_library(mylib STATIC IMPORTED) # 直接引入已存在的二进制文件 set_target_properties(mylib PROPERTIES IMPORTED_LOCATION /path/to/libmylib.a) # 不需要编译,直接使用

总结

  • add_subdirectory引入的是构建规则/目标定义(逻辑实体)

  • 目标文件.o,.a,.exe)是在后续make/cmake --build构建阶段才生成的

  • 好处:配置阶段快速,可以根据条件决定是否引入子目录,依赖关系清晰

这就是为什么 CMake 分两个阶段(配置+生成 vs 构建)—— 先用add_subdirectory组织构建逻辑,再实际编译产生二进制文件。

  1. 配置阶段:记录"需要构建libmylib.amain"

  2. 构建阶段

    • 先编译util.cpputil.o

    • 归档util.olibmylib.a(中间产物)

    • 编译main.cppmain.o

    • 链接main.o + libmylib.amain(最终可执行文件)

http://www.jsqmd.com/news/615982/

相关文章:

  • OpenClaw多模态翻译器:Kimi-VL-A3B-Thinking图文混合内容转换方案
  • 2026年SCD43二氧化碳传感器选型:SGD43S-M3-S5冷媒传感器/SGD43S-M3-S7冷媒传感器/选择指南 - 优质品牌商家
  • 一文读懂 Python 作用域
  • 微信对接OpenClaw的常见问题和解决方案滥
  • OpenClaw云端体验:通过星图平台快速部署千问3.5-35B-A3B-FP8
  • 2026双头Pogopin怎么选:双排pogopin连接器/大电流pogopin连接器/弹簧针/探针/插件pogopin连接器/选择指南 - 优质品牌商家
  • Tomcat 下载安装保姆级图文教程2026新(附安装包)
  • OpenClaw+Qwen2.5-VL-7B:低成本自动化内容生成方案
  • linux最常见基本命令
  • Winform+正运动控制卡+Halcon识别进行轨迹绘制
  • DHT118266库深度解析:嵌入式DHT传感器驱动设计与跨平台移植
  • 盲人辅助工具:OpenClaw+Gemma-3-12b-it的屏幕阅读增强方案
  • 反直觉观点 先做可观测性再做智能 否则迭代速度会崩盘
  • CF1805 VP 记录
  • OpenClaw+千问3.5-9B自动化报告:从数据到PPT一键生成
  • golang如何实现负载均衡器组件_golang负载均衡器组件实现详解
  • ModbusTool终极指南:工业自动化通信调试的完整解决方案
  • OpenClaw异常处理:Qwen3-4B任务中断的自动恢复机制
  • 方寸精准,定位无忧|KH-GPS10104-WY 无源陶瓷天线
  • CH9328 UART转USB键盘库:极简HID设备开发方案
  • 2026年知名的静音门窗用户口碑推荐厂家 - 行业平台推荐
  • 2026年4月宠物绝育医院哪家好,宠物绝育/狗狗绝育/母狗绝育/狗狗心脏病专家/猫咪心脏病专家,宠物绝育医院口碑推荐 - 品牌推荐师
  • OpenClaw资源监控技巧:Qwen2.5-VL-7B多模态任务性能调优
  • BCC_ESP32S3:ESP32-S3专用电机控制库详解
  • 嵌入式开发必备终端工具与效率提升技巧
  • OS 性能设计索引
  • MySQL的高可用解决:主从模式与MHA,MGR
  • 2026中型IT运维公司怎么选:中型IT外包公司/中型IT服务公司/中型IT运维公司/中型运维管理服务公司/大型IT外包公司/选择指南 - 优质品牌商家
  • QuickRecorder终极指南:5分钟掌握macOS专业屏幕录制
  • EcomGPT电商智能助手效果惊艳展示:中英泰越四语营销文案生成作品集