首页 > 解决方案 > 将 --whole-archive 链接器选项与 CMake 和具有其他库依赖项的库一起使用

问题描述

我有一个项目,它曾经是一组巨大的源文件,所有文件都被编译然后链接为一个可执行文件。作为使项目更加模块化的第一步,我将构建分解为几个更小的块并使其成为静态库。有一个层次结构,因此Exe1将链接到静态库Lib2ALib2B. Lib2A将取决于 static Lib3Alib3Blib3C等。这里的数字显示了它们在层次结构中的层。

问题是我需要--whole-archive在链接时使用,否则找不到来自底层库的某些符号。

当我添加以下链接时Exe1

target_link_libraries(Exe1 -Wl,--whole-archive Lib2A Lib2B -Wl,--no-whole-archive)

我最终得到了一个实际的链接阶段命令,例如:

g++ -o Exe1 -Wl,--whole-archive libLib2A.a libLib2B.a -Wl,--no-whole-archive libLib3A.a libLib3B.a libLib3C.a

不可避免地,一些第 3 层静态库中的符号会丢失,并且我会出现丢失符号错误。

我希望因为Lib2ALib3*库作为依赖项,所以它们也会--whole-archive在链接器命令的“内部”部分,但它们会出现在外部。

我尝试了许多不同的组合(例如,将这些--whole-archive东西放在较低层),但还没有遇到使用 CMake 的方法。我究竟做错了什么?

谢谢

标签: c++cmakeg++

解决方案


对于 3.12 和更新版本的 CMake,我会使用对象库。

我为早于该版本的版本找到的解决方法是创建一个中间静态库,该库使用一些属性魔法将所有链接依赖项放在 --whole-archive 部分中。对我来说,顶级静态库被称为“源”。它本身实际上不包含任何内容,但对一堆其他静态库具有链接依赖关系。我创建了“源组合”,如下所示:

add_library(source-combined STATIC "")
set_target_properties(source-combined PROPERTIES LINKER_LANGUAGE CXX)

target_link_libraries(source-combined PUBLIC
  -Wl,--whole-archive
  $<TARGET_PROPERTY:source,INTERFACE_LINK_LIBRARIES>
  -Wl,--no-whole-archive
)

现在,当我通过链接这个源组合库来创建可执行文件或共享库时,我得到了 --whole-archive 和 --no-whole-archive 作为整个静态库集的书挡,这些静态库是链接依赖项'资源'。偶然发现这种技术需要很长时间,所以我正在分享它。


推荐阅读