CMake头文件仅包装库包含问题:C接口头无法被CPP头引用
)
set(
API_C_Headers
test.h
...
)
set (
API_C_Private_Headers
...
)
set(
API_C_Sources
Sources/test.cpp
)
add_library(
API_C SHARED
${API_C_Headers}
${API_C_Private_Headers}
${API_C_Sources}
)
set_target_properties(
API_C PROPERTIES VERSION ${PROJECT_VERSION}
)
target_link_libraries(
API_C
${API_C_DYNAMIC_LIBRARIES}
)
foreach( DYNAMIC_LIBRARY ${API_C_DYNAMIC_LIBRARIES} )
add_custom_command( TARGET API_C POST_BUILD COMMAND "${CMAKE_COMMAND}" -E copy_if_different "$<TARGET_FILE:${DYNAMIC_LIBRARY}>" $<TARGET_FILE_DIR:API_C> )
add_custom_command( TARGET API_C POST_BUILD COMMAND "${CMAKE_COMMAND}" -E copy_if_different "$<TARGET_LINKER_FILE:${DYNAMIC_LIBRARY}>" $<TARGET_FILE_DIR:API_C> )
endforeach()
set_property( TARGET API_C PROPERTY FOLDER "API" )
source_group(
"Private Header Files" FILES ${API_C_Private_Headers}
)
### API/CPP/CMakeList.txt ```cmake cmake_minimum_required( VERSION 3.4 ) project(API VERSION 0.0.1) set( API_CPP_Headers test.hpp ... ) add_library( API_CPP INTERFACE ${API_CPP_Headers} ) target_include_directories(API_CPP INTERFACE . ) target_link_libraries( API_CPP INTERFACE API_C ) set_target_properties( API_CPP PROPERTIES VERSION ${PROJECT_VERSION} ) set_property( TARGET API_CPP PROPERTY FOLDER "API" )
API/Example/CMakeList.txt
cmake_minimum_required( VERSION 3.4 ) project(API VERSION 0.0.1) set( API_EXAMPLE_Headers ) set ( API_EXAMPLE_Private_Headers ) set( API_EXAMPLE_Sources main.cpp ) add_library( API_EXAMPLE SHARED ${API_EXAMPLE_Headers} ${API_EXAMPLE_Private_Headers} ${API_EXAMPLE_Sources} ) set_target_properties( API_EXAMPLE PROPERTIES VERSION ${PROJECT_VERSION} ) target_link_libraries( API_EXAMPLE INTERFACE API_CPP ) set_property( TARGET API_EXAMPLE PROPERTY FOLDER "API" ) source_group( "Private Header Files" FILES ${API_EXAMPLE_Private_Headers} )
解决步骤
1. 给C核心库公开头文件路径
API_C库没有对外暴露自己的头文件目录,导致依赖它的API_CPP无法自动获取包含路径。修改API/C/CMakeList.txt,在add_library之后添加:
# 公开当前目录作为头文件路径,让依赖该库的目标能直接引用头文件 target_include_directories(API_C PUBLIC .)
2. 调整C++包装库的包含路径或头文件引用方式
有两种可选方式:
方式一:修改头文件引用
在API/CPP/test.hpp中直接引用C头文件:#include "test.h"因为
API_C已经公开了自己的目录,API_CPP依赖API_C后会自动继承这个包含路径。方式二:调整C++库的包含路径
如果想保留#include "API/C/test.h"的写法,修改API/CPP/CMakeList.txt中的target_include_directories:# 将API根目录加入包含路径,这样就能通过相对路径找到C接口的头文件 target_include_directories(API_CPP INTERFACE ../)
3. 修正示例项目的链接语法
API_EXAMPLE是共享库目标,target_link_libraries中不应使用INTERFACE关键字,修改API/Example/CMakeList.txt:
target_link_libraries(API_EXAMPLE PRIVATE API_CPP)
验证
完成上述修改后,重新生成CMake项目并编译,API/CPP/test.hpp就能正确包含C核心头文件,示例项目也能正常编译运行。
内容的提问来源于stack exchange,提问作者Sam Coutteau

