Примечание. Полный рабочий пример ниже. Исходный вопрос следует:
У меня возникают проблемы с использованием параметра ld -rpath с $ORIGIN.
Поскольку я не мог найти полный пример, я думал, что попытаюсь написать его сам, чтобы я и другие могли использовать его позже. Как только я получу его работу, я приправлю его.
I спросил об этом раньше, но я думаю, что мой пост был немного запутанным.
Пример проекта создает одну общую библиотеку и один исполняемый файл, который ссылается на указанную библиотеку.
Он очень маленький (3 файла, 22 строки, включая buildscript).
Вы можете загрузить проект из здесь
Структура файла (до сборки):
-
project/-
src/-
foo.cpp -
main.cpp
-
-
make.sh
-
project/src/foo.cpp
int foo()
{ return 3; }
project/src/main.cpp
int foo();
#include <iostream>
int main()
{
std::cout << foo() << std::endl;
return 0;
}
project/make.sh
# Make directories:
mkdir -p -v obj
mkdir -p -v lib
mkdir -p -v run
# Build the library:
g++ -c -o obj/foo.o src/foo.cpp -fPIC
g++ -shared -o lib/foo.sh obj/foo.o
# Build the executable:
g++ -c -o obj/main.o src/main.cpp
g++ -o run/main.run obj/main.o -Wl,-rpath,'$ORIGIN/../../lib' -Llib -l:foo.sh
В каталоге project запустите make.sh (убедитесь, что он выполним).
Структура файла (после сборки):
-
project/-
src/-
foo.cpp -
main.cpp
-
-
obj/-
foo.o -
main.o
-
-
lib/-
foo.so
-
-
run/-
main.run
-
-
make.sh
-
run/main.run теперь должен загружать lib/foo.sh при выполнении из любой точки.
Проблемы
В настоящее время это работает только частично.
Файлы компилируются и имеют ссылку OK, но при запуске из любого каталога он не может связываться, кроме project (который является точкой упражнения).
Проверка main.run на readelf -d показывает: 0x0000000000000001 (NEEDED) Shared library: [lib/foo.sh] 0x000000000000000f (RPATH) Library rpath: [$ORIGIN/../../lib]
Что выглядит близко (я бы предпочел [foo.sh], чем [lib/foo.sh], но я исправлю это позже).
AFAICT $ORIGIN в -Wl,-rpath,'$ORIGIN/../../lib' означает project/run/main.run, поэтому этот путь rpath должен стать project/lib.
Я пробовал $ORIGIN/.., $ORIGIN/../lib, $ORIGIN/../.., $ORIGIN/../../lib безрезультатно.
Примечание. Я использую -l:, для которого требуется полное имя файла библиотеки (среди других причин проще script с переменными, когда все функции принимают одинаковый формат имени).
Кто-нибудь знает, почему это не работает?
Или поочередно, есть ли кто-либо или знаете полный рабочий пример?