2.4. GCC でのライブラリーの作成
ライブラリーを作成する手順と、Linux オペレーティングシステムでライブラリーに使用される必要な概念について説明します。
2.4.1. ライブラリーの命名規則
特別なファイルの命名規則をライブラリーに使用します。foo として知られるライブラリーは、libfoo.so
ファイルまたは libfoo.a
ファイルとして存在する必要があります。この規則は、リンクする GCC の入力オプションでは自動的に理解されますが、出力オプションでは理解されません。
ライブラリーにリンクする場合は、
-lfoo
のように、-l
オプションと foo の名前でしか、ライブラリーを指定することができません。$ gcc ... -lfoo ...
-
ライブラリーの作成時には、
libfoo.so
、libfoo.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 がシステムにインストールされている。
- ライブラリーのソースコードがある。
手順
- ライブラリーソースのディレクトリーに移動します。
位置独立コードオプション
-fPIC
でオブジェクトファイルに各ソースファイルをコンパイルします。$ gcc ... -c -fPIC some_file.c ...
オブジェクトファイルは、オリジナルのソースコードファイルと同じファイル名ですが、拡張子が
.o
となります。オブジェクトファイルから共有ライブラリーをリンクします。
$ gcc -shared -o libfoo.so.x.y -Wl,-soname,libfoo.so.x some_file.o ...
使用するメジャーバージョン番号は X で、マイナーバージョン番号は Y です。
libfoo.so.x.y
ファイルを、システムの動的リンカーが検索できる適切な場所にコピーします。Red Hat Enterprise Linux では、ライブラリーのディレクトリーは/usr/lib64
となります。# cp libfoo.so.x.y /usr/lib64
このディレクトリーにあるファイルを操作するには、root パーミッションが必要な点に注意してください。
soname メカニズムのシンボリックリンク構造を作成します。
# ln -s libfoo.so.x.y libfoo.so.x # ln -s libfoo.so.x libfoo.so
関連情報
- Linux ドキュメントプロジェクト - Program Library HOWTO - 3.共有ライブラリー
2.4.4. GCC および ar での静的ライブラリーの作成
オブジェクトファイルを特別なアーカイブファイルに変換して、静的にリンクするライブラリーを作成できます。
Red Hat は、セキュリティー上の理由から、静的リンクの使用は推奨していません。静的リンクは、特に Red Hat が提供するライブラリーに対して、必要な場合にのみ使用してください。詳細は、「静的リンクおよび動的リンク」 を参照してください。
前提条件
- GCC と binutils がシステムにインストールされている。
- 静的リンクおよび動的リンクを理解している。
- ライブラリーとして共有している関数を含むソースファイルが利用できる。
手順
GCC で仲介となるオブジェクトファイルを作成します。
$ gcc -c source_file.c ...
必要に応じて、さらにソースファイルを追加します。作成されるオブジェクトファイルはファイル名を共有しますが、拡張子は
.o
を使用します。binutils
パッケージのar
ツールを使用して、オブジェクトファイルを静的ライブラリー (アーカイブ) に変換します。$ ar rcs libfoo.a source_file.o ...
libfoo.a
ファイルが作成されます。nm
コマンドを使用して、作成されたアーカイブを検証します。$ nm libfoo.a
- 静的ライブラリーファイルを適切なディレクトリーにコピーします。
ライブラリーにリンクする場合、GCC は自動的に
.a
のファイル名の拡張子 (ライブラリーが静的リンクのアーカイブであること) を認識します。$ gcc ... -lfoo ...
関連情報
Linux の man ページ ar(1):
$ man ar