CMake安装目标:共享库无法包含接口库公共头文件的解决方法
解决CMake中依赖接口库的共享库安装目标配置问题
问题根源
接口库的target_sources(PUBLIC)不会自动将头文件注入到依赖它的共享库的INTERFACE_SOURCES中。因为接口库本身没有编译输出,PUBLIC关键字对接口库的源文件设置无效,必须用INTERFACE关键字来声明对外暴露的源文件;另外,target_include_directories仅负责编译时的头文件路径指引,和安装时的文件复制是两个独立环节。
解决方案
1. 正确配置接口库与共享库
接口库需用INTERFACE关键字声明头文件和包含目录,确保依赖它的共享库能继承这些属性:
# 定义接口库 add_library(MyInterface INTERFACE) # 设置头文件的编译期和安装期路径 target_include_directories(MyInterface INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/interface> $<INSTALL_INTERFACE:include> ) # 显式声明接口库对外暴露的头文件(可选,若需通过INTERFACE_SOURCES传递) target_sources(MyInterface INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include/interface/interface.h ) # 定义共享库并依赖接口库 add_library(MyShared SHARED src/shared.cpp) # 用PUBLIC确保接口库的属性传递给共享库的依赖方 target_link_libraries(MyShared PUBLIC MyInterface) # 设置共享库自身的头文件路径 target_include_directories(MyShared PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/shared> $<INSTALL_INTERFACE:include> )
2. 简化的安装配置
不需要依赖INTERFACE_SOURCES来收集头文件,直接通过install(DIRECTORY)复制所有公共头文件,同时安装目标库:
# 安装共享库和接口库,导出目标配置 install(TARGETS MyShared MyInterface EXPORT MyLibraryTargets LIBRARY DESTINATION lib INCLUDES DESTINATION include ) # 直接将所有公共头文件安装到include目录 install(DIRECTORY include/interface include/shared DESTINATION include ) # 导出CMake配置文件,方便其他项目通过find_package引用 install(EXPORT MyLibraryTargets FILE MyLibraryTargets.cmake DESTINATION lib/cmake/MyLibrary )
关于target_include_directories与target_sources的疑惑
target_include_directories仅负责告诉编译器在哪里查找头文件,属于编译期的路径配置;而install操作是部署环节,需要明确指定哪些文件要被复制到安装目录,两者职责完全独立。
INTERFACE_SOURCES的主要作用是传递那些需要被依赖目标编译时使用的源文件(比如生成的动态头文件),对于普通的静态公共头文件,直接用install(DIRECTORY)复制是更直观简便的方式,无需依赖INTERFACE_SOURCES。
内容的提问来源于stack exchange,提问作者Frank
相关产品推荐
相关产品推荐

