Linux C Library (libc) について 佐野武俊 / Taketoshi Sano, (kgh12351@nifty.ne.jp) $Date: 1999/05/20 11:27:05 $, ($Revision: 1.11 $) Linux C Library (libc) の概要について、その役割と歴史などを簡単にまと めたものです。内容および文書の構成についての御意見をお待ちしておりま す。 1. 「ライブラリ」とは まずは JF にある GCC-HOWTO (v1.17/Daniel Barlow 氏, 翻訳は v1.17j2/中 野さん) の中から、関連する文章を引用します。 6.1. 共有ライブラリと static なライブラリ プログラム作成の最終段階は「リンク」と呼ばれます。全ての部品を 結合して、足りないものがないかどうか調べる作業です。 「ファイルを開く」といったような類の作業は、多くのプログラムで 行われます。したがってこのような機能を持つ「部品」はライブラリ の形で提供されています。普通の Linux システムでは、ライブラリは /lib と /usr/lib にあります(他の場所にあることもままありますが)。 つまり「ライブラリ」とは、上記の引用文で説明されているように 多くのプログラムで共通して使われるような、汎用的な『部品』と して使われるコードを集めたもの です。 UNIX 上でのソフトウェア開発は歴史上 C 言語で行なわれることが多 かったため、 (基本的なコマンドやライブラリ自身の開発は、いくつかの例外 を除いてほとんど C 言語によっています) 「最も基本的な部品」を集めたラ イブラリの名前は "libc" と付けられています。 例えばファイルを開くための関数である fopen(3) とか、標準出力に文字を表 示するための関数である printf(3) などが "libc" ライブラリに含まれてい ます。 2. 共有ライブラリ 再び、 JF の GCC-HOWTO から引用します。 static なライブラリを用いる場合は、リンカはプログラムが必要と する部品を探し、出力する実行ファイルにその部品をコピーします。 共有ライブラリの場合は違った作業が行われます。 リンカは出力ファイルに「このプログラムが実行されるときには、 まずこれこれのライブラリがロードされていないといけませんよ」と いったメッセージを埋め込みます。したがって明らかに共有ライブラリを 用いる方が実行ファイルのサイズは小さくなります。 また消費するメモリやディスク容量も小さくなります。 Linux における デフォルトの振る舞いでは、共有ライブラリがあればそちらを用い、 なければ static なリンクを行います。実行ファイルを共有ライブラリ 形式にしたいのに static になってしまった場合は、正しい位置に 共有ライブラリのファイルがあって(a.outでは *.sa、 ELF では *.so です)、 それらが読み込み可能になっているかどうかをチェックしてください。 「共有ライブラリ」は、そのライブラリを使うプログラムすべてによって「共 有」 (あるいは共用、原文では shared) されるものです。 リンク (実行形式作成) 時に「static」なライブラリを使用した場合は各実行 形式ファイルの内部にそのライブラリからコピーされたコードが保存されるた め、実際に動作する時はそれぞれのコードが独立にメモリーへ読み込まれま す。同じライブラリを使うプログラムを複数起動すると、まったく同じコード の部分もすべて独立にメモリーへ読み込まれるため、メモリーの使用量は起動 した数にほぼ比例して増えます。 一方「共有ライブラリ」を使用した場合、各実行形式ファイルの内部には 「メッセージ」だけが保存されており、起動された時にそのプログラムの実行 に必要な共有ライブラリがメモリー上に無ければ読み込まれますが、同じライ ブラリを使う他のプログラムによって既に読み込まれていれば、新たにメモリ ーへ読み込まれるのはそのプログラム固有のコードだけとなり、メモリー使用 量がずっと少なくてすみます。 libc5 環境では、通常のコマンド (/bin/sh, /bin/cp, /bin/ls など) が動作 時に使用する "libc" の実体は "/lib/libc.so.5.4.33" などのように "libc.so.5.x.y" という形式の名前が付けられたファイルです。 このファイルには "/lib/libc.so.5" という名前のリンクが付随しており、各 プログラムは動作時にこのリンクファイルを手がかりとして実体である /lib/libc.so.5.x.y にアクセスします。 一方プログラムの make 時にはリンカ (ld) はまず /usr/lib/libc.so にアク セスします。このファイルは libc5 環境では /lib/libc.so.5 へのリンクに なっており、このリンク先のファイルから得られる情報が動作時に共有ライブ ラリを探すための「手がかり (上記の「メッセージ」)」として各実行形式 ファイルの内部に埋め込まれます。これについて詳細を知りたい方は、 JF の GCC-HOWTO を "soname"というキーワードで検索してみてください。 libc6 (glibc2) 環境ではちょっと話が違っていて、 "/usr/lib/libc.so" は 以下のような ld のスクリプトになっています。 /* GNU ld script Use the shared library, but some functions are only in the static library, so try that secondarily. */ GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a ) しかし、リンカ (ld) が共有ライブラリを探すためにまずこのファイル (/usr/lib/libc.so) を見るという点は libc5 の場合と同じです。違うのは、 動作時の共有ライブラリとして探しにいくべきファイルがリンクによって示さ れているのではなく /lib/libc.so.6 という名前で示されている、という点で すね。 なお、libc6 (glibc2) 環境でも、libc 以外の、例えば算術演算ライブラリの 含まれている libm などでは /usr/lib/libm.so から /lib/libm.so へのリン クが張られています。 ちなみに、上記の引用文中にある "a.out" や "ELF" などは「共有ライブラ リ」の構造 (種類) を示す用語です。最近の Linux システムならすべて "ELF" だと思っておけば良いでしょう。 ELF についての詳細は JF の ELF-HOWTO を読んで下さい。 3. Linux C Library : コードの起源 さて、 "libc" が「多くのプログラムで共通して使われるような、汎用的な 『部品』として使われるコードを集めた」ライブラリの中でも、「最も基本的 な部品」を集めたライブラリであることを覚えておいて下さい。 そして、ここで「 Linux とはカーネルのことである」ということを思い出し て下さい。 "Linux システム" で使用されている「ライブラリ」の開発は、 Linux カーネ ルの開発とは独立しています。 Debian 1.3.1 (bo) の /usr/doc/libc5/copyright というファイルによれば This is the Debian GNU/Linux prepackaged version of the Linux C library. The Linux C library was adapted from, apparently, the GNU C library version 1.07.4, with additions from 4.4BSD. Please see the file `glibc' in the source dis- tribution for complete details. Note that glibc 2.* uses a mostly rewritten library which will be used as libc6 on Linux. これは Debian GNU/Linux によってパッケージ化された Linux C ライブラリです。 Linux C ライブラリは、バージョン 1.07.4 の GNU C ライブラリをベースに、 4.4BSD からいくつかの機能を追加 して作成されました。詳細についてはソース配布物中の "glibc" という名前のファイルを参照して下さい。 また glibc 2.* はほとんど完全に書き直されたライブラリであ り、これは Linux システム上で libc6 として使われるはずのもの である、ということに注意して下さい。 と書かれています。つまり、 Linux の "libc" (C library) は GNU の libc 1.07.4 をベースに、 4.4BSD からの拡張機能を加えて開発されてきたもの、 ということです。 3.1. Linux C Library : libc5 (ELF) 数年前、共有ライブラリの形式が "a.out" から "ELF" へと移行した頃は、 Linux 用 "libc" のバージョンが 4 から 5 へ移行した時期でもありました。 ためしに、 "file /lib/libc.so.?.*" を実行してみて下さい。私のシステム (Debian 1.3.1) では /lib/libc.so.4.6.27: \\ Linux/i386 demand-paged executable (QMAGIC), stripped /lib/libc.so.5.4.33: \\ ELF 32-bit LSB shared object, Intel 386, version 1, stripped が表示されます。 "Linux/i386 demand-paged executable (QMAGIC)" はこの共有ライブラリが "a.out" 形式であることを、また "ELF 32-bit LSB shared object, Intel 386, version 1," はこの共有ライブラリが "ELF" 形式であることを示しま す。 JF の GCC-HOWTO には「 6.4.3.1. ZMAGIC と QMAGIC」という節 があります。 QMAGIC 以前は ZMAGIC という "a.out" 形式が使わ れていたようです。つまり "a.out" 形式にはいくつかの種類があ るのです。 3.2. Linux C Library : libc6 (glibc2) さて、 Linux C ライブラリのバージョン 5 "libc5" までは上記のように GNU libc 1 系統をベースに開発が進められてきましたが、この "libc5" 系統はす でに新機能に関する開発が終了しています。 現在開発されているバージョンは GNU libc 2.x (Linux libc 6) です。これ が "Linux libc6" ではなく、 "glibc2" と呼ばれることが多い理由は、従来 Linux C Library が libc5 までは GNU libc を起源に持ってはいても、それ に大幅な変更を加えた「別物」になっていたことに比べ、新しい libc6 が 「GNU libc 2 そのもの」であるということによります。 以下、 JF の Glibc 2 HOWTO (v1.5/Erig Green 氏、翻訳は岡本さん、遠藤さ ん) より一部引用します。 1.1. glibc2について Glibc2 は GNU C ライブラリの最新版です。現在、変更なしで動作するのは、 GNU Hurd システムと Linux i386, m68k, alpha システムです。PowerPC, MIPS, Sparc, Sparc 64, Arm 用の Linux 向けには 2.1 版で対応の予定です。 将来的には、ほかのアーキテクチャーとオペレーティングシステム用にも 順次対応の予定です。 Linux では, glibc2 は Linux libc 5 の後継、つまりlibc バージョン6 として 用いられます。Linux libc 開発者たちは libc5 を (glibc2 で) 置き換えて しまおうとしています。 2.0.6 の段階で、 glibc は十分な品質を持つと 見なされています。バージョン 2.1 (近い将来発表予定) は、より多くの 機種へ移植され、新しい機能も追加されて、中心的に用いられるように なるでしょう。 以前、 GNU Bulletin で見たのですが、例えば によると、 GNU libc 2.0 の開発は GNU/Hurd を主な対象として Roland McGrath 氏によって行なわれてきたが、現在は途中から Linux/i386 を主に担 当してきた Ulrich Drepper 氏が中心となって行なわれており、 Linux/Alpha を担当する David Mosberger-Tang 氏および Richard Henderson 氏、それに Linux/m68k を担当する Andreas Schwab 氏が協力しているようです。 また Linux libc5 の主要な開発者だった H.J.Lu 氏も glibc2 の開発に参加 しており、 libc5.4.46 のアナウンス では Hi, Gals and Guys, The Linux C library 5 is phasing out. I am only maintaining it for very serious bug fixes only. People who want new features and other improvements should use the Linux C library 6, aka, the GNU C library 2. Please check the glibc 2 web site for details. やあ、みなさん。 Linux C ライブラリ 5 は徐々に消滅していこうとしています。私は単に 非常に重大なバグフィックスのみのために現在のコードを保守しています。 新機能やその他の改良が必要な人は、 Linux C ライブラリ 6、 つまり GNU C ライブラリ 2 を使いましょう。詳細は glibc 2 のウェブサイト を参照してください。 と書かれています。 つまり、ここで言いたいのは GNU libc 2 の開発が現状 Linux C Library の開発者たちによって主に行なわれているということで す。 これが「 Linux libc6 = GNU libc 2 」の背景です。 4. Linux C Library : 今後の発展 最近、 glibc2.0 に代わる新しいリリースとして glibc2.1 が公開されまし た。 alpha.gnu.org や kernel.org から入手できます。この文書の執筆時点 では glibc-2.1.1-pre2 が公開された最新バージョンのようです。現在主流の libc6 (glibc2) は、徐々にこの glibc2.1 に移行していくものと思われま す。 私もまだ実際に使ってはいませんが、 glibc2.1 を glibc2.0 と比較するとス レッドまわりなどが改善されているとのことです。なお実際にスレッドの機能 (主に SMP システムでの性能向上に有効) を利用するには linuxthreads とい う別パッケージが必要だそうです。注意してください。 一方、 glibc2.1 では特殊な仕掛を使って glibc2.0 とのバイナリ互換性を維 持しているらしいですが、ソースは一部変更が必要な (つまりソース互換では ない) ようです。また locale の扱いが glibc2.0 とは変更されている (基本 的な枠組としては、よリ完成度を高めた仕様になっているらしい) などの話も 聞きます。少し前までは日本語 (ja_JP.ujis) を扱うためには設定ファイルの 修正が必要と言われていたのですが、最近 (2.1.1) は標準でそのまま使える ようになってきたらしいです。 これからどうなっていくのか、今後もライブラリ開発の動向から目が離せませ んね。 5. おわりに 5.1. お願い ここまで、とりあえず書けた部分だけでまとめてみましたが、まだまだ不足し ている情報があるはずです。「これも追加して欲しい」という意見をお持ちの 方は是非教えて下さい。よろしくお願いします。 5.2. 謝辞 この文書は LDP/JF の GCC-HOWTO, ELF-HOWTO, Glibc 2 HOWTO やその他の参 考文献から得られた情報をまとめたものです。 Linux ユーザーの役に立つ文 書を数多く集積し、世界に発信している LDP と JF のみなさんに感謝しま す。 5.3. この文書の配布について copyrighted (c) 1999 Taketoshi Sano この文書は GNU パブリックライセンス (GPL) バージョン 2 かそれ以降の条 件、あるいは標準的な Linux ドキュメントプロジェクト (LDP) の条件に基づ いた配布ならば自由にしていただいてかまいません。これらのライセンスはこ のドキュメントが入手できるようなサイトから入手できます。LDP の条件は (翻訳をのぞく) いかなる修正も許可していません。修正されたバージョンは GPL の基でのみ配布されるものとすることが可能です。