2010-11-22 9 views
13

Как разрабатывается проект моей команды, мы генерируем библиотеку общих объектов для нашего приложения из всех наших объектных файлов .o. Моя задача (надеюсь, она достаточно конкретна, но также достаточно общая, чтобы быть полезной для других!) Заключается в связывании только с объектными файлами, которые были изменены с момента создания исполняемого файла. Например, вот командная строка, которую я использую для сборки .so:Инкрементное связывание с использованием gcc on linux. Является ли это возможным?

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, которая, как представляется, просто объединяет все объектные файлы в один большой файл объекта. К сожалению, не кажется, что это то, что я хочу.

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

EDIT: пример того, что я пытался с -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, поэтому я предполагаю, что он не может иметь все объектные файлы. Я чувствую, что это то, что я, вероятно, совершу небольшую ошибку. У кого-нибудь есть совет? Заранее спасибо.

+0

Действительно ли фаза связи доминирует над вашими инкрементальными сборками? Если нет, зачем беспокоиться? – dmckee 2010-11-22 19:46:19

+0

Можете ли вы показать нам, что вы пробовали с помощью `-i` /` -r`? Похоже, что * это * вариант, который вы хотите, хотя я ожидаю, что вы столкнетесь с конфликтами символов (учитывая, что опция «заменить» отсутствует). – 2010-11-22 19:48:35

ответ

6

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

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

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

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

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

3

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

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

# 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, как это было раньше.