CMake中如何仅为指定库设置链接器标志?解决别名目标报错
问题描述
我有一个针对单个test.cpp文件的CMake文件如下:
if (TARGET SMS++::UCBlock AND TARGET SMS++::MILPSolver) add_executable(TUDPS_test test.cpp) target_link_libraries(TUDPS_test PRIVATE SMS++::MILPSolver SMS++::UCBlock) add_test(NAME TUDPS_test COMMAND TUDPS_test WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) endif ()
希望仅为SMS++::MILPSolver指定链接器标志:
"-Wl,--whole-archive,--allow-multiple-definition"
且该标志不作用于SMS++::UCBlock或未来添加的其他依赖项。尝试执行以下命令时:
target_link_options(SMS++::MILPSolver "-Wl,--whole-archive,--allow-multiple-definition")
出现错误:
CMake Error at tests/CMakeLists.txt:14 (target_link_options): target_link_options can not be used on an ALIAS target.
原因是MILPSolver的CMakeLists.txt中定义了别名:
# This alias is defined so that executables in this same project can use # the library with this notation. add_library(${modNamespace}::${modName} ALIAS ${modName})
请教应该在当前CMake文件还是子模块SMS++::MILPSolver的CMakeLists.txt中添加该链接器标志?
解决方案
有两种可行方案,按需选择:
1. 修改子模块SMS++::MILPSolver的CMakeLists.txt
若该链接器标志是MILPSolver库本身所需、对所有依赖它的目标都生效的设置,直接修改子模块代码:找到别名指向的原始库目标(即${modName}对应的实际库名),添加链接选项:
# 在子模块CMakeLists.txt的库定义部分添加 target_link_options(${modName} PRIVATE "-Wl,--whole-archive,--allow-multiple-definition")
这样所有依赖SMS++::MILPSolver的目标都会自动继承该设置,无需重复配置。
2. 在当前测试项目的CMake文件中配置
若该标志仅需对当前TUDPS_test生效,不影响其他依赖MILPSolver的项目,可通过链接组实现仅对目标库应用标志:
target_link_libraries(TUDPS_test PRIVATE SMS++::UCBlock # 用链接选项包裹MILPSolver,确保仅作用于该库 "$<$<LINK_LANGUAGE:CXX>:-Wl,--whole-archive>" SMS++::MILPSolver "$<$<LINK_LANGUAGE:CXX>:-Wl,--no-whole-archive>" "$<$<LINK_LANGUAGE:CXX>:-Wl,--allow-multiple-definition>" )
通过--whole-archive和--no-whole-archive包裹SMS++::MILPSolver,限定标志作用范围,同时添加--allow-multiple-definition选项。此方式无需修改子模块代码,仅对当前测试目标生效。
内容的提问来源于stack exchange,提问作者orthoressyco
相关产品推荐
相关产品推荐

