объектный файл из .a не включен в .so - PullRequest
4 голосов
/ 11 августа 2010

Я создал файл .c, который преобразуется в файл .o вместе с примерно 300 другими файлами .c и включен в статическую библиотеку .a.Эта библиотека, наряду со многими другими, используется для создания динамической библиотеки .so.При анализе файлов .a и .so с nm я обнаружил, что по какой-то причине символы, определенные в файле .c, присутствуют в файле .a, но отсутствуют в файле .so.Я не могу думать ни о какой причине, что это должно произойти.Может кто-нибудь помочь мне здесь?Для создания двух двоичных файлов используются следующие шаги:

gcc -fvisibility=hidden -c foo.c -o foo.c.o
ar cr libbar.a foo.c.o ...
gcc -fvisibility=hidden -fPIC -o libfinal.so libbar.a x.o y.a ... 

Причина, по которой я указал скрытую видимость, заключается в том, что я хочу показать только несколько выбранных символов.Чтобы выставить символы из foo.c, я указал атрибут видимости, чтобы сигнатуры функций в заголовке foo.h выглядели так:

extern int _____attribute_____ ((visibility ("default"))) func ();

РЕДАКТИРОВАТЬ: команда nm libbar.a | grep Ctx дает:

000023c5 T CtxAcquireBitmap
000026e9 T CtxAcquireArray
00001e77 T CtxCallMethod

Однако, nm libfinal.so | grep Ctx ничего не показывает.

ОБНОВЛЕНИЕ: Найдена другая запись , в котором обсуждается использование опции --whole-archive.Кроме того, наткнулся на параметр --export-dynamic, который, по-видимому, указывает компоновщику сохранять символы, на которые нет ссылок.Расследование дальше.

Ответы [ 3 ]

4 голосов
/ 11 августа 2010

Попробуйте использовать параметр компоновщика --whole-archive, чтобы включить все объекты в общую библиотеку при компоновке

gcc -o libfinal.so -Wl,--whole-archive libbar.a x.o y.a -Wl,--no-whole-archive

С man ld:

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

Два замечания при использовании этой опции от gcc: во-первых, gcc не знает об этой опции, поэтому вы должны использовать -Wl, -whole-archive. Во-вторых, не забудьте использовать -Wl, -no-whole-archive после вашего списка архивов , потому что gcc добавит свой собственный список архивов в ваш список ссылку, и вы можете не захотеть, чтобы этот флаг также влиял на них.

1 голос
/ 11 августа 2010

Насколько я знаю, при компиляции с использованием .a, gcc будет извлекать только те объекты, на которые ссылаются другие модули.Если ваше намерение состоит в том, чтобы включить весь контент .a в .so, простая «compile / link xc в libfinal.so с использованием контента в libbar.a» не то, что вам нужно.

0 голосов
/ 23 августа 2010

Создание фиктивной ссылки на необходимые символы в моем основном файле не решило проблему. Ссылочные символы появились в двоичном дампе (полученном с использованием nm) с маркером U (= undefined). Мне удалось решить проблему, связав объектный файл напрямую при создании файла .so, вместо того, чтобы сначала включить его в библиотеку .a. Поскольку эти функции были помечены extern, они были включены в .so, хотя на них не ссылались в библиотеке. Если бы они не были помечены extern, они не были бы включены, как сказал Сильвайнулг.

Спасибо Дмитрию за указание опции --whole-archive. Я не знал, что такая опция существует.

...