CMake同项目生成库的链接问题及项目结构优化咨询
问题描述
我是CMake新手,尝试链接同一项目中生成的库。简化后的项目结构如下:
MyProject ├── CMakeLists.txt ├── Library1 │ └── CMakeLists.txt │ └── include │ └── foo.h │ └── bar.h │ └── src │ └── foo.cpp │ └── bar.cpp ├── Library2 │ └── CMakeLists.txt │ └── include │ └── baz.h │ └── src │ └── baz.cpp
根目录CMakeLists.txt:
cmake_minimum_required (VERSION 3.17.0) project(MyProject) option(BUILD_SHARED_LIBS ON) add_subdirectory(Library1) add_subdirectory(Library2)
Library1/CMakeLists.txt:
project(Library1) add_library(library1 src/foo.cpp src/bar.cpp ) target_include_directories(library1 PUBLIC ${CMAKE_SOURCE_DIR}/Library1/include )
Library2/CMakeLists.txt:
project(Library2) add_library(library2 src/baz.cpp ) target_include_directories(library2 PUBLIC ${CMAKE_SOURCE_DIR}/Library1/include ${CMAKE_SOURCE_DIR}/Library2/include ) find_library(LIB1 library1 HINTS ${CMAKE_SOURCE_DIR}/Library1) target_link_libraries(library2 PUBLIC LIB1)
运行cmake MyProject时出现如下错误:
CMake Error: The following variables are used in this project, but they are set to NOTFOUND. LIB1 linked by target 'library2' in directory 'MyProject/Library2' --- Generating done CMake Generate step failed. Build files cannot be regenerated correctly.
请问如何在library1目标需经cmake --build MyProject生成的情况下,将library2链接到library1?当前项目结构是否合理?
解决方案
1. 修复库链接问题
无需使用find_library查找同一项目内的库,CMake处理add_subdirectory(Library1)后,已在全局作用域注册library1目标,直接在target_link_libraries中使用该目标名即可,同时可优化头文件路径写法:
修改Library2/CMakeLists.txt为:
project(Library2) add_library(library2 src/baz.cpp ) # 改用CMAKE_CURRENT_SOURCE_DIR避免硬编码全局路径,提升可移植性 target_include_directories(library2 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ) # 直接使用library1目标,CMake会自动处理依赖顺序、库路径及头文件继承 target_link_libraries(library2 PUBLIC library1)
关键说明:
- 同一项目内通过
add_subdirectory创建的库目标,CMake会自动跟踪依赖关系,无需手动查找库文件。 library1的PUBLIC包含目录会通过链接传递给library2,因此library2无需手动添加Library1/include路径。- 使用
CMAKE_CURRENT_SOURCE_DIR替代CMAKE_SOURCE_DIR硬编码,可避免项目目录结构调整后出现路径错误。
2. 项目结构合理性分析
当前项目结构符合多库项目的典型布局,是合理的:
- 每个库独立拥有
include和src目录,代码组织清晰,便于维护和复用。 - 根目录CMakeLists.txt统一管理子项目,符合CMake最佳实践。
可选优化点:
- 根目录的
option(BUILD_SHARED_LIBS ON)可全局控制所有add_library生成的库类型,设置合理。 - 子库中的
project指令可保留或移除,移除不影响功能,但保留可让子库的CMake环境更独立。
内容的提问来源于stack exchange,提问作者Dominic Sesto
相关产品推荐
相关产品推荐

