Почему я должен определять LD_LIBRARY_PATH с экспортом каждый раз, когда я запускаю свое приложение? - PullRequest
41 голосов
/ 30 марта 2009

У меня есть код, который использует некоторые общие библиотеки (код c на gcc). При компиляции я должен явно определить каталоги include и библиотеки, используя -I и -L, так как они не находятся в стандартных местах. Когда я пытаюсь запустить код, я получаю следующую ошибку:

./sync_test 
./sync_test: error while loading shared libraries: libsync.so: cannot open shared object file: No such file or directory

Однако, сделайте следующее, все работает просто отлично:

export LD_LIBRARY_PATH="/path/to/library/"
./sync_test

Теперь, странная часть, это работает только один раз. Если я попытаюсь запустить sync_test снова, я получу ту же ошибку, если сначала не введу команду экспорта. Я попытался добавить следующее в мой .bashrc, но это не имело никакого значения:

LD_LIBRARY_PATH="/path/to/library/"

Ответы [ 7 ]

44 голосов
/ 30 марта 2009

Вам следует избегать установки LD_LIBRARY_PATH в вашем .bashrc. См. "Why LD_LIBRARY_PATH is bad" для получения дополнительной информации.

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

gcc ... -Wl,-rpath /path/to/library -L/path/to/library -lsync -o sync_test

EDIT:

Другой способ - использовать обертку, подобную этой

#!/bin/bash

LD_LIBRARY_PATH=/path/to/library sync_test "$@"

Если sync_test запускает любые другие программы, они могут в конечном итоге использовать библиотеки в /path/to/library, которые могут или не могут быть предназначены.

42 голосов
/ 30 марта 2009

Используйте

export LD_LIBRARY_PATH="/path/to/library/"

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

Попробуйте -R/path/to/library/ пометить, когда вы создаете ссылку, программа будет выглядеть в этом каталоге, и вам не нужно будет устанавливать какие-либо переменные среды.

РЕДАКТИРОВАТЬ: Похоже, -R только для Solaris, и вы на Linux.

Альтернативным способом было бы добавить путь к /etc/ld.so.conf и запустить ldconfig. Обратите внимание, что это глобальное изменение, которое будет применяться ко всем динамически связанным двоичным файлам.

10 голосов
/ 30 марта 2009

Вы можете просто поместить все это в одну строку:

LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/path/to/library" ./sync_test

Должно немного облегчить жизнь, даже если это ничего не меняет.

10 голосов
/ 30 марта 2009

Вы 'экспортировали' в свой .bashrc?

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:"/path/to/library"
4 голосов
/ 07 августа 2012

Вместо переопределения пути поиска библиотеки во время выполнения с LD_LIBRARY_PATH, вы могли бы вместо этого вставить его в двоичный файл с помощью rpath. Если вы связываетесь с GCC, добавление -Wl,-rpath,<libdir> должно сработать, если вы связываетесь с ld, это просто -rpath <libdir>.

2 голосов
/ 30 марта 2009

Что вы также можете сделать, если это то, что вы установили в своей системе, это добавить каталог, содержащий общие библиотеки, в ваш файл / etc / ld.so.conf или создать новый файл в / etc / ld.so.conf.d /

(Я оба проверил дистрибутив RHEL5 и Ubuntu, так что я думаю, что он универсален для Linux)

Программа ldconfig убедится, что они включены в систему в целом.

См. Следующую ссылку для получения дополнительной информации: www.dwheeler.com / крепят-программы / Secure-Programs-HOWTO / dlls.html

1 голос
/ 25 октября 2016

Вы можете добавить в свой код систему вызовов с новым определением:

sprintf(newdef,"export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:%s:%s",ld1,ld2);
system(newdef);

Но я не знаю, что это правильное решение, но оно работает.

Привет

...