CMake引入子目录cmake文件时Ninja无法找到规则的原因咨询
CMake引入子目录cmake文件后Ninja找不到构建规则的原因
1. 子目录cmake文件的路径未做相对路径适配
当你用include(subdir/sub.cmake)引入子目录的脚本时,脚本里的文件路径默认是相对于主CMakeLists.txt所在目录,而非子目录本身。如果直接写相对路径(比如src/main.cpp),CMake会在项目根目录找这个文件,自然找不到,导致Ninja生成的规则缺失。
解决时要用到CMAKE_CURRENT_LIST_DIR变量——它代表当前被include的cmake文件所在的目录,用它拼接路径就能定位到子目录下的文件:
# subdir/sub.cmake 正确写法 add_executable(myapp ${CMAKE_CURRENT_LIST_DIR}/src/main.cpp)
2. 构建目标未正确关联到顶层项目
如果子目录cmake文件里定义的目标(比如add_library生成的库)没有和顶层的可执行目标关联,Ninja可能不会把这些目标的构建规则纳入全局任务。比如你在子脚本里建了一个库,但顶层CMakeLists.txt没通过target_link_libraries把它链接到主可执行文件,Ninja就会忽略这个库的构建规则。
3. CMake作用域导致变量解析错误
include只是把脚本内容插入到当前作用域执行,不会切换到子目录的作用域。如果子脚本里用了PROJECT_SOURCE_DIR这类变量,它们依然指向项目根目录,而非子目录。如果依赖这些变量拼接路径,就会出现路径错误,让Ninja找不到对应文件。
4. 旧构建缓存残留
如果之前用错误的路径生成过构建文件,即使修正了CMake脚本,CMake的CMakeCache.txt或Ninja的缓存文件可能还残留旧的错误配置。这种情况要彻底删除build目录下的所有生成文件,重新运行cmake ..生成构建脚本,再执行ninja。
内容的提问来源于stack exchange,提问作者stustd
相关产品推荐
相关产品推荐

