c++ - 是否可以执行差异链接?

标签 c++ gcc linker clang differential-execution

我有一个二进制文件,它使用大量具有许多相互依赖性的目标文件进行链接。每当我重新编译其中一个时,我都需要链接整个二进制文件。

链接器(特别是 GCC 或 Clang 的链接器)是否支持某种“差异链接”方法,其中保留了所有其他链接部分之间相互关系的足够信息,因此唯一需要的工作是重新编译单个部分时完成的是它与其他部分的关系+将它们放在二进制文件中吗?

注意:我最感兴趣的是 C++,但我想这个问题至少可以推广到 C,也可能推广到其他编译语言。

最佳答案

在 MSVC 中,这称为“增量链接”。有趣的是,我发现 GCC 可能在某种程度上支持这一点,请尝试使用“-Wl,-i”或“-Wl,-r”参数来GCC(实际上 CLang 应该也支持,因为这些“-Wl”参数只是传递给 ld)。


我以前从未使用过它,但我使用以下 makefile 完成了这项工作:

OBJS := a.o b.o c.o main.o

all:    test_app

test_app:   test_app.reloc
    g++ -o $@ $^

# build a "relocatable" object for incremental linking (either -i or -r)
test_app.reloc: $(OBJS)
    g++ -Wl,-i -nostdlib -nostartfiles -o $@ $^

$(OBJS):    makefile

%.o:    %.cpp
    g++ -c -o $@ $<

这构建了应用程序,但我不完全确定它在内部做了什么,如果它真的做了类似于在 MSVC 中完成的“增量链接”。

特别是,参数“-nostdlib”在使用“-Wl,-i”时是必需的,这样默认的库就不会被传递给 ld(然后找不到它们 - 没有它我有错误“/usr/bin/ld:找不到 -lgcc_s”)。


实际上可能工作得更好的另一个版本(不确定,这需要在更大的应用程序上进行测试,以查看单个对象更新的链接时间是否有一些增益):

OBJS := a.ro b.ro c.ro main.ro

all:    test_app

test_app:   $(OBJS)
    g++ -o $@ $^

%.o:    %.cpp
    g++ -c -o $@ $<

%.ro:   %.o
    g++ -Wl,-i -nostdlib -nostartfiles -o $@ $<
  • 基本上为每个对象创建可重定位文件(这可能是将 obj 文件链接到可执行文件的重要部分),然后只更新必要的可重定位文件。对于使用 relocatables 将所有内容链接在一起的最后链接步骤(但之前已经完成了部分链接)。

也可以创建目标文件的“组”,将其分组到一个可重定位文件中,这样最后的目标文件就会更少(虽然不确定最后是否会带来任何东西)。

关于c++ - 是否可以执行差异链接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42245133/

相关文章:

c - gcc:为什么在更改 .c 文件后重建时链接失败,但在最初构建时却没有?

c++ - 严格的别名似乎不一致

c - "Variably modified ' 变量名 ' at file scope"大小在宏中定义

c++ - 在 Makefile 中链接时定义变量的问题

c - 如何使用 ld 检测链接中的歧义

c++ - 尝试读取数组C++时For循环崩溃程序

c++ - 关闭后如何销毁子窗口?

c++ - MFC:如何在单击按钮时最小化窗口?

c++ - 将数字与 NaN 进行比较的结果是什么?

c++ - 将静态库链接到共享库并隐藏导出的符号