Где исполняемые файлы ищут общие объекты во время выполнения?

102

Я понимаю, как определить, включать общие объекты во время компоновки / компиляции. Однако мне все еще интересно, как исполняемые файлы выглядят для общего объекта ( *.soбиблиотек) во время выполнения.

Например, мое приложение a.outвызывает функции, определенные в lib.soбиблиотеке. После компиляции я перехожу lib.soв новый каталог в моем $HOME.

Как я могу сказать, a.outчтобы найти его там?

rahmu
источник

Ответы:

102

Разделяемая библиотека HOWTO объясняет большинство механизмов , вовлеченных, и динамический загрузчик руководство переходит в более подробно. Каждый вариант Unix имеет свой собственный путь, но большинство использует один и тот же исполняемый формат ( ELF ) и имеют похожие динамические компоновщики (производные от Solaris). Ниже я обобщу общее поведение с акцентом на Linux; проверьте руководства вашей системы для полной истории.

Короче говоря, когда он ищет динамическую библиотеку ( .soфайл), компоновщик пытается:

  • каталоги, перечисленные в LD_LIBRARY_PATHпеременной среды ( DYLD_LIBRARY_PATHв OSX);
  • каталоги, перечисленные в rpath исполняемого файла ;
  • каталоги в системном поисковом пути, который (по крайней мере в Linux) состоит из записей в /etc/ld.so.confплюс /libи /usr/lib.

Rpath хранится в исполняемом файле (это динамический атрибут DT_RPATHили DT_RUNPATH). Он может содержать абсолютные пути или пути, начинающиеся с того, $ORIGINчтобы указывать путь относительно местоположения исполняемого файла (например, если исполняемый файл находится в, /opt/myapp/binа его rpath равен, $ORIGIN/../lib:$ORIGIN/../pluginsто динамический компоновщик будет искать /opt/myapp/libи /opt/myapp/plugins). Rpath обычно определяется, когда исполняемый файл компилируется, с -rpathопцией ld, но впоследствии вы можете изменить ее с помощью chrpath.

В сценарии вы описали, если вы разработчик или упаковщик приложения и предназначаются для того , чтобы установить в …/bin, …/libструктуре, а затем связать с -rpath='$ORIGIN/../lib'. Если вы устанавливаете предварительно собранный двоичный файл в своей системе, либо поместите библиотеку в каталог на пути поиска ( /usr/local/libесли вы системный администратор, в противном случае - каталог, который вы добавляете $LD_LIBRARY_PATH), либо попробуйте chrpath.

жилль
источник
3
В некоторых системах /lib64и /usr/lib64используются для 64-разрядных двоичных файлов и /libи /usr/libиспользуются для 32-разрядных двоичных файлов.
Марк Лаката
Почему в этом правильном ответе ничего не говорится о ldconfig ??
Любит Вероятность
1
@LovesProbability Поскольку вопрос был о том, где исполняемые файлы ищут библиотеки, которые не связаны ldconfig. ldconfigввязывается при установке библиотеки.
Жиль
1
Обратите внимание, что «системный путь поиска» для *.soбиблиотек не совпадает с $PATH. Путь поиска указан @enzotib в их ответе. Чтобы распечатать пути, которые будут искать, запустите ldconfig -v 2>/dev/null | grep -v ^$'\t'.
Эндрю Бейт
для меня, чтобы запустить ldconfig, мне понадобилась /sbin/ldconfigи другая магия Эндрю Бэйта, чтобы заставить его работать без полномочий root
Robert Lugg
16

В Linux поведение объясняется в ld(1)справочной странице

       The linker uses the following search paths to locate required
       shared libraries:

       1.  Any directories specified by -rpath-link options.

       2.  Any directories specified by -rpath options.  The difference
           between -rpath and -rpath-link is that directories specified by
           -rpath options are included in the executable and used at
           runtime, whereas the -rpath-link option is only effective at
           link time. Searching -rpath in this way is only supported by
           native linkers and cross linkers which have been configured
           with the --with-sysroot option.

       3.  On an ELF system, for native linkers, if the -rpath and
           -rpath-link options were not used, search the contents of the
           environment variable "LD_RUN_PATH".

       4.  On SunOS, if the -rpath option was not used, search any
           directories specified using -L options.

       5.  For a native linker, the search the contents of the environment
           variable "LD_LIBRARY_PATH".

       6.  For a native ELF linker, the directories in "DT_RUNPATH" or
           "DT_RPATH" of a shared library are searched for shared
           libraries needed by it. The "DT_RPATH" entries are ignored if
           "DT_RUNPATH" entries exist.

       7.  The default directories, normally /lib and /usr/lib.

       8.  For a native linker on an ELF system, if the file
           /etc/ld.so.conf exists, the list of directories found in that
           file.

       If the required shared library is not found, the linker will issue
       a warning and continue with the link.
enzotib
источник
1
Msgstr "Каталоги по умолчанию, обычно / lib и / usr / lib." -> Как я могу узнать, нормально ли работает моя система?
Торстен Стаерк
2
Вопрос о времени выполнения, а не о времени соединения
Talespin_Kit
2

Я уверен , что ответ здесь ldconfig.

ldconfig создает необходимые ссылки и кэш для самых последних общих библиотек, найденных в каталогах, указанных в командной строке, в файле /etc/ld.so.conf и в доверенных каталогах (/ lib и / usr / lib). Кэш используется компоновщиком времени выполнения, ld.so или ld-linux.so. ldconfig проверяет заголовок и имена файлов библиотек, с которыми он сталкивается, при определении того, какие версии должны обновлять свои ссылки.

http://linux.die.net/man/8/ldconfig

Шон С.
источник
0

Для запуска приложений файл /proc/1234/mapsсодержит все актуальные динамически связанные библиотеки.

Где 1234pid запущенного исполняемого файла.

Linux следует LD_LIBRARY_PATH и другим переменным, как указано в ответе Жиля.

user138692
источник
4
Хорошо, что вы подтверждаете во втором предложении, что ответ Жиля помогает. Первая часть, однако, не способствует объяснению того, как определить, где находятся файлы, только откуда они были получены, если они уже найдены. В целом это должен быть просто комментарий, а не ответ.
Антон