我有一个项目,它曾经是一组巨大的源文件,所有这些源文件都经过编译然后链接为一个可执行文件。作为使项目更加模块化的第一步,我将构建分解为几个更小的块,并使它们成为静态库。有一个层次结构,因此Exe1将链接到静态库Lib2A和Lib2B. Lib2A将取决于 static Lib3A、lib3B、lib3C等。此处的数字显示了它们在层次结构中的层。
问题是我需要--whole-archive在链接时使用,否则找不到底层库中的某些符号。
当我添加以下链接时Exe1:
target_link_libraries(Exe1 -Wl,--whole-archive Lib2A Lib2B -Wl,--no-whole-archive)
Run Code Online (Sandbox Code Playgroud)
我最终得到了一个实际的链接阶段命令,例如:
g++ -o Exe1 -Wl,--whole-archive libLib2A.a libLib2B.a -Wl,--no-whole-archive libLib3A.a libLib3B.a libLib3C.a
Run Code Online (Sandbox Code Playgroud)
不可避免地,某些第 3 层静态库中的符号会丢失,并且会出现丢失符号错误。
我期望因为Lib2A有Lib3*库作为依赖项,所以它们也会--whole-archive在链接器命令的“内部”部分,但它们出现在外部。
我尝试了许多不同的组合(例如将--whole-archive东西放在较低层),但还没有遇到使用 CMake 的方法。我究竟做错了什么?
谢谢
Ric*_*ehe 15
对于 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
)
Run Code Online (Sandbox Code Playgroud)
现在,当我通过链接到这个源组合库来创建可执行文件或共享库时,我得到了 --whole-archive 和 --no-whole-archive 作为整个静态库集的书挡,这些静态库是'来源'。偶然发现这种技术花了很长时间,所以我正在分享它。
如果您需要使用链接器选项--whole-archive,那么您肯定应该使用对象库:
# Lib2A/CMakeLists.txt
add_library(Lib2A OBJECT ${Lib2A_SRC})
Run Code Online (Sandbox Code Playgroud)
# Lib2B/CMakeLists.txt
add_library(Lib2B OBJECT ${Lib2B_SRC})
Run Code Online (Sandbox Code Playgroud)
它是可移植的并且不需要使用链接器选项--whole-archive。