Инкрементное связывание с использованием gcc на Linux.Является ли это возможным? - PullRequest
16 голосов
/ 22 ноября 2010

При разработке проекта моей команды мы генерируем библиотеку Shared Object для нашего приложения из всех наших .o объектных файлов.Моя задача (надеюсь, она достаточно конкретная, но достаточно общая, чтобы быть полезной другим!) - связать только те объектные файлы, которые изменились с момента последнего создания исполняемого файла.Например, вот командная строка, которую я использую для создания .so:

g++34 -shared -rdynamic -m64 -Wl,-rpath,'$ORIGIN' MyObject1.o MyObject2.o MyObject3.o MyObject4.o   -o libMySharedLibrary.so

, которая работает как ожидалось!:) Моя цель - теперь иметь возможность связывать только измененные объектные файлы, чтобы ускорить параллельный процесс связывания.Примером команды может быть:

g++34 -shared -rdynamic -m64 -Wl,-rpath,'$ORIGIN' MyObject1.o MyObject3.o   -o libMySharedLibrary.so

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

В ходе моих исследований я обнаружил, что для компоновщика есть опция -i, которая совпадает с опцией -r, которая, по-видимому, просто объединяет все объектные файлы в один большой объектный файл.,К сожалению, не похоже, что это то, что я хочу.

Короче говоря, я хотел бы ссылаться только на измененные объектные файлы после начальной ссылки, что приведет к более быстрому процессу создания ссылок для будущих ссылок.Есть ли способ сделать это?

РЕДАКТИРОВАТЬ: пример того, что я пытался с -i/-r:

Пример команды: g++34 -Wl,-r -nostdlib -rdynamic -m64 -Wl,-rpath,'$ORIGIN' MyObject1.o MyObject2.o MyObject3.o MyObject4.o -o AllMyObjects.o

Мне пришлось добавить тег -nostdlib, чтобы остановитьон кричал мне о необходимости и удалил -shared, потому что общие объекты не разрешены с тегом -r.

Похоже, эта команда отбросит все мои файлы .o в один большой файл .o.Так что, если бы я мог просто обновить этот файл .o, добавив только измененные файлы .o, это было бы здорово.После того, как AllMyObjects.o был изначально создан, я попробовал эту команду: g++34 -Wl,-r -nostdlib -rdynamic -m64 -Wl,-rpath,'$ORIGIN' MyObject1.o MyObject3.o -o AllMyObjects.o, но она также создала бы намного меньшую (по размеру файла) AllMyObjects.o, поэтому я предполагаю, что она не может иметь всеобъектные файлы.Я чувствую, что это то, что я, вероятно, делаю небольшую ошибку.У кого-нибудь есть совет?Заранее спасибо.

Ответы [ 2 ]

6 голосов
/ 22 ноября 2010

Похоже, вы правы, что -shared и -r не работают вместе. Я скептически относился к вашей старой версии GCC, но даже в Ubuntu 10.10 я вижу то же самое:

$ ld -shared -r
/usr/bin/ld.bfd.real: -r and -shared may not be used together

К сожалению, это означает, что вы зашли в тупик, если вам абсолютно необходимы общие объекты. Линкер binutils просто не реализует его.

Если вам подойдут статические библиотеки, это просто архивы, которыми легко манипулировать с помощью утилиты ar.

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

4 голосов
/ 03 июля 2012

Вы можете получить то же поведение, что и после использования архивных / статических библиотек, но первоначальная ссылка все равно займет столько же времени.

Использование файла архива:

# Initially create the archive
ar r libmylib.a <all object files>

# Create your shared object (re-use this line after libmylib.a is updated)
g++ -shared -rdynamic -m64 -Wl,-rpath,'$ORIGIN' libmylib.a -o libmylib.so     

# Update the archive file
ar r libmylib.a updated1.o updated2.o

Как я уже сказал, для того, чтобы связать .so, все равно потребуется то же время, что и раньше.

...