Я только что сделал простой пример использования параметра ld -rpath
с $ ORIGIN
здесь (рабочую версию см. Во втором ответе). Я пытаюсь создать пример, в котором main.run
ссылается на foo.so
, который, в свою очередь, ссылается на bar.so
, все с использованием rpath
и $ ORIGIN
.
Файловая структура времени выполнения:
- project /
- библиотека /
- реж /
- sub /
- bar.so
- foo.so
- run /
- 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-link)
Итак, мои вопросы:
$ ORIGIN
в пределах foo.so разрешается в project / lib / dir
(где foo.so
- это) или project / run
(где main.run
(исполняемый файл, связывающий его) есть)? project / lib / dir
, что кажется лучшим способом (хотя я пытался использовать оба варианта). -rpath-link
. Вы можете скачать проект здесь . Это настолько просто, насколько это возможно. 4 коротких источника и сценарий.
После распаковки просто запустите ./ make.sh
из project /
.
Примечание: Я использую -l:
. Это не должно ничего менять, за исключением того, что библиотеки называются как foo.so
вместо libfoo.so
, а вместо них - -l: foo.so
. из -lfoo
.