【问题标题】:Incremental linking using gcc on linux. Is it possible?在 Linux 上使用 gcc 进行增量链接。可能吗?
【发布时间】:2011-05-14 01:25:53
【问题描述】:

按照我团队项目的开发方式,我们从所有.o 对象文件中为我们的应用程序生成一个共享对象库。我的任务(希望它足够具体,但也足够通用以对其他人有用!)是仅链接自上次创建可执行文件以来已更改的目标文件。例如,这是我用来构建 .so 的命令行:

g++34 -shared -rdynamic -m64 -Wl,-rpath,'$ORIGIN' MyObject1.o MyObject2.o MyObject3.o MyObject4.o   -o libMySharedLibrary.so

按预期工作! :) 我的目标是从现在开始只能链接更改的目标文件,以加快并发链接过程。一个示例命令是:

g++34 -shared -rdynamic -m64 -Wl,-rpath,'$ORIGIN' MyObject1.o MyObject3.o   -o libMySharedLibrary.so

这将使用较新的目标文件更新libMySharedLibrary.so,同时还保留libMySharedLibrary.so 中的旧目标文件。实际上,当我使用上面的命令生成libMySharedLibrary.so 时,文件大小比包含所有目标文件时的文件大小要小得多,所以我几乎可以肯定上面的命令没有做我想要的。

通过我的研究,我发现链接器有一个-i 选项,它与-r 选项相同,它似乎也只是将所有目标文件合并到一个大目标文件中。不幸的是,这似乎不是我想要的。

简而言之,我想在初始链接之后仅链接更改的目标文件,从而加快未来链接的链接过程。有没有办法做到这一点?

编辑:我用-i/-r 尝试过的一个例子:

示例命令:g++34 -Wl,-r -nostdlib -rdynamic -m64 -Wl,-rpath,'$ORIGIN' MyObject1.o MyObject2.o MyObject3.o MyObject4.o -o AllMyObjects.o

我不得不添加-nostdlib 标签来阻止它对我大喊大叫需要它,并删除了-shared,因为-r 标签不允许共享对象。

这个命令似乎将我所有的 .o 文件拼成一个大的 .o 文件。因此,如果我可以从现在开始仅使用已更改的 .o 文件更新该 .o 文件,那就太好了。在最初创建 AllMyObjects.o 之后,我尝试了这个命令:g++34 -Wl,-r -nostdlib -rdynamic -m64 -Wl,-rpath,'$ORIGIN' MyObject1.o MyObject3.o -o AllMyObjects.o,但它也会创建一个更小的(文件大小)AllMyObjects.o,所以我假设它不可能拥有所有目标文件。我觉得这是我可能会犯一个小错误的事情。有人有什么建议吗?提前致谢。

【问题讨论】:

  • 链接阶段真的在你的增量构建中占主导地位吗?如果没有,为什么要麻烦?
  • 你能告诉我们你对-i/-r的尝试吗?看起来它 您想要的选项,但我预计您会遇到符号冲突(考虑到没有“替换”选项)。
  • 链接阶段不是我构建中最耗时的部分。不过,这是我的组长交给我的任务。我们已经擅长仅编译已更改的内容。目前,我们只编译已更改的内容,同时每次都重新链接每个目标文件。
  • 更新了我迄今为止使用 -r 尝试过的内容。感谢您的帮助。
  • 这是一个没有-static的最小可运行示例和综合基准测试:stackoverflow.com/questions/29391965/…也许我们应该编辑这个问题标题说“共享对象”。

标签: linux gcc ld object-files incremental-linking


【解决方案1】:

关于-shared-r 不能一起工作,您似乎是对的。我对你的旧 GCC 版本持怀疑态度,但即使在 Ubuntu 10.10 上我也能看到同样的结果:

$ ld -shared -r
/usr/bin/ld.bfd.real: -r and -shared may not be used together

不幸的是,如果您绝对需要共享对象,这意味着您已经走到了死胡同。 binutils 链接器根本没有实现它。

如果您可以选择静态库,它们只是可以使用ar 实用程序轻松操作的存档。

否则,您将不得不查看不同的链接器或编译器套件。不过,我不能保证你会发现这个功能,它看起来很奇特。

【讨论】:

  • 好的。非常感谢您的快速回复。我一定会和我的团队负责人谈谈,看看是否可以选择使用静态库。同样在我的研究中,我发现了一个名为“gold”的替代链接器,它是由谷歌的 Ian Lance Taylor 开发的。它于 2008 年 3 月被添加到 binutils 中。我也可能会对此进行研究。我希望有一种方法可以使用默认链接器来做到这一点,但事实并非如此。再次感谢您的帮助!
  • 我似乎安装了gold,但gold -shared -r 给出了相同的结果。
  • 哈哈当然是这样。 :) 再次感谢您的帮助。
  • -r 并不像您认为的那样做。它告诉链接器创建一个目标文件而不是可执行文件或共享库。所以 ld 不支持 -r-shared 一起,因为它是零意义的。这意味着“创建一个作为常规对象文件的共享库”。
  • 如果这是真的,那么 GNU binutils ld 的联机帮助页并没有真正这样描述它。但看起来 OSX ld 的手册页更清晰:“-r 合并目标文件以生成另一个文件类型为 MH_OBJECT 的 mach-o 目标文件。”
【解决方案2】:

您可以在使用归档/静态库后获得您的行为,但初始链接仍将花费相同的时间。

使用存档文件:

# Initially create the archive
ar r libmylib.a <all object files>

# Create your shared object (re-use this line after libmylib.a is updated)
g++ -shared -rdynamic -m64 -Wl,-rpath,'$ORIGIN' libmylib.a -o libmylib.so     

# Update the archive file
ar r libmylib.a updated1.o updated2.o

正如我所说,实际链接 .so 所需的时间仍与以前相同。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 2011-06-08
  • 2013-03-01
  • 1970-01-01
  • 2011-07-05
  • 2016-03-04
  • 2018-05-22
相关资源
最近更新 更多