моделирование поведения --whole-archive для каждого символа

Я знаком с тем, что делает параметр компоновщика --whole-archive при использовании статического архива.

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

Для ясности, допустим, у меня есть .a, который выполняет две функции:

void foo() {}
void bar() {}

Я хотел бы убедиться, что любой исполняемый файл, созданный путем связывания с этим архивом, всегда будет иметь символ foo (), независимо от того, используется ли foo () или нет. Меня так же не волнует bar ()

Спасибо.


person MK.    schedule 08.02.2016    source источник
comment
Может быть, с помощью скрипта компоновщика?   -  person Marc Glisse    schedule 09.02.2016
comment
sourceware.org/binutils/docs/ld/File-Commands.html INPUT Например, если вы всегда хотите включать subr.o каждый раз, когда вы создаете ссылку, но вас не беспокоит размещение его в каждой командной строке ссылки, тогда вы можете поместить `INPUT (subr.o) 'в ваш скрипт компоновщика.   -  person Marc Glisse    schedule 11.02.2016


Ответы (3)


Для этого вы можете использовать опцию -u:

gcc -O2 foo.c -o foo -umysymbol -lmylib

Это заставляет компоновщик рассматривать mysymbol как неопределенный и разрешать его, связывая его из указанных библиотек.

На странице руководства ld:

-u символ

--undefined = символ

Принудительно вводить символ в выходной файл как неопределенный символ. Это может, например, вызвать связывание дополнительных модулей из стандартных библиотек. `-u 'может повторяться с разными аргументами опции для ввода дополнительных неопределенных символов.

person Ctx    schedule 08.02.2016
comment
--undefined выглядит хорошо, хотя это означает, что нужно изменить последний этап сборки исполняемого файла. Я надеялся найти способ рекламировать публичный характер символа в самой библиотеке. - person MK.; 09.02.2016
comment
@MK Я понимаю, но боюсь, что это вряд ли возможно. Он всегда работает наоборот, основные бинарные триггеры связывают символы. - person Ctx; 09.02.2016

Боюсь, для этого вам нужно будет изменить привязку.

Вы должны понимать, что объекты в архиве (.a), которые могут быть связаны или не связаны с вашим исполняемым файлом, являются не определениями отдельных символов, а отдельными членами архива, которые являются объектными файлами < / em>, каждый из которых может определять произвольное количество символов. Если вы хотите связать символ из архива, вы связываете весь элемент архива, который его определяет. 1

Основное различие между связыванием архива (.a) с исполняемым файлом и связыванием объектного файла (.o) заключается в том, что объектный файл будет связан безоговорочно, тогда как член архива будет связан только в том случае, если он предоставляет определение по крайней мере для одного символа, на который была сделана ссылка, но который не был определен при проверке архива.

Следовательно, обычный, не обходной способ гарантировать, что символ foo безоговорочно связан, - это связать файл объекта, который его определяет. Невозможно пометить члена архива foo.o как должен быть связан, потому что, если вы должны связать foo.o, вы делаете это путем связывания foo.o.

Итак, если foo находится в члене архива foo.o, вы можете извлечь этот член из архива:

ar x libthing.a foo.o

и добавьте foo.o в вашу связь, даже если у вас нет foo источника для компиляции foo.o.

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

Я надеялся найти способ рекламировать публичный характер символа в самой библиотеке.

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


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

person Mike Kinghan    schedule 09.02.2016

Следующее, кажется, сработало для меня.

В функции в моей библиотеке, которая, как я знаю, всегда вызывается, я делаю следующее:

static volatile auto var = &foo

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

person MK.    schedule 10.02.2016