У меня есть двоичный файл, который связан с использованием большого количества объектных файлов с множеством взаимозависимостей. Всякий раз, когда я перекомпилирую хотя бы один из них, мне нужно связать весь двоичный файл.
Поддерживают ли линкеры (в частности, GCC или Clang) какой-либо метод «дифференциального линкинга», в котором хранится достаточно информации о взаимосвязях между всеми другими связанными частями, так что единственная работа, которую необходимо выполнить, когда перекомпилируется ли одна часть — это ее отношения с другими частями + объединение их в двоичную форму?
Примечание: меня больше всего интересует C ++, но я предполагаю, что этот вопрос обобщает, по крайней мере, C и, возможно, другие скомпилированные языки.
В MSVC это называется «инкрементное связывание». Интересно, что то, что я обнаружил, что GCC может поддерживать это в некоторой степени, попробуйте использовать «-Wl,-i
» или же «-Wl,-r
msgstr «параметры для GCC (должны также поддерживаться CLang, так как они»-Wl
«параметры просто передаются ld
).
Я никогда не использовал его раньше, но я сделал эту работу со следующим make-файлом:
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: 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 $@ $<
Также возможно создать «группы» объектных файлов, которые будут сгруппированы в один перемещаемый объект, так что их будет меньше в конце (хотя не уверен, что это приведет к чему-либо в конце).
Других решений пока нет …