如何编写同父目录下多静态库的CMakeLists及头文件引用报错问题
解决方案
1. #1位置(StaticLib/CMakeLists.txt)编写代码
cmake_minimum_required(VERSION 3.16) # 可根据你使用的CMake版本调整最低要求 # 按依赖顺序添加子库,LIB1被LIB2依赖因此优先添加 add_subdirectory(LIB1) add_subdirectory(LIB2)
2. 头文件找不到问题修复
问题原因
你的报错是因为LIB2的公共头文件mysub.h直接引用了LIB1的头文件,属于公共接口依赖,但你之前的CMake配置没有声明该依赖的传递性,导致主程序编译时只能拿到LIB2的头文件目录,无法获取LIB1的头文件路径。
规范配置其余CMakeLists
按照以下写法调整其余CMake配置即可解决问题,同时符合CMake最佳实践:
LIB1/CMakeLists.txt
add_library(LIB1 STATIC myadd.cpp myadd.h) # PUBLIC属性表示该头目录同时对LIB1自身编译、以及依赖LIB1的目标生效 target_include_directories(LIB1 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
LIB2/CMakeLists.txt
add_library(LIB2 STATIC mysub.cpp mysub.h) # 声明LIB2自身的公共头目录 target_include_directories(LIB2 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) # PUBLIC链接LIB1:表示LIB2的公共接口依赖LIB1,所有依赖LIB2的目标会自动继承LIB1的头目录、链接配置 target_link_libraries(LIB2 PUBLIC LIB1)
顶层CMakeLists.txt(TopLevel目录下)
cmake_minimum_required(VERSION 3.16) project(MyDemoProject) # 添加静态库根目录 add_subdirectory(StaticLib) # 生成主程序可执行文件 add_executable(Main main.cpp) # 只需链接LIB2即可,LIB1的依赖会自动传递 target_link_libraries(Main PRIVATE LIB2)
额外注意事项
- 不要使用全局
include_directories配置头路径,基于目标的target_include_directories声明粒度更细,不会引入不必要的全局头目录污染 - 依赖声明的属性要按需选择:
- PUBLIC:目标的接口和实现都用到该依赖,依赖会向上传递
- PRIVATE:只有目标的实现用到该依赖,不会向上传递
- INTERFACE:只有目标的公共接口用到该依赖,目标自身编译不需要该依赖,会向上传递
- 双下划线开头的头文件保护符
__MY_SUB__HPP属于C++标准保留的实现相关标识符,用户代码使用存在冲突风险,建议修改为MY_SUB_HPP格式
内容的提问来源于stack exchange,提问作者Savner_Dig
相关产品推荐
相关产品推荐

