在Linux上使用gcc进行增量链接,这是否可行?

21

我们团队的项目开发方式是,从所有的 .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,同时保留其中较旧的目标文件。我发现链接器有一个 -i 选项,它与 -r 选项相同,似乎可以将所有目标文件组合成一个大目标文件。但不幸的是,这并不是我想要的。简而言之,我想在初始链接后仅链接更改过的目标文件,以便将来的链接过程更快。有没有办法实现这一点?

链接阶段是否真的主导了您的增量构建?如果没有,为什么要费心呢? - dmckee --- ex-moderator kitten
你能展示一下你尝试使用-i/-r的代码吗?看起来这正是你想要的选项,但我预计你会遇到符号冲突(考虑到没有“替换”选项)。 - Stéphan Kochen
链接阶段不是我构建过程中耗时最长的部分。然而,这是我的团队领导给我的任务。我们已经很擅长只编译发生变化的内容。目前,我们只编译发生变化的内容,但每次都重新链接每个对象文件。 - Raphael Raven
更新了使用-r的尝试。感谢您的帮助。 - Raphael Raven
这里是一个最小可运行示例和合成基准,不需要使用“-static”:https://dev59.com/-F0b5IYBdhLWcg3wQPbw#53959624 或许我们应该编辑这个问题的标题,改为“共享对象”。 - Ciro Santilli OurBigBook.com
2个回答

7

看起来你是对于 -shared-r 不能同时使用的看法是正确的。我对于你提到的旧版GCC有些怀疑,但是即使在Ubuntu10.10上,我也发现了相同的问题:

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

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

如果静态库是一个选项,它们只是可以使用ar工具轻松操作的存档文件。

否则,你将不得不寻找不同的链接器或编译套件。我不能保证你会找到这个功能,尽管它似乎很少见。


好的。非常感谢您的快速回复。我一定会与我的团队领导交流,看看是否可以使用静态库。在我的研究中,我发现了一种名为“gold”的替代链接器,由Google的Ian Lance Taylor开发。它于2008年3月添加到binutils中。我也可能会研究一下这个。我希望有一种方法可以使用默认的链接器来完成这个任务,但似乎不是这样的情况。再次感谢您的帮助! - Raphael Raven
4
我似乎已经安装了 gold,但是执行 gold -shared -r 命令结果没有变化。 - Stéphan Kochen
哈哈,当然会这样。:) 再次感谢你的帮助。 - Raphael Raven
1
“-r”并不是你想象中的那样。它告诉链接器创建一个目标文件,而不是可执行文件或共享库。因此,ld不支持同时使用“-r”和“-shared”,因为这毫无意义。这意味着“创建一个既是共享库又是普通目标文件的文件”。 - Maarten
如果是这样的话,那么GNU binutils ld 的手册并没有真正描述它。但是看起来OSX ld 的手册更清晰:“-r将目标文件合并以生成另一个带有文件类型MH_OBJECT的mach-o对象文件。” - Stéphan Kochen

5
你可以使用存档/静态库来达到你想要的行为,但初始链接仍将花费相同的时间。
使用存档文件:
# 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 文件所需的时间仍然与以前相同。

1
更好的是,您可以使用ar T薄型存档来避免将所有对象复制到存档中的膨胀:https://dev59.com/n3I95IYBdhLWcg3wyBCc#27676016 这就是Linux内核开始做的事情:https://unix.stackexchange.com/questions/5518/what-is-the-difference-between-the-following-kernel-makefile-terms-vmlinux-vml/482978#482978 - Ciro Santilli OurBigBook.com

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接