大型多模块项目如何基于CMake配置内部target依赖关系
CMake多依赖项目配置方案
1. 根目录CMakeLists.txt配置
首先根目录的CMakeLists.txt按依赖顺序添加子目录,保证被依赖的库先被定义:
# 根目录CMakeLists.txt cmake_minimum_required(VERSION 3.16) project(my_project) # 先按依赖顺序添加库目录:lib1 > lib2 > lib3 add_subdirectory(libs/lib1) add_subdirectory(libs/lib2) add_subdirectory(libs/lib3) # 最后添加应用目录 add_subdirectory(apps/app1) add_subdirectory(apps/app2)
2. 单库CMakeLists.txt编写规范
核心是用target_link_libraries配合PUBLIC/PRIVATE/INTERFACE关键字自动处理依赖传递,不需要手动管理构建顺序或者头文件路径。
lib1示例
# libs/lib1/CMakeLists.txt add_library(lib1 src/file1.c src/file2.c ) # PUBLIC属性的头文件路径会自动传递给依赖lib1的目标 target_include_directories(lib1 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src )
lib2示例(依赖lib1)
# libs/lib2/CMakeLists.txt add_library(lib2 src/file1.c src/file2.c ) target_include_directories(lib2 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src ) # PUBLIC声明依赖lib1,lib1的头文件、链接参数会自动传递给依赖lib2的目标 target_link_libraries(lib2 PUBLIC lib1 )
lib3示例(依赖lib2,自动继承lib1的依赖)
# libs/lib3/CMakeLists.txt add_library(lib3 src/file1.c src/file2.c ) target_include_directories(lib3 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src ) # 只需直接声明依赖lib2,无需额外处理lib1的传递依赖 target_link_libraries(lib3 PUBLIC lib2 )
3. 应用目录CMakeLists.txt示例
# apps/app1/CMakeLists.txt add_executable(app1 src/main.c ) # 按需链接依赖的库,传递依赖会自动处理 target_link_libraries(app1 PRIVATE lib3 )
补充问题解答
- 首先你提到的
add_dependencies(lib1 lib2)语法写错了,add_dependencies的第一个参数是需要等待依赖构建完成的目标,如果你要声明lib2依赖lib1,正确写法是add_dependencies(lib2 lib1)。 - 这种写法完全不需要,只要你用了
target_link_libraries声明库依赖,CMake会自动处理构建顺序,不需要额外加add_dependencies。 - 即使你非要用
add_dependencies,也不能在add_subdirectory之前声明,此时两个target还没有被add_library定义,CMake会直接报错找不到目标,必须要等两个target都定义完成后再写这条语句。
内容的提问来源于stack exchange,提问作者Pavlo
相关产品推荐
相关产品推荐

