我有一個二進制鏈接使用大量的對象文件與許多相互依賴性。每當我重新編譯其中一個,我需要鏈接整個二進制文件。是否可以執行差異鏈接?
鏈接器(特別是GCC或Clang的鏈接器)是否支持某種「差異鏈接」方法,其中有關於所有其他鏈接部分之間的內部關係的足夠信息,以便唯一需要的工作當單個部分重新編譯時是否與其他部分的關係+將它們放在二進制文件中?
注:我最感興趣的是C++,但我想這個問題至少推廣到C,可能還會推廣到其他編譯語言。
我有一個二進制鏈接使用大量的對象文件與許多相互依賴性。每當我重新編譯其中一個,我需要鏈接整個二進制文件。是否可以執行差異鏈接?
鏈接器(特別是GCC或Clang的鏈接器)是否支持某種「差異鏈接」方法,其中有關於所有其他鏈接部分之間的內部關係的足夠信息,以便唯一需要的工作當單個部分重新編譯時是否與其他部分的關係+將它們放在二進制文件中?
注:我最感興趣的是C++,但我想這個問題至少推廣到C,可能還會推廣到其他編譯語言。
在MSVC中,這被稱爲「增量鏈接」。有趣的是,我發現GCC可能會在某種程度上支持這一點,請嘗試對GCC使用「-Wl,-i
」或「-Wl,-r
」參數(實際上也應該由CLang支持,因爲這些「-Wl
」參數僅傳遞給ld
) 。
我從來沒有使用過它,但我做了下面的Makefile這項工作:
OBJS := a.o b.o c.o main.o
all: test_app
test_app: test_app.reloc
g++ -o [email protected] $^
# build a "relocatable" object for incremental linking (either -i or -r)
test_app.reloc: $(OBJS)
g++ -Wl,-i -nostdlib -nostartfiles -o [email protected] $^
$(OBJS): makefile
%.o: %.cpp
g++ -c -o [email protected] $<
這將構建應用程序,但我不完全知道它在內部做,如果真的在MSVC中完成類似「增量鏈接」的操作。
特別是,當使用「-Wl,-i」時,參數「-nostdlib」是必須的,這樣默認的libs將不會被傳遞給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 [email protected] $^
%.o: %.cpp
g++ -c -o [email protected] $<
%.ro: %.o
g++ -Wl,-i -nostdlib -nostartfiles -o [email protected] $<
也可以在一個可重新定位的對象文件中創建「組」,這樣在最後會有更少的對象文件(不知道是否會在結尾處帶來任何東西) 。
當我使用這些選項時,您可以再寫一些關於工作流程的內容嗎?例如假設我的源文件是'a.cpp','b.cpp'和'c.cpp',分開編譯,沒有include,我希望在重新編譯'a.cpp'時能夠做更少的鏈接工作。我最初應該運行什麼,我應該用新的'a.o'運行? – einpoklum
使用示例makefile更新 – axalis
關於第二個makefile:關鍵是gcc能夠輕鬆地將.ro文件合併爲一個可執行文件。好的,但是 - 爲什麼我們甚至需要.cpp - > .o步驟呢?爲什麼不立即做.cpp - > .ro? – einpoklum