如何在链接CMake OBJECT库到SHARED库时传递其FILE_SET?
现有CMake配置如下:objlib是OBJECT库,shrlib是SHARED库且链接了objlib,但objlib的头文件不会随shrlib一同安装。手动收集objlib头文件并添加到shrlib的方式不够优雅,希望找到通过target_link_libraries自动关联的规范实现方法。
add_library(objlib OBJECT) target_sources(objlib PUBLIC FILE_SET HEADERS FILES foo.h bar.h PRIVATE foo.cpp bar.cpp ) add_library(shrlib SHARED) target_sources(shrlib PUBLIC FILE_SET HEADERS FILES baz.h PRIVATE baz.cpp ) target_link_libraries(shrlib PRIVATE objlib) install(TARGETS shrlib FILE_SET HEADERS DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mysubdir )
规范实现方案
方法1:使用CMake 3.23+文件集引用(推荐)
借助CMake的生成器表达式直接引用objlib的HEADERS文件集,让shrlib自动继承其头文件,无需手动收集路径:
add_library(objlib OBJECT) target_sources(objlib PUBLIC FILE_SET HEADERS FILES foo.h bar.h PRIVATE foo.cpp bar.cpp ) # 配置objlib的INTERFACE包含目录,确保构建和安装阶段都能找到头文件 target_include_directories(objlib INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/mysubdir> ) add_library(shrlib SHARED) target_sources(shrlib PUBLIC FILE_SET HEADERS # 直接引用objlib的HEADERS文件集 FILES $<TARGET_FILE_SET:objlib,HEADERS> baz.h PRIVATE baz.cpp ) target_link_libraries(shrlib PRIVATE objlib) install(TARGETS shrlib FILE_SET HEADERS DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mysubdir )
关键说明:
$<TARGET_FILE_SET:objlib,HEADERS>:CMake 3.23+支持的生成器表达式,可自动获取objlib的HEADERS文件集中的所有文件,避免手动维护路径。target_include_directories的INTERFACE配置:确保依赖shrlib的代码在构建和安装后都能正确找到头文件。- 安装
shrlib时,objlib的头文件会被自动包含到指定目录。
方法2:兼容CMake 3.23以下版本
如果需要适配旧版本CMake,可通过get_target_property获取objlib的INTERFACE属性来关联头文件:
add_library(objlib OBJECT) target_sources(objlib PUBLIC FILE_SET HEADERS FILES foo.h bar.h PRIVATE foo.cpp bar.cpp ) target_include_directories(objlib INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/mysubdir> ) add_library(shrlib SHARED) # 获取objlib的INTERFACE头文件和包含目录 get_target_property(OBJLIB_INTERFACE_SOURCES objlib INTERFACE_SOURCES) get_target_property(OBJLIB_INTERFACE_INCLUDE_DIRS objlib INTERFACE_INCLUDE_DIRECTORIES) target_sources(shrlib PUBLIC FILE_SET HEADERS BASE_DIRS ${OBJLIB_INTERFACE_INCLUDE_DIRS} FILES ${OBJLIB_INTERFACE_SOURCES} baz.h PRIVATE baz.cpp ) target_link_libraries(shrlib PRIVATE objlib) install(TARGETS shrlib FILE_SET HEADERS DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mysubdir )
内容的提问来源于stack exchange,提问作者flyx
相关产品推荐
相关产品推荐

