Включение статически всей библиотеки вместо частей библиотеки при компоновке / компиляции - PullRequest
1 голос
/ 25 февраля 2020

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

Ответы [ 2 ]

6 голосов
/ 25 февраля 2020

Существует опция компоновщика GNU --whole-archive, которая делает именно это:

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

Подробнее см. man ld.

Когда вы связываете с gcc или clang, передайте этот параметр компоновщику как -Wl,--whole-archive.

0 голосов
/ 26 февраля 2020

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

oldlib=/some/where/libwhatnot.a
newlib=libwhatnot1.a
bigobj=libwhatnot.o
tmpdir=libwhatnot.relink

mkdir "$tmpdir"
cd "$tmpdir"
ar x "$oldlib"
ld -r -o "../$bigobj" *
rm -f *
cd ..
rmdir "$tmpdir"
ar r "$newlib" "$bigobj"
rm -f "$bigobj"

Возможно, вам придется пересмотреть, как сохранить отладочную информацию (вероятно, -g опция ld).

Сценарий должен иметь дело с такими проблемами, как каталог, который уже существует и не может cd в него - rm -f * может привести к серьезным неприятностям, если он выполняется в каталоге, другом чем тот, который был только что создан. Но основная идея c - извлекать, создавать отдельный объектный файл, архивировать это - означает, что библиотека полностью или ничего, по желанию.

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

Опция -r существует для линкеров начиная с (по крайней мере) 7-го издания Unix в конце 70-х годов; обычно он доступен и обычно не используется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...