Общая библиотека Linux, которая использует неопределенную символ общей библиотеки - PullRequest
13 голосов
/ 07 июня 2010

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

Есть идеи ????

о да.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)   

означает, чтонет. # в конце libb ???

Ответы [ 2 ]

18 голосов
/ 07 июня 2010

Вы можете легко проверить, где ожидается 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)

Если это not found, путь 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 .


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

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

0 голосов
/ 21 апреля 2015

Не забывайте, что порядок libs (все аргументы -lxxx) важен (по крайней мере, в gcc) при связывании всех ваших объектов и библиотек для генерации вашего исполняемого файла.

Краткий пример:

ЛИЭС = -L. -ltest1 -ltest2

OBJS = code1.o code2.o

gcc $ (LIBS) $ (OBJS) -o mysoft

, который в некоторых случаях может потерпеть неудачу, тогда как

gcc $ (OBJS) -o mysoft $ (LIBS)

не будет

...