如何在C++/CMake项目中使用绝对路径头文件包含
C++/CMake模板头文件包含问题解决方案
项目结构
. ├── CMakeLists.txt ├── README.md └── src ├── CMakeLists.txt └── geometry ├── CMakeLists.txt └── line ├── CMakeLists.txt ├── line.cpp └── line.h
各层级CMakeLists.txt内容
./CMakeLists.txt
cmake_minimum_required(VERSION 3.20.0) project(cmake_template VERSION 0.0.1 LANGUAGES CXX) add_subdirectory(src)
./src/CMakeLists.txt
add_subdirectory(geometry)
./src/geometry/CMakeLists.txt
add_subdirectory(line)
./src/geometry/line/CMakeLists.txt
add_library(line line.cpp) target_include_directories(line PUBLIC .)
代码实现
line.h
#include <string> class Line{ private: std::string name; public: Line(std::string); virtual void display(); };
line.cpp
#include "src/geometry/line/line.h" #include <iostream> Line::Line(std::string name):name(name){} void Line::display(){ std::cout << "A line with name " << this->name << "\n"; }
编译报错
执行命令 cmake -S . -B build && cmake --build build/ 时出现如下错误:
[1/2] Building CXX object src/geometry/line/CMakeFiles/line.dir/line.cpp.o FAILED: src/geometry/line/CMakeFiles/line.dir/line.cpp.o /usr/bin/clang++ -I../src/geometry/line/. -g -MD -MT src/geometry/line/CMakeFiles/line.dir/line.cpp.o -MF src/geometry/line/CMakeFiles/line.dir/line.cpp.o.d -o src/geometry/line/CMakeFiles/line.dir/line.cpp.o -c ../src/geometry/line/line.cpp ../src/geometry/line/line.cpp:1:10: fatal error: 'src/geometry/line/line.h' file not found #include "src/geometry/line/line.h" ^~~~~~~~~~~~~~~~~~~~~~~~~~ 1 error generated. ninja: build stopped: subcommand failed.
问题
- 不修改上层CMakeLists.txt,仅修改
./src/geometry/line/CMakeLists.txt,如何实现使用绝对路径#include "src/geometry/line/line.h"包含头文件? - 如何使用
<>形式包含该绝对路径(即#include <src/geometry/line/line.h>)?
解决方案
问题1:使用绝对路径""包含头文件
当前target_include_directories仅添加了当前目录(.,即src/geometry/line),编译器无法从该目录找到src/geometry/line/line.h的层级路径。只需将项目根目录(即顶层CMakeLists.txt所在目录)加入目标的包含路径即可。
修改./src/geometry/line/CMakeLists.txt为:
add_library(line line.cpp) # 将项目根目录加入包含路径,允许从根目录开始引用头文件 target_include_directories(line PUBLIC ${CMAKE_SOURCE_DIR})
CMAKE_SOURCE_DIR是CMake内置变量,指向项目顶层CMake配置文件所在的目录,无需手动指定路径,兼容性更强。修改后编译器会自动添加-I项目根目录参数,#include "src/geometry/line/line.h"即可正确找到文件。
问题2:使用<>形式包含绝对路径
C++中<>通常用于标准库或系统头文件,但只要将项目根目录加入编译器的包含路径,同样可以用<>引用项目内的头文件,符合《Canonical CPP Project Structure》的规范。
- 同样修改
./src/geometry/line/CMakeLists.txt为上述内容:
add_library(line line.cpp) target_include_directories(line PUBLIC ${CMAKE_SOURCE_DIR})
- 将
line.cpp中的包含语句修改为:
#include <src/geometry/line/line.h>
编译时编译器会在包含路径中搜索src/geometry/line/line.h,即可正常找到文件完成编译。这种方式能明确头文件在项目中的位置,避免同名文件冲突,提升代码可读性。
内容的提问来源于stack exchange,提问作者Der Fänger im Roggen
相关产品推荐
相关产品推荐

