Можно ли выполнить дифференциальную связь?

У меня есть двоичный файл, который связан с использованием большого количества объектных файлов с множеством взаимозависимостей. Всякий раз, когда я перекомпилирую хотя бы один из них, мне нужно связать весь двоичный файл.

Поддерживают ли линкеры (в частности, GCC или Clang) какой-либо метод «дифференциального линкинга», в котором хранится достаточно информации о взаимосвязях между всеми другими связанными частями, так что единственная работа, которую необходимо выполнить, когда перекомпилируется ли одна часть — это ее отношения с другими частями + объединение их в двоичную форму?

Примечание: меня больше всего интересует C ++, но я предполагаю, что этот вопрос обобщает, по крайней мере, C и, возможно, другие скомпилированные языки.

2

Решение

В MSVC это называется «инкрементное связывание». Интересно, что то, что я обнаружил, что GCC может поддерживать это в некоторой степени, попробуйте использовать «-Wl,-i» или же «-Wl,-rmsgstr «параметры для 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 $@ $<
  • По сути, создание перемещаемого файла для каждого объекта (который может быть, возможно, значительной частью связывания obj-файлов с исполняемым файлом), а затем просто обновление необходимых перемещаемых объектов. Для последнего шага связи используйте переместимые элементы, чтобы связать все вместе (но часть связи уже была сделана ранее).

Также возможно создать «группы» объектных файлов, которые будут сгруппированы в один перемещаемый объект, так что их будет меньше в конце (хотя не уверен, что это приведет к чему-либо в конце).

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]