Инкрементное связывание с использованием gcc на linux. Является ли это возможным?

При разработке проекта моей команды мы генерируем библиотеку общих объектов для нашего приложения из всех наших .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 ответа

Решение

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

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

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

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

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

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

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

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

Другие вопросы по тегам