Примечание. Полный рабочий пример приведен ниже. Исходный вопрос следует:
У меня проблемы с использованием параметра -rpath
ld с $ORIGIN
.
Поскольку я не смог найти полный пример, я подумал, что постараюсь написать один сам, чтобы я и другие могли использовать его позже. Как только я получу это, я приведу это в порядок.
Я спрашивал об этом раньше , но я думаю, что мой пост был немного запутанным.
В примере проекта создается одна общая библиотека и один исполняемый файл, который ссылается на указанную библиотеку.
Он очень маленький (3 файла, 22 строки, включая buildscript).
Вы можете скачать проект с здесь
Структура файла (перед сборкой):
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/
obj/
lib/
run/
make.sh
run/main.run
теперь должен загружать lib/foo.sh
при выполнении из любого места.
Проблемы
В настоящее время это работает только частично.
Файлы компилируются и связываются нормально, но при запуске из какого-либо каталога, кроме 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:
, для которого требуется полное имя файла библиотеки (среди прочих причин проще создавать сценарии с переменными, когда все функции принимают одинаковый формат имени).
Кто-нибудь знает, почему это не работает?
Или, альтернативно, кто-нибудь знает или знает полный рабочий пример?