Linuxの静的ライブラリとは?プログラムに組み込まれるライブラリの仕組みを初心者向けに解説
生徒
「Linuxの静的ライブラリって、普通のファイルとは何が違うんですか?」
先生
「静的ライブラリは、よく使うプログラムの部品をまとめておき、実行ファイルを作るときに必要な部分を組み込める仕組みです。」
生徒
「共有ライブラリや動的ライブラリとは別のものですか?」
先生
「役割は似ていますが、組み込まれるタイミングや実行時の使われ方が違います。Linuxでよく見る拡張子や作り方も含めて順番に見ていきましょう。」
Linuxを初めて学ぶ人や、 OS・プロセス・メモリ管理・仮想マシン・コンテナの仕組みを図解で理解したい人におすすめの定番書籍です。
試して理解 Linuxのしくみを見る※ Amazonアソシエイト広告リンク
1. Linuxの静的ライブラリとは?
Linuxの読み方はLinux(リナックス)です。静的ライブラリの読み方は静的ライブラリ(セイテキライブラリ)で、英語ではstatic library(スタティックライブラリ)といいます。静的ライブラリとは、複数のプログラムから再利用したい処理を一つにまとめ、実行ファイルを作るリンク処理のときに必要な部分を取り込めるようにしたファイルです。
ライブラリの読み方はlibrary(ライブラリ)です。プログラミングでいうライブラリは、本を並べる図書館ではなく、便利な処理をまとめた部品集を意味します。たとえば計算処理、文字列操作、画像処理、通信処理などを毎回最初から作るのではなく、共通の部品として用意して再利用できます。
LinuxでC言語やC++の静的ライブラリを扱う場合は、ファイル名の末尾に.aが付く形式をよく使います。たとえばlibcalc.aという名前なら、計算処理をまとめた静的ライブラリだと考えられます。先頭にlibを付ける名前はLinuxでよく使われる慣習です。
初心者の方は、静的ライブラリを「よく使う部品を入れておく工具箱」と考えるとわかりやすいでしょう。プログラムを完成させるときに必要な工具だけを取り出して実行ファイルへ組み込むイメージです。
2. 静的ライブラリと静的リンクの関係
静的ライブラリを理解するときは、静的リンクという言葉も一緒に覚えておくと整理しやすくなります。静的リンクの読み方は静的リンク(セイテキリンク)で、英語ではstatic linking(スタティックリンキング)といいます。リンクとは、コンパイルして作られたプログラムの部品を結び付け、最終的な実行ファイルを作る処理です。
ソースコードは、そのままでは通常Linux上で直接実行できません。まずコンパイラでオブジェクトファイルへ変換し、そのあと必要なライブラリや別のオブジェクトファイルをリンカが結び付けます。コンパイラの読み方はcompiler(コンパイラ)、リンカの読み方はlinker(リンカ)です。
静的ライブラリを利用する場合、リンク時に必要なコードが実行ファイル側へ取り込まれます。そのため、完成した実行ファイルを起動するたびに元の静的ライブラリを読み込むわけではありません。この点が、実行時に共有ライブラリを利用する動的リンクとの大きな違いです。
静的ライブラリは部品を保存しておくファイルで、静的リンクはその部品を実行ファイルへ結び付ける処理です。名前は似ていますが、ファイルそのものと処理を区別して覚えるとわかりやすくなります。
3. オブジェクトファイルとaファイルの仕組み
静的ライブラリは、一般に複数のオブジェクトファイルをまとめて作ります。オブジェクトファイルの読み方はobject file(オブジェクトファイル)です。C言語では.oという拡張子がよく使われます。これはソースコードをコンパイルしたあと、最終的な実行ファイルになる前の機械語に近いデータを保存したファイルです。
たとえばadd.cというC言語のソースコードをgcc -cでコンパイルすると、add.oというオブジェクトファイルを作れます。GCCの読み方はGCC(ジーシーシー)です。GCCはLinuxでC言語などをコンパイルするときによく使われるコンパイラです。
printf 'int add(int a, int b){return a + b;}\n' > add.c
gcc -c add.c -o add.o
ls -l add.o
-rw-r--r-- 1 user user 1112 Aug 10 10:00 add.o
-cを付けると、リンク処理まで進めずにオブジェクトファイルを作成します。大きなプログラムでは、機能ごとにソースコードを分け、それぞれをオブジェクトファイルにしてからまとめる方法が使われます。
静的ライブラリの.aファイルは、このようなオブジェクトファイルをまとめたアーカイブです。アーカイブの読み方はarchive(アーカイブ)で、複数のファイルを一つにまとめたものを意味します。
4. arコマンドで静的ライブラリを作成する方法
Linuxで静的ライブラリを作成するときによく使われるのがarコマンドです。arの読み方はar(アール)です。オブジェクトファイルを一つのアーカイブへまとめたり、静的ライブラリの中身を確認したりできます。
先ほど作成したadd.oをlibcalc.aという静的ライブラリへまとめる場合は、次のように実行します。
ar rcs libcalc.a add.o
ar t libcalc.a
add.o
ar rcsでは、指定したオブジェクトファイルをアーカイブへ登録します。続くar tは、静的ライブラリの中にどのオブジェクトファイルが入っているか確認するための操作です。この例ではadd.oが一つ登録されていることがわかります。
実際の開発では、足し算、引き算、文字列処理など複数の機能を別々のオブジェクトファイルとして作り、一つの静的ライブラリにまとめることもできます。これにより、共通処理を整理して管理しやすくなり、複数のプログラムから再利用できるようになります。
5. 作成した静的ライブラリをプログラムへ組み込む方法
静的ライブラリを作ったら、別のプログラムをビルドするときに利用できます。ビルドの読み方はbuild(ビルド)で、ソースコードから実行可能なプログラムを作る一連の作業を意味します。
次の例では、静的ライブラリに入っているadd関数を利用するプログラムを作り、gccでリンクします。-L.は現在のディレクトリもライブラリを探す場所に加える指定で、-lcalcはlibcalcという名前のライブラリを利用する指定です。
printf '#include <stdio.h>\nint add(int, int);\nint main(void){printf("%d\\n", add(10, 20));return 0;}\n' > main.c
gcc main.c -L. -lcalc -o calc-app
./calc-app
30
-lcalcと書く場合、ライブラリ名の先頭にあるlibと末尾の拡張子を省略して指定します。つまりlibcalc.aなら-lcalcと書きます。この命名方法はLinuxのライブラリを利用するときによく登場するため、覚えておくと実際のコマンドを読みやすくなります。
なお、同じ名前の共有ライブラリが検索対象に存在する環境では、通常の-l指定で共有ライブラリが選ばれる場合があります。確実に特定の静的ライブラリを使う学習例では、gcc main.c ./libcalc.a -o calc-appのようにファイルを直接指定する方法もあります。
6. arとnmで静的ライブラリの中身を確認する
作成した静的ライブラリの内容を調べたいときは、arだけでなくnmコマンドも役立ちます。nmの読み方はnm(エヌエム)です。オブジェクトファイルやライブラリに含まれている関数名などのシンボル情報を確認できます。
シンボルの読み方はsymbol(シンボル)です。ここでは、プログラム中の関数や変数などを識別するための名前だと考えるとわかりやすいでしょう。
nm -g --defined-only libcalc.a
add.o:
0000000000000000 T add
この例では、静的ライブラリの中にaddという関数が定義されていることを確認できます。実際の表示はCPUの種類やコンパイラ、Linux環境によって異なる場合があります。
ライブラリを受け取ったものの「どんな部品が入っているのかわからない」という場合には、ar tでオブジェクトファイルの一覧を見て、nmで関数名などを調べるという流れが役立ちます。Linuxの開発やトラブル調査で利用される基本的な確認方法です。
7. 静的ライブラリと共有ライブラリの違い
Linuxでは静的ライブラリだけでなく、共有ライブラリもよく使われます。共有ライブラリの読み方は共有ライブラリ(キョウユウライブラリ)で、英語ではshared library(シェアードライブラリ)といいます。Linuxでは.soが付くファイルをよく見かけます。
静的ライブラリは、リンクするときに必要なコードが実行ファイル側へ取り込まれます。そのため、完成した実行ファイルは静的ライブラリの一部を自分の中に持つ形になります。一方、共有ライブラリを利用するプログラムは、一般に実行時に外部の共有ライブラリを読み込みます。
静的ライブラリの利点は、実行時に元の静的ライブラリへ依存しない形にしやすいことです。特定の環境へ小さなツールを配布するときなどに扱いやすい場合があります。一方で、ライブラリのコードが実行ファイルへ組み込まれるため、複数のプログラムが同じライブラリを使うと、それぞれの実行ファイルが大きくなりやすいという特徴があります。
共有ライブラリは、複数のプログラムで共通のライブラリを利用しやすいため、同じコードをそれぞれへ組み込まずに済みます。ただし、実行する環境に必要な共有ライブラリがなかったり、互換性の問題があったりすると、プログラムが起動できない場合があります。
静的ライブラリは実行ファイルを作るときにコードを取り込む方式、共有ライブラリは実行時に外部のライブラリを利用する方式として考えると、初心者でも違いを整理しやすくなります。
8. 静的ライブラリを使うメリットと注意点
静的ライブラリのメリットの一つは、複数のプログラムで共通する処理をまとめて管理できることです。計算処理やデータ変換などを一つの静的ライブラリにしておけば、それぞれのプログラムへ同じソースコードを何度もコピーする必要がありません。プログラムの部品を分けて整理できるため、開発もしやすくなります。
さらに、静的リンクされたコードは実行ファイルへ取り込まれるため、実行時に元の.aファイルを一緒に置いておく必要は通常ありません。配布先で同じ静的ライブラリを用意しなくても実行できる形にしやすいことは、静的ライブラリの特徴です。
一方で、ライブラリのコードを実行ファイルへ含める分、ファイルサイズが大きくなりやすい点には注意が必要です。また、静的ライブラリに不具合やセキュリティ上の問題が見つかって修正版へ更新しても、すでにリンク済みの実行ファイルが自動的に新しい内容へ変わるわけではありません。修正版を使って再びリンクし、実行ファイルを作り直す必要があります。
そのため、静的ライブラリと共有ライブラリは、どちらか一方が常に優れているというものではありません。配布のしやすさ、実行ファイルの大きさ、更新方法、利用するLinux環境などを考えて選びます。
9. Linux初心者が静的ライブラリで覚えておきたい用語
Linuxの静的ライブラリを学習するときは、ソースコード、コンパイル、オブジェクトファイル、アーカイブ、リンク、実行ファイルという流れを意識すると理解しやすくなります。ソースコードをコンパイルして.oファイルを作り、それらをarでまとめると.a形式の静的ライブラリを作れます。そして別のプログラムをビルドするときに、その静的ライブラリの必要なコードをリンクします。
歴史的にも、静的ライブラリはプログラムの共通部品をまとめる方法として古くから利用されてきました。その後、複数の実行中プログラムでライブラリを共有しやすくする共有ライブラリや動的リンクも広く使われるようになりました。現在のLinuxでも、用途に応じて静的ライブラリと共有ライブラリの両方が利用されています。
Linux初心者が最初からリンカ内部の細かい仕組みをすべて覚える必要はありません。まずは、.cがソースコード、.oがコンパイル後の部品、.aが複数の部品をまとめた静的ライブラリ、最終的にそれらをリンクして実行ファイルを作るという関係を理解しましょう。
実際にgcc -cでオブジェクトファイルを作り、ar rcsで静的ライブラリにまとめ、gccでリンクしてプログラムを実行すると、文章だけで覚えるよりも仕組みが見えやすくなります。さらにar tやnmで中身を確認できるようになると、Linuxのライブラリ管理やプログラムのビルドについて理解を深められます。