LINUX.ORG.RU

Не удалять неиспользуемые символы при линковке

 , ,


0

1

Столкнулся с такой, новой для себя, проблемой. Есть проект построеный по модульной архитектуре. Есть главный бинарник (App), главная динамическая библиотека (A.so) и отдельный модуль (B.so).

Библиотека A.so линкуется с разными сторонними динамическими диблиотеками, типа boost, ssl, crypto. В исходных кодах A.so описываются всякие скущности которые ссылаются на эти сторонние библиотеки.

Основной бинарик App линкуется с A.so и использует только одну маленькую функцию из этой библиотеки. Т.е. не используется ничего связанного с ssl,cryprto, boost и прочим.

Модуль B.so использует сущности связанный с boost,ssl,crypto но не линкует сторонние библиотеки.

Во время сборки всего это получается такая хрень. Так как App не использует явно функции,объекты и прочее определенные в A.so и связанные с boost,ssl,crypto то они тупо отбрасываются линковщиком и их нет ни в зависимостях ни у App ни у A.so.

Далее App через dlopen загружает B.so (который нуждается в boost,ssl,crypto) и, о боже, ни у кого не оказывается этих зависимостей, и я получаю unresolved symbols.

Вопрос, как разрешить эту спорную ситуацию. Проблема усугубляется еще тем что на системе redhat этой проблемы не возникает, и все нужные зависимости оказываются в A.so и также гладко качуют в App, B.so (при ее загрузке). А в ubuntu все не используемые зависимости просто отбрасываются из A.so и из за этого наступает невозможность загрузить B.so который нуждается в этих зависимостях.

Еще раз повторюсь, boost,ssl,crypto используются в исходных кодах динамически загружаемой библиотеки A.so и у нее же в правилах написано линковаться с ними. Но так как это - динамически загружаемая библиотека, то понятно дело они только определяются там, но не используются явно (т.е. не создаются объекты, не вызываются функции). И они отбрасываются и либа не резолвит все используемые в ней сторонние зависимости.


Для сборки проекта используется Cmake. Я сравнил команду линковки A.so на redhat и на ubuntu и они блин идентичны.

Redhat

ld --version GNU ld version 2.20.51.0.2-5.36.el6 20100205

Ubuntu

ld --version GNU ld (GNU Binutils for Ubuntu) 2.23.2

Cupper ()
Последнее исправление: Cupper (всего исправлений: 1)
Ответ на: комментарий от Cupper

Вот так выкглядит команда линковки

/usr/bin/c++ -fPIC -Wall -Wextra -Wconversion -Wcast-qual -Winline -Woverloaded-virtual -Wctor-dtor-privacy -Wnon-virtual-dtor -Wold-style-cast -Wpacked -Wredundant-decls -fexceptions -pthread -fpic -pipe -g -O0 -shared -Wl,-soname,libA.so.0 -o libA.so.0.0 some_other.cc.o -lboost_log-mt -lboost_log_setup-mt -lboost_filesystem-mt -lboost_system-mt -lboost_thread-mt -lboost_regex-mt -ldl -lcrypto -lssl -Wl,-rpath,::::::::::::::::::::::::::::::::::::::

разница между двуями системами в /usr/bin/c++

RedHat

gcc версия 4.4.7

Ubuntu

gcc версия 4.7.3

Cupper ()
Последнее исправление: Cupper (всего исправлений: 1)
Ответ на: комментарий от nanoolinux

