リンク/コンパイル時にインクルード共有オブジェクトを定義する方法を理解しています。ただし、実行時に実行可能ファイルが共有オブジェクト(*.so
ライブラリ)をどのように検索するのかはまだ疑問です。
たとえば、私のアプリa.out
はlib.so
ライブラリで定義された関数を呼び出します。コンパイル後、lib.so
を$HOME
の新しいディレクトリに移動します。
a.out
にそこを探しに行くにはどうすればよいですか?
共有ライブラリHOWTO は関連するメカニズムのほとんどを説明し、 ダイナミックローダーマニュアル はより詳細に説明します。それぞれのUNIXバリアントには独自の方法がありますが、ほとんどは同じ実行可能形式( [〜#〜] elf [〜#〜] )を使用し、同様の 動的リンカー ( Solaris)。以下では、Linuxに焦点を当てて一般的な動作を要約します。詳細については、システムのマニュアルを確認してください。
簡単に言えば、動的ライブラリ(.so
ファイル)を探すときに、リンカーは次のことを試みます。
LD_LIBRARY_PATH
環境変数にリストされたディレクトリ(OSXではDYLD_LIBRARY_PATH
)。/etc/ld.so.conf
に加えて/lib
と/usr/lib
のエントリで構成されます。Rpathは実行可能ファイルに格納されます(これはDT_RPATH
またはDT_RUNPATH
動的属性です)。絶対パスまたは$Origin
で始まるパスを含めて、実行可能ファイルの場所を基準とした相対パスを示すことができます(たとえば、実行可能ファイルが/opt/myapp/bin
にあり、そのrpathが$Origin/../lib:$Origin/../plugins
である場合、動的リンカーは/opt/myapp/lib
および/opt/myapp/plugins
を調べます)。 rpathは通常、_ld
の-rpath
オプションを使用して実行可能ファイルをコンパイルするときに決定されますが、後で chrpath
を使用して変更できます。
説明するシナリオで、あなたがアプリケーションの開発者またはパッケージャーであり、…/bin
、…/lib
構造体にインストールされることを意図している場合は、-rpath='$Origin/../lib'
とリンクします。ビルド済みのバイナリをシステムにインストールする場合は、ライブラリを検索パスのディレクトリ(システム管理者の場合は/usr/local/lib
、それ以外の場合は$LD_LIBRARY_PATH
に追加するディレクトリ)に置くか、chrpath
。
Linuxでは、動作はld(1)
のmanページで明示されています
The linker uses the following search paths to locate required shared libraries: 1. Any directories specified by -rpath-link options. 2. Any directories specified by -rpath options. The difference between -rpath and -rpath-link is that directories specified by -rpath options are included in the executable and used at runtime, whereas the -rpath-link option is only effective at link time. Searching -rpath in this way is only supported by native linkers and cross linkers which have been configured with the --with-sysroot option. 3. On an ELF system, for native linkers, if the -rpath and -rpath-link options were not used, search the contents of the environment variable "LD_RUN_PATH". 4. On SunOS, if the -rpath option was not used, search any directories specified using -L options. 5. For a native linker, the search the contents of the environment variable "LD_LIBRARY_PATH". 6. For a native ELF linker, the directories in "DT_RUNPATH" or "DT_RPATH" of a shared library are searched for shared libraries needed by it. The "DT_RPATH" entries are ignored if "DT_RUNPATH" entries exist. 7. The default directories, normally /lib and /usr/lib. 8. For a native linker on an ELF system, if the file /etc/ld.so.conf exists, the list of directories found in that file. If the required shared library is not found, the linker will issue a warning and continue with the link.
ここでの答えはldconfig
だと思います。
ldconfigは、コマンドラインで指定されたディレクトリ、ファイル/etc/ld.so.conf、および信頼されたディレクトリ(/ libおよび/ usr/lib)にある最新の共有ライブラリへの必要なリンクとキャッシュを作成します。キャッシュは、実行時リンカーld.soまたはld-linux.soによって使用されます。 ldconfigは、リンクを更新する必要があるバージョンを決定するときに、ライブラリのヘッダーとファイル名を確認します。
アプリケーションを実行するには、ファイル/proc/1234/maps
には、実際に動的にリンクされたすべてのライブラリが含まれています。
どこ 1234
は実行中の実行可能ファイルのPIDです。
Gillesの回答で指摘されているように、LinuxはLD_LIBRARY_PATHおよびその他の変数に従います。