ライブラリパスの設定を指定する方法は?


91

私が使用したC ++プログラムをコンパイルしていますg++ld.soリンク時に使用したいライブラリがあります。ただし、同じ名前のライブラリがに存在し/usr/local/libld直接指定しているライブラリよりもそのライブラリを選択しています。どうすれば修正できますか?

以下の例では、私のライブラリファイルは/my/dir/libfoo.so.0です。私が試したことはうまくいきません:

  • 私のg ++​​コマンドは g++ -g -Wall -o my_binary -L/my/dir -lfoo bar.cpp
  • en`変数の/my/dir先頭または末尾に追加する$PATH
  • /my/dir/libfoo.so.0引数としてg ++に追加する

1
他にどのようなlibfoo.*ファイルが存在し、 - .soW / O .0.a、などなど?
Alex Martelli、2010

回答:


92

新しいライブラリのパスを追加しますLD_LIBRARY_PATH(Macでは名前が少し異なります...)

ソリューションは-L/my/dir -lfooオプションを使用して動作するはずです。実行時にLD_LIBRARY_PATHを使用してライブラリの場所を指定します。

LD_LIBRARY_PATHを使用する場合の注意 - 要約すると(リンクから):

..implications ..:
Security:LD_LIBRARY_PATHで指定されたディレクトリが標準の場所の前に検索される(!)ことを覚えていますか?このようにして、悪意のある人がアプリケーションに悪意のあるコードを含む共有ライブラリのバージョンをロードさせる可能性があります。これが、setuid / setgid実行可能ファイルがその変数を無視する理由の1つです!
パフォーマンス:リンクローダーは、共有ライブラリが存在するディレクトリが見つかるまで、指定されたすべてのディレクトリを検索する必要があります。すべての共有ライブラリに対して、アプリケーションはリンクされます!これは、open()への多くのシステムコールを意味し、「ENOENT(そのようなファイルまたはディレクトリはありません)」で失敗します!パスに多くのディレクトリが含まれている場合、失敗した呼び出しの数は直線的に増加し、アプリケーションの起動時間からそれを知ることができます。ディレクトリの一部(またはすべて)がNFS環境にある場合、アプリケーションの起動時間が長くなり、システム全体の速度が低下する可能性があります。
矛盾:これは最も一般的な問題です。LD_LIBRARY_PATHは、アプリケーションに、リンクされていない共有ライブラリを強制的にロードさせます。これは、元のバージョンと互換性がない可能性が非常に高いです。これは非常に明白である可能性があります。つまり、アプリケーションがクラッシュするか、選択したライブラリが元のバージョンで行っていたはずの動作を行わない場合、誤った結果が生じる可能性があります。特に後者はデバッグが難しい場合があります。

または

リンカーへのgccを介してrpathオプションを使用-ランタイムライブラリの検索パス。標準のdir(gccオプション)を検索する代わりに使用されます。

-Wl,-rpath,$(DEFAULT_LIB_INSTALL_PATH)

これは一時的な解決策に適しています。リンカーは、まず標準のディレクトリを調べる前に、LD_LIBRARY_PATHでライブラリを検索します。

LD_LIBRARY_PATHを永続的に更新したくない場合は、コマンドラインで即座に更新できます。

LD_LIBRARY_PATH=/some/custom/dir ./fooo

リンカーが知っているライブラリを確認することができます(例):

/sbin/ldconfig -p | grep libpthread
        libpthread.so.0 (libc6, OS ABI: Linux 2.6.4) => /lib/libpthread.so.0

また、アプリケーションが使用しているライブラリを確認できます。

ldd foo
        linux-gate.so.1 =>  (0xffffe000)
        libpthread.so.0 => /lib/libpthread.so.0 (0xb7f9e000)
        libxml2.so.2 => /usr/lib/libxml2.so.2 (0xb7e6e000)
        librt.so.1 => /lib/librt.so.1 (0xb7e65000)
        libm.so.6 => /lib/libm.so.6 (0xb7d5b000)
        libc.so.6 => /lib/libc.so.6 (0xb7c2e000)
        /lib/ld-linux.so.2 (0xb7fc7000)
        libdl.so.2 => /lib/libdl.so.2 (0xb7c2a000)
        libz.so.1 => /lib/libz.so.1 (0xb7c18000)

21
LD_LIBRARY_PATHは、実行時に設定され、コンパイル時に設定されLIBRARY_PATHます。gcc.gnu.org/onlinedocs/gcc/Environment-Variables.htmlを
Bjoern Dahlgren

1
ライブラリがシステムライブラリと完全に異なる場合、つまり常に使用するライブラリである場合は、rpathソリューションを使用してください。LD_LIBRARY_PATHはテスト用のハックであり、実行可能ファイルを正しく機能させるために必要ではありません。
user2746401 2015年

1
Mac用のDYLD_LIBRARY_PATH
cbinder 2015年

ここでは、この回答に基づいて動作します(C用)の完全なサンプルコマンドは次のとおりです。gcc myFile.c -o myFile.o -l myLibraryBaseName -Wl,-rpath,locationOfMyLibrary -L locationOfMyLibrary
ジェットブルー

25

これは古い質問ですが、誰もこれについて言及していないようです。

あなたは幸運なことに、すべてがリンクしていた。

変える必要があった

g++ -g -Wall -o my_binary -L/my/dir -lfoo bar.cpp

これに:

g++ -g -Wall -o my_binary -L/my/dir bar.cpp -lfoo

リンカーは、解決する必要があるシンボルを追跡します。最初にライブラリを読み取る場合、必要なシンボルがないため、ライブラリ内のシンボルは無視されます。リンクする必要があるものの後にライブラリーを指定して、リンカーがライブラリー内で検索するシンボルを持つようにします。

また、必要に応じて、または-lfooという名前のファイルを検索します。ない。したがって、ライブラリの名前または名前を適切なものに変更します。libfoo.alibfoo.solibfoo.so.0ln

gccのmanページを引用するには:

-l library
   ...
   It makes a difference where in the command you 
   write this option; the linker searches and processes 
   libraries and object files in the order they are 
   specified.  Thus, foo.o -lz bar.o searches library z 
   after file foo.o but before bar.o.  If bar.o refers 
   to functions in z, those functions may not be loaded.

ファイルをg++のコマンドラインに直接追加しても問題ありませんが、もちろんそれをの前に置いbar.cppて、必要なシンボルがないためにリンカがファイルを無視するようにします。シンボルがまだ必要ないためです。


21

ライブラリへの絶対パスを指定すると問題なく機能します。

g++ /my/dir/libfoo.so.0  ...

-lfoo絶対パスを追加したら、削除したことを覚えていますか?


1
このソリューションは私にとってもうまくいきました-ディストリビューション開発パッケージ以外のQt5のバージョンに対してリンクを張ろうとしました。ありがとう。
wump

これを@バージョン付きシンボルで機能させるにはどうすればよいですか?最小限の例:github.com/cirosantilli/cpp-cheat/blob/...
チロSantilli郝海东冠状病六四事件法轮功

11

別の方法として、-Lおよび-Iオプションを指定せずに、ライブラリを探す場所とヘッダーを探す場所を示す環境変数LIBRARY_PATHとを使用することもできますCPLUS_INCLUDE_PATH(これCPATHも機能します)。

編集: CPATHを有するヘッダを含む-ICPLUS_INCLUDE_PATHして-isystem


使用例を追加していただけませんか?
Hanna Khalil、2016年

export LIBRARY_PATH = /path/to/libコンパイルしているのと同じコンソールセッションで
Alexandre Hamez

0

WindowsでDLLを操作するために使用され、linux / QTで.soバージョン番号をスキップしたい場合、追加CONFIG += pluginするとバージョン番号が削除されます。.soへの絶対パスを使用して、リンカにそれを与えることは、Klatchko氏が述べたようにうまく機能します。

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