CMake中include目录继承问题:依赖项目需重复指定?
首先明确:你遇到的情况完全正常,include_directories() 本身就不会把包含路径传递给依赖当前库的外部项目。这是由它的作用域和CMake的目标依赖机制决定的。
为什么include_directories()不会被依赖项目继承?
include_directories() 是一个全局范围的指令——它只会影响当前CMakeLists.txt文件、以及该文件后续添加的子目录中的所有目标。它并不会将这些包含路径关联到你构建的库目标上,所以当另一个项目(比如A)依赖你的库L时,CMake没有理由自动把L里用include_directories()设置的路径传递给A。
简单说:include_directories() 是给"当前CMake上下文"用的,不是给"依赖该上下文生成的目标"用的。
正确的做法:使用target_include_directories()
CMake推荐用目标导向的指令来管理包含路径,也就是target_include_directories()。它可以把包含路径和具体的库目标绑定,并且通过PUBLIC/INTERFACE/PRIVATE关键字精确控制哪些路径需要传递给依赖者:
PRIVATE:只有库L自己编译时需要,不需要对外暴露的路径(比如L内部的私有头文件)INTERFACE:库L自己不需要,但依赖L的项目(比如A)需要的路径PUBLIC:库L自己需要,同时依赖L的项目也需要的路径
针对你的场景,修改L的CMakeLists.txt:
# 假设你构建的库目标名为libL add_library(libL src/main.cpp src/subL/subL.cpp # 其他源文件... ) # 用target_include_directories替代include_directories target_include_directories(libL PUBLIC # L的公共头文件目录,A需要引用的L的头文件在这里 ${CMAKE_CURRENT_SOURCE_DIR}/headers # subL的头文件目录,因为A需要直接引用,所以设为PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/subL/headers PRIVATE # 如果L有自己私有的头文件目录,在这里设置,不会传递给A ${CMAKE_CURRENT_SOURCE_DIR}/src/private_headers )
这样,当你在A的CMakeLists.txt中链接libL时:
add_executable(appA src/main.cpp # 其他源文件... ) # 链接libL,CMake会自动把libL的PUBLIC/INTERFACE包含路径添加到appA的编译选项中 target_link_libraries(appA PRIVATE libL)
A的代码就可以直接引用subL的头文件,无需再手动添加include_directories()。
额外提示
include_directories() 是CMake比较旧的用法,虽然还能用,但容易导致全局路径污染(比如多个项目设置的路径冲突)。优先使用target_include_directories()这种目标绑定的方式,代码更清晰,依赖关系也更明确。
内容的提问来源于stack exchange,提问作者arennuit

