ライブラリの場所をバイナリにどのように指定しますか?(Linux)


34

この質問では、特定の例を使用しますが、実際には、これは依存ライブラリを見つけることができないLinux上のほとんどすべてのバイナリに一般化されます。だから、私はライブラリがないために実行されないプログラムを持っています:

./cart5: error while loading shared libraries: libcorona-1.0.2.so: cannot open shared object file: No such file or directory

lddはこの問題にいくつかの光を当てています。

linux-vdso.so.1 =>  (0x00007fff18b01000)
libcorona-1.0.2.so => not found
libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.3/libstdc++.so.6 (0x00007f0975830000)
libm.so.6 => /lib/libm.so.6 (0x00007f09755af000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007f0975399000)
libc.so.6 => /lib/libc.so.6 (0x00007f0975040000)
libz.so.1 => /lib/libz.so.1 (0x00007f0974e2b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0975b36000)

ただし、コロナはインストールされます。

oliver@human$ find / -name libcorona-1.0.2.so 2> /dev/null

/usr/local/lib64/libcorona-1.0.2.so
/home/oliver/installed/corona-1.0.2/src/.libs/libcorona-1.0.2.so

「見つからない」ライブラリを探す場所をバイナリに指示するにはどうすればよいですか?

回答:


43

1回限りの場合は、変数LD_LIBRARY_PATHを検索するディレクトリのコロン区切りリストに設定します。これはPATH、実行可能ファイルに似ていますが、標準システムディレクトリが、環境で指定されたディレクトリの後に追加で検索される点が異なります。

LD_LIBRARY_PATH=/usr/local/lib64 ./cart5

ライブラリを標準以外の場所に保持し、それ自体でライブラリを見つけることができないプログラムがある場合、ラッパースクリプトを作成できます。

#!/bin/sh
if [ -n "$LD_LIBRARY_PATH" ]; then
  LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib64
else
  LD_LIBRARY_PATH=/usr/local/lib64
fi
export LD_LIBRARY_PATH
exec /path/to/cart5 "$@"

標準システムディレクトリのリストはに保持され/etc/ld.so.confます。最近のシステムでは、このファイルに他のファイルを含めることができます。yoursにのようなものが含まれている場合include /etc/ld.so.conf.d/*.conf/etc/ld.so.conf.d/mala.conf追加するディレクトリを含む新しいファイルを作成します。変更し/etc/ld.so.confたファイルまたはインクルードしたファイルを実行/sbin/ldconfigした後、変更を有効にします(これによりキャッシュが更新されます)。

LD_LIBRARY_PATHまた、FreeBSDの、NetBSDの、OpenBSDの、SolarisとのTru64など、他の多くのUnixにも適用されます。HP-UXが持っているSHLIB_PATHとMac OS Xを持っているがDYLD_LIBRARY_PATH/etc/ld.so.confより広く、ほとんどのUnix上の類縁体が、場所や構文異なっています。)


1
素晴らしい、ありがとう。/etc/ld.so.confについてはまったく知りませんでしたが、将来的には非常に役立ちます。
マラ

15

LD_LIBRARY_PATHを回避したい場合は、リンク中にこれを行うこともできます。

gcc -o exename -L/path/to/dynamiclib/ -lnameofLib \
    -Wl,-R/path/to/dynamiclib/ sourceCode1.c ...

-Wl、...は、追加のコマンドをリンカーに渡すために使用されます。この場合、-Rを使用すると、このパスを.soの「デフォルト検索パス」として保存するようにリンカーに指示します。

私のサイトでは、このような多くの小さなヒントをメモしています。

https://www.thanassis.space/tricks.html


ただし、問題のライブラリ自体が検索する共有ライブラリを持っている場合、バイナリに格納されているrpathはサブライブラリの検索に再帰的に適用されません。私は...その後、再帰的検索に適用されますない環境でLD_LIBRARY_PATHを設定するよりも、この他の周りの方法を発見していない
イーサン・

@イーサン:本当。しかし、本当のことは、いくつかのバイナリ用の共有ライブラリを「パッケージ化」する通常のシナリオは、それらをすべて一緒に配置することです。たとえば/opt/mypackage/bin/someBinary、に保存するライブラリが必要になります/opt/mypackage/lib/。/ optの下にインストールされたほとんどすべてのプロプライエタリSWはこのルールに従います。つまり、上記の方法ですべてのそのようなインストールがカバーされます。その後、通常は/ opt /の下のバイナリを指すシンボリックリンクを/ usr / binの下に追加します-「デフォルトの検索パス」が.so適切な/opt/.../libフォルダーの下でs を見つけることを知っています。
ttsiodras

ええ、私の場合は私が...そのビルドディレクトリにリンクではなく、それをインストールすることによって、パッケージをテストしたいと思った(ただし、パッケージには、いくつかの内部の.soのいくつかの相互依存関係を持っていた...の回避策の多様ちょうど迷惑)
イーサン

0

これは、libcoronaが正しいパスにインストールされていないことを示しています。libcoronaディレクトリを正しいパスに移動すると、問題は解決されます。


これは他の答えよりもどうですか?
トト

@Totoは他の答えとは異なり、基本的に手動でファイルをインストールしています...それはこの答えが必ずしも良いというわけではありませんが、考慮すべきオプションです(Windowsでもライブラリをコピーすることでこれを行います) system32 / sysWOW64(アプリがそれらを見つけられない場合)、推奨されているものではありません。
Tcll
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.