G ++ 4.9.2 и 8.2.0 - окончательная зависимость двоичного файла с поиском пути по умолчанию в каталоге ./../lib (неявная проблема RPATH) - PullRequest
2 голосов
/ 18 марта 2020

Я столкнулся со странной разницей между двоичным файлом, созданным 4,9.2 G ++ и 8.2.0 G ++ на Linux, при обновлении с первого на второе. Я смог сузить его до приведенного ниже уменьшенного фрагмента

//main.cpp
int main(){}
//emptylib.cpp
#!/bin/sh
#to build and verify output
rm -rf bin lib *.o

gcc_bin=/path/to/gcc_4.9.2/bin
#gcc_bin=/path/to/gcc_8.2.0/bin

${gcc_bin}/g++ -B${gcc_bin} -c main.cpp
${gcc_bin}/g++ -B${gcc_bin} -c emptylib.cpp
${gcc_bin}/g++ -B${gcc_bin} -shared emptylib.o -o libemptylib.so
${gcc_bin}/g++ -B${gcc_bin} main.o -o main -L. -lemptylib

mkdir bin
mkdir lib
mv libemptylib.so lib/
mv main bin/

ldd bin/main

Результат немного странный, потому что я не предоставил -rpath=../lib, но все же, с 4.9.2 драйвер компилятора, который я получаю (в выводе ldd):

libemptylib.so => /path/to/bin/../lib/libemptylib.so

и 8.2.0

libemptylib.so => not found

, библиотека не разрешается, как я и ожидал , Я не смог увидеть какую-либо документацию, которая намекает на поиск ../lib в любой версии, но я не ожидал бы, что это будет поведение какой-либо версии. Была ли это ошибка в 4.9.2 или более ранней версии или что-то, что не должно было произойти с самого начала?

В качестве примечания, у 8.2.0 и 4.9.2 нет ld внутри их каталога bin (несмотря на то, что я поместил -B в фрагмент кода), поэтому оба драйвера компилятора используют / usr / bin / ld (я проверял столько же) и выдают разные результаты на основе Только драйвер компилятора.

Обновление:

По запросу я запустил readelf -d bin/main в обоих двоичных файлах и получил разные выходные данные для rpath. G CC 4.9.2 дал мне:

0x000000000000000f (RPATH)    Library rpath: [$ORIGIN:$ORIGIN/../lib64:$ORIGIN/../lib:/path/to/gcc_libs/lib64:/path/to/gcc_libs/lib:/path/to/gcc_4.9.2/lib64:/path/to/gcc_4.9.2/lib]

, где у 8.2.0 этого не было

0x0000000000000001 (NEEDED)   Shared Library: [libemptylib.so]

Так что, думаю, у меня есть ответ на то, что произошло. Так, как это закончилось в моем двоичном в 4.9.2, и почему это изменилось между этими двумя версиями, где теперь это не в 8.2.0?

1 Ответ

0 голосов
/ 19 марта 2020

Я получил другой вывод для rpath. rpath: [$ORIGIN:$ORIGIN/../lib64:$ORIGIN/../lib:/path/to/gcc_libs/lib64:/path/to/gcc_libs/lib:/path/to/gcc_4.9.2/lib64:/path/to/gcc_4.9.2/lib]

Таким образом, разница в том, как были настроены G CC 4.9.2 и 8.2.0.

Я предполагаю, что 8.2 пришел из вашего дистрибутива (или по крайней мере был настроен с путями установки по умолчанию), тогда как 4.9 был настроен для установки в /path/to/gcc_4.9.2.

Это объясняет, почему 4.9 добавляет -rpath с /path/to/gcc_4.9.2/lib64 для 64-битных сборок. Однако он не объясняет, откуда взято $ORIGIN из /path/to/gcc_4.9.2/lib (последнее не должно быть частью 64-битной сборки).

Конфигурирование G CC, чтобы он точно поместил что нужно, не больше и не меньше, это немного чёрных магов c. Я не удивлюсь, если в 4.9 появятся ошибки в этой области.

...