soファイルには、共有ライブラリ(コンパイル時にシンボルをロードしてスキャンし、プログラムの起動時に再度ロードしてリンクする)とモジュール(実行時にロードしてリンクする)の2種類があります。共有ライブラリの考え方は、プログラムが特定のバージョンのライブラリを必要とするということです。このバージョンはコンパイル時に決定されます。プログラムがコンパイルされると、ライブラリの新しい(互換性のない)バージョンがインストールされた場合でも、プログラムは引き続き機能するはずです。つまり、新しいバージョンは別のファイルである必要があるため、新しい(または最近コンパイルされた)プログラムが新しいバージョンを使用している間も、古いプログラムは古いライブラリを使用できます。
このシステムを適切に使用するには、プログラムは、必要なライブラリバージョンが引き続きインストールされることを何らかの方法で確認する必要があります。これは、ディストリビューションのパッケージングシステムのタスクの1つです。プログラムを含むパッケージは、必要なバージョンのライブラリパッケージに依存している必要があります。
しかし、あなたはモジュールについて話しているようです。物事はそこで異なります。ld.so(共有ライブラリのロードを処理する)がそれらをロードするものではないため、それらはそのようなバージョンを持っていません。プログラムはこれらのモジュールにバンドルされている必要があります。これにより、モジュールのバージョンは、それらを使用するプログラムと常に互換性があります。これはほとんどのプログラムで機能します。
ただし、プログラムでサードパーティのモジュールが許可されている場合は機能しません。したがって、彼らは独自のバージョン管理システムを考え出すことができます。これはnssが行ったことのようです(私はそれに精通していませんが)。これは、モジュールがどのように見えるかを指定するプロトコルバージョン(現在は2)を定義していることを意味します。定義する必要のあるシンボル、関数が期待する引数、これらの種類のもの。プロトコルのバージョン2に従ってモジュールを作成する場合は、モジュールに.so.2という名前を付ける必要があります(サポートされているバージョンを確認する方法であるため)。互換性のない新しいプロトコル3を作成すると、.so.3の検索が開始されます。モジュールが見つからなくなります。新しいプロトコルもサポートされないため、これは良いことです。