Я пытаюсь узнать, как использовать параметр -rpath
в компоновщике GCC (ld) с $ORIGIN
.
Я пытаюсь найти самый простой пример (см. Ниже), и все ссылки, которые я прочитал, говорят, что я делаю это правильно.
Однако, когда я запускаю исполняемый файл, он не может найти общий объект, если я не запускаю его из $ORIGIN
.
Использование readelf -d в исполняемом файле (main.run) показывает:
0x0000000000000001 (NEEDED) Shared library: [lib/foo.so]
...
0x000000000000000f (RPATH) Library rpath: [$ORIGIN]
...
Структура файла (соответствующие файлы):
Выполнение изнутри dll_test работает нормально.
Выполнение из другого места (/ make / test) выдает ошибку:
dll_test / main.run: ошибка при загрузке
общие библиотеки: lib / foo.so: невозможно
открыть общий объектный файл: такого файла нет
или каталог
Я использую -l:foo.so
вместо -lfoo
, но это ни на что не должно повлиять (надеюсь).
ИСТОЧНИКИ ФАЙЛОВ
dll_test/src/foo.cpp
int foo()
{ return 1; }
dll_test/src/main.cpp
int foo();
#include <iostream>
int main()
{
std::cout << foo() << std::endl;
}
ПОСТРОЕННЫЙ СКРИПТ
dll_test/make.sh
mkdir -p -v obj
mkdir -p -v lib
g++ -c -o obj/foo.o src/foo.cpp -fPIC
g++ -shared -o lib/foo.so obj/foo.o
g++ -c -o obj/main.o src/main.cpp
g++ -o main.run obj/main.o -Wl,-rpath,'$ORIGIN' -Llib -l:foo.so
Для сборки создайте эти файлы в соответствующих местах и просто запустите "sh make.sh" из dll_test (или там, где находится корень проекта).
Он должен сгенерировать «dll_test / main.run».
Запуск "main.run" из dll_test должен работать (вывод 1).
Запуск "main.run" изнутри dll_test завершается неудачно. Зачем?
Кроме того, путь к foo.so хранится в main.run как [lib / foo.so]. Могу ли я получить его [foo.so], чтобы я мог использовать -Wl, -rpath, '$ ORIGIN / lib'?