View in Telegram
Компоновка с динамическими библиотеками [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/
Теперь можно предоставить пользователю простой установочный пакет с программой и необходимыми библиотеками, который он сможет установить в любое место и успешно запуститься. Как говориться, "Дело сделано" - принимайте работу под ключ.
Love Center - Dating, Friends & Matches, NY, LA, Dubai, Global
Love Center - Dating, Friends & Matches, NY, LA, Dubai, Global
Find friends or serious relationships easily