如何让CMake不安装引入的包/子模块?这是标准方案吗?
问题解答
是的,EXCLUDE_FROM_ALL是解决这类第三方依赖打包冗余问题的标准且推荐的方案之一。
原因分析
默认情况下,通过add_subdirectory或FetchContent引入的第三方子项目,其所有构建目标(包括静态库)都会被加入到CMake的默认ALL构建目标中。当你执行install或CPack打包时,若你的可执行文件链接了这些静态库,CMake会自动将这些依赖库的安装规则纳入执行流程,最终导致大量静态库被打包进产物,造成体积冗余。
EXCLUDE_FROM_ALL的作用
添加该参数后,第三方子项目的目标不会被自动加入到默认的ALL目标集合中:
- 只有当你的项目明确依赖的目标才会被触发构建,避免无意义的编译
- 第三方子项目自带的
install规则不会被自动执行,从根源上阻止CPack将这些依赖库打包进最终产物
具体使用示例
- 针对
add_subdirectory集成Azure IoT C SDK
add_subdirectory(azure-iot-sdk-c EXCLUDE_FROM_ALL)
- 针对
FetchContent集成fmt库
FetchContent_Declare( fmt GIT_REPOSITORY https://github.com/fmtlib/fmt.git GIT_TAG 9.1.0 ) FetchContent_GetProperties(fmt) if(NOT fmt_POPULATED) FetchContent_Populate(fmt) # 在add_subdirectory时传入EXCLUDE_FROM_ALL add_subdirectory(${fmt_SOURCE_DIR} ${fmt_BINARY_DIR} EXCLUDE_FROM_ALL) endif() # 链接fmt库到你的可执行文件 target_link_libraries(your_executable PRIVATE fmt::fmt)
注意事项
- 确保你的可执行文件通过
target_link_libraries明确声明了对第三方库目标的依赖,否则EXCLUDE_FROM_ALL会导致依赖库不被构建,最终链接失败 - 若后续需要分发第三方依赖库(比如动态库),可移除
EXCLUDE_FROM_ALL,或通过install(TARGETS)单独指定需要安装的依赖目标
内容的提问来源于stack exchange,提问作者Alessandro Bertulli
相关产品推荐
相关产品推荐

