我有一个项目,曾经是一个巨大的源文件集,所有得到编译,然后链接为一个可执行文件。作为使项目更加模块化的第一步,我将构建分解为几个较小的块,并使它们成为静态库。有一个层次结构,所以Exe1
将链接到静态库Lib2A
和Lib2B
。Lib2A
将依赖于静态Lib3A
、lib3B
、lib3C
等。这里的数字显示它们在层次结构中的层。
问题是我需要在链接时使用--whole-archive
,否则找不到底层库中的一些符号。
当我添加下面的链接Exe1
:
target_link_libraries(Exe1 -Wl,--whole-archive Lib2A Lib2B -Wl,--no-whole-archive)
字符串
最后,我得到了一个实际的link stage命令,如下所示:
g++ -o Exe1 -Wl,--whole-archive libLib2A.a libLib2B.a -Wl,--no-whole-archive libLib3A.a libLib3B.a libLib3C.a
型
不可避免地,一些第3层静态库中的符号丢失了,我得到了丢失符号的错误。
因为Lib2A
有Lib3*
库作为依赖项,所以我希望它们也在链接器命令的--whole-archive
部分的“内部”,但它们显示在外部。
我尝试了很多不同的组合(例如:将--whole-archive
放在较低层),但还没有遇到使用CMake的方法。我做错了什么?
谢啦,谢啦
5条答案
按热度按时间vh0rcniy1#
对于3.12和更新版本的CMake,我将使用对象库。
我为更早的版本找到的解决方法是创建一个中间静态库,它使用一些属性魔术将所有链接依赖项放置在--whole-archive部分中。对我来说,顶级静态库被称为“源代码”。它本身实际上什么都不包含,但它依赖于一堆其他静态库。我创建了'source-combined'如下:
字符串
现在,当我通过链接到这个结合了源代码的库来创建一个可执行文件或共享库时,我会得到--whole-archive和--no-whole-archive作为围绕整个静态库集的书挡,这些静态库是'source'的链接依赖项。我花了很长时间才偶然发现这个技术,所以我分享它。
6vl6ewon2#
以下为我工作。考虑两个库:
我们需要my_clib的整个存档,以及my_platform到它的链接。
字符串
czq61nw13#
如果你需要使用链接器选项
--whole-archive
,那么你应该使用对象库:个字符
它是可移植的,不需要使用链接器选项
--whole-archive
。64jmpszr4#
作为上述答案的另一种选择,我需要得到一些快速和肮脏的东西,以查看添加整个归档目标标志(或将代码库转换为对象库...)的努力是否是正确的解决方案。通过遵循默认链接命令的CMake源代码,我修改了我的项目命令:
字符串
它工作了一个治疗!虽然不是最好的解决方案,但至少会很快得到一些结果。
nom7f22z5#
CMake 3.24添加了一个官方的方法来使用
LINK_LIBRARY:WHOLE_ARCHIVE
生成器表达式来完成此操作:字符串
也就是说,使用对象库通常是一种更简单的解决方案。这样,您所链接的库中的已编译目标文件列表就可以在最终的链接器命令中按原样使用,而不是首先创建静态库文件。