You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在链接CMake OBJECT库到SHARED库时传递其FILE_SET?

问题:OBJECT库头文件随SHARED库安装的规范实现方式

现有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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 10:25:17