为何链接库的包含目录未正确传递?CMake配置问题排查
问题描述
静态库依赖链为 myTest -> myFoo -> myBar,在myTest的头文件test_file.h中写入#include "myBar/my_bar_class.h"时,编译报错找不到该文件。打印myTest的INTERFACE_INCLUDE_DIRECTORIES属性,仅显示自身和myFoo的包含目录,未包含myBar的路径。以下是各库的CMake配置:
myTest库的CMakeLists.txt
cmake_minimum_required(VERSION 3.23) add_library(myTest STATIC) target_sources(myTest INTERFACE FILE_SET HEADERS BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/myTest/test_file.h ) target_link_libraries( PUBLIC myFoo ) ...
myFoo库的CMakeLists.txt
cmake_minimum_required(VERSION 3.23) add_library(myFoo STATIC) target_sources(myFoo INTERFACE FILE_SET HEADERS BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/myFoo/a.h ) target_link_libraries( PUBLIC myBar ) target_include_directories(myFoo INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/myFoo> $<INSTALL_INTERFACE:include/myFoo> ) ...
myBar库的CMakeLists.txt
cmake_minimum_required(VERSION 3.23) add_library(myBar STATIC) target_sources(myBar INTERFACE FILE_SET HEADERS BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/myBar/my_bar_class.h ) target_include_directories(myFoo INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/myBar> $<INSTALL_INTERFACE:include/myBar> ) ...
问题修复
- 核心错误:myBar的CMakeLists.txt中,
target_include_directories的目标写错了——本该设置myBar的包含目录,却误写为myFoo。这导致myBar自身没有配置INTERFACE包含目录,依赖链无法将myBar的头文件路径传递给上层的myTest。 - 具体修正步骤:
- 修正myBar的
target_include_directories目标,并调整路径根目录:
这里将根目录设为target_include_directories(myBar INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include> )include而非include/myBar,是因为你的头文件包含语句是#include "myBar/my_bar_class.h",需要让编译器找到include作为根路径,才能正确解析子目录下的头文件。 - 同步调整myFoo的
target_include_directories逻辑,保持一致性:target_include_directories(myFoo INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include> )
- 修正myBar的
- 逻辑说明:CMake的
PUBLIC/INTERFACE依赖传递是基于目标自身属性的,只有myBar正确配置了自己的INTERFACE包含目录,myFoo通过PUBLIC链接myBar时,才能把myBar的INTERFACE属性传递给myTest,最终让myTest找到myBar的头文件。
内容的提问来源于stack exchange,提问作者Sean M.
相关产品推荐
相关产品推荐

