注:完全に機能する例を以下に示します。元の質問は次のとおりです。
ldの-rpath
パラメータを。で使用すると問題が発生します$ORIGIN
。
完全な例が見つからなかったので、後で自分や他の人が使えるように、自分で書いてみようと思いました。動作するようになったら、片付けます。
以前に質問しましたが、私の投稿は少し混乱していたと思います。
サンプルプロジェクトは、1つの共有ライブラリとそのライブラリにリンクする1つの実行可能ファイルをビルドします。
非常に小さいです(3ファイル、ビルドスクリプトを含む22行)。ここ
からプロジェクトをダウンロードできます
ファイル構造(ビルド前):
project/
src/
foo.cpp
main.cpp
make.sh
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/
foo.cpp
main.cpp
obj/
foo.o
main.o
lib/
foo.so
run/
main.run
make.sh
run/main.run
lib/foo.sh
これで、どこからでも実行時にロードされるはずです。
問題
現在、これは部分的にしか機能しません。ファイルはコンパイルされ、リンクはOKですが、(演習のポイントである)
以外のディレクトリから実行するとリンクに失敗します。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
inは、このrpathがになるようにすることを-Wl,-rpath,'$ORIGIN/../../lib'
意味します。project/run/main.run
project/lib
私は、、、、無駄にしようとしました$ORIGIN/..
。$ORIGIN/../lib
$ORIGIN/../..
$ORIGIN/../../lib
注:私は-l:
完全なライブラリファイル名を必要とするものを使用しています(他の理由の中でも、すべての関数が同じ名前形式をとる場合、変数を使用してスクリプトを作成する方が簡単です)。
なぜこれが機能しないのか誰かが知っていますか?
または、代わりに、誰かが完全な実例を持っているか知っていますか?