在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 $@ $^
test_app.reloc: $(OBJS)
g++ -Wl,-i -nostdlib -nostartfiles -o $@ $^
$(OBJS): makefile
%.o: %.cpp
g++ -c -o $@ $<
这将构建应用程序,但我不完全确定它在内部执行的操作,是否像MSVC中执行的“增量链接”一样。
特别是,在使用“-Wl,-i”时,“-nostdlib”参数是必需的,以便默认库不会传递给ld(然后无法找到它们-没有它,我遇到了错误“/usr/bin/ld: cannot find -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文件链接到可执行文件的重要部分),然后仅更新必要的可重定位文件。对于最终的链接步骤,使用可重定位文件将所有内容链接在一起(但已经完成了部分链接)。
还可以创建对象文件组的“组”,以便将它们分组为单个可重定位文件,这样最后就会少一些文件(不确定这是否会在最后带来任何好处)。
a.cpp
、b.cpp
和c.cpp
,分别单独编译,没有包含文件,并且我希望在重新编译a.cpp
时能够减少链接工作量。最初应该运行什么,然后用新的a.o
运行什么? - einpoklum