GNU/Linux >> Linux の 問題 >  >> Linux

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

解決策 1:

LD_LIBRARY_PATH を設定してダイナミック リンカに検索場所を知らせることができますが、より良いオプションがあります。共有ライブラリは、標準的な場所の 1 つに配置できます。/etc/ld.so.conf を参照してください。 (Linux の場合) および /usr/bin/crle (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");
}

hello.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 [email protected] $<
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 $< [email protected]
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!

解決策 2:

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

解決策 3:

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

$ LD_LIBRARY_PATH=. ./binary

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

解決策 4:

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

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

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

解決策 5:

まだ答えが見つからない人のために、私は次の提案で自分自身を見つけました:

sudo ldconfig -v を使用して ld.so.cache を更新してみてください。

私のために働いた.


Linux
  1. Linuxのディレクトリツリーで最も古いファイルを見つける方法

  2. $ pathにあるスクリプトの同じディレクトリの下にあるファイルを参照しますか?

  3. 使用している Fedora のバージョンを確認するにはどうすればよいですか?

  1. C で実行可能ファイルの場所を見つけるにはどうすればよいですか?

  2. Python でファイルまたはディレクトリの所有者を見つける方法

  3. ディレクトリ全体で dos2unix を実行するにはどうすればよいですか?

  1. ディレクトリの md5 チェックサムを計算するにはどうすればよいですか?

  2. buildinfo.sh ファイルはどこにありますか?

  3. Linux の <conio.h> ヘッダー ファイルはどこにありますか? <conio.h> が見つからないのはなぜですか?