この章では、副プログラムのライブラリを使用する方法と作成する方法を説明します。静的ライブラリと動的ライブラリの両方を説明します。
ソフトウェアライブラリとは、通常、すでにコンパイルされ、1 つのバイナリライブラリファイルにまとめられた副プログラムの集合のことです。この集合の個々のメンバーは、ライブラリの要素またはモジュールと呼ばれています。リンカーはライブラリファイルを検索し、ユーザーのプログラムによって参照されるオブジェクトモジュールを読み込み、実行可能バイナリプログラムを構築します。詳細は、ld(1) のマニュアルページと Solaris の『リンカーとライブラリ』を参照してください。
基本的にソフトウェアライブラリには、次の 2 種類があります。
静的ライブラリ- 実行前にモジュールが実行ファイルに結合されるライブラリ。静的ライブラリには、一般的に libname.a という名前が付けられます。.a 接尾辞はアーカイブを意味します。
動的ライブラリ- 実行時にモジュールが実行可能ファイルに結合されるライブラリ。動的ライブラリには、一般的に libname.so という名前が付けられます。.so 接尾辞は共有オブジェクトを意味します。
静的 (.a) バージョンと動的 (.so) バージョンの両方を持つ一般的なシステムライブラリを次に示します。
Fortran 95 ライブラリ: libfsu、libfui、libfai、libfai2、libfsumai、libfprodai、libfminlai、libfmaxlai、libminvai、libmaxvai、libifai、libf77compat
C ライブラリ: libc
ライブラリを使用すると、次の 2 つの利点があります。
プログラムが呼び出すライブラリルーチンのソースコードが必要ありません。
必要なモジュールだけが読み込まれます。
プログラムでライブラリファイルを使用すると、一般的に使用されるサブルーチンをより簡単に共有できるようになります。プログラムのリンク時にライブラリに名前を指定するだけで、プログラム内のリファレンスを解釈処理するこれらのライブラリモジュールがリンクされて、実行可能ファイルにマージされます。
ライブラリの使用と読み込みに関する要約情報を得るには、LD_OPTIONS 環境変数を介してリンカーに追加オプションを渡します。コンパイラは、オブジェクトのバイナリファイルを生成するときに、これらのオプション (およびそのほかの必要なオプション) を使用してリンカーを呼び出します。
直接リンカーを呼び出すより、コンパイラを使用することをお勧めします。多くのコンパイラオプションが特定のリンカーオプションまたはライブラリリファレンスを必要としており、これらのオプションやリファレンスなしでリンクすると予期せぬ結果を招くおそれがあるからです。
demo% setenv LD_OPTIONS ’–m -Dfiles’ demo% f95 -o myprog myprog.f 例: LD_OPTIONS を使用してロードマップを作成する場合 |
リンカーのオプションには、コンパイラのコマンド行と同じものがあり、f95 コマンド上に直接指定できます。これらのオプションは、 -Bx、-dx、-G、-hname、-Rpath、および -ztext です。詳細は、f95(1) のマニュアルページか『Fortran ユーザーズガイド』を参照してください。
リンカーのオプションと環境変数の例と説明は、Solaris の『リンカーとライブラ リ』を参照してください。
リンカーの -m オプションは、ライブラリのリンク情報を表示するロードマップを生成します。実行可能バイナリプログラムの構築中にリンクされるルーチンが、そのルーチンが取り出されたライブラリと共にリストされます。
demo% setenv LD_OPTIONS '-m' demo% f95 any.f any.f: MAIN: リンクエディタメモリーマップ 出力 入力 仮想 セクション セクション アドレス サイズ .interp 100d4 11 .interp 100d4 11 (null) .hash 100e8 2e8 .hash 100e8 2e8 (null) .dynsym 103d0 650 .dynsym 103d0 650 (null) .dynstr 10a20 366 .dynstr 10a20 366 (null) .text 10c90 1e70 .text 10c90 00 /opt/SUNWspro/lib/crti.o .text 10c90 f4 /opt/SUNWspro/lib/crt1.o .text 10d84 00 /opt/SUNWspro/lib/values-xi.o .text 10d88 d20 sparse.o ... |
ほかにもリンカーのデバッグ機能があり、リンカーの –Dkeyword オプションで利用できます。完全なリストを表示するには、-Dhelp を使用します。
例: -Dhelp オプションを使用して、リンカーのデバッグ支援オプションをリストします。
demo% ld -Dhelp … debug: args 入力引数の処理を表示します debug: bindings シンボルバインディングを表示します; debug: detail 詳しい情報を提供します debug: entry エントランス条件の記述子を表示します … demo% |
たとえば、-Dfiles リンカーオプションは、リンクの処理中に参照されるすべてのファイルとライブラリをリストします。
demo% setenv LD_OPTIONS '-Dfiles' demo% f95 direct.f direct.f: MAIN direct: debug: file=/opt/SUNWspro/lib/crti.o [ ET_REL ] debug: file=/opt/SUNWspro/lib/crt1.o [ ET_REL ] debug: file=/opt/SUNWspro/lib/values–xi.o [ ET_REL ] debug: file=direct.o [ ET_REL ] debug: file=/opt/SUNWspro/lib/libM77.a [ archive ] debug: file=/opt/SUNWspro/lib/libF77.so [ ET_DYN ] debug: file=/opt/SUNWspro/lib/libsunmath.a [ archive ] … |
ほかのリンカーオプションについての詳細は、『リンカーとライブラリ』を参照してください。
コンパイルとリンクを別のステップで行う場合は、整合性のあるコンパイルとリンクのオプションを選択することが重要です。オプションによっては、プログラムの一部をコンパイルするときに使用したら、リンクするときにも同じオプションを使用する必要があります。また、いくつかのオプションでは、リンクステップを含め、すべてのソースファイルをそのオプションでコンパイルする必要があります。
そのようなオプションは、『Fortran ユーザーズガイド』のオプションに関する説明の中で示されています。
例: -fast を使用して sbr.f をコンパイルし、C ルーチンをコンパイルしてから、別のステップでリンクします。
demo% f95 -c -fast sbr.f demo% cc -c -fast simm.c demo% f95 -fast sbr.o simm.o リンクステップ; -fast をリンカーに渡す |
リンカーは、いくつかの場所で、指定された順序でライブラリを検索します。検索の対象となるのは、標準のパスと、コンパイラオプション -Rpath、-llibrary、-Ldir で指定された場所、環境変数 LD_LIBRARY_PATH で設定されている場所です。
リンカーによって使用される標準のライブラリ検索パスはインストールパスによって決定されます。これらのパスは、静的な読み込みか動的な読み込みかによって異なります。標準インストールは、Sun Studio コンパイラソフトウェアを /opt/SUNWspro/ に配置します。
静的リンカーは、実行可能ファイルの構築中に、次のパス (ほかにもあります) で、指定された順序で、ライブラリを検索します。
/opt/SUNWspro/lib |
Sun Studio の共有ライブラリ |
/usr/ccs/lib/ |
SVr4 ソフトウェアの標準の場所 |
/usr/lib |
UNIX ソフトウェアの標準の場所 |
前述のパスは、リンカーによって使用されるデフォルトのパスです。
動的リンカーは、実行時に、指定された順序で、共有ライブラリを検索します。
ユーザーが -Rpath で指定したパス
/opt/SUNWspro/lib/
/usr/lib 標準 UNIX デフォルト
検索パスは、実行可能ファイルに組み込まれます。
LD_LIBRARY_PATH 環境変数を使用して、-llibrary オプションで指定したライブラリをリンカーが検索すべきディレクトリパスを指定します。
複数のディレクトリはコロンで区切って指定できます。通常、 LD_LIBRARY_PATH 変数は、コロンで区切ったディレクトリのリストを、次のようにセミコロンで区切って 2 つ持ちます。
dirlist1;dirlist2
最初に、dirlist1 のディレクトリが検索され、次に、コマンド行上で明示的に指定された -Ldir ディレクトリが検索され、最後に、dirlist2 と標準ディレクトリが検索されます。
つまり、次のように、複数の -L でコンパイラが呼び出された場合
f95 ... -Lpath1 ... -Lpathn ...
検索順序は次のようになります。
dirlist1 path1 ... pathn dirlist2 standard_paths
LD_LIBRARY_PATH 変数に、コロンで区切ったディレクトリリストが 1 つだけ含まれる場合、そのリストは dirlist2 として解釈されます。
Solaris オペレーティング環境では、64 ビットの依存関係を検索するときに、類似の環境変数 LD_LIBRARY_PATH_64 を使用して LD_LIBRARY_PATH を無効にできます。詳細は、Solaris の『リンカーとライブラリ』および ld(1) マニュアルページを参照してください。
32 ビット SPARC プロセッサでは、LD_LIBRARY_PATH_64 は無視されます。
LD_LIBRARY_PATH だけを定義している場合は、32 ビットと 64 ビットの両方のリンクに使用されます。
LD_LIBRARY_PATH と LD_LIBRARY_PATH_64 を定義している場合は、32 ビットのリンクには LD_LIBRARY_PATH が使用され、64 ビットのリンクには LD_LIBRARY_PATH_64 が使用されます。
実際に運用するソフトウェアでは、可能なかぎり LD_LIBRARY_PATH 環境変数を使用しないでください。実行時リンカーの検索パスに影響を与える一時的なメカニズムとしては便利ですが、この環境変数を参照できる動的な実行可能ファイルはすべてその検索パスを変更します。そのため、予想できない結果になるか、パフォーマンスが低下する可能性があります。
-llibrary コンパイラオプションを使用して、リンカーが外部参照を解決するときに検索する追加のライブラリを指定します。たとえば、オプション -lmylib は、ライブラリ libmylib.so か libmylib.a を検索リストに追加します。
リンカーは標準ディレクトリパスを探して、追加の libmylib ライブラリを見つけます。-L オプション (および、LD_LIBRARY_PATH 環境変数) は、標準パス以外でライブラリを探す場所をリンカーに伝えるパスのリストを作成します。
libmylib.a がディレクトリ /home/proj/libs にある場合、オプション –L/home/proj/libs は、実行可能ファイルを構築するときに探すべき場所をリンカーに伝えます。
demo% f95 -o pgram part1.o part2.o -L/home/proj/libs -lmylib |
特定の参照が解決されていない場合、ライブラリは 1 度だけ検索され、さらに、検索中のその時点で未定義のシンボルだけが検索されます。コマンド行上に複数のライブラリをリストする場合、これらのライブラリは、コマンド行に指定された順序で検索されます。 -llibrary オプションは、次のように配置します。
-llibrary オプションは .f、.for、.F、.f95、または .o ファイルのあとに配置します。
libx 中の関数を呼び出し、これらの関数が liby 中の関数を参照する場合、-lx は -ly より前に配置します。
-Ldir オプションは、dir ディレクトリパスをライブラリ検索リストに追加します。リンカーは、まず、-L オプションで指定されたディレクトリでライブラリを検索し、次に、標準ディレクトリで検索します。このオプションは、適用する –llibrary オプションより前に配置された場合だけ有効です。
動的ライブラリで、ライブラリ検索のパスと読み込みの順序の変更は、静的リンクのときとは異なります。実際のリンクは、構築時ではなく、実行時に行われます。
実行ファイルを構築するとき、リンカーは共有ライブラリへのパスを実行可能ファイル自身に記録します。これらの検索パスは、-Rpath オプションで指定できます。対照的に、-Ldir オプションは、構築時に -llibrary オプションで指定されたライブラリを見つける場所を示しますが、このパスをバイナリ実行可能ファイルに記録しません。
実行可能ファイルが作成されたときに構築されるディレクトリパスは、dump コマンドを使用して表示できます。
例: a.out に構築されたディレクトリパスをリストします。
demo% f95 program.f -R/home/proj/libs -L/home/proj/libs -lmylib demo% dump -Lv a.out | grep RPATH [5] RPATH /home/proj/libs:/opt/SUNWspro/lib |
実行時、リンカーは、実行可能ファイルに必要な動的リンクを探す場所を次から決定 します。
実行時の LD_LIBRARY_PATH の値
実行可能ファイルが構築されたときに -R で指定されたパス
すでに説明したように、LD_LIBRARY_PATH の使用は予想できない副作用があるので、お勧めできません。
必要なライブラリを見つけることができなかったとき、動的リンカーは次のようなエラーメッセージを発行します。
ld.so: prog: fatal: libmylib.so: can't open file: |
メッセージは、そこにあるべきライブラリが存在しなかったことを示しています。実行可能ファイルを構築したときには共有ライブラリのパスを指定したが、そのあとでライブラリが移動された可能性があります。たとえば、/my/libs/ 中のユーザー独自の動的ライブラリを使用して a.out を構築し、そのあとでライブラリをほかのディレクトリに移動した場合などです。
ldd を使用して、実行可能ファイルがライブラリを検索する場所を検出します。
demo% ldd a.out libfui.so.1 => /opt/SUNWspro/lib/libfui.so.1 libfai.so.1 => /opt/SUNWspro/lib/libfai.so.1 libfai2.so.1 => /opt/SUNWspro/lib/libfai2.so.1 libfsumai.so.1 => /opt/SUNWspro/lib/libfsumai.so.1 libfprodai.so.1 => /opt/SUNWspro/lib/libfprodai.so.1 libfminlai.so.1 => /opt/SUNWspro/lib/libfminlai.so.1 libfmaxlai.so.1 => /opt/SUNWspro/lib/libfmaxlai.so.1 libfminvai.so.1 => /opt/SUNWspro/lib/libfminvai.so.1 libfmaxvai.so.1 => /opt/SUNWspro/lib/libfmaxvai.so.1 libfsu.so.1 => /opt/SUNWspro/lib/libfsu.so.1 libsunmath.so.1 => /opt/SUNWspro/lib/libsunmath.so.1 libm.so.1 => /usr/lib/libm.so.1 libc.so.1 => /usr/lib/libc.so.1 libdl.so.1 => /usr/lib/libdl.so.1 /usr/platform/SUNW,Ultra-5_10/lib/libc_psr.so.1 |
可能であれば、適切なディレクトリにライブラリを移動またはコピーするか、リンカーが検索するディレクトリ中にそのディレクトリへのソフトリンクを作成します (ln -s を使用します)。または、LD_LIBRARY_PATH が正しく設定されていない可能性があります。LD_LIBRARY_PATH が実行時に必要なライブラリへのパスを含んでいるかどうかを検査します。
静的ライブラリファイルは、ar(1) ユーティリティーを使用して、すでにコンパイルされたオブジェクトファイル (. o ファイル) から構築します。
リンカーは、リンクするプログラム中で参照される入口を持つ要素をライブラリから抽出します。 たとえば、副プログラム、入口名、BLOCKDATA 副プログラム中で初期化される COMMON ブロックなどです。これらの抽出された要素 (ルーチン) は、リンカーによって生成される a.out 実行可能ファイルに恒久的にリンクされます。
静的ライブラリとリンクには、動的なライブラリとリンクと比較した場合、主に 3 つの問題に注意しなければいけません。
静的ライブラリは自己依存性 (独立性) に優れていますが、適用性に劣ります。
a.out 実行可能ファイルを静的にリンクすると、必要なライブラリルーチンは実行可能バイナリファイルの一部となります。しかし、a.out 実行可能ファイルにリンクされた静的ライブラリルーチンを更新する必要が出てきた場合 a.out ファイル全体をリンクし、生成し直さなければ、更新されたライブラリを利用することができません。動的ライブラリを使用すれば、ライブラリは a.out ファイルの一部とはならず、リンクは実行時に行われます。更新された動的ライブラリを利用するために必要なことは、新しいライブラリをシステムにインストールするだけです。
静的ライブラリの「要素」は個々のコンパイル単位 .o ファイルです。
1 つのコンパイル単位 (ソースファイル) には複数の副プログラムが含まれている場合があるので、いっしょにコンパイルすると、これらのルーチンは静的ライブラリ中の 1 つのモジュールとなります。つまり、コンパイル単位中のすべてのルーチンがいっしょに a.out 実行可能ファイルに読み込まれるが、実際に呼び出されるのはこれら副プログラムの 1 つだけであるということを意味します。この状況は、複数のライブラリルーチンを複数のコンパイル可能ソースファイルに分散するという最適化によって改良できます。ただし、プログラムによって実際に参照されるライブラリモジュールだけが実行可能ファイルに読み込まれます。
静的ライブラリのリンクでは、リンクの順序が重要です。
リンカーは、コマンド行に現れる順番、すなわち左から右に入力ファイルを処理します。リンカーがライブラリの要素を読み込むべきかどうかは、すでに処理されたライブラリの要素によって決定されます。この順番は、要素がライブラリファイル中で現れる順番に依存するだけでなく、コンパイルコマンド行上で指定されたライブラリの順番にも依存します。
例: Fortran プログラムが main.f と crunch.f の 2 つのファイルに記述され、crunch.f だけがライブラリにアクセスする場合、crunch.f または crunch.o より前にライブラリを参照するとエラーになります。
demo% f95 main.f -lmylibrary crunch.f -o myprog |
(誤)
demo% f95 main.f crunch.f -lmylibrary -o myprog |
(正)
1 つのプログラムのルーチンすべてがいくつかのソースファイルのグループに分散されており、また、これらのソースファイルすべてがサブディレクトリ test_lib/ にあるものと仮定します。
さらに、それぞれのファイルがユーザーのプログラムによって呼び出される 1 つの副プログラムと、その副プログラムからは呼び出されるがライブラリ中のほかのルーチンからは呼び出されない「ヘルパー」ルーチンを持つように、ファイルを編成すると仮定します。また、複数のライブラリルーチンから呼び出されるヘルパールーチンはすべて 1 つのソースファイルにまとめられているとします。これによって、合理的に上手に編成されたソースファイルとオブジェクトファイルのセットができます。
各ソースファイルの名前は、そのファイルの中の最初のルーチンの名前から決定すると仮定します。ほとんどの場合、それはライブラリ中の主要なファイルです。
demo% cd test_lib demo% ls total 14 2 dropx.f 2 evalx.f 2 markx.f 2 delte.f 2 etc.f 2 linkz.f 2 point.f |
低レベルの「ヘルパー」ルーチンはすべてファイル etc.f にまとめられます。ほかのファイルには、1 つまたは複数の副プログラムが入ります。
まず、-c オプションを使用して、各ライブラリソースファイルをコンパイルし、対応する再配置可能な .o ファイルを生成します。
demo% f95 -c *.f demo% ls total 42 2 dropx.f 4 etc.o 2 linkz.f 4 markx.o 2 delte.f 4 dropx.o 2 evalx.f 4 linkz.o 2 point.f 4 delte.o 2 etc.f 4 evalx.o 2 markx.f 4 point.o demo% |
次に、 ar を使用して、静的ライブラリ testlib.a を作成します。
demo% ar cr testlib.a *.o |
このライブラリを使用するためには、コンパイルコマンド上にライブラリファイルを指定するか、-l と -L コンパイルオプションを使用します。次の例では .a ファイルを直接使用します。
demo% cat trylib.f C testlib ルーチン群をテストするためのプログラム x=21.998 call evalx(x) call point(x) print*, ’value ’,x end demo% f95 -o trylib trylib.f test_lib/testlib.a demo% |
主プログラムがライブラリ中の 2 つのルーチンだけを呼び出しているところに注目してください。ライブラリ中の呼び出されないルーチンが実行可能ファイルに読み込まれていないことを確認するには、nm によって表示される実行可能ファイル中の名前のリストで調べます。
demo% nm trylib | grep FUNC | grep point [146] | 70016| 152|FUNC |GLOB |0 |8 |point_ demo% nm trylib | grep FUNC | grep evalx [165] | 69848| 152|FUNC |GLOB |0 |8 |evalx_ demo% nm trylib | grep FUNC | grep delte demo% nm trylib | grep FUNC | grep markx demo% ..etc |
前述の例では、grep は名前のリストから、実際に呼び出されたライブラリルーチンの項目だけを見つけます。
ライブラリを参照するもう 1 つの方法は、-llibrary と -Lpath オプションを使用する方法です。ここでは、libname.a の規則に従うため、ライブラリの名前を変更しなければいけません。
demo% mv test_lib/testlib.a test_lib/libtestlib.a demo% f95 -o trylib trylib.f -Ltest_lib -ltestlib |
-llibrary と -Lpath オプションは、ほかのユーザーが参照できるように、/usr/local/lib のようなシステム上の一般的にアクセス可能なディレクトリにインストールされたライブラリに使用できます。たとえば、 libtestlib.a を /usr/local/lib に置いた場合、次のコマンドを使用してコンパイルするよう、ほかのユーザーに知らせてください。
demo% f95 -o myprog myprog.f -L/usr/local/lib -ltestlib |
2、3 の要素だけをコンパイルし直す場合、ライブラリ全体をコンパイルし直す必要はありません。ar の -r オプションを使用すると、静的ライブラリ中の個々の要素を置換できます。
例: 静的ライブラリ中の 1 つのルーチンをコンパイルし直し、置換します。
demo% f95 -c point.f demo% ar -r testlib.a point.o |
ar を使用して構築しているときに静的ライブラリ中の要素を整列するには、コマンド lorder(1) と tsort(1) を使用します。
demo% ar -cr mylib.a 'lorder exg.o fofx.o diffz.o | tsort' |
動的ライブラリファイルは、リンカー ld によって、実行開始後に実行可能ファイルにリンクできるコンパイル済みオブジェクトモジュールから構築されます。
動的ライブラリのもう 1 つの特長は、各プログラムのメモリーにモジュールを複製することなく、システムで実行中のほかのプログラムからモジュールを使用できることです。 この理由のため、動的ライブラリは共有ライブラリとも呼ばれます。
動的ライブラリには次のような特長があります。
オブジェクトモジュールは、コンパイルとリンクの処理中に、リンカーによって 実行可能ファイルにリンクされるのではありません。リンクは実行時まで延期さ れます。
共有ライブラリのモジュールは、実行プログラムがそのモジュールを初めて参照したときに、システムメモリーにリンクされます。以降の実行プログラムがそのモジュールを参照した場合、その参照は最初のコピーにマップされます。
動的ライブラリを使用すると、プログラムの管理が簡単になります。更新された動的ライブラリをシステムにインストールすると、すぐに、そのライブラリを使用するすべてのアプリケーションに影響を与えます。実行可能ファイルにリンクし直す必要はありません。
動的ライブラリは、いくつかの長所と短所を考慮しなければいけません。
より小さな a.out ファイル
実行時までライブラリルーチンのリンクを延期するということは、実行可能ファイルのサイズが、ライブラリの静的バージョンを呼び出す同等な実行可能ファイルより小さいということを意味します。つまり、実行可能ファイルは、ライブラリルーチンのバイナリを含みません。
プロセスメモリーの利用率が減少する可能性
ライブラリを使用するいくつかのプロセスが同時にアクティブになったとき、ライブラリの 1 つのコピーだけがメモリーに常駐し、そのコピーがすべてのプロセスによって共有されます。
オーバーヘッドが増加する可能性
実行時、ライブラリルーチンを読み込み、リンク編集するための余分なプロセッサ時間が必要になります。また、ライブラリの位置独立コーディングのため、静的ライブラリにおける再配置可能なコーディングよりも実行速度が遅くなる可能性があります。
システム全体のパフォーマンスが向上する可能性
ライブラリの共有によるメモリー利用率の減少が、システム全体のパフォーマンスにとってはよい結果となるはずです (メモリースワップの入出力アクセス時間が減少します)。
プログラムのパフォーマンス状況は、各プログラムによって大きく異なります。動的ライブラリと静的ライブラリの間でパフォーマンスの向上 (または低下) を予想することは必ずしもできません。しかし、必要なライブラリの両方の形式が利用できる場合、それぞれのライブラリを使用してユーザーのプログラムのパフォーマンスを評価する価値はあります。
位置独立コード (PIC) は、リンクエディタによる再配置を必要とせず、プログラムの 任意のアドレスにリンクできます。このようなコードは、本質的に同時プロセス間で共有できます。したがって、動的共有ライブラリを構築する場合、-xcode コンパイラオプションを使用して、位置に依存しないように構成要素ルーチンをコンパイルしなければいけません。
位置独立コードの中では、大域的なデータへの個々の参照は、大域的なオフセットテーブルへのポインタを通じての参照としてコンパイルされます。関数呼び出しはそれぞれ、手続きリンケージテーブルを通して、相対アドレッシングモードでコンパイルされます。この大域的なオフセットテーブルのサイズは、SPARC プロセッサでは 8K バイトに制限されています。
コンパイラフラグ -xcode=v を使用すると、バイナリオブジェクトのコードアドレス空間を指定できます。このコンパイラフラグを使用して、32 ビット、44 ビット、または 64 ビットの絶対アドレス、さらに小型モデルと大型モデルの位置に依存しないコードを生成できます。-xcode=pic13 は古い -pic と等価で、-xcode=pic32 は -PIC と等価です。
-xcode=pic32 コンパイラオプションは -xcode=pic13 と似ていますが、さらに、大域的なオフセットテーブルが 32 ビットのアドレス空間に渡ることを許可します。詳細は、f95(1) のマニュアルページか『Fortran ユーザーズガイド』を参照してください。
コンパイル時、ライブラリのリンクが動的であるか静的であるかを指定できます。このようなオプションは実際にはリンカーオプションですが、コンパイラによって認識されリンカーに渡されます。
–Bdynamic は、可能であれば必ず共有動的リンクの優先を設定します。– Bstatic は、リンクを静的ライブラリだけに制限します。
静的バージョンと動的バージョンの両方とも利用できるとき、このオプションを使用して、コマンド行上から設定を切り替えます。
f95 prog.f -Bdynamic -lwells -Bstatic -lsurface
実行可能ファイル全体に対して動的リンクを許可または禁止します。このオプションをコマンド行で使用できるのは 1 回だけです。
–dy は、動的共有ライブラリへのリンクを許可します。-dn は、動的ライブラリへのリンクを禁止します。
libm.a や libc.a などの静的システムライブラリによっては、Solaris の 64 ビットオペレーティング環境では使用できないものもあります。このようなライブラリは動的ライブラリ専用として提供されます。64 ビット環境で -dn を使用すると、いくつかの静的システムライブラリが見つからないことを示すエラーが出力されます。また、コンパイラのコマンド行を -Bstatic で終了しても同じ結果になります。
特定のライブラリの静的バージョンとリンクするには、次のようなコマンド行を使用します。
f95 -o prog prog.f -Bstatic -labc -lxyz -Bdynamic
この場合、ユーザーの libabc.a と libxyz.a ファイルがリンクされて (libabc.so や libxyz.so ではない)、最後の -Bdynamic によってシステムライブラリを含めて残りのライブラリが動的にリンクされます。
さらに複雑な状況では、適切な -Bstatic や -Bdynamic を必要に応じて使用して、リンク手順で各システムライブラリとユーザーライブラリを明示的に参照する必要があります。まず、LD_OPTIONS に '-Dfiles' を設定して、必要なライブラリをすべてリストします。次に、-nolib (システムライブラリの自動リンクを抑制する) を指定してリンク手順を実行し、必要なライブラリを明示的に参照します。次に例を示します。
f95 -m64 -o cdf -nolib cdf.o -Bstatic -lsunmath \ -Bdynamic -lm -lc
リンクローダーとコンパイラによって想定された動的ライブラリの命名規則に従うために、ユーザーが作成した動的ライブラリの名前には接頭辞 lib と接頭辞 .so を付けます。たとえば、libmyfavs.so は、コンパイラオプション -lmyfavs によって参照できます。
またリンカーは任意のバージョン番号接頭辞も受け付けます。たとえば、libmyfavs.so.1 はこのライブラリのバージョン 1 です。
コンパイラの -hname オプションは、構築される動的ライブラリの名前として name を記録します。
動的ライブラリを構築するには、-xcode オプションとリンカーオプション -G、-ztext、-hname を使用して、ソースファイルをコンパイルする必要があります。これらのリンカーオプションは、コンパイラのコマンド行で利用できます。
静的ライブラリの例と同じファイルを使用して、動的ライブラリを作成できます。
例: -pic とほかのリンカーオプションを使用してコンパイルします。
demo% f95 -o libtestlib.so.1 -G -xcode=pic13 -ztext \ –hlibtestlib.so.1 *.f |
-ztext は、位置独立コード以外のもの (たとえば、再配置可能なテキストなど) があった場合に警告を発します。
例: 動的ライブラリを使用して実行可能ファイル a.out を作成します。
demo% f95 -o trylib -R`pwd` trylib.f libtestlib.so.1 demo% file trylib trylib:ELF 32–bit MSB 実行可能 SPARC version 1 [動的にリンクされています][取り除かれていません] demo% ldd trylib libtestlib.so.1 => /export/home/U/Tests/libtestlib.so.1 libfui.so.1 => /opt/SUNWspro/lib/libfui.so.1 libfai.so.1 => /opt/SUNWspro/lib/libfai.so.1 libc.so.1 => /usr/lib/libc.so.1 |
例では、-R オプションを使用して、動的ライブラリへのパス (現在のディレクトリ) を実行可能ファイルにリンクしていることに注目してください。
file コマンドは、実行可能ファイルが動的にリンクされていることを表示します。
動的ライブラリを構築する際、初期化された共通ブロックを同じライブラリに集め、そのほかのライブラリの前に参照することにより、共通ブロックを正しく初期化する (DATA または BLOCK DATA を使用) ことを保証します。
例:
demo% f95 -G -xcode=pic32 -o init.so blkdat1.f blkdat2.f blkdat3.f demo% f95 -o prog main.f init.so otherlib1.so otherlib2.so |
最初のコンパイルにより、共通ブロックを定義し、BLOCK DATA 単位でそれらを初期化するファイルの動的ライブラリが作成されます。2 番目のコンパイルにより、実行可能バイナリが作成され、コンパイル済み主プログラムをアプリケーションが必要とする動的ライブラリにリンクします。すべての共通ブロックを初期化する動的ライブラリは、その他すべてのライブラリより前に最初に現れます。これにより、ブロックが正しく初期化されたことが保証されます。
次の表に、コンパイラと共にインストールされるライブラリを示します。
表 4–1 コンパイラと共に提供される主なライブラリ
ライブラリ |
名称 |
必要なオプション |
---|---|---|
f95 サポート組み込み手続き |
libfsu |
なし |
f95 インタフェース |
libfui |
なし |
f95 配列組み込みライブラリ |
libf*ai |
なし |
f95 区間演算組み込みライブラリ |
libifai |
-xinterval |
Sun の数学関数ライブラリ |
libsunmath |
なし |
ユーザーの実行可能ファイルが、runtime.libraries README ファイルにリストされている Sun 動的ライブラリを使用している場合、ユーザーのライセンスには、そのライブラリをユーザーの顧客に再配布する権利が含まれます。
この README ファイルは、次の Sun Studio SDN ポータルにあります。
http://developers.sun.com/sunstudio/documentation/ss12/
ヘッダーファイル、ソースコード、オブジェクトモジュール、オブジェクトモジュールの静的ライブラリは、いかなる形式でも再配布または公開しないでください。
詳細は、ソフトウェアライセンスを参照してください。