c++ - 将 --whole-archive 链接器选项与 CMake 和具有其他库依赖项的库一起使用
问题描述
我有一个项目,它曾经是一组巨大的源文件,所有文件都被编译然后链接为一个可执行文件。作为使项目更加模块化的第一步,我将构建分解为几个更小的块并使其成为静态库。有一个层次结构,因此Exe1
将链接到静态库Lib2A
和Lib2B
. Lib2A
将取决于 static Lib3A
、lib3B
、lib3C
等。这里的数字显示了它们在层次结构中的层。
问题是我需要--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 层静态库中的符号会丢失,并且我会出现丢失符号错误。
我希望因为Lib2A
有Lib3*
库作为依赖项,所以它们也会--whole-archive
在链接器命令的“内部”部分,但它们会出现在外部。
我尝试了许多不同的组合(例如,将这些--whole-archive
东西放在较低层),但还没有遇到使用 CMake 的方法。我究竟做错了什么?
谢谢
解决方案
对于 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 作为整个静态库集的书挡,这些静态库是链接依赖项'资源'。偶然发现这种技术需要很长时间,所以我正在分享它。
推荐阅读
- python - 我想用 django 在 htm 文件中导入 python 代码
- android - Android 将数据从 IntentService 发送到绑定的 Activity
- r - 尝试在 R 中实现套索时出现“参数 Y 缺失”?
- php - MySQL & Eloquent 查询
- apache - NiFi GenerateTableFetch 不存储每个 database.name 的状态
- sql-server - 将记录的数据库列中的数据分解为多条记录
- python - 如何使用 sklearn.countvectorizer?
- c# - 在 ASP.NET Core 中使用 ADO.NET 作为数据访问层
- python - 如何在 Google Dataflow 上安装 python 包并将其导入我的管道?
- java - 可在任何 Android 设备上工作的坐标