Вот вывод ldd A.so на redhat

	linux-vdso.so.1 =>  (0x00007fff423ff000)
	libboost_log-mt.so => /usr/lib64/libboost_log-mt.so (0x00007fb696f38000)
	libboost_log_setup-mt.so => /usr/lib64/libboost_log_setup-mt.so (0x00007fb696ad6000)
	libboost_filesystem-mt.so.X.YZ.0 => /usr/lib64/libboost_filesystem-mt.so.X.YZ.0 (0x00007fb6968c0000)
	libboost_system-mt.so.X.YZ.0 => /usr/lib64/libboost_system-mt.so.X.YZ.0 (0x00007fb6966bd000)
	libboost_thread-mt.so.X.YZ.0 => /usr/lib64/libboost_thread-mt.so.X.YZ.0 (0x00007fb6964a5000)
	libboost_regex-mt.so.X.YZ.0 => /usr/lib64/libboost_regex-mt.so.X.YZ.0 (0x00007fb69618c000)
	libdl.so.2 => /lib64/libdl.so.2 (0x00007fb695f88000)
	libcrypto.so.10 => /usr/lib64/libcrypto.so.10 (0x00007fb695bed000)
	libssl.so.10 => /usr/lib64/libssl.so.10 (0x00007fb695990000)
	libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007fb69568a000)
	libm.so.6 => /lib64/libm.so.6 (0x00007fb695405000)
	libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fb6951ef000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fb694fd2000)
	libc.so.6 => /lib64/libc.so.6 (0x00007fb694c3e000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fb69762c000)
	libboost_date_time-mt.so.X.YZ.0 => /usr/lib64/libboost_date_time-mt.so.X.YZ.0 (0x00007fb694a2d000)
...

Вот на ubuntu

	linux-vdso.so.1 =>  (0x00007fff54b39000)
	libboost_log-mt.so.X.YZ.0 => /path/lib/libboost_log-mt.so.X.YZ.0 (0x00007f844f520000)
	libboost_log_setup-mt.so.X.YZ.0 => /path/lib/libboost_log_setup-mt.so.X.YZ.0 (0x00007f844f01c000)
	libboost_filesystem.so.X.YZ.0 => /path/lib/libboost_filesystem.so.X.YZ.0 (0x00007f844ee06000)
	libboost_system.so.X.YZ.0 => /path/lib/libboost_system.so.X.YZ.0 (0x00007f844ec02000)
	libboost_thread.so.X.YZ.0 => /path/lib/libboost_thread.so.X.YZ.0 (0x00007f844e9e7000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f844e7b7000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f844e5b3000)
	libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f844e2af000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f844dfaa000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f844dd94000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f844d9ca000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f844fc0f000)
	librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f844d7c2000)

Я слукавил в начале сказав что boost тоже не подтягивается. Как видно, отсуствуют только ssl и crypto.

B.so идентичны.

Cupper ()
Ответ на: комментарий от vasily_pupkin

вы натолкнули меня на мысли о противоречии фактов.

Я проверил A.so и она действительно не содержит не одного симовла связанного с ssl, но не смотря на это линкует ssl либы в себя.

B.so напротив, содержит сиволы связанные с ssl но не линкует эту либо.

Я выше сказал, что я пробывал добавлять недостающие либы в B.so и это не сработало. Я ошибся, в тот раз я по ошибке смотрел в старые собранные файлы. По факту если добавить libssl к B.so то симолы корректно резолвятся.

Не понятым остается факт почему на redhat эта схема работает. А на ubuntu нет.

Cupper ()
Ответ на: комментарий от Cupper

пробывал

гм.

Не понятым остается факт почему на redhat эта схема работает. А на ubuntu нет.

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

Новый линковщик выкидывает зависимость из А. т.к. А ничего от туда не использует. И когда загружается В, символов нет.

Я только что проверил у себя. Действительно, линковщик выкидывает зависимость, если из неё ничего не тянули. Что собсвенно подтверждает тот факт, что чем портируемее по, тем оно качественее.

nanoolinux ★★★★ ()
Ответ на: комментарий от Cupper

Я не знаю через какую жопу надо было действовать, что бы получить какие-то «недостающие либы». Тут или загружается не то, или ищется не там.

vasily_pupkin ★★★★★ ()
Ответ на: комментарий от AptGet

Твоё сообщение совпадает с максимальной точкой информационной дельта функции в этом треде. Т.е. каждый буква содержит более чем килобайт информации.

И вообще у меня сегодня пятница, т.к. завтра выходной.

nanoolinux ★★★★ ()

Можно приложению в RPATH указать директорию с библиотекой A.so (например, "./lib").

Тогда B.so автоматически подтянет зависимости при dlopen.

Adonai ★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.