如何在CMake中构建可互相寻址的带命名空间子项目
报错原因
find_package在子项目的配置阶段就会执行,此时总项目的libsConfig.cmake还没有完成安装,你放在构建目录下的配置文件没有被加入CMake的搜索路径,因此无法被找到。
纯CMake实现方案(无需外部bash/python脚本)
完全可以通过原生CMake实现你要的一次性构建、顺序编译安装的需求,以下是两种适配不同场景的方案:
方案1:构建树导出(适配Boost/Poco式组件调用)
这是主流组件化库采用的标准实现,无需提前安装依赖即可让子项目识别find_package调用:
- 总项目根CMakeLists.txt开头添加配置,提前把构建目录加入搜索路径
# 总项目根CMakeLists.txt cmake_minimum_required(VERSION 3.16) project(libs) # 提前声明组件列表 set(LIBS_SUPPORTED_COMPONENTS lib1 lib2) # 把构建目录加入配置文件搜索路径 set(libs_DIR ${CMAKE_BINARY_DIR} CACHE PATH "libs配置文件路径") list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR})
- 编写
libsConfig.cmake.in模板放在总项目根目录,用于生成组件式配置文件
@PACKAGE_INIT@ # 检查请求的组件是否存在 foreach(comp ${libs_FIND_COMPONENTS}) if(NOT ${comp} IN_LIST LIBS_SUPPORTED_COMPONENTS) message(FATAL_ERROR "不支持的组件:${comp}") endif() # 引入对应组件的目标导出文件 include(${CMAKE_CURRENT_LIST_DIR}/libs-${comp}Targets.cmake) endforeach()
- 在总项目CMakeLists.txt中生成配置文件到构建目录
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/libsConfig.cmake.in ${CMAKE_BINARY_DIR}/libsConfig.cmake @ONLY )
- 每个子项目添加别名和构建树导出
# lib1的CMakeLists.txt add_library(lib1 src/lib1.cpp) # 构建阶段直接提供别名,和安装后的命名空间保持一致 add_library(libs::lib1 ALIAS lib1) # 导出构建阶段的目标文件到构建目录 export(TARGETS lib1 NAMESPACE libs:: FILE ${CMAKE_BINARY_DIR}/libs-lib1Targets.cmake )
配置完成后,lib2中的find_package(libs COMPONENTS lib1 REQUIRED)调用可以直接在构建阶段正常识别,不需要提前安装lib1。
方案2:分阶段顺序构建(适配先安装lib1再编译lib2的需求)
如果你的流程要求必须走安装逻辑,可以用CMake内置的ExternalProject模块实现顺序依赖:
# 总项目CMakeLists.txt include(ExternalProject) # 定义lib1构建规则,指定安装路径 ExternalProject_Add(lib1 SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib1 CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/install INSTALL_COMMAND make install ) # 定义lib2构建规则,指定依赖lib1,同时传入lib1的安装路径 ExternalProject_Add(lib2 SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib2 CMAKE_ARGS -DCMAKE_PREFIX_PATH=${CMAKE_BINARY_DIR}/install DEPENDS lib1 )
执行总项目构建时,CMake会自动先编译安装lib1,再编译lib2,完全符合你要的顺序要求。
多开发者场景适配
- 有权限访问lib1源码的开发者:直接拉取总项目,用上述两种方案均可一次性完成构建
- 无权限访问lib1源码的开发者:仅拉取lib2项目,提前把预编译好的libs安装路径添加到
CMAKE_PREFIX_PATH即可正常调用find_package
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

