Существует ли rpath для динамически подключаемых библиотек?

Существует ли rpath для динамически подключаемых библиотек?

Итак, проект, над которым я работаю, использует несистемный каталог для хранения некоторых DLL, используемых кодом. Я не хочу помещать их в системные каталоги, поэтому исполняемые файлы имеют rpath, установленный для поиска DLL. Однако, поскольку добавляется все больше и больше библиотек, теперь есть DLL, которые зависят от других DLL в этом каталоге.

Эти библиотеки не могут найти библиотеки DLL, от которых они зависят, поскольку они не находятся в каталоге, который ищет компоновщик, например, в системном каталоге.

Есть ли способ заставить DLL искать этот конкретный несистемный каталог? Например, rpath? И как это сделать с библиотекой? Система сборки, используемая для проекта, — CMake, если это поможет в ответе.

Этот ответ не работает, так как в библиотеке нет тега rPath:https://unix.stackexchange.com/a/272286/4193

Я рассматривал возможность использования LD_LIBRARY_PATH, и это работает, но это раздражает при наборе текста и не очень здорово, когда другие люди используют приложение. Если есть способ добавить тег rPathв библиотеку, это был бы лучший вариант.

Приветствуются ссылки на предыдущие соответствующие вопросы и ответы.

решение1

Существует ли rpath для динамически подключаемых библиотек?

Да, есть. Вы можете использовать -Wl,-rpathс общими объектами ELF так же, как и с исполняемыми файлами ELF. Клонируйте небольшой пример, который я выложил здесь:

git clone https://gist.github.com/ardrabczyk/6aeb8545c9b754d6b15be390af4bdff0

Запустите makeдля компиляции. Проверьте, какие библиотеки необходимы main исполняемому файлу ELF:

$ readelf -d ./main

Dynamic section at offset 0xe30 contains 22 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libtwo.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000f (RPATH)              Library rpath: [.]
(...)

И проверьте, какие библиотеки нужны libtwo.so:

$ readelf -d ./libtwo.so

Dynamic section at offset 0xe38 contains 22 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libone.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000f (RPATH)              Library rpath: [libs]
 (...)

Как вы можете видеть, оба mainи libtwo.soнуждаются в некоторых общих объектах и ​​оба имеют установленный rpath. Вам не нужно устанавливать LD_LIBRARY_PATH для запуска ./main:

$ ./main
I'm in bar()

main всегда будет искать свою зависимость libtwo.so в .текущем каталоге, а libtwo.so в свою очередь всегда будет искать свою зависимость libone.so в libsкаталоге. Если libsотсутствует, ./main не запустится:

$ mv libs libs.bak
$ ./main
./main: error while loading shared libraries: libone.so: cannot open shared object file: No such file or directory

Восстановить:

$ mv libs.bak libs
$ ./main
I'm in bar()

решение2

Поскольку вы не хотите рассматривать его как часть системы, используйте его таким, какой он есть: пользовательским приложением!

Если вы добавите ~/.local/lib/в свой LD_LIBRARY_PATH, вы можете разместить все там. Просто создайте частичную структуру FHS под ~/.local/какмусорное ведро,и т. д.,либиделиться. Таким образом, вам не нужно вызывать программу с предшествующей переменной environmemt. Все остальные системы просто должны будут добавить этот каталог к ​​своей переменной окружения library path. Очень аккуратно и unixish.

Если вы отвергнете и это решение, то останется только одна возможность. Либо вы используете фиксированный путь, который ожидается в каждой системе, либо переменную окружения, которая содержит путь и также ожидается.

Связанный контент