CMake配置问询:构建依赖自有开发中库的独立应用方案
解决方案:CMake配置满足同级库与应用独立构建需求
一、目录结构规划
先明确符合你需求的目录层级:
Programs/ ├── Lib/ │ ├── CMakeLists.txt │ ├── include/ │ │ └── lib/ │ │ └── core.h │ └── src/ │ └── core.cpp ├── AppA/ │ ├── CMakeLists.txt │ └── src/ │ └── main.cpp └── AppB/ ├── CMakeLists.txt └── src/ └── main.cpp
二、各模块CMakeLists.txt配置
1. Lib/CMakeLists.txt
负责库的编译配置,兼容静态/共享两种模式:
cmake_minimum_required(VERSION 3.16) project(MyLib VERSION 0.1.0 LANGUAGES CXX) # 基础编译标准 set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 收集库源码 file(GLOB_RECURSE LIB_SOURCES src/*.cpp) # 生成库(通过BUILD_SHARED_LIBS变量控制静态/共享) add_library(MyLib ${LIB_SOURCES}) # 导出头文件路径,让依赖应用能找到 target_include_directories(MyLib PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include> ) # 共享库专属配置:设置版本信息(可选) if(BUILD_SHARED_LIBS) set_target_properties(MyLib PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR} ) endif()
2. AppA/CMakeLists.txt(AppB配置完全类似)
核心是引入同级Lib并建立依赖,确保单独构建时只处理Lib和自身:
cmake_minimum_required(VERSION 3.16) project(AppA LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 引入同级Lib目录,指定独立的构建目录(避免污染Lib源码目录) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../Lib ${CMAKE_CURRENT_BINARY_DIR}/Lib_build) # 收集应用源码 file(GLOB_RECURSE APP_SOURCES src/*.cpp) # 生成可执行文件 add_executable(AppA ${APP_SOURCES}) # 链接MyLib库 target_link_libraries(AppA PRIVATE MyLib) # 共享库专属配置:设置运行时库路径(确保可执行文件能找到共享库) if(BUILD_SHARED_LIBS) set_target_properties(AppA PROPERTIES INSTALL_RPATH "$ORIGIN/../lib" BUILD_WITH_INSTALL_RPATH ON ) endif()
三、核心问题解答
1. 能否用add_subdirectory处理同级目录?
完全可以。上述配置中,AppA通过add_subdirectory的两个参数实现:第一个参数指定Lib的源码路径(相对AppA的路径),第二个参数指定Lib的构建目录(放在AppA的构建目录下的子文件夹中)。这种方式既避免了在Lib源码目录生成构建文件,又能让CMake自动检测Lib的更新——当你单独构建AppA时,若Lib的源码或构建产物过期,CMake会优先构建Lib,再编译AppA,完全符合你的需求。
2. 静态库与共享库的配置差异
- 静态库:默认模式(无需设置
BUILD_SHARED_LIBS),库会被直接嵌入可执行文件,构建后的AppA可独立运行,无需额外处理运行时路径。需注意:若Lib依赖其他系统库,要确保链接阶段包含这些依赖。 - 共享库:需通过cmake命令行指定
-DBUILD_SHARED_LIBS=ON启用。此时会生成单独的.so/.dll文件,必须配置INSTALL_RPATH确保可执行文件运行时能定位到库。另外,共享库可设置版本信息,方便后续迭代更新。
四、单独构建示例(以AppA为例)
# 进入AppA目录,创建独立构建文件夹 cd Programs/AppA mkdir build && cd build # 生成构建文件(默认静态库,如需共享库加-DBUILD_SHARED_LIBS=ON) cmake .. # 开始构建,CMake会自动处理Lib的更新与编译 make -j4
构建完成后,Lib的产物存放在AppA/build/Lib_build,AppA的可执行文件在AppA/build,与AppB的构建完全隔离。
内容的提问来源于stack exchange,提问作者Joymaker
相关产品推荐
相关产品推荐

