我有一个可执行文件,它由几个目标文件构建,并与多个静态和共享库链接。我想为其中一个链接库指定-Wl,-whole-archive链接器选项。
例如,从此命令:
/usr/bin/c++ _objectFiles_ -o _myExec_ _someCommonOptions_ _myLibraries_ -Wl,-rpath _path to libs_
我想得到这个命令:
/usr/bin/c++ _objectFiles_ -o _myExec_ _someCommonOptions_ _allOtherLibs_ \
-Wl,-whole-archive _one particular lib_ -Wl,-no_whole-archive -Wl,-rpath _path to libs_
我能使用cmake实现这一目标吗?据我所知,当我添加类似
的内容时set_target_properties(myExec PROPERTIES LINK_FLAGS "-Wl,-whole-archive")
然后为所有链接库设置-whole-archive
选项,这绝对不是我想要的。
谢谢。
答案 0 :(得分:33)
这个帖子Linking static libraries into shared libs?有一个方法。
SET (MYLIB -Wl,--whole-archive my_particular_lib -Wl,--no-whole-archive)
....
TARGET_LINK_LIBRARIES(yourtarget ${normalstuff} ${MYLIB} ${othernormalstuff})
如果库名称与库名称相匹配 项目中的另一个目标a 将自动添加依赖项 在构建系统中确保 链接的库是最新的 在目标链接之前。物品名称 以' - '开头,但不是'-l'或 '-framework'被视为链接器 标志。
所以-Wl
选项不应该被CMake干扰/接触。
答案 1 :(得分:3)
TARGET_LINK_LIBRARIES(myTarget -Wl,--whole-archive myLib -Wl,--no-whole-archive)
只需替换myTarget
和myLib
Oryginal帖子:https://stackoverflow.com/a/37564428/1052261
答案 2 :(得分:0)
正如@RichvonLehe 指出的那样,如果您有多个库,建议的解决方案可能不起作用。 CMake 将 -Wl,--whole-archive my_particular_lib -Wl,--no-whole-archive
视为 3 个独立的库,并且不保证排序。在我的特殊情况下,我发现我最终在 -Wl,--whole-archive
和 -Wl,--no-whole-archive
标志之间包含了一堆其他档案,从而导致重复的符号定义。
不幸的是,您也可能无法将所有内容都用引号括起来。如果您执行 -Wl,--whole-archive,$<TARGET_FILE:my_particular_lib>,--no-whole-archive
或类似操作,您会发现 CMAKE 不再将 my_particular_lib 视为符号目标,而是将整个字符串视为链接标志。如果 my_particular_lib 碰巧有其他 CMake 副作用,例如 target_include_directories() 或在我的情况下,PUBLIC HEADERS,它们将不再包含在内。
最终我不得不求助于间接层。诀窍是使用 INTERFACE 库作为顶层的东西。使用一个库 (my_lib_part_1) 来悬挂我需要由其他目标传递继承的所有属性,例如 PUBLIC HEADERS,以及另一个库 (my_lib_part_2) 没有任何需要继承的属性,只提供 .a 存档。
即使是这样也是缺乏的。 CMake 很难拥有空的 STATIC 库,并且不允许您将 PUBLIC HEADERS 放在 INTERFACE 库上(还没有?)。
add_library(my_lib INTERFACE)
add_library(my_lib_part_1 STATIC
foo.cpp
)
add_library(my_lib_part_2 STATIC
bar.cpp
)
target_link_libraries(my_lib
INTERFACE
my_lib_part_1
# It is very important this is in quotes so CMake treats it as a single flag
"-Wl,--whole-archive $<TARGET_FILE:my_lib_part_2> -Wl,--no-whole-archive"
)
set_target_properties(my_lib_part_1 PROPERTIES
PUBLIC_HEADER "my_public_header.hpp"
)
set_target_properties(my_lib_part_2 PROPERTIES
POSITION_INDEPENDENT_CODE ON
)