Я только что сделал базовый пример использования опции ld -rpath
с $ORIGIN
здесь (см. 2-й ответ для рабочей версии). Я пытаюсь создать пример, где main.run
ссылается на foo.so
, который, в свою очередь, ссылается на bar.so
, все используют rpath
и $ORIGIN
.
Структура файла во время выполнения:
- проект /
- Библиотека /
- реж /
- к югу /
- bar.so
- foo.so
- бежать /
- main.run (не удается собрать)
Я собираю foo.so используя:
g++ -c -o obj/foo.o src/foo.cpp -fPIC
g++ -shared -o lib/dir/foo.so obj/foo.o -Wl,-soname,foo.so -Wl,-rpath,'$ORIGIN/sub' -Llib/dir/sub -l:bar.so
Который строит нормально. ldd lib/dir/foo.so
может даже найти bar.so
Однако, когда я пытаюсь связать main.run
с foo.so
, foo.so
не может найти bar.so.
Я собираю main.so используя:
g++ -c -o obj/main.o src/main.cpp
g++ -o run/main.run obj/main.o -Wl,-rpath,'$ORIGIN/../lib/dir' -Llib/dir -l:foo.so
Это прекрасно работает, если используется другая версия foo.so
, которая не рекурсивно связывает. (Раскомментируйте строки в make.sh, в проекте ниже, чтобы протестировать).
Однако, используя обычный foo.so
я получаю эту ошибку при сборке main.run
:
/usr/bin/ld: предупреждение: bar.so, необходимый для lib/dir/foo.so, не найден (попробуйте использовать чернила -rpath или -rpath -l)
Итак, мои вопросы:
- Разрешает ли
$ORIGIN
в foo.soproject/lib/dir
(где находитсяfoo.so
) илиproject/run
(гдеmain.run
(main.run
файл, связывающий его))?
Кажется, что ldd указывает на то, что этоproject/lib/dir
, что может показаться лучшим способом (хотя я пытался предположить и то и другое). - Как получить их для связи (при сохранении перемещаемости) - предпочтительно без использования
-rpath-link
.
Вы можете скачать проект здесь. Это так просто, как я могу это сделать. 4 коротких источника и скрипт.
После распаковки просто запустите ./make.sh
из project/
.
Примечание: я использую -l:
Это не должно ничего менять, за исключением того, что библиотеки называются как foo.so
вместо libfoo.so
, и заполняются -l:foo.so
вместо -lfoo
.