Ну, у меня что-то работает.Но я не очень понимаю, почему это работает.Для меня это похоже на ошибку в ld.
Я запустил strace -f -o /var/tmp/strace.out -- g++ ...
для компиляции main.run.Статический компоновщик на самом деле пытается открыть файлы, буквальное имя которых выглядит как «$ ORIGIN / lib / dir / sub / bar.so», среди 20-30 других вещей.(Другими словами, он ищет фактический каталог с именем $ORIGIN
. Серьезно.)
Он также ищет путь -rpath-link для имени "lib / dir / sub / bar.так ", а не просто" bar.so ".Понятия не имею, почему.
В любом случае, это ссылка на main.run, которая работает на меня:
g++ -o run/main.run obj/main.o -Wl,-rpath,'$ORIGIN/../lib/dir' -Wl,-rpath-link,. -Llib/dir -l:foo.so
Она идентична вашей, но со вставленным -Wl,-rpath-link,.
.
[приложение]
Хорошо, я думаю, что вижу, что происходит.Во-первых, статический компоновщик (GNU ld) просто не учитывает $ ORIGIN в библиотеках, с которыми он связывается.
Во-вторых, поведение при использовании -lbar
по сравнению с -l:bar.so
очень отличается.
Выполнить readelf -a
на foo.so
.В вашей сборке он показывает зависимость от "lib / dir / sub / bar.so".Вот почему установка ссылки rpath на "."исправляет сборку main.run;это заставляет статический компоновщик искать "."для "lib / dir / sub / bar.so", который он находит.
Если вы переименуете bar.so в libbar.so и создадите ссылку foo.so, чтобы использовать -lbar
вместо -l:bar.so
,та же самая readelf показывает, что foo.so теперь зависит от "libbar.so" (без компонента path).С этим foo.so вы можете заставить работать ссылку main.run, используя -Wl,-rpath-link,lib/dir/sub
, как и следовало ожидать, если бы вы знали, что статический компоновщик просто не соблюдает $ ORIGIN.
Кстати, яне вижу синтаксиса -l:bar.so
, документированного где-либо в руководстве GNU ld.Из любопытства, как у вас это получилось?
Если предположить, что это поддерживаемая функция, это выглядит как ошибка (-l: bar.so создаёт зависимость от lib / dir / sub / bar.so вместо просто bar.so).Вы можете устранить эту ошибку, установив для rpath-link значение '.'для main.run, или вы можете переименовать материал обычным способом (libxxx.so).