Ld library path linux
В прошлый раз мы с Вами обнаружили, что запуск программ, скомпилированных вместе с динамическими библиотеками, вызывает ошибку:
Это сообщение выдает загрузчик динамических библиотек(динамический линковщик — dynamic linker), который в нашем случае не может обнаружить библиотеку libfsdyn.so. Для настройки динамического линковщика существует ряд программ.
Первая программа называется ldd. Она выдает на экран список динамических библиотек используемых в программе и их местоположение. В качестве параметра ей сообщается название обследуемой программы. Давайте попробуем использовать ее для нашей программы rezultdyn:
Как видите все правильно. Программа использует три библиотеки:
- libc.so.6 — стандартную библиотеку функций языка C++.
- ld-linux.so.2 — библиотеку динамической линковки программ ELF формата.
- libfsdyn.so — нашу динамическую библиотеку функций.
Нашу библиотеку она найти не может. И правильно! Динамический линковщик ищет библиотеки только в известных ему каталогах, а каталог нашей программы ему явно не известен.
Для того, чтобы добавить нашу директорию с библиотекой в список известных директорий надо подредактировать файл /etc/ld.so.conf. Например, у меня этот файл состоит из таких строк:
Во всех этих директории хранятся всеми используемые библиотеки. В этом списке нет лишь одной директории — /lib, которая сама по себе не нуждается в описании, так как она является главной. Получается, что наша библиотека станет «заметной», если поместить ее в один их этих каталогов, либо отдельно описать в отдельном каталоге. Давайте для теста опишем, добавим строку в конец файла ld.so.conf:
У меня этот файл валяется в домашнем каталога пользователя root, у Вас он может быть в другом месте. Теперь после этого динамический линковщик будет знать где можно найти наш файл, но после изменения конфигурационного файла ld.so.conf необходимо, чтобы система перечитала настройки заново. Это делает программа ldconfig. Пробуем запустить нашу программу:
Как видите все заработало 🙂 Если теперь Вы удалите добавленную нами строку и снова запустите ldconfig, то данные о расположении нашей библиотеки исчезнут и будет появляться таже самая ошибка.
Но описанный метод влияет на всю систему в целом и требует доступа администратора системы, т.е. root. А если Вы простой пользователь без сверх возможностей ?!
Для такого случая есть другое безболезненное решение. Это использование специальной переменной среды LD_LIBRARY_PATH, в которой перечисляются все каталоги содержащие пользовательские динамические библиотеки. Для того, чтобы установить эту переменную в командной среде bash надо набрать всего несколько команд. Для начала посмотрим есть ли у нас такая переменная среды:
У меня в ответ выводится пустая строка, означающая, что такой переменной среды нет. Устанавливается она следующим образом:
После этого программа rezultdyn будет прекрасно работать. В случае, если у Вас в системе эта переменная среды уже уставновлена, то, чтобы не испортить ее значение, надо новый каталог прибавить к старому значению. Делается это другой командой:
Если Вы обнулите эту переменную, то снова библиотека перестанет работать:
Вы также параллельно можете зайти в систему под другим пользователем или даже тем же самым, но если Вы захотите просмотреть значение LD_LIBRARY_PATH, то увидите ее прежнее значение. Это означает, что два разных пользователя Linux не могут влиять на работу друг друга, а это и есть самое главное хорошее отличие систем Unix от большинства других систем.
LD_LIBRARY_PATH, the shared lib path in linux
I wrote a shared object, say libsd.so , and I put libsd.so and its header file sd.h in
Here is another program using libsd.so , say test.c , then compile it like this:
Then I run test like this:
So I set export LD_LIBRARY_PATH=. , then it works. But if I unset LD_LIBRARY_PATH and put LD_LIBRARY_PATH=
/.bashrc , then source
/.bashrc , again it doesn’t work for ./test , WHY?
/lib is difference from putting LD_LIBRARY_PATH=
2 Answers 2
Without the export your declared LD_LIBRARY_PATH is only valid in the script (.bashrc). With the export it should work, but it is usually not a good idea to set your LD_LIBRARY_PATH like this.
If you don’t want to install your library in the system path (e.g. /usr/lib) you should probably use a script that sets LD_LIBARAY_PATH locally and starts your application.
Try $HOME/lib instead of
/lib — it should be the same but I’ve seen cases where
wasn’t expanded properly when used in an variable assignment.
To check, try echo $LD_LIBRARY_PATH which gives you the current value.
Re export : If you omit the export , then the variable is only known to the current shell process and will not be exported to child processes. So if you omit it, echo $LD_LIBRARY_PATH will get the value because the variable is expanded by the shell before the echo command/builtin has a chance to do anything. But ./test won’t see it because it’s not exported to the new subprocess.
/.bashrc , and echo $LD_LIBRARY_PATH gives the current value, do you mean if I want ./test to work, I should still export LD_LIBRARY_PATH ? – Alcott Feb 23 ’12 at 11:48
Как правильно использовать LD_LIBRARY_PATH?
Решил на выходных повтыкать в одну игру с gog, а там в start.sh есть такой кусок:
просто у тебя есть эти нужные библиотеки, а в указанной директории нет
То есть, если задана эта переменная, то системные папки не проверяются?
Похоже, что LD_LIBRARY_PATH уже содержит какие-то пути, в т.ч. к libGL.so.1, но этот скрипт вместо того, чтобы добавить к ним свои, затирает их.
васче это странно. как их можно затереть?
Очень просто, в переменной лежало одно значение, а export в скрипте положил новое вместо старого. Правильно было бы добавить в начало:
никогда так не делал и всё работало. просто, скорее всего, там и ./$bin_name тоже какой-то скрипт.
просто у тебя есть эти нужные библиотеки, а в указанной директории нет
Наоборот. В указанной директории есть какие-то библиотеки, с которыми игра не работает.
Это же очень легко выяснить. Если ОП напишет в консоли echo $LD_LIBRARY_PATH , и там не пусто, и в одном из этих каталогов есть libGL.so.1, то игра не нашла libGL из-за того, что скрипт изменил значение LD_LIBRARY_PATH, стерев те пути, которые там были.
Запускается игра и при отсутствии export LD_LIBRARY_PATH в скрипте, скорее всего, из-за того, что нужные библиотеки (которые лежали в game и lib) есть и в системных каталогах.
На правах мэйнтэйнера: чем не устроил games-strategy/spaz ?
Или там версия старая?
Update: пардон, почудилось что ты задавал вопрос про humble bundle версию, а не про gog.
В том-то и дело что в LD_LIBRARY_PATH пусто по-умолчанию.
How to set the environmental variable LD_LIBRARY_PATH in linux
I have first executed the command: export LD_LIBRARY_PATH=/usr/local/lib
Then I have opened .bash_profile file: vi
/.bash_profile . In this file, I put:
Then if the terminal is closed and restarted, typing echo $LD_LIBRARY_PATH displays no result.
How to set the path permanently?
/.bash_profile ? I tend to forget that. And then like @neckTwi said run ldconfig – ashley Jun 15 ’16 at 11:01
10 Answers 10
You should add more details about your distribution, for example under Ubuntu the right way to do this is to add a custom .conf file to /etc/ld.so.conf.d , for example
inside the file you are supposed to write the complete path to the directory that contains all the libraries that you wish to add to the system, for example
remember to add only the path to the dir, not the full path for the file, all the libs inside that path will be automatically indexed.
Save and run sudo ldconfig to update the system with this libs.
Proper use of LD_LIBRARY_PATH or ldconfig for a software package
I’m aware of the general basics of using ldconfig and LD_LIBRARY_PATH , but I’m hoping for a little guru help with my situation.
I have a portable software package that resides in its own directory and has its own versions of many libraries.
There are MANY binaries and scripts that run from this directory.
Some of the binaries (apache, php, postgres) may also have separate versions installed on the system.
Since there might be two versions of php, it doesn’t suffice to create /etc/ld.so.conf.d/myapp.conf if the system can’t determine which version of «myapp» to use the ldconfig file for.
I’m looking for best practices on configuring such a system. The person who initially set up the software pack exported LD_LIBRARY_PATH so that ALL applications on the system used it.
I’m trying to isolate just the applications in the package directory.
Some parameters to work with:
/mypack — contains everything for the software package
/mypack/local/lib — contains required libraries that may not be compatible with the system
even though the versions are the same, the one in /mypack may not be compatible with the distro and will break the system if it’s used
binary example: php exists in both /mypack and in the default directory php from /mypack should use libs from /mypack/local/lib and the distro version should use /lib