【问题标题】:Looking for a Static Link Order tool on Linux [closed]在 Linux 上寻找静态链接顺序工具 [关闭]
【发布时间】:2011-09-20 00:26:14
【问题描述】:

是否有任何不错的工具可以在 Linux 下使用 g++ 确定最佳静态链接顺序?我熟悉一般问题,包括(如有必要)使用对单个库或 --start-group 和 --end-group 的重复引用来解决循环依赖关系,但如果可能的话,我想要什么,是一个工具,它将获取一堆 .a 文件并为它们输出一个好的静态链接顺序,如有必要重复库,同时将重复保持在最低限度。

背景:我正在开发一个包含大约 800K 行继承的 c++ 代码的项目,并试图将其重构为更小、更易于管理的块。一些现有的文件是巨大的单体——今天我一直在努力处理一个定义了 113 个类和结构的 34K 行 .h 文件。许多类几乎完全内联定义在 .h 文件中。当我把它分成更小的块,并将一些实现代码迁移到 .cpp 文件中时,Linux 上所需的链接顺序不断变化。这可能是因为每个包含 .h 文件的库都用于编译它自己需要的任何类的实现,现在它们必须链接到单个库文件中的通用实现。从长远来看,我们可能会将一些类重新组织到不同的库中,并打破一些依赖链,但现在依赖关系非常复杂,我正试图将可能改变行为的代码扰动降到最低。我不希望每次更改时都必须手动找出正确的链接顺序。有什么建议吗?

【问题讨论】:

    标签: c++ linker g++


    【解决方案1】:

    我不知道有一个副手,但你可以自己实现一个。只需使用 nm 从每个静态库中获取符号列表,使用它来构建依赖关系图,然后对图执行拓扑排序以获得正确的链接顺序。

    或者,使用部分链接 (ld -r) 而不是静态库。由于这会输出一个合并的 .o 文件,因此您的最终链接可以按任何顺序声明库,并且它们都将正确链接。缺点是链接器将无法丢弃未使用的源文件,因为它们在使用数据可用之前已经链接到整体文件中(您可以通过在编译期间传递 -ffunction-sections -fdata-sections 并在最终链接上传递 -Wl,--gc-sections 来解决此问题,尽管这可能会影响编译所需的时间)

    【讨论】:

    • 我已经想到了,但问题比这更棘手。如果您需要等待所有打电话给您的人,然后才能被包括在内,则拓扑排序会起作用。但这在这里不是必需的:如果库 A 有一个符号 a 需要来自库 B 的符号 b,那么只要在链接顺序中存在更早的人,B 就可以(实际上,可能有必要)在 A 之前也需要 b 的订单。我可能会设计出一个合理的算法,但这需要时间,同时还有一些工作需要完成。所以我更喜欢已经存在的经过实战考验的解决方案。
    • @dewtell:在某些情况下这种方法可能行不通,但您确定您的代码库是其中之一吗?
    • @Andrew - 非常确定。基于 .h 文件包含,在很多情况下,lib1 中的 file1a 引用 lib2 中 file2a 中定义的符号,而 lib2 中的 file2b 引用 lib1 中 file1b 中定义的符号。
    【解决方案2】:

    您可以使用共享库而不是静态库并使用-fPIC 选项进行编译。

    【讨论】:

    • 这在短期内对我们来说不是一个好主意,因为它会从根本上改变我们发布和安装程序的方式,并引入一个全新的错误来源。从长远来看,这是我们可以考虑的,但可能不仅仅是为了解决这个特定问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-30
    • 1970-01-01
    • 2010-11-23
    • 1970-01-01
    • 1970-01-01
    • 2013-09-11
    相关资源
    最近更新 更多