使用FetchContent与add_subdirectory时的CMake install目标配置问题
CMake嵌套目录安装配置与机制解析
一、解决配置方案
针对_deps内容误安装、.pc文件报错问题,按以下步骤调整:
1. 顶层CMakeLists.txt显式控制安装范围
顶层无需编写具体install逻辑,但要明确仅包含本地子目录的install目标,排除FetchContent生成的_deps目录。在顶层CMakeLists.txt末尾添加:
# 仅安装本地子目录的install目标,排除_deps下的外部依赖 install(DIRECTORY DESTINATION "${CMAKE_INSTALL_PREFIX}" COMPONENT local_components) install(EXPORT local-targets DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" COMPONENT local_components) # 遍历所有本地子目录,将它们的install目标关联到local_components foreach(subdir IN ITEMS 本地子目录1 本地子目录2 ...) if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/CMakeLists.txt") add_subdirectory(${subdir}) # 将子目录的install目标归到local_components,避免_deps的目标混入 set_target_properties(${subdir}_targets PROPERTIES INSTALL_COMPONENT local_components) endif() endforeach()
替换本地子目录1 本地子目录2 ...为你的实际本地子目录名称。
2. 给FetchContent拉取的外部库设置EXCLUDE_FROM_ALL
在子目录中使用FetchContent时,添加EXCLUDE_FROM_ALL参数,让外部库的install目标不被默认执行:
FetchContent_Declare( external_lib GIT_REPOSITORY https://xxx/xxx.git GIT_TAG xxx EXCLUDE_FROM_ALL ON ) FetchContent_MakeAvailable(external_lib)
这样外部库只会被构建,不会被install到系统目录。
3. 解决.pc文件报错问题
如果报错的.pc文件是外部库生成的,要么在外部库的构建选项中禁用.pc文件生成(比如设置BUILD_PKGCONFIG=OFF之类的选项,具体看外部库的CMake配置),要么在顶层添加过滤规则,跳过该文件的安装:
# 跳过指定.pc文件的安装 install(CODE " file(GLOB PC_FILES \"${CMAKE_INSTALL_PREFIX}/lib/pkgconfig/xxx.pc\") if(PC_FILES) file(REMOVE \${PC_FILES}) endif() " COMPONENT local_components)
替换xxx.pc为报错的文件名。
二、CMake嵌套目录下install目标的处理机制
- 传递性执行:当顶层执行
make install或cmake --install时,会遍历所有通过add_subdirectory添加的子目录,以及子目录中引入的所有目标(包括FetchContent拉取的外部库),默认执行所有存在的install目标。 - FetchContent的默认行为:FetchContent拉取的外部库会被集成到当前项目的构建树中,其CMakeLists.txt中的install目标会被当作项目自身的目标处理,除非设置
EXCLUDE_FROM_ALL,否则会被执行。 - INSTALL_COMPONENT的作用:通过给目标设置
INSTALL_COMPONENT,可以将不同的install目标分组,执行install时可以指定--component参数仅安装特定组的内容,避免误安装外部依赖。 - CMAKE_INSTALL_PREFIX的继承:所有子目录(包括_deps下的外部库)默认继承顶层的
CMAKE_INSTALL_PREFIX,所以如果外部库没有修改该变量,会将内容安装到顶层指定的目录(比如/usr/local)。
针对ARM模拟器schroot环境的注意事项
在schroot的ARM交叉编译环境中,确保:
- 顶层设置了正确的
CMAKE_SYSTEM_NAME和交叉编译工具链,避免外部库使用主机架构的配置 - FetchContent拉取的外部库如果有架构相关的选项,要显式设置为ARM架构对应的参数
内容的提问来源于stack exchange,提问作者TS_
相关产品推荐
相关产品推荐

