Де виконувані файли шукають спільні об’єкти під час виконання?


102

Я розумію, як визначити включені спільні об'єкти під час з'єднання / компіляції. Однак мені все ще цікаво, як виконувані файли шукають спільний об'єкт ( *.soбібліотеки) під час виконання.

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

Як я можу сказати a.outпіти шукати його там?

Відповіді:


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
Роберт Лугг

16

У Linux поведінка пояснюється на ld(1)сторінці man

       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.

1
"Каталоги за замовчуванням, як правило, / 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містить усі фактично динамічно пов'язані бібліотеки.

Де 1234під запущеного виконуваного файлу.

Linux слідує за LD_LIBRARY_PATH та іншими змінними, на що вказував у відповідь Гілл.


4
Приємно, що у другому реченні ви підтверджуєте, що відповідь Гілла допомагає. Перша частина, однак, зовсім не сприяє поясненню того, як сказати a.out, де знаходяться файли, лише де вони отримані, якщо вони вже знайдені. Всього в цьому має бути просто коментар, а не відповідь.
Антон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.