Символы из вспомогательной библиотеки не экспортируются в исполняемый файл - PullRequest
7 голосов
/ 14 ноября 2010

У меня есть программа, myprogram, которая связана со статической удобной библиотекой, назовите ее libconvenience.a, которая содержит функцию, func().Функция func() нигде не вызывается в myprogram;он должен быть в состоянии вызываться из библиотеки плагинов, plugin.so.

Символ func() не экспортируется динамически в myprogram.Если я бегу

nm myprogram | grep func

, я ничего не получаю.Тем не менее, он не отсутствует в libconvenience.a:

nm libconvenience/libconvenience.a | grep func
00000000 T func

Я использую Automake, но если я делаю последнеевместо этого выполняется ручное связывание в командной строке, оно также не работает:

gcc -Wl,--export-dynamic -o myprogram *.o libconvenience/libconvenience.a `pkg-config --libs somelibraries`

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

gcc -Wl,--export-dynamic -o myprogram *.o libconvenience/*.o `pkg-config --libs somelibraries`

Если я добавлю фиктивный вызов к func() где-то в myprogram, тогдаfunc() также отображается в символах myprogram.Но я подумал, что --export-dynamic должен был экспортировать все символы независимо от того, были ли они использованы в программе или нет!

Я использую automake 1.11.1 и gcc 4.5.1 на Fedora 14. Я такжеиспользуя Libtool 2.2.10 для сборки plugin.so (но не вспомогательной библиотеки).

Я не забыл вставить -Wl,--export-dynamic в myprogram_LDFLAGS, и при этом я не забыл поставить исходный код, содержащий func() в libconvenience_a_SOURCES (некоторые из Google указывают, что это общие причины этой проблемы.)

Может кто-нибудь помочь мне понять, что здесь происходит?

Ответы [ 2 ]

4 голосов
/ 14 ноября 2010

Мне удалось это решить. Именно эта заметка из превосходной книги Джона Калькот по автоинструментам указала мне правильное направление:

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

Чтобы противодействовать этому поведению, можно использовать флаг --whole-archive для libtool. Тем не менее, это приводит к тому, что все символы из всех системных библиотек также загружаются, что приводит к множеству ошибок определения двойных символов. Таким образом, --whole-archive должно быть прямо перед libconvenience.a в командной строке компоновщика, и после него должно следовать --no-whole-archive, чтобы другие библиотеки не обрабатывались таким образом. Это немного сложно, так как automake и libtool на самом деле не гарантируют, что ваши флаги будут в том же порядке в командной строке, но эта строка в Makefile.am добилась цели:

myprogram_LDFLAGS = -Wl,--export-dynamic \
    -Wl,--whole-archive,libconvenience/libconvenience.a,--no-whole-archive
0 голосов
/ 14 ноября 2010

Если вам нужно, чтобы func был в plugin.so, постарайтесь найти его там, если это возможно. Удобные библиотеки предназначены для этого - удобство для ссылки на исполняемый файл или lib в качестве промежуточного шага.

...