動的ライブラリファイルは、リンカー 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 番目のコンパイルにより、実行可能バイナリが作成され、コンパイル済み主プログラムをアプリケーションが必要とする動的ライブラリにリンクします。すべての共通ブロックを初期化する動的ライブラリは、その他すべてのライブラリより前に最初に現れます。これにより、ブロックが正しく初期化されたことが保証されます。