内部にld.so(8) のマニュアルページ、それは言う
ライブラリの依存関係を解決するとき、動的リンカはまず各依存関係文字列にスラッシュが含まれていることを確認します。これは、スラッシュを含むライブラリパス名がリンク時に指定された場合に発生します。スラッシュが見つかると、依存関係文字列は(相対または絶対)パス名として解釈され、そのパス名を使用してライブラリがロードされます。
gcc
スラッシュパスでライブラリをリンクする方法は?私はそれを試しましたが、-l
パスパラメータ自体ではなく、さまざまなパスを取得するために使用するライブラリ名でのみ機能するようです。
次の質問:この方法で相対パスに接続するときの相対パスは何ですか(たとえば、バイナリを含むディレクトリまたは実行時の作業ディレクトリ)。
検索中に見つかったすべてのリンクされたガイドは、およびをRPATH
使用LD_LIBRARY_PATH
して議論されましたRUNPATH
。 .で始まるパスは廃止され、RPATH
ほとんどの議論では相対パスへの接続を許可しますが、上書きされる可能性がある点でわずかに脆弱ですLD_LIBRARY_PATH
。相対パスがより強力であるかどうか疑問に思います(これについて議論する内容が見つからないため、おそらくパスがランタイムディレクトリに相対的であるため)。RUNPATH
$ORIGIN
LD_LIBRARY_PATH
答え1
(今は)gcc
質問のまたはリンク部分を無視し、代わりに次のようにバイナリを修正した場合patchelf
Linuxシステムでは
$ ldd hello
linux-vdso.so.1 => (0x00007ffd35584000)
libhello.so.1 => not found
libc.so.6 => /lib64/libc.so.6 (0x00007f02e4f6f000)
/lib64/ld-linux-x86-64.so.2 (0x00007f02e533c000)
$ patchelf --remove-needed libhello.so.1 hello
$ patchelf --add-needed ./libhello.so.1 hello
$ ldd hello
linux-vdso.so.1 => (0x00007ffdb74fc000)
./libhello.so.1 => not found
libc.so.6 => /lib64/libc.so.6 (0x00007f2ad5c28000)
/lib64/ld-linux-x86-64.so.2 (0x00007f2ad5ff5000)
libhello.so.1
ファイルを含む適切なディレクトリが存在する場合、ライブラリへの相対パスを持つバイナリが作成されました。
$ cd english/
$ ../hello
hello, world
$ cd ../lojban/
$ ../hello
coi rodo
パスがプロセスの作業ディレクトリに相対的であることがわかりました。、これは特にさまざまな問題を引き起こすでしょう。安全 質問。これはおそらく、異なるバージョンのライブラリをテストするなど、生産的な用途に使用できます。patchelf
相対的な作業ディレクトリを複雑にすることなく、2つの異なるバイナリをコンパイルしたり、必要なライブラリからコンパイルする方が簡単になる可能性があります。
コンパイルステップ
libhello
たった一通helloworld
の電話
$ cat libhello.c
#include <stdio.h>
void helloworld(void)
{
printf("coi rodo\n");
}
そしてコンパイル
CFLAGS="-fPIC" make libhello.o
gcc -shared -fPIC -Wl,-soname,libhello.so.1 -o libhello.so.1.0.0 libhello.o -lc
ln -s libhello.so.1.0.0 libhello.so.1
ln -s libhello.so.1.0.0 libhello.so
hello
呼び出しを行うメソッドはhelloworld
次のようにコンパイルされます。
$ cat hello.c
int main(void)
{
helloworld();
return 0;
}
$ CFLAGS="-lhello -L`pwd`/english" make hello
パッチなし
振り返ると、gcc
相対ディレクトリパスを使用するようにコマンドを変更します。
$ gcc -shared -fPIC -Wl,-soname,./libhello.so.1 -o libhello.so.1.0.0 libhello.o -lc
$ cd ..
$ rm hello
$ CFLAGS="-lhello -L`pwd`/lojban" make hello
$ ldd hello | grep hello
./libhello.so.1 => not found
$ english
$ ../hello
hello, world
一般的な方法でライブラリをコンパイルし、必要に応じて使用してくださいpatchelf
。
答え2
リンカーにオプションを渡すだけです。たとえば、ncursesビルドディレクトリ(削除されたライブラリに依存)からテストプログラムを実行するには、次のオプションを使用します(gccコマンドラインから)。
-Wl,-rpath,../lib
相対パス名が含まれています。同じオプションで絶対パス名を含めることができます。
-Wl,-rpath,../lib:/usr/local/ncurses6/lib
これはローカルテストには役立ちますが、さまざまな理由でシステムにインストールするのには適していません。 Debian は 1990 年代からこれに反対する政策を持っていますが、一貫した議論はほとんどありません (例:RPATHの問題一部の情報を収集します。)
答え3
gccを使って簡単にコンパイルする場合は、次のようにします。
gcc -o prog main.c ./liblib.so
コンパイル後、プログラムはthrigの答えと同じように動作します。このコマンドはテスト環境でのみ使用する必要があると思います。