使用CMake FetchContent引入子项目时CMAKE_SOURCE_DIR变量异常问题咨询
问题解答
1. 是否属于子项目的开发错误/缺陷?
是。${CMAKE_SOURCE_DIR}的CMake官方定义是整个构建会话的根源码目录,当通过FetchContent引入子项目时,子项目会作为主项目的一部分参与构建,因此这个变量必然指向主项目的源码根目录。
子项目中若用${CMAKE_SOURCE_DIR}来引用自身的文件路径,属于错误用法——正确的做法是使用${PROJECT_SOURCE_DIR}(指向当前项目的根目录)或${CMAKE_CURRENT_SOURCE_DIR}(指向当前CMakeLists.txt所在的目录),这两个变量才是与子项目自身路径绑定的。
2. 主项目的解决办法
不需要用cmake -P脚本,直接通过FetchContent的补丁机制就能修复:在FetchContent_Declare中增加PATCH_COMMAND,用字符串替换工具批量修正子项目CMakeLists.txt中的变量错误。
示例代码(单文件替换)
include(FetchContent) FetchContent_Declare(subproject GIT_REPOSITORY https://url/to/my_subproject # 替换子项目根目录CMakeLists.txt中的变量 PATCH_COMMAND ${CMAKE_COMMAND} -E sed -i "s/CMAKE_SOURCE_DIR/PROJECT_SOURCE_DIR/g" ${CMAKE_CURRENT_BINARY_DIR}/_deps/subproject-src/CMakeLists.txt ) FetchContent_MakeAvailable(subproject)
递归替换所有子目录的CMakeLists.txt
如果子项目的配置文件分散在多个子目录,可使用递归查找替换:
include(FetchContent) FetchContent_Declare(subproject GIT_REPOSITORY https://url/to/my_subproject # 递归替换所有CMakeLists.txt中的变量 PATCH_COMMAND find ${CMAKE_CURRENT_BINARY_DIR}/_deps/subproject-src -name "CMakeLists.txt" -exec ${CMAKE_COMMAND} -E sed -i "s/CMAKE_SOURCE_DIR/PROJECT_SOURCE_DIR/g" {} \; ) FetchContent_MakeAvailable(subproject)
若你有权限修改子项目代码,最彻底的方式是直接修正子项目中的变量用法,从根源解决问题。
内容的提问来源于stack exchange,提问作者hfhc2
相关产品推荐
相关产品推荐

