通常、共有オブジェクト (.so) をビルドするときは、mylib.so.2.3.1 などの接尾辞を追加して、バージョンも処理します。あなたのプログラムがこの lib または他の新しいバージョンをロードできることを確認するには、名前付きのリンクを作成します
mylib.so -> mylib.so.2.3.1
mylib.so.2 -> mylib.so.2.3.1
mylib.so.2.3 -> mylib.so.2.3.1
したがって、.so の後のすべては version.sub-version.build (または類似のもの) を表します。また、同じライブラリの複数のバージョンがこのスキームと共存する可能性があり、プログラムを特定のバージョンを使用するように切り替えるために必要なすべてのことです。バージョンに適切なリンクを配置する必要があります。
動的にリンクされた ELF バイナリ (別のライブラリまたは実行可能ファイル) は、共有オブジェクト名または soname を使用します 実行時に実行可能ファイルがリンクされるライブラリを特定します。
ライブラリが ELF 共有ライブラリとして作成されると、コンパイル時のリンク エディタは、ライブラリの SONAME をライブラリ自体に挿入する実行可能ファイルに DT_SONAME フィールドを挿入します。 DT_SONAME は、ELF 標準で次のように定義されています。
<ブロック引用>
この要素は、NULL で終わる文字列の文字列テーブル オフセットを保持し、共有オブジェクトの名前を指定します。オフセットは、DT_STRTAB
に記録されたテーブルへのインデックスです。 エントリ。これらの名前の詳細については、以下の「共有オブジェクト依存関係」を参照してください。
そのため、実行可能ファイルが作成されると、SONAME が埋め込まれます。実行可能ファイルが実行されるときに、動的ライブラリの事前定義された場所にあるファイル内のライブラリを探すためにリンカーによって使用されます。ウィンドウ内の定義済みの場所は、DLL が存在する場所です。 Linux と Mac OS X およびその他の System V 互換システムでは、/lib
になります。 そして /usr/lib
使用するリンカーに依存し、リンカー独自の構成で定義できます。
すべてのイベントで、リンカは soname エントリで指定されたライブラリがそれらの場所のいずれかに存在するかどうかを確認し、存在する場合はそれを使用します。
標準では、soname は STRING であり、バージョニング規則は事後的に事実上の標準になったと述べており、次のようになっていることに注意してください。
soname を libmyname.so.A
にします ライブラリのファイル名を libmyname.so.A.B または libmyname.so.A.B.C にします (MacOSX では libmyname.A.B.dylib です)。 libmyname.so.A.B[.C]?
からソフトリンクを作成する libmyname.so.A
まで .
A
ライブラリの ABI が同じままである間、同じままです。
B
(または B.C
) がマイナー バージョンになります。
Linux では、ライブラリのバージョンがパッケージのバージョン番号と同じであることは非常に一般的です。これには長所と短所があります。
libtool の形式化
GNU libtool は動的ライブラリを構築するためによく使用され、より正式なバージョン管理システムと強力なロジックを備えています。 sonames の libtool バージョン管理システムは非常にうまく機能し、複雑なライブラリに採用されて物事をまっすぐに保ちます。
libtool の下では、バージョン管理は次のようになります:
<ブロック引用>libmylib-最新 .リリース .年齢
libtool の下では、ライブラリが進化するにつれて機能が追加および削除されるという考えがあります。
ライブラリを開発しているとしましょう。バージョンを 0.0.0
として使用することから始めます .
ここで、いくつかのバグを修正するとしましょう。リリースのみを増やします。
そのため、新しい名前は libmylib.0.1.0 または libmylib.0.2.0 などになります. バグを修正するだけで ABI を変更しないリリースごとに.
と言う道中。うーん!このサブ機能をもっとうまくできたので、新しい関数セットを追加して何かを改善することができましたが、他の人がまだあなたのライブラリを使用しているため、古い (非推奨の) 機能をそこに残しています.
ルールは次のとおりです:
<ブロック引用> <オール>各 libtool ライブラリの「0:0:0」のバージョン情報から始めます。
バージョン情報は、ソフトウェアの公開リリースの直前にのみ更新してください。より頻繁な更新は不要であり、現在のインターフェイス番号がより速く大きくなることを保証するだけです.
ライブラリのソース コードが前回の更新以降にまったく変更されていない場合は、リビジョンを増やします (「c:r:a」は「c:r+1:a」になります)。
最後の更新以降に追加、削除、または変更されたインターフェイスがある場合は、current をインクリメントし、リビジョンを 0 に設定します。
最後の公開リリース以降に追加されたインターフェースがある場合は、年齢を増やしてください。
最後の publicrelease 以降に削除または変更されたインターフェイスがある場合は、 age を 0 に設定してください。
詳細については、libtool のドキュメントを参照してください
更新 ...
以下は、私の説明に誤りがあるというコメントでした。回答のコメントに入れることができるよりも少し詳細が必要なわけではないので、以下を参照してください。
最初の反対意見
<ブロック引用>
ここにエラーがあります:Linux では、バージョンは libmylib.(current-age).release.age の形式で、括弧は評価される式を示します。たとえば、Linux で current:revision:age =37:1:1 の GLPK 4.54 は、ライブラリ ファイル libglpk.so.36.1.1 をインストールします。詳細については、たとえば
反論
TLDR:autotools.io は正式なソースではありません。説明Flameeyes は素晴らしい開発者であり、Gentoo のメンテナーの 1 人ですが、それは 彼 でした。 誰が間違いを犯し、libtool 仕様の「経験則」の大まかな解釈を作成しました。これで 99% の確率でシステムが壊れるわけではありませんが、その場しのぎの方法で current を更新する場合は、 :
<ブロック引用>これらの値を扱うときの経験則は次のとおりです。
常に改訂値を増やしてください。
インターフェイスが追加、削除、または変更されるたびに、現在の値を増やします。
ABI に加えられた変更が下位互換性がある場合にのみ、年齢の値を増やしてください。
彼は続けて、Gtk の複数のバージョンを維持するには、ライブラリのバージョンをライブラリ NAME に追加し、バージョン番号を単にダンプするのが最善であると述べています。 (GTK+ と同様):
<ブロック引用>この状況では、ライブラリのバージョン情報の一部をライブラリの名前に追加するのが最善の方法です。これは、Glib の libglib-2.0.so.0 soname によって例示されます。そのためには、theMakefile.am 内の宣言を次のようにする必要があります:
lib_LTLIBRARIES = libtest-1.0.la
libtest_1_0_la_LDFLAGS = -version-info 0:0:0
まあ、それは動的リンクとシンボル解決のバージョン管理の力を完全に台無しにするための単なるクロックポットアプローチです!.彼はただそれをオフにすると言っています。馬の鼻くそ!経験豊富な開発者でさえ、オープン ソース プロジェクトの構築と維持に苦労しており、新しいバージョンのライブラリがインストールされるたびにバイナリが死んでいく状況に常に遭遇しています (バイナリが相互に破壊するため)。
libtool のバージョン管理アプローチは 非常によく考えられています . アルゴリズムです そしてそのステップは順序付けられています 指示 1 6まで 動的にリンクされたライブラリのコードが更新されるたびに、これに従う必要があります。
新規および現在の開発者は、それらを注意深く読み、すばらしいソフトウェアの寿命を通じてライブラリのバージョン番号がどうなるかを視覚化してください。そうすれば、以前にリンクされたすべてのソフトウェアに気付くでしょう。 は常にあなたのすばらしいライブラリの最新かつ正確なバージョンを正しく使用し、それらのどれも使用しません かつ ライブラリの名前に咲く数字を追加する必要はありません (楽しみや美学のためでない限り)。