実行するls -l
と、拡張機能/usr/lib
付きのライブラリがたくさん表示されます。"sameName.so.*.*"
- これらの拡張機能の重要性は何ですか?
- ソフトリンクが作成される理由 それらの用途は何ですか?
一例が理解に大いに役立ちます。
これは、共有オブジェクト ファイルのバージョン管理に使用されるトリックです。これは、遅延リンクが原因で発生した恐ろしい DLL 地獄を回避する方法です。
遅延リンク (または遅延バインディング) の利点は、実行可能ファイルを実際に再リンクすることなく、実行可能ファイルのコンポーネントを変更できることです。これにより、特に新しい実行可能ファイルを出荷することなく、サードパーティ コンポーネントのバグ修正が可能になります。
デメリットはメリットと全く同じです。実行可能ファイルは、基礎となるライブラリについて行った仮定が変更されていることを検出でき、これがあらゆる種類の問題を引き起こす可能性があります。
共有オブジェクトのバージョン管理は、これを回避する 1 つの方法です。もう 1 つは、オブジェクトをまったく共有しないことですが、これには長所と短所があり、ここでは説明しません。
例として、 のバージョン 1 があるとしxyz.so
ます。ファイルとそのファイルへのシンボリック リンクがあります。
pax> ls -al xyz*
-rw-r--r-- 1 pax paxgroup 12345 Nov 18 2009 xyz.so.1
lrwxrwxrwx 1 pax paxgroup 0 Nov 18 2009 xyz.so -> xyz.so.1
これで、実行可能ファイルを作成してexe1
にリンクすると、実行時にロードする必要があるものとして実行可能ファイルxyz.so
に格納されるように、シンボリック リンクがたどられます。xyz.so.1
そのようにして、共有ライブラリを次のようにアップグレードすると:
pax> ls -al xyz*
-rw-r--r-- 1 pax paxgroup 12345 Nov 18 2009 xyz.so.1
-rw-r--r-- 1 pax paxgroup 67890 Nov 18 2009 xyz.so.2
lrwxrwxrwx 1 pax paxgroup 0 Nov 18 2009 xyz.so -> xyz.so.2
元の実行可能ファイルexe1
は引き続き共有オブジェクトのバージョン 1 をロードします。
ただし、ここで作成する実行可能ファイル ( などexe2
) は、バージョン 2 の共有オブジェクトにリンクされます。
実際の実装の詳細は多少異なる場合があります (私の回答は以前の UNIX に基づいており、Linux はシンボリック リンクをたどるよりももう少しインテリジェントにバージョン管理を行っているようです)。IBM developerWorks には、それがどのように行われたかについてのすばらしい記事があります。
共有オブジェクトを作成するときは、実際の名前とsoname
. これらは、共有オブジェクトをインストールするために使用されます (オブジェクトとそのリンクの両方を作成します)。
したがって、次のような状況になる可能性があります。
pax> ls -al xyz*
-rw-r--r-- 1 pax paxgroup 12345 Nov 18 2009 xyz.so.1.5
lrwxrwxrwx 1 pax paxgroup 0 Nov 18 2009 xyz.so.1 -> xyz.so.1.5
lrwxrwxrwx 1 pax paxgroup 0 Nov 18 2009 xyz.so -> xyz.so.1
のをxyz.so.1.5
持っています。SONAME
xyz.so.1
リンカーが にリンクするとxyz.so
、 までリンクをたどり、そのをxyz.so.1.5
使用して実行可能ファイルに格納します。次に、実行可能ファイルを実行すると、特定の(バージョン 1.5 である必要はありません)を指すものをロードしようとします。SONAME
xyz.so.1
xyz.so.1
xyz.so.1.N
そのため、リンクをインストールxyz.so.1.6
して更新し、xyz.so.1
代わりにそれを指すようにすると、既にリンクされている実行可能ファイルが代わりにそれを使用します。
この多層方式の利点の 1 つは、互換性がない可能性のある同じ名前のライブラリ ( xyz.so.1.*
、xyz.so.2.*
) を複数持つことができることですが、各メジャー バージョン内では、互換性があると想定されているため、それらを自由にアップグレードできます。
新しい実行可能ファイルをリンクする場合:
xyz.so
と、最新のメジャー バージョンの最新のマイナー バージョンが取得されます。xyz.so.1
のものは、特定のメジャー バージョンの最新のマイナー バージョンを取得します。xyz.so.1.2
のものは、特定のメジャー バージョンの特定のマイナー バージョンを取得します。これは、共有ライブラリのバージョン管理スキームです。すべてのライブラリには 3 つの名前が必要です。
libfoo.so.1.2.3
libfoo.so.1.2
。この名前は、実際にはライブラリ バイナリ自体の内部に書き込まれ、リンク時に実行可能ファイルに記録されます。これは通常、ライブラリの実際の名前 (通常は最新バージョン) へのシンボリック リンクです。libfoo
バージョン 1がインストールされているとします: libfoo.so
-> libfoo.so.1.0
-> libfoo.so.1.0.0
. でプログラムbar
をビルドします-lfoo
。SONAME により、実行時にリンクされlibfoo
、ロードされるようになりました。次に、実際のバイナリを置き換えることによりlibfoo.so.1.0
、パッチが適用されているがバイナリ互換性があるものにアップグレードします。まだリンクしており、再構築する必要はありません。libfoo.so.1.0.1
bar
libfoo.so.1.0
baz
ここで、libfoo v1.1 の互換性のない変更を利用する新しいプログラムを作成したいとします。新しいバージョンをインストールすると、システムに 2 つのバージョンが並行してインストールされます。
libfoo.so.1.0
->libfoo.so.1.0.1
libfoo.so
-> libfoo.so.1.1
->libfoo.so.1.1.0
リンカー名が最新バージョンに更新されたことに注意してください (これは、でインストールしたヘッダーに対応するバージョンです/usr/include
)。
をビルドすると、実行時baz
にリンクしlibfoo.so
てロードされます。libfoo.so.1.1
それはbar
まだ実行libfoo.so.1.0
されておらず、更新する必要はありません。