実行可能ファイルと同じディレクトリに.soが見つかりませんか?


45

libtest.so動的にリンクする必要がある実行可能ファイルがあるので、それらを同じディレクトリに入れてから:

cd path_to_dir
./binary

しかし、これを得た:

error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory

libtest.so実行可能ファイル自体と同じディレクトリに既にあるものを見つけることができないのはどうしてですか?

回答:


25

ローダーは、経由で明示的に指示されない限り、共有オブジェクトの現在のディレクトリをチェックしません$LD_LIBRARY_PATH。詳細については、ld.so(8)manページを参照してください。


echo $LD_LIBRARY_PATH私のマシンでは空です:
linuxer


2
ローダーがライブラリを探すための追加ディレクトリを指定します。
イグナシオバスケス-エイブラムス

1
* nixのパス:は、セミコロンではなくコロン()で区切られます。
イグナシオバスケス-エイブラムス

3
LD_LIBRARY_PATHは通常、実稼働環境では適切な選択ではありません。素早いハックや、単体テストの実行時にアンインストールされたバイナリーが共有ライブラリーを見つけるのを助けるようなものです(./configure; make; make checkを考えてください)。バイナリをビルドするときは、ライブラリを標準の場所(/etc/ld.so.confにリストされている)に置くか、-Rフラグをリンカーに渡して、バイナリに場所を知らせます。
オートマトン

57

LD_LIBRARY_PATHを設定して、動的リンカーに参照先を知らせることができますが、より良いオプションがあります。共有ライブラリを標準の場所のいずれかに配置できます。これらの場所のリストについては/etc/ld.so.conf/usr/bin/crle(Linuxの場合)および(Solarisの場合)を参照してください

-R <path>バイナリをビルドするときにリンカーに渡すことができます。これ<path>により、共有ライブラリ用にスキャンされるディレクトリのリストに追加されます。以下に例を示します。最初に、問題を示します。

libtest.h:

void hello_world(void);

libtest.c:

#include <stdio.h>
void hello_world(void) {
  printf("Hello world, I'm a library!\n");
}

こんにちはC:

#include "libtest.h"
int main(int argc, char **argv) {
  hello_world();
}

Makefile(タブを使用する必要があります):

all: hello
hello: libtest.so.0
%.o: %.c
        $(CC) $(CFLAGS) -fPIC -c -o $@ $<
libtest.so.0.0.1: libtest.o
        $(CC) -shared -Wl,-soname,libtest.so.0 -o libtest.so.0.0.1 libtest.o
libtest.so.0: libtest.so.0.0.1
        ln -s $< $@
clean:
        rm -f hello libtest.o hello.o libtest.so.0.0.1 libtest.so.0

実行してみましょう:

$ make
cc  -fPIC -c -o libtest.o libtest.c
cc -shared -Wl,-soname,libtest.so.0 -o libtest.so.0.0.1 libtest.o
ln -s libtest.so.0.0.1 libtest.so.0
cc     hello.c libtest.so.0   -o hello
$ ./hello 
./hello: error while loading shared libraries: libtest.so.0: cannot open shared object file: No such file or directory

修正方法 -R <path>リンカーフラグに追加します(ここでは、設定しますLDFLAGS)。

$ make clean
(...)
$ make LDFLAGS="-Wl,-R -Wl,/home/maciej/src/tmp"
(...)
cc   -Wl,-R -Wl,/home/maciej/src/tmp  hello.c libtest.so.0   -o hello
$ ./hello 
Hello world, I'm a library!

バイナリを見ると、それが必要であることがわかりますlibtest.so.0

$ objdump -p hello | grep NEEDED
  NEEDED               libtest.so.0
  NEEDED               libc.so.6

バイナリは、指定されたディレクトリで、標準の場所とは別にそのライブラリを探します。

$ objdump -p hello | grep RPATH
  RPATH                /home/maciej/src/tmp

バイナリで現在のディレクトリを検索する場合は、RPATHをに設定できます$ORIGIN。ドル記号がmakeによって解釈されないようにする必要があるため、これは少し注意が必要です。これを行う1つの方法を次に示します。

$ make CFLAGS="-fPIC" LDFLAGS="-Wl,-rpath '-Wl,\$\$ORIGIN'"
$ objdump -p hello | grep RPATH
  RPATH                $ORIGIN
$ ./hello 
Hello world, I'm a library!

1
make手動で呼び出すときなど、使用しない場合は、空の文字列に展開されないようにしてg++ください-Wl,-rpath='$ORIGIN'(一重引用符に注意してください)$ORIGIN
モルポーク

14

実行可能ファイルと同じディレクトリから共有オブジェクトをロードするには、単に次を実行します:

$ LD_LIBRARY_PATH=. ./binary

注:システムのLD_LIBRARY_PATH変数は変更されません。変更は、これにのみ影響し、プログラムの実行にのみ影響します。


4

答えが得られずにまだ苦労している人のために、私は次のような提案を見つけました。

次を使用してld.so.cacheの更新を試みることができます。 sudo ldconfig -v

私のために働いた。


私のためにも働いた。
ジョエル

3

ビルドにCMakeを使用している場合はCMAKE_EXE_LINKER_FLAGS、次を設定できます。

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath='$ORIGIN'")

これにより、すべてのビルドタイプ(Debug、Releaseなど)のリンカーフラグが適切に伝達され、最初に現在の作業ディレクトリで.soファイルが検索されます。


0

動的リンカーは、ライブラリを探す場所を決定します。Linuxの場合、動的リンカーは通常GNU ld.so(または互換性の理由で通常同じ動作をする代替手段です)。

ウィキペディアからの引用:

GNU Cライブラリの動的リンカーは、次の場所で共有ライブラリを検索します。

  1. DT_RPATHバイナリの動的セクション属性に(コロンで区切られた)パスが存在し、そのDT_RUNPATH属性が存在しない場合。
  2. 環境変数内の(コロンで区切られた)パス。LD_LIBRARY_PATH実行可能ファイルがsetuid/ setgidバイナリでない場合は、無視されます。LD_LIBRARY_PATHオプション--library-path(例:/lib/ld-linux.so.2 --library-path $ HOME / mylibs myprogram)を指定して動的リンカーを呼び出すと、オーバーライドできます。
  3. DT_RUNPATH存在する場合、バイナリの動的セクション属性の(コロンで区切られた)パス。
  4. ldconfigキャッシュファイル(多くの場合/etc/ld.so.cache)に基づく検索。これには、拡張ライブラリパス(で設定/etc/ld.so.conf)で以前に見つかった候補ライブラリのコンパイル済みリストが含まれます 。ただし、バイナリが-z nodefaultlibリンカーオプションでリンクされている場合、デフォルトのライブラリパスのライブラリはスキップされます。
  5. 信頼できるデフォルトのパス/libで、次に/usr/lib。バイナリが-z nodefaultlibリンカーオプションでリンクされた場合、この手順はスキップされます。

ソース:https : //en.wikipedia.org/wiki/Rpath

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.