SO(共有オブジェクト)番号はどのように機能しますか?

SO(共有オブジェクト)番号はどのように機能しますか?

Linuxでは、共有オブジェクトが「so number」を使用していることがわかります。つまり、共有オブジェクトの異なるバージョンには異なる拡張子が付与されます。たとえば、次のようになります。

  • example.so.1
  • example.so.2

私は、2つのバージョンのライブラリがシステムに(Windowsの「DLL Hell」の代わりに)存在するように、2つの異なるファイルを持つアイデアを理解しています。これが実際にどのように機能するのか疑問に思います。私はこれが実際にexample.so最新バージョンへのexample.so.2シンボリックリンクであることをよく見ます。.2それでは、以前のバージョンを使用しているアプリケーションはどのようにexample.soそれを正しく識別しますか?どの番号を使用すべきかを規定する規則はありますか?それともこれはコンベンションだけですか?システム間でソフトウェアバイナリが転送されるWindowsとは異なり、システムに最新バージョンの共有オブジェクトがある場合、ソースからコンパイルすると自動的に古いバージョンにリンクされますか?

私はこれが関連していると思いますldconfigが、どうなるかはよくわかりません。

答え1

バイナリ自体は、自分が依存する共有ライブラリのバージョンを知り、具体的に要求します。ldd以下を使用して依存関係を表示できますls

$ ldd /bin/ls
    linux-gate.so.1 =>  (0xb784e000)
    librt.so.1 => /lib/librt.so.1 (0xb782c000)
    libacl.so.1 => /lib/libacl.so.1 (0xb7824000)
    libc.so.6 => /lib/libc.so.6 (0xb76dc000)
    libpthread.so.0 => /lib/libpthread.so.0 (0xb76c3000)
    /lib/ld-linux.so.2 (0xb784f000)
    libattr.so.1 => /lib/libattr.so.1 (0xb76bd000)

ご覧のとおり、これはlibpthread.so.0単なるものではありませんlibpthread.so


シンボリックリンクを使用する理由はリンカのためです。直接接続する場合は、フラグをlibpthread.so指定するとプレフィックスとサフィックスが自動的に追加されます。サフィックスを追加するように指示できないため、シンボリックリンクは追加を容易にするために最新バージョンのライブラリを指します。gcc-lpthreadlib.so.so.0

答え2

共有ライブラリの数は、LinuxでライブラリのAPIを識別するために使用される規則です。一般的な形式は次のとおりです。

libFOO.so.MAJOR.MINOR

ご存知のように、通常はlibFOO.soからlibFOO.so.MAJOR.MINORへのシンボリックリンクがあります。 ldconfigは、このリンクを最新バージョンに更新する役割を果たします。

MAJORは通常、APIが変更されると増加します(新しいエントリポイントが削除されるか、パラメータまたはタイプが変更されます)。 MINORは通常、バグ修正リリースがリリースされたとき、または既存のAPIを中断することなく新しいAPIが導入されると増加します。

より広範な議論はここにあります。共有ライブラリの分析

答え3

共有ライブラリは、次のスキームに従ってバージョンを指定する必要があります。

blah.so.X.Y.Z

どこ

  • X = 以前のバージョンと互換性のない ABI バージョン
  • Y = 以前のバージョンと互換性のあるABIバージョン
  • Z =内部変更のみ可能 - ABI変更なし

hello.so.1他のすべての数字は以前のバージョンと互換性があるため、最初の数字はライブラリの「バージョン」を識別するために必要な唯一の数字であるため、通常は最初の数字のみが表示されます。

ldconfigシステムで使用可能な共有ライブラリとライブラリパスがある場所を一覧表示するテーブルを維持します。次のコマンドを実行してこれを確認できます。

ldconfig -p

Red Hatなどのパッケージをビルドすると、バイナリから呼び出された共有ライブラリはRPMのビルド時に照会され、パッケージの依存関係として追加されます。したがって、パッケージをインストールすると、インストーラはそのパッケージがシステムhello.so.1にすでにインストールされていることを確認しますldconfig

次のようにして、パッケージの依存関係を表示できます。

rpm -qpR hello.rpm

Windowsとは異なり、このシステムでは、hello.so複数のバージョンをシステムにインストールし、同時に他のアプリケーションで使用できます。

答え4

libNAME.so は、-lNAME で指定されたライブラリーを初めて検索するときにコンパイラー/リンカーが使用するファイル名です。共有ライブラリファイル内にSONAMEというフィールドがあります。このフィールドは、ビルドプロセスがライブラリ自体を共有オブジェクト(so)に初めて関連付けるときに設定されます。このSONAMEは、リンクされた共有オブジェクトに応じて、リンカが実際に実行可能ファイルに保存するものです。通常、SONAME は libNAME.so.MAJOR 形式であり、ライブラリが関連付けられている既存の実行可能ファイルと互換性がないときはいつでも変更され、必要に応じてインストールされたライブラリの両方のメジャーバージョンを保持できます。 (例:libNAME.so)また、ライブラリのマイナーバージョン間の簡単なアップグレードをサポートするために、libNAME.so.MAJORは通常、libNAME.so.MAJOR.MINORなどのファイルへのリンクです。新しいマイナーバージョンをインストールできます。完了すると、以前のマイナーバージョンへのリンクが新しいマイナーバージョンに移動し、アップグレードされたライブラリを使用するようにすべての新しい実行をすぐにアップグレードします。私の答えも参照してくださいLinux、GNU GCC、ld、バージョンスクリプト、ELFバイナリ形式 - どのように機能しますか?

関連情報