第17章 GCC でのライブラリーの作成

本章では、ライブラリーの作成手順と、Linux オペレーティングシステムで使用するために必要なライブラリーのコンセプトを説明します。

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

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

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

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

関連資料

17.2. soname のメカニズム

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

前提条件

問題の概要

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

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

soname のメカニズム

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

ライブラリー fooX.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 は、検証するライブラリーの実際のファイル名に置き換えます。

17.3. 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

関連資料

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

オブジェクトファイルを特別なアーカイブファイルに変換して、静的にリンクするためにライブラリーを作成することが可能です。

注記

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

前提条件

ステップ

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

    $ gcc -c source_file.c ...

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

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

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

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

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

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

    $ gcc ... -lfoo ...

関連資料

  • ar ツールの Linux man ページ:

    $ man ar