如何将CMake目标作为链接库添加并排除其传递链接库?
CMake链接目标时排除传递依赖的方法
针对你遇到的问题,CMake提供了几种可行的方法来链接目标但排除其传递依赖,以下是实用方案:
方案一:直接链接目标的对象文件(适用于所有CMake版本)
通过$<TARGET_OBJECTS:target>获取原目标的对象文件集合,直接链接到测试目标,这种方式不会引入任何传递依赖。但需要手动同步原目标的编译定义和包含目录,因为对象文件不携带这些信息:
# 假设原业务目标为 legacy_lib,测试目标为 legacy_test target_link_libraries(legacy_test PRIVATE $<TARGET_OBJECTS:legacy_lib>) # 同步原目标的编译定义 target_compile_definitions(legacy_test PRIVATE $<TARGET_PROPERTY:legacy_lib, COMPILE_DEFINITIONS>) # 同步原目标的包含目录 target_include_directories(legacy_test PRIVATE $<TARGET_PROPERTY:legacy_lib, INCLUDE_DIRECTORIES>)
方案二:使用INTERFACE目标包装必要部分(灵活可控)
创建一个INTERFACE目标,仅导入原目标的编译环境(包含目录、编译定义等),再单独链接原目标的库文件,完全隔离传递依赖:
# 创建INTERFACE目标 add_library(legacy_lib_interface INTERFACE) # 复制原目标的编译定义到INTERFACE目标 target_compile_definitions(legacy_lib_interface INTERFACE $<TARGET_PROPERTY:legacy_lib, COMPILE_DEFINITIONS>) # 复制原目标的包含目录到INTERFACE目标 target_include_directories(legacy_lib_interface INTERFACE $<TARGET_PROPERTY:legacy_lib, INCLUDE_DIRECTORIES>) # 测试目标链接INTERFACE目标和原目标的库文件 target_link_libraries(legacy_test PRIVATE legacy_lib_interface $<TARGET_FILE:legacy_lib>)
方案三:使用LINK_ONLY关键字(CMake 3.12+)
CMake 3.12及以上版本支持LINK_ONLY修饰符,直接在target_link_libraries中使用即可排除传递依赖,这是最简洁的方式:
target_link_libraries(legacy_test PRIVATE legacy_lib LINK_ONLY)
注意事项
- 若原目标是静态库,以上三种方案均能有效隔离传递依赖;若为动态库,
LINK_ONLY同样适用,但需注意动态库自身的运行时依赖是否需要桩化。 - 手动同步编译选项时,需区分原目标中
INTERFACE和PRIVATE属性的差异,确保测试目标的编译环境与原目标一致。
内容的提问来源于stack exchange,提问作者RAM
相关产品推荐
相关产品推荐

