Linux совместно использовал библиотеку, которая пользуется общей библиотекой неопределенный символ

две общих библиотеки liba.so и libb.so. liba.so используют libb.so. Все c файлы компилируются с-fPIC. Соединение использования - совместно использованный. Когда мы называем dlopen на liba.so, он не может найти символы в libb.so... мы получаем "неопределенный символ" ошибка. Мы можем dlopen libb.so без ошибок. Мы знаем, что liba находит libb, потому что мы не получаем файл, не найденный ошибкой. Мы получаем файл, не найденный ошибкой, когда мы удаляем libb.so. Мы попробовали-lutil и никакую удачу.

Какие-либо идеи????

о, да. gcc 4.1.2

обновление: Мы используем rpath при соединении liba, таким образом, он может найти libb.

ldd liba.so возвраты:

linux-gate.so.1 => (0xffffe000)  
libb.so => ./libb.so (0xf6ef9000)  <-------- LIBB 
libutil.so.1 => /lib/libutil.so.1 (0xf6ef5000)  
libdl.so.2 => /lib/libdl.so.2 (0xf6ef1000)  
libm.so.6 => /lib/libm.so.6 (0xf6ec9000)  
libpthread.so.0 => /lib/libpthread.so.0 (0xf6eb1000)  
librt.so.1 => /lib/librt.so.1 (0xf6ea8000)  
libc.so.6 => /lib/libc.so.6 (0xf6d62000)  
/lib/ld-linux.so.2 (0x007d0000)   

это - significat, что нет никакого.# в конце libb???

14
задан johnnycrash 7 June 2010 в 18:35
поделиться

1 ответ

Вы можете легко проверить, где должна находиться libb.so с помощью команды ldd:

 $ ldd liba.so
    linux-gate.so.1 =>  (0xb77b0000)
    libb.so.1 => not found
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb75b6000)
    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7572000)
    libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb742b000)
    /lib/ld-linux.so.2 (0xb77b1000)

Если она не найдена, libb. so путь к ней должен быть добавлен в /etc/ld.so.conf или переменную оболочки LD_LIBRARY_PATH.

Другим способом является установка rpath в самом liba.so - по сути, это жесткое кодирование пути, чтобы при запуске бинарника динамический компоновщик знал, где искать разделяемые библиотеки.

Если rpath не установлен, он сначала будет искать в LD_LIBRARY_PATH, затем в путях, указанных в /etc/ld.so.conf (или /etc/ld.so.conf.d/). После добавления в ls.so.conf не забудьте выполнить /sbin/ldconfig

Динамический компоновщик ищет зависимые разделяемые библиотеки по их soname (если оно установлено) - если soname не установлено (например, с помощью -Wl,-soname,libb.so.1), поиск будет производиться по имени библиотеки.

Пример: libb.so.1.0 - это ваша фактическая библиотека, имеющая soname - libb.so.1. Обычно вы имеете следующую структуру файлов:

libb.so -> libb.so.1
libb.so.1 -> libb.so.1.0
libb.so.1.0

где libb.so и libb.so.1 - симлинки.

Обычно вы ссылаетесь на libb.so, когда собираете какое-то приложение или другую библиотеку, зависящую от libb.so.

gcc -shared -Wl,-soname,liba.so.1 -o liba.so.1.2 -L/libb/path -lb

При запуске приложения (или выполнении dlopen - ваш случай) - динамический компоновщик будет искать файл с именем libb.so.1 - soname зависимой библиотеки, если установлено soname, а не libb.so.

Вот почему вам нужен симлинк libb.so.1, указывающий на реальную библиотеку.

Если вы используете ld.so.conf и ldconfig, он создаст симлинк с именем soname, указывающий на файл библиотеки, если этот симлинк отсутствует.

Вы можете посмотреть ld-linux man page для получения более полезной информации.


Если библиотека найдена, но некоторые символы отсутствуют, попробуйте собрать libb.so с опцией -Wl,--no-undefined
gcc -shared -Wl,-soname,libb.so.1 -Wl,--no-undefined -o libb.so.1.2

Это должно выдать ошибку, если вы не определили какой-то символ.

20
ответ дан 1 December 2019 в 12:51
поделиться