ライブラリを使用すると、アプリケーション間でコードを共有したり、非常に大規模なアプリケーションを単純化することができます。Sun C++ コンパイラでは、さまざまなライブラリを使用できます。この章では、これらのライブラリの使用方法を説明します。
Solaris オペレーティング環境では、いくつかのライブラリが /usr/lib にインストールされます。このライブラリのほとんどは C インタフェースを持っています。デフォルトでは libc、libm、libw ライブラリが CC ドライバによってリンクされます。ライブラリ libthread は、-mt オプションを指定した場合にのみリンクされます。それ以外のシステムライブラリをリンクするには、 -l オプションでリンク時に指定する必要があります。たとえば、libdemangle ライブラリをリンクするには、リンク時に -ldemangle を CC コマンド行に指定します。
demo% CC text.c -ldemangle
C++ 5.0 コンパイラには、独自の実行時ライブラリが複数あります。すべての C++ アプリケーションは、CC ドライバによってこれらのライブラリとリンクされます。 C++ 5.0 コンパイラには、これ以外にも便利なライブラリがいくつかあります。詳細は、詳細は、「C++ コンパイラで提供されるライブラリ」の節を参照してください。
Sun C++ コンパイラには、いくつかのライブラリが添付されています。これらのライブラリには、互換モード (-compat=4) だけで使用できるもの、標準モード (-compat=5) だけで使用できるもの、あるいは両方のモードで使用できるものがあります。libgc ライブラリと libdemangle ライブラリには C インタフェースがあり、どちらのモードでもアプリケーションにリンクできます。
次の表に、Sun C++ コンパイラに添付されるライブラリと、それらを使用できるモードを示します。
ライブラリ |
名称 |
使用できるモード |
---|---|---|
libCrun |
C++ 実行時 |
-compat=5 |
libCstd |
C++ 標準ライブラリ |
-compat=5 |
libiostream |
従来の iostream |
-compat=5 |
libC |
C++ 実行時、従来の iostream |
-compat=4 |
libC_mtstubs |
mt スタブライブラリ |
-compat=4、-compat=5 |
libcomplex |
複素数ライブラリ |
-compat=4 |
librwtool |
Tools.h++ 7.0 |
-compat=4、-compat=5 |
librwtool_dbg |
デバック可能な Tools.h++ 7.0 |
-compat=5 |
libgc |
ガベージコレクション |
C インタフェース |
libgc_dbg |
デバッグ可能なガベージコレクション |
-compat=4、-compat=5 |
libdemangle |
復号化 |
C インタフェース |
これらのライブラリについて簡単に説明します。
libCrun: このライブラリには、コンパイラが標準モード (-compat=5) で必要とする実行時サポートが含まれています。new と delete、例外、RTTI がサポートされます。
libCstd: これは C++ 標準ライブラリです。特に、このライブラリには iostream が含まれています。既存のソースで従来の iostream を使用している場合には、ソースを新しいインタフェースに合わせて修正しないと、標準 iostream を使用できません。詳細は、標準 C++ ライブラリのマニュアルを参照してください。
libiostream: これは標準モード (-compat=5)で構築した従来の iostream ライブラリです。既存のソースで従来の iostream を使用している場合には、libiostream を使用すれば、ソースを修正しなくてもこれらのソースを標準モード (-compat=5) でコンパイルできます。このライブラリを使用するには、-library=iostream を使用します。
libC: これは互換モード (-compat=4) で必要なライブラリです。このライブラリには C++ 実行時サポートだけでなく従来の iostream も含まれています。
libC_mtstubs: このライブラリには一部の libthread 関数のスタブが含まれています。このライブラリはスレッドが 1 つのアプリケーションの場合にリンクされます。 -mt オプションでアプリケーションを構築する場合は、libC_mtstubs の代わりに libthread がリンクされます。
libcomplex: このライブラリは、互換モード (-compat=4) で複素数の演算を行うときに必要です。標準モードの場合は、 libCstd の複素数演算の機能が使用されます。
libwtool: (Tools.h++ 7) これは RougeWave の Tools.h++ バージョン 7 ライブラリです。
libgc: これはガベージコレクションライブラリ (Sun WorkShop Memory Monitor の構成要素) です。このライブラリの詳細は、Web ブラウザで次のファイルを参照してください。
/opt/SUNWspro/SC5.0/htmldocs/locale/ja/gc/start.html
コンパイラがこれとは異なるディレクトリにインストールされている場合は、次のようにしてください。install_directory にはインストール先を入力してください。
install_directory/SC5.0/htdocs/start.html
libdemangle: このライブラリは C++ 符号化名を復号化するときに使用します。
これらのライブラリには、CC ドライバによってデフォルトでリンクされるものと、明示的にリンクしなければならないものがあります。標準モードでは、次のライブラリが CC ドライバによってデフォルトでリンクされます。
-lm -liostream -lCstd -lCrun -lC_mtstubs -lw -lcx -lc
互換モードでは、次のライブラリがデフォルトでリンクされます。
-lm -lC -lC_mtstubs -lw -lcx -lc
詳細は、「-library=l[,...l]」を参照してください。
CC ドライバには、ライブラリを使用するためのオプションがいくつかあります。
リンクするライブラリを指定するには、-l オプションを使用します。
ライブラリを検索するディレクトリを指定するには、-L オプションを使用します。
Sun C++ コンパイラに添付された次のライブラリを指定するには、-library オプションを使用します。
libCrun
libCstd
libiostream
libC
libcomplex
librwtool、librwtool_dbg
libgc、libgc_dbg
-library オプションと -staticlib オプションの両方に指定されたライブラリは静的にリンクされます。次にオプションの例をいくつか示します。
demo% CC test.cc -library=rwtools7,iostream
Tools.h++ バージョン 7 と libiostream ライブラリが動的にリンクされます。
demo% CC test.cc -library=gc -staticlib=gc
demo% CC test.cc -compat=4 -staticlib=libC
test.cc が互換モードでコンパイルされ、libC が静的にリンクされます。互換モードでは libC がデフォルトでリンクされるので、このライブラリを -staticlib オプションに指定する必要はありません。
demo% CC test.cc -library=no%Crun,no%Cstd
本来ならデフォルトで使用される libCrun ライブラリと libCstd ライブラリが、リンクされなくなります。
デフォルトでは、CC は、指定されたコマンド行オプションに従ってさまざなシステムライブラリをリンクします。-xnolib (または-nolib) が指定された場合は、-l オプションで明示的に指定されたライブラリだけをリンクします (-xnolib または-nolib が使用された場合は、-library オプションを指定しても無視されます)。
-R オプションは、動的ライブラリの検索パスを実行可能ファイルに組み込むときに使用します。実行時リンカーは、実行時にこれらのパスを使ってアプリケーションに必要な共有ライブラリを探します。CC ドライバは、デフォルトで -R/opt/SUNWspro/lib を ld に渡します (コンパイラが標準の場所にインストールされている場合)。共有ライブラリのデフォルトパスが実行可能ファイルに組み込まれないようにするには、-norunpath を使用します。
一般に、クラスライブラリを使用するには 2 つの手順が必要です。まず、ソースコードに適切なヘッダーをインクルードし、次にプログラムをオブジェクトライブラリとリンクします。
C++ 5.0 コンパイラには、2 通りの iostream が実装されています。
従来の iostream : この用語は、C++ 4.0、4.0.1、4.1、4.2 コンパイラに添付された iostream ライブラリ、およびそれ以前に cfront ベースの 3.0.1 コンパイラに添付された iostream ライブラリを指します。このライブラリの標準はありませんが、既存のすべてのコードがこれを使用しています。このライブラリは、互換モードの libC の一部であり、標準モードの libiostream にもあります。
標準の iostream : これは C++ 標準ライブラリ libCstd に含まれていて、標準モードだけで使用されます。これは、バイナリレベルでもソースレベルでも「従来の iostream」とは互換性がありません。
すでに C++ のソースがある場合、そのコードは従来の iostream を使用しており、次の例のような形式になっていると思われます。
// ファイル prog.cc #include <iostream.h> int main() { cout << "Hello, world!" << endl; return 0; }
次のコマンドは、互換性モードで prog1.cc をコンパイル、リンクして、prog1 という実行可能なプログラムを生成します。従来の iostream ライブラリは、互換性モードのときにデフォルトでリンクされる libC ライブラリに含まれています。
demo% CC -compat prog1.cc -o prog1
//ファイル prog1.cc #include <iostream> int main() { std::cout << "Hello, world!" << std::endl; return 0; }
次のコマンドは、prog2.cc をコンパイル、リンクして、prog2 という実行可能なプログラムを生成します。コンパイルは標準モードで行われ、このモードでは、標準の iostream ライブラリを含む libCstd がデフォルトでリンクされます。
demo% CC prog2.cc -o prog2
標準ライブラリには、C++ 4.2 コンパイラに付属していた complex ライブラリに似た、テンプレート化された complex ライブラリがあります。標準モードでコンパイルする場合は、<complex.h> ではなく、<complex> を使用する必要があります。互換性モードで <complex> を使用することはできません。
互換性モードでは、リンク時に complex ライブラリを明示的に指定しなければなりません。標準モードでは、complex ライブラリは libCstd に含まれており、デフォルトでリンクされます。
標準モード用の complex.h ヘッダーはありません。C++ 4.2 では、「complex」 はクラス名ですが、標準 C++ では「complex」はテンプレート名です。したがって、旧式のコードを変更せずに動作できるようにする typedef を使用することはできません。
このため、複素数を使用する、4.2 用のコードで標準ライブラリを使用するには、多少の編集が必要になります。たとえば、次のコードは 4.2 用に作成されたものであり、互換性モードでコンパイルされます。
// ファイル ex1.cc (互換モード) #include <iostream.h> #include <complex.h> int main() { complex x(3,3), y(4,4); complex z = x * y; cout << "x=" << x << ", y=" << y << ", z=" << z << endl; }
次の例では、ex1.cc を互換モードでコンパイル、リンクし、生成されたプログラムを実行しています。
demo% CC -compat ex1.cc -library=complex demo% a.out x=(3, 3), y=(4, 4), z=(0, 24)
次は、標準モードでコンパイルされるように ex2.cc と書き直された ex1.cc です。
// ファイル ex2.cc (ex1.cc rewritten for standard mode) #include <iostream> #include <complex> int main() { std::complex<double> x(3,3), y(4,4); std::complex<double> z = x * y; std::cout << "x=" << x << ", y=" << y << ", z=" << z << std::endl; }
次の例では、書き直された ex2.cc をコンパイル、リンクして、生成されたプログラムを実行しています。
demo% CC ex2.cc demo% a.out x=(3,3), y=(4,4), z=(0,24)
次の表は、C++ ライブラリにリンクするためのコンパイラオプションをまとめています。詳細は、「-library=l[,...l]」を参照してください。
ライブラリ |
コンパイルモード |
オプション |
---|---|---|
従来の iostream |
-compat=4 -compat=5 |
不要 -library=iostream |
complex |
-compat=4 -compat=5 |
-library=complex 不要 |
Tools.h++ v7 |
-compat=4 -compat=5 |
-library=rwtool7 -library=rwtool7,iostream |
Tools.h++ v7 デバッグ |
-compat=4 -compat=5 |
-library=rwtool7_dbg -library=rwtool7_dbg,iostream |
ガベージコレクション |
-compat=4 -compat=5 |
-library=gc -library=gc |
ガベージコレクション デバッグ |
-compat=4 -compat=5 |
-library=gc_dbg -library=gc_dbg |
デフォルトでは、CC ドライバは、デフォルトライブラリのそれぞれについて -llib オプションをリンカーに渡すことによって、libc や libm などの共有ライブラリをいくつかリンクします (互換性モードと標準モードのデフォルトライブラリについては、「デフォルトの C++ ライブラリ」を参照)。
これらデフォルトライブラリを静的にリンクする場合は、-xnolib コンパイラオプションを使用できます。-xnolib オプションを指定すると、ドライバは自動的には -l オプションを ld に渡しません。-l オプションは、自分で渡す必要があります。次の例は、Solaris 2.5.1、2.6、7 オペレーティング環境で libCrun と静的に、libw、libm、libc と動的にリンクする方法を示します。
demo% CC test.c -xnolib -lCstd -Bstatic -lCrun -Bdynamic -lC_mtstubs -lm -lw -lcx -lc
-l オプションの順序は重要です。-lc の前に -lCstd、-lCrun、-lm、-lw、-lcx オプションがあることに注意してください。
x86 プラットフォームでは、-lcx オプションはありません。
他のライブラリにリンクする CC オプションもあります。そうしたライブラリへのリンクも -xnolib によって行われないように設定できます。たとえば、-mt オプションを指定すると、CC ドライバは -lC_mtstubs ではなく、-lthread を ld に渡します。これに対し、-mt と-xnolib の両方を使用すると、CC ドライバは ld に -lthread を渡しません。詳細は、「-xnolib」を参照してください。ld については、Solaris に関するマニュアル『リンカーとライブラリ』を参照してください。
-library オプションと -staticlib オプションを組み合わせることによって、C++ ライブラリを静的にリンクすることもできます。この方法は、前述の方法よりはるかに簡単です。たとえば、上記の例は次のようにして実行できます。
demo% CC test.c -staticlib=Crun
C++ コンパイラには、次の共有ライブラリが含まれています。
libCrun.so.1
libC.so.5
libcomplex.so.5
librwtool.so.2
libgc.so.1
libgc_dbg.so.1
プログラムにリンクされた各共有オブジェクトは、生成される実行可能ファイル (a.out ファイル) に記録されます。この情報は、実行時に ld.so が使用して動的リンク編集を行います。ライブラリコードをアドレス空間に実際に組み込むのは後になるため、共有ライブラリを使用するプログラムの実行時の動作は、環境の変化 (つまり、ライブラリを別のディレクトリに移動すること) に影響を受けます。たとえば、Solaris 2.6 オペレーティング環境でプログラムが /opt/SUNWspro/SC5.0/lib の libcomplex.so.5 とリンクされている場合、後で libcomplex.so.5 ライブラリを /opt2/SUNWspro/SC5.0/lib に移動すると、このバイナリコードを実行したときに次のメッセージが表示されます。
ld.so.1: a.out: libcomplex.so.5: open に失敗しました: ファイルもディレクトリもありません。
ただし、環境変数 LD_BINARY_PATH に新しいライブラリの ディレクトリを設定すれば、古いバイナリコードを再コンパイルせずに実行できます。
demo% setenv LD_LIBRARY_PATH /opt2/SUNWspro/SC5.0/lib:${LD_LIBRARY_PATH}
demo$ LD_LIBRARY_PATH=/opt2/SUNWspro/SC5.0/lib:${LD_LIBRARY_PATH} demo$ export LD_LIBRARY_PATH
LD_BINARY_PATH には、ディレクトリのリストが含まれています。ディレクトリは通常コロンで区切られています。C++ のプログラムを実行すると、動的ローダーがデフォルトディレクトリより前に LD_BINARY_PATH のディレクトリを検索します。
実行可能ファイルにどのライブラリが動的にリンクされるのかを知るには、ldd コマンドを使用します。
% ldd a.out
共有ライブラリを移動することはめったにないので、この手順が必要になることはほとんどありません。
共有ライブラリを dlopen で開く場合は、RTLD_GLOBAL を使用しないと例外が機能しません。
共有ライブラリの詳しい使い方については、Solaris 7 の『リンカーとライブラリ』を参照してください。
C には、<stdio.h>、<string.h>、<stdlib.h> などの 17 個の標準ヘッダーがあります。これらのヘッダーは Solaris に標準で付属しており、/user/include に置かれています。C++ にも同様のヘッダーがありますが、さまざまな宣言の名前が大域の名前空間とstd 名前空間の両方に存在するという条件が付加されています。管理上の理由から、C++ コンパイラでは、/usr/include ディレクトリにあるヘッダーはそのまま残して、C++ 用のヘッダーを別に用意しています。
また、C++ には、C 標準ヘッダー(<cstdio>、<cstring>、<cstdlib>) のそれぞれについても専用のバージョンがあります。C++ 版の C 標準ヘッダーでは、宣言名は std 名前空間にのみ存在します。C++ には、32 個の独自の標準ヘッダー(<string>、<utility>、<iostream>など) も追加されています。
標準ヘッダーの実装で、C++ ソースコード内の名前がインクルードするテキストファイル名として使用されているとしましょう。たとえば、標準ヘッダーの <string> が、あるディレクトリにある string というファイルを参照するものとします。この実装には、次の欠点があります。
ファイル名に接尾辞がない場合、ヘッダーファイルだけ検索したり、ヘッダーファイル用のメークファイルを作成したりできない
コンパイラのコマンド行に -I/usr/include を指定すると、コンパイラ専用の include ディレクトリの前に /usr/include が検索されるため、正しいバージョンの標準 C ヘッダーが検出されない
string というディレクトリまたは実行可能プログラムがあると、そのディレクトリまたはプログラムが標準ヘッダーファイルの代わりに検出される可能性がある
.KEEP_STATE が有効なときのメークファイルのデフォルトの相互依存関係により、標準ヘッダーが実行可能プログラムに置き換えられる可能性がある
こうした問題を解決するため、コンパイラの include ディレクトリには、ヘッダーと同じ名前を持つファイルと、一意の接尾辞 .SUNWCCh を持つ、そのファイルへのシンボリックリンクが含まれています (SUNW はコンパイラに関係するあらゆるパッケージに対する接頭辞、CC は C++ コンパイラの意味、.h はヘッダーファイルの通常の接尾辞)。つまり <string> と指定された場合、コンパイラは <string.SUNWCCh> と書き換え、その名前を検索します。接尾辞付きの名前は、コンパイラ専用の include ディレクトリにだけ存在します。このようにして見つけられたファイルがシンボリックリンクの場合 (通常はそうである)、コンパイラは、エラーメッセージやデバッガの参照でそのリンクを 1 回だけ間接参照し、その参照結果 (この場合は string) をファイル名として使用します。ファイルの依存関係情報を送るときは、接尾辞付きの名前の方が使用されます。
この名前の書き換えは、2 つのバージョンがある 17 個の標準 C ヘッダーと 32 個の標準 C++ヘッダーのいずれかを、パスを指定せずに山括弧 < > に囲んで指定した場合にだけ行われます。山括弧の代わりに引用符が使用されるか、パスが指定されるか、他のヘッダーが指定された場合、名前の書き換えは行われません。次の表は、よくある書き換え例をまとめています。
ソースコード |
コンパイラによる検索 |
注釈 |
---|---|---|
<string> |
string.SUNWCCh |
C++の string テンプレート |
<cstring> |
cstring.SUNWCCh |
C の string.h の 1 バージョン |
<string.h> |
string.h.SUNWCCh |
C の string.h |
<fcntl.h> |
fcntl.h |
標準 C および C++ヘッダー以外 |
“string” |
string |
山括弧ではなく、引用符付きの場合 |
<../string> |
../string |
パス指定がある場合 |