Ошибка при загрузке разделяемых библиотек

Мое дерево проекта выглядит примерно так:

src/ include/ Makefile lib/ lib/3rdparylib/ 

Я не кодировал 3rdpartylib , но решил внедрить его исходный код в мою проектную упаковку. Я компилирую программное обеспечение, выполнив следующие шаги:

 $ cd lib/3rdpartylib/ $ make $ ln -s 3rdpartylib.so.0 3rdpartylib.so 

Затем я скомпилирую каждый из исходных файлов следующим образом:

 $ gcc -c src/file.c -I include -o file.o -l 3rdparylib -L lib/3rdpartylib -I lib/3rdpartylib/include 

Затем я связываю:

 $ gcc file1.o file2.o -l3rdpartylib -L lib/3rdpartylib -o myapp 

Когда я нахожусь на своей основной машине, она работает отлично. Сегодня я попытался запустить его на другой машине. Он скомпилирован и связан без каких-либо проблем. Однако, когда я попытался запустить приложение, я получил следующее сообщение об ошибке.

./myapp: ошибка при загрузке разделяемых библиотек: 3rdpartylib.so.0: невозможно открыть файл общих объектов: нет такого файла или каталога

Я попытался сделать следующее:

 export LD_LIBRARY_PATH=/path/to/3rdpartylib.so 

Кажется, это работает. Но я понимаю, что использование LD_LIBRARY_PATH является плохой практикой. Меня беспокоит, чтобы эта переменная настраивалась каждый раз, когда я хочу запускать свое приложение.

Что мне не хватает? Почему он работает на моей основной машине (где LD_LIBRARY_PATH не настроен ни на что), а не на другом компьютере? Имеет ли значение, что другая машина является виртуальной?

Если это поможет, моя основная машина – это Debian box, а моя «новая» машина – Sabayon (Gentoo), работающая в Virtualbox.

4 Solutions collect form web for “Ошибка при загрузке разделяемых библиотек”

Важно то, какой дистрибутив Linux использует каждая машина, потому что они обрабатывают пути библиотеки по-разному. На машине Gentoo (Sabayon), если вы хотите использовать стороннюю библиотеку в общесистемной системе, вы должны:

  • Создайте файл под /etc/env.d/ который будет содержать дополнительную настройку среды. Файлы называются с использованием схемы [0-9][0-9]somename – две начальные цифры определяют порядок, в котором они используются. Хорошая практика требует, чтобы ваши пользовательские настройки были добавлены (рядом) последними , поэтому 99 – это правильное начало, если оно работает. Как добраться: Создайте файл с именем like

     /etc/env.d/99mythirdpartylib 

    содержащий

     LDPATH=/path/to/your/library 
  • Чтобы сделать изменения активными без перезагрузки, запустите их как root:

     env-update && source /etc/profile 

    (который обновит среду, а также запустит ldconfig ).

Ссылка , если хотите.

Если вы не хотите устанавливать путь поиска глобальной библиотеки для всей системы с помощью /etc/env.d , вы можете:

Просто установите LD_LIBRARY_PATH в PATH вашей библиотеки (вы сами установили ее в самой библиотеке, которая не будет работать), то же, что вы установили с параметром -L в gcc, например

 export LD_LIBRARY_PATH="$PROJ/lib/3rdpartylib/:$LD_LIBRARY_PATH" 

(последняя часть предназначена для сохранения переменной, если она уже установлена, что не должно быть нормально). Это будет работать только в вашей текущей оболочке, и вам придется настраивать ее каждый раз.

Или вы связываете, используя «статические» пути поиска библиотеки следующим образом:

 gcc file1.o file2.o -L./lib/3rdpartylib -Wl,-rpath=./lib/3rdpartylib -l3rdpartylib -o myapp 

-Wl указывает аргументы commmand, которые не будут обрабатываться gcc, но вместо этого передаются в компоновщик. Поскольку путь поиска библиотеки будет записан в двоичный файл, это будет работать даже на разных компьютерах (если библиотека существует)

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

Линия:

 $ gcc file1.o file2.o -l3rdpartylib -L lib/3rdpartylib -o myapp 

ищет файл lib3rdpartylib.so в вашем пути к библиотеке, который даже не включает lib/3rdpartylib ! Если вы посмотрите на страницу gcc man, в ней указано, что при указании пути к библиотеке с -L он должен появиться перед флагами -l или не будет выполняться поиск. Действительно, самым простым решением является просто связать с самой библиотекой:

 $ gcc file1.o file2.o lib/3rdpartylib/3rdpartylib.so -o myapp 

Таким образом, библиотека будет искать в библиотечных путях и динамически загружаться при myapp .

Если вы хотите проверить его, просто установите strace -eopen ./myapp после его установки и посмотрите, откуда он пытается загрузить библиотеку.

Вы должны сообщить своей системе, где искать библиотеки. Эта работа выполняется /etc/ld.so.cache . Вы можете добавить библиотеки или целые каталоги в /etc/ld.so.conf .

Вы можете восстановить кеш, выполнив:

 # /sbin/ldconfig -v 
Interesting Posts
Linux и Unix - лучшая ОС в мире.