如何通过CMake强制使用#include <mylib/header.h>形式引入头文件?
我正在开发一个包含多个库的项目,部分库文件的名称和其他库或STL文件名称相同/相似,后续容易引发混淆。虽然直接用#include<file.h>引入自定义库头文件很方便,但我希望重构CMake代码,强制要求使用#include<mylib/file.h>的形式引入自定义库头文件。
当前项目结构如下:
CMakeLists.txt | |- mylib | |- CMakeLists.txt | |- include | |- header1.h | |- header2.h | |- test |- CMakeLists.txt |- mylib |- header1_test.cpp |- header2_test.cpp
现有三个CMakeLists.txt内容:
主CMakeLists.txt
# main CMakeLists.txt # ... requirements, etc. ... # ... fetch and include GoogleTest ... add_subdirectory(mylib) add_subdirectory(test)
mylib/CMakeLists.txt
# mylib/CMakeLists.txt add_library(mylib INTERFACE) target_include_directories(mylib INTERFACE include/)
test/CMakeLists.txt
# test/CMakeLists.txt # link directories link_directories(../mylib) # test executable add_executable(header1_test mylib/header1_test.cpp) add_executable(header2_test mylib/header2_test.cpp) # link libraries target_link_libraries(header1_test PRIVATE mylib PRIVATE gtest_main) target_link_libraries(header2_test PRIVATE mylib PRIVATE gtest_main) # discover tests gtest_discover_tests(header1_test) gtest_discover_tests(header2_test)
要实现强制用#include<mylib/file.h>引入头文件,需要调整项目目录结构和CMake配置,具体步骤如下:
1. 调整mylib的头文件目录结构
把include目录下的头文件迁移到include/mylib子目录中,更新后的目录结构:
mylib/ |- include |- mylib |- header1.h |- header2.h
这一步让头文件的物理路径匹配#include<mylib/file.h>的逻辑路径,是实现需求的核心基础。
2. 修改mylib的CMakeLists.txt
将头文件搜索路径指向include目录(而非原来的include/,用绝对路径更可靠),确保依赖mylib的目标能通过mylib/file.h的路径找到头文件。
修改后的mylib/CMakeLists.txt:
add_library(mylib INTERFACE) # 用CMAKE_CURRENT_SOURCE_DIR确保路径可靠性 target_include_directories(mylib INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include")
3. 更新测试代码的头文件引入方式
在header1_test.cpp和header2_test.cpp中,将原来的#include<header1.h>替换为#include<mylib/header1.h>,示例:
// header1_test.cpp #include <mylib/header1.h> #include <gtest/gtest.h> TEST(Header1Test, BasicTest) { // 测试逻辑 }
4. 优化test目录的CMake配置(可选)
原test目录中的link_directories(../mylib)属于冗余配置,因为target_link_libraries会自动处理依赖路径,直接删除该行即可。
优化后的test/CMakeLists.txt:
# test/CMakeLists.txt # test executable add_executable(header1_test mylib/header1_test.cpp) add_executable(header2_test mylib/header2_test.cpp) # link libraries target_link_libraries(header1_test PRIVATE mylib gtest_main) target_link_libraries(header2_test PRIVATE mylib gtest_main) # discover tests gtest_discover_tests(header1_test) gtest_discover_tests(header2_test)
验证效果
完成上述修改后,如果尝试用#include<header1.h>的旧方式引入头文件,编译器会直接报错,从而达到强制使用#include<mylib/file.h>形式的目的。
内容的提问来源于stack exchange,提问作者fakl

