Ресурсивная линковка с помощью rpath

Я хотел бы создать исполняемый файл (exec), который связывает динамическую библиотеку (shared2), которая связывает другую общую библиотеку (shared1), чтобы мне не нужно было указывать shared1 в make-файле exec. В частности, shared2 указывает -rpath на shared1, но когда я компилирую exec, этот rpath оценивается относительно exec, а не shared2. Это потребовало от меня указать -rpath к shared1 внутри exec (чего я хочу избежать).

Следующий пример с игрушкой иллюстрирует мою точку зрения:

Дерево каталогов это:

Exec
    main.cpp
    makefile
shared2
    shared2
        shared2.cpp
        shared2.h
        makefile
shared1
    shared1.cpp
    shared1.h
    makefile

Exec/создать файл

app: main.o
    g++ main.o -o app -L../shared2/shared2 -Wl,-rpath,../shared2/shared2 -lshared2 #-Wl,-rpath,../shared1

main.o: main.cpp
    g++ -g -c -o main.o main.cpp -I../shared2/shared2

clean:
    rm -f app main.o

общий2/общий2/сделать файл

libshared2.so: shared2.o
    g++ -shared shared2.o -o libshared2.so -L../../shared1 -Wl,-rpath,../../shared1 -lshared1 

shared2.o: shared2.cpp
    g++ -fPIC -g -c -o shared2.o shared2.cpp -I../../shared1

clean:
    rm -f libshared2.so shared2.o

общий1/сделать файл

libshared1.so: shared1.o
    g++ -shared shared1.o -o libshared1.so

shared1.o: shared1.cpp
    g++ -fPIC -g -c -o shared1.o shared1.cpp

clean:
    rm -f libshared1.so shared1.o

Я заставил main.cpp использовать что-то из shared2.cpp, а что-то в shared2.cpp использовать что-то из shared1.cpp.

Когда я перехожу к компиляции Exec/makefile, rpath, указанный в shared2/shared2/makefile, оценивается относительно местоположения Exec/makefile, и, следовательно, компиляция завершается неудачно. Обратите внимание, что часть, которую я процитировал в первом make-файле, необходима для его успешного выполнения, но я хотел бы избежать этого.

Есть ли обходной путь?

Большое спасибо :)


person megavore    schedule 06.02.2014    source источник


Ответы (1)


Предполагая, что вы заботитесь о Linux или Solaris, измените это:

libshared2.so: shared2.o
    g++ -shared shared2.o -o libshared2.so -L../../shared1 \
        -Wl,-rpath,../../shared1 -lshared1

К этому:

libshared2.so: shared2.o
    g++ -shared shared2.o -o libshared2.so -L../../shared1 \
       -Wl,-rpath,'$$ORIGIN/../../shared1' -lshared1

Примечание. Одинарные кавычки вокруг $$ORIGIN обязательны.

person Employed Russian    schedule 07.02.2014
comment
Уважаемый Employed Russian, Спасибо за ваш ответ. Когда я делаю, как вы предложили, когда он компилирует exec, я получаю /usr/bin/ld: предупреждение: libshared1.so, необходимое для ../shared2/shared2/libshared2.so, не найдено (попробуйте использовать -rpath или -rpath -ссылка) ../shared2/shared2/libshared2.so: неопределенная ссылка на `func1()' collect2: ошибка: ld вернул 1 статус выхода Я использую Ubuntu 12.04, g++ 4.8 - person megavore; 07.02.2014
comment
Каков результат ldd libshared2.so? - person Brad Lanam; 17.03.2014
comment
@megavore Обратите внимание, что ответ предполагает, что вы редактируете Makefile. Если вы выполняете команду напрямую, вам нужно заменить $$ORIGIN на $ORIGIN (один знак $). - person Employed Russian; 18.03.2014