2.4. GCC でのライブラリーの作成

ライブラリーを作成する手順と、Linux オペレーティングシステムでライブラリーに使用される必要な概念について説明します。

2.4.1. ライブラリーの命名規則

特別なファイルの命名規則をライブラリーに使用します。foo として知られるライブラリーは、libfoo.so ファイルまたは libfoo.a ファイルとして存在する必要があります。この規則は、リンクする GCC の入力オプションでは自動的に理解されますが、出力オプションでは理解されません。

  • ライブラリーにリンクする場合は、-lfoo のように、-l オプションと foo の名前でしか、ライブラリーを指定することができません。

    $ gcc ... -lfoo ...
  • ライブラリーの作成時には、libfoo.solibfoo.a など、完全なファイル名を指定する必要があります。

2.4.2. soname のメカニズム

動的に読み込んだライブラリー (共有オブジェクト) は、soname と呼ばれるメカニズムを使用して、複数の互換性のあるライブラリーを管理します。

前提条件

  • 動的リンクとライブラリーを理解している。
  • ABI の互換性の概念を理解している。
  • ライブラリーの命名規則を理解している。
  • シンボリックリンクを理解している。

問題の概要

動的に読み込んだライブラリー (共有オブジェクト) は、独立した実行ファイルとして存在します。そのため、依存するアプリケーションを更新せずに、ライブラリーを更新できます。ただし、この概念では、以下の問題が発生します。

  • 実際のライブラリーバージョンを特定
  • 同じライブラリーに対して複数のバージョンが必要
  • 複数のバージョンでそれぞれ ABI の互換性を示す

soname のメカニズム

この問題を解決するには、Linux では soname と呼ばれるメカニズムを使用します。

foo ライブラリーの X.Y バージョンは、バージョン番号 (X) が同じ値でマイナーバージョンが異なるバージョンと、ABI の互換性があります。互換性を確保してマイナーな変更を加えると、Y の数字が増えます。互換性がなくなるような、メジャーな変更を加えると、X の数字が増えます。

foo ライブラリーバージョン X.Y は、libfoo.so.x.y ファイルとして存在します。ライブラリーファイルの中に、soname が libfoo.so.x の値として記録され、互換性を指定します。

アプリケーションを構築すると、リンカーが libfoo.so ファイルを検索して、ライブラリーを特定します。この名前のシンボリックリンクが存在し、実際のライブラリーファイルを参照している必要があります。次にリンカーは、ライブラリーファイルから soname を読み込み、アプリケーションの実行ファイルに記録します。最後に、リンカーにより、名前でもファイル名でもなく、soname を使用してライブラリーで依存関係を宣言するアプリケーションが作成されます。

ランタイムの動的リンカーが実行前にアプリケーションをリンクすると、soname がアプリケーションの実行ファイルから読み込まれます。この soname は libfoo.so.x と呼ばれます。この名前のシンボリックリンクが存在し、実際のライブラリーファイルを参照している必要があります。soname が変更しないため、これにより、バージョンの Y コンポーネントに関係なく、ライブラリーを読み込むことができます。

注記

バージョン番号の Y の部分は、1 つの数字である必要はありません。また、ライブラリーによっては、名前にバージョンが組み込まれているものもあります。

ファイルからの soname の読み込み

somelibrary ライブラリーファイルの soname を表示します。

$ objdump -p somelibrary | grep SONAME

somelibrary は、検証するライブラリーのファイル名に置き換えます。

2.4.3. GCC での動的ライブラリーの作成

動的にリンクされたライブラリー (共有オブジェクト) では以下が可能です。

  • コードを再利用してリソースを予約する
  • ライブラリーコードの更新を容易化にしてセキュリティーを強化する

以下の手順に従って、ソースから動的ライブラリーを構築してインストールします。

前提条件

  • soname メカニズムを理解している。
  • GCC がシステムにインストールされている。
  • ライブラリーのソースコードがある。

手順

  1. ライブラリーソースのディレクトリーに移動します。
  2. 位置独立コードオプション -fPIC でオブジェクトファイルに各ソースファイルをコンパイルします。

    $ gcc ... -c -fPIC some_file.c ...

    オブジェクトファイルは、オリジナルのソースコードファイルと同じファイル名ですが、拡張子が .o となります。

  3. オブジェクトファイルから共有ライブラリーをリンクします。

    $ gcc -shared -o libfoo.so.x.y -Wl,-soname,libfoo.so.x some_file.o ...

    使用するメジャーバージョン番号は X で、マイナーバージョン番号は Y です。

  4. libfoo.so.x.y ファイルを、システムの動的リンカーが検索できる適切な場所にコピーします。Red Hat Enterprise Linux では、ライブラリーのディレクトリーは /usr/lib64 となります。

    # cp libfoo.so.x.y /usr/lib64

    このディレクトリーにあるファイルを操作するには、root パーミッションが必要な点に注意してください。

  5. soname メカニズムのシンボリックリンク構造を作成します。

    # ln -s libfoo.so.x.y libfoo.so.x
    # ln -s libfoo.so.x libfoo.so

関連情報

2.4.4. GCC および ar での静的ライブラリーの作成

オブジェクトファイルを特別なアーカイブファイルに変換して、静的にリンクするライブラリーを作成できます。

注記

Red Hat は、セキュリティー上の理由から、静的リンクの使用は推奨していません。静的リンクは、特に Red Hat が提供するライブラリーに対して、必要な場合にのみ使用してください。詳細は、「静的リンクおよび動的リンク」 を参照してください。

前提条件

  • GCC と binutils がシステムにインストールされている。
  • 静的リンクおよび動的リンクを理解している。
  • ライブラリーとして共有している関数を含むソースファイルが利用できる。

手順

  1. GCC で仲介となるオブジェクトファイルを作成します。

    $ gcc -c source_file.c ...

    必要に応じて、さらにソースファイルを追加します。作成されるオブジェクトファイルはファイル名を共有しますが、拡張子は .o を使用します。

  2. binutils パッケージの ar ツールを使用して、オブジェクトファイルを静的ライブラリー (アーカイブ) に変換します。

    $ ar rcs libfoo.a source_file.o ...

    libfoo.a ファイルが作成されます。

  3. nm コマンドを使用して、作成されたアーカイブを検証します。

    $ nm libfoo.a
  4. 静的ライブラリーファイルを適切なディレクトリーにコピーします。
  5. ライブラリーにリンクする場合、GCC は自動的に .a のファイル名の拡張子 (ライブラリーが静的リンクのアーカイブであること) を認識します。

    $ gcc ... -lfoo ...

関連情報

  • Linux の man ページ ar(1):

    $ man ar