使用CMake构建C++项目时如何配置头文件路径引入common目录头文件
CMake 跨目录头文件找不到问题修复方案
两次尝试的核心错误
- 第一次属于命令用法写错:
target_include_directories只接收头文件目录路径作为参数,你把定义的CMake目标Common直接当路径传进去,CMake只会把它识别成名为Common的普通文件夹去查找,根本不会关联你之前定义的INTERFACE库,头文件搜索路径完全没加上。 - 第二次逻辑方向正确,但踩了相对路径解析的坑:CMake中直接写裸相对路径时,不会自动锚定当前CMakeLists.txt所在目录,尤其是嵌套子目录、处理INTERFACE目标传递属性的场景,最终拼出来传给编译器的头文件路径和实际的
src/common/include不匹配,自然找不到文件。
正确配置(推荐模块化方案)
这种方案把common抽成独立的头文件库,后续其他模块依赖common、common目录新增源码时都更好维护。
1. 顶层CMakeLists.txt修改
核心是用${CMAKE_CURRENT_SOURCE_DIR}变量锚定当前文件所在的绝对路径,彻底避免相对路径解析错误:
cmake_minimum_required(VERSION 3.0.0) project(MyProject VERSION 1.0.0) # 定义common模块的INTERFACE头文件库 add_library(Common INTERFACE) # 明确指定头文件目录的绝对路径,锚定到顶层src目录 target_include_directories(Common INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/common/include) add_subdirectory(main_lib) add_executable(myproj main.cpp) # mainpub已经通过PUBLIC链接Common,依赖会自动传递,这里不需要额外链接Common target_link_libraries(myproj PUBLIC mainpub)
2. main_lib目录下CMakeLists.txt修改
注意链接CMake目标必须用target_link_libraries命令,不能塞到头文件目录配置里:
add_library(mainpub src/one/one.cpp) target_include_directories(mainpub PUBLIC include) # PUBLIC属性会把Common的头文件搜索路径自动传递给所有依赖mainpub的目标(比如最终的myproj可执行文件) target_link_libraries(mainpub PUBLIC Common)
简易方案(不需要抽Common模块时用)
如果不想单独定义Common目标,直接在main_lib的配置里加头文件路径即可,同样要做路径锚定:
add_library(mainpub src/one/one.cpp) target_include_directories(mainpub PUBLIC include # 从当前main_lib目录往上一级回到src根目录,再进入common/include ${CMAKE_CURRENT_SOURCE_DIR}/../common/include )
顶层CMakeLists保持最初的原始配置不用改动即可。
额外排查项
如果改完配置还是报同样的错,先核对目录名:
你的a_h_file.hpp完整路径必须是src/common/include/common/data_type/a_h_file.hpp,也就是common/include下的子文件夹名要和include代码里写的common/data_type完全一致,注意data_type的下划线不要漏写、不要拼错(比如不要写成无下划线的datatype)。
内容的提问来源于stack exchange,提问作者KansaiRobot
相关产品推荐
相关产品推荐

