TGViewer
LinuxCamp | DevOps LinuxCamp | DevOps @linuxcamp_tg · 13.6K subscribers
Post #40 3.11K
Компоновка с динамическими библиотеками [2]

Мы уже познакомились с двумя способами оповещения динамического компоновщика о местоположении разделяемых библиотек:

1. Определение переменной среды LD_LIBRARY_РАТН.
2. Установка библиотеки в один из стандартных каталогов (lib, /usr/lib).

Но есть и третий путь: на этапе статической сборки в исполняемый файл (приложение либо разделяемую библиотеку) можно встроить список каталогов, по которым требуется производить поиск. Для этого можно воспользоваться параметром компоновщика -rpath:


/* определяем путь "./lib/demo/", как значение для поля DT_RPATH/DT_RUNPATH в исполняемом файле prog */
$ gcc -Wl,-rpath=./lib/demo/ -o prog prog.c -L=./lib/demo/ -ldemo

$ gcc -Wl,rpath=./demo2/ -shared -o libdemo.so mod1.o -L=./demo2 -ldemo2


Результатом компоновки будет запись метки RUNPATH в ELF файле:


$ readelf -d prog

Dynamic section at offset 0xd78 contains 29 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libdemo.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000001d (RUNPATH) Library runpath: [./lib/demo/]

$ ldd prog
libdemo.so => ./lib/demo/libdemo.so (0x0000ffffb7790000)


Данный способ бывает полезен:

1. На этапе локальных сборок приложений. Вместо того, чтобы всегда указывать переменную окружения LD_LIBRARY_PATH, можно прописать 2 сценария сборки (debug/release) - в последнем сборка происходит без -rpath и все библиотеки устанавливаются в директории, о которых динамический компоновщик в курсе.

2. При установке приложений, версии зависимостей которых отличаются от тех, которые доступны в системе. В таком случае имеет место размещение библиотек в директориях, о известных известно только целевому исполняемому файлу.

Разница между DT_RPATH и DT_RUNPATH:

В былые времена спецификация формата ELF допускала исключительно встраивание DT_RPATH, однако в последующих версиях данного формата эта метка считается устаревшей - в качестве замены был представлен DT_RUNPATH.

Разница между двумя указанными записями заключается в их приоритете относительно переменной среды LD_LIBRARY_PATH: DT_RPATH переопределяет LD и обрабатывается с наибольшим приоритетом, DT_RUNPATH имеет меньший вес и рассматривается сразу после LD.

По умолчанию современные версии компоновщика записывают значение -rpath в метку DT_RUNPATH. Чтобы задействовать вместо этого DT_RPATH, следует дополнительно указать параметр --disable-new-dtags:


$ gcc -g -Wall -Wl,--disable-new-dtags,-rpath=./lib/demo \
-o prog main.c -L=./lib/demo/ -ldemo

$ objdump -p prog | grep PATH
RPATH ./lib/demo/


Использование переменной $ORIGIN в списке rpath:

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

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

Для решения данной проблемы динамический компоновщик позволяет указать в параметре -rpath специальную строку, $ORIGIN, которую он умеет анализировать и интерпретировать как «каталог, содержащий приложение». Это значит, что поиск динамических зависимостей будет происходить по пути, относительно тому, в котором приложение установлено:


$ gcc -Wl,-rpath,'$ORIGIN'/lib/demo ...

$ objdump -p prog | grep PATH
RPATH $ORIGIN/lib/demo/


Теперь можно предоставить пользователю простой установочный пакет с программой и необходимыми библиотеками, который он сможет установить в любое место и успешно запуститься. Как говориться, "Дело сделано" - принимайте работу под ключ.
  • 🔥 11
  • 👍 7
  • ❤‍🔥 3
  • ❤ 2
  • 🕊 2
More from @linuxcamp_tg
  1. Oct 9, 2026🤖Обходим «белый список» вместе с STRELKA Думали, что белые списки не обходятся когда глуш…
  2. Sep 28, 2026Проекту GNU вчера исполнилось 43 года 1983 год: Ричард Столлман объявил планы разработать…
  3. Sep 25, 2026Linux будет работать на ноутах с Snapdragon X2. Qualcomm добавляет полноценную поддержку L…
  4. Sep 24, 2026Так все по делу)) Советует же самый быстрый фикс LinuxCamp | #memes
  5. Sep 23, 2026Планы на 3 октября — прийти на RWB Infra x Security Meetup Мы направим прожекторы на инфра…
  6. Sep 22, 2026Ещё одна рекордная неделя для AI-разработки в Linux. На прошлой неделе в ядро попало 1 634…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →