Инкрементное связывание с использованием GCC на Linux. Является ли это возможным?
-
27-09-2019 - |
Вопрос
То, как проект моей команды разработан, мы генерируем общую библиотеку объектов для нашего приложения со всех всех наших .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. Так что, если бы я мог просто обновить этот файл отсюда выходу с только измененными файлами, это было бы здорово. После первоначально созданы AllmyObjects.o, я попробовал эту команду: g++34 -Wl,-r -nostdlib -rdynamic -m64 -Wl,-rpath,'$ORIGIN' MyObject1.o MyObject3.o -o AllMyObjects.o
, но он также создал бы намного меньше (размер файла-размер) AllMyObjects.o
, Итак, я предполагаю, что он не может иметь все объектные файлы. Я чувствую, что это то, что я, вероятно, сделаю небольшую ошибку. У кого-нибудь есть какие-либо советы? Заранее спасибо.
Решение
Похоже, ты прав -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
Как это было раньше.