これまで,ソースコードパッケージの開発者が共有ライブラリの力を利用したい 場合,パッケージを実行するそれぞれのプラットフォームに対し,カスタムサポー トコードを書く必要がありました.パッケージインストーラが構築されるライブ ラリの種類を選択できるように,コンフィグレーションインターフェースを設計 する必要もありました.
GNU Libtoolは,一つのスクリプトで,プラットフォーム特有の依存とユーザイ ンターフェースの両方をカプセル化することで,開発者の仕事を単純にします. それぞれのホスト形式の完全な機能を一般的なインタフェースを通して利用でき るようにGNU Libtoolは設計されていますが,やっかいな癖はプログラマから隠 されます.
GNU Libtoolの一貫したインターフェースは再保証されます... ユーザは好
みのソースコードパッケージを共有ライブラリに構築するため,曖昧なドキュメ
ントを読む必要がありません.それらはパッケージのconfigureスクリプ
ト(または同等品)を実行し,libtoolはいやな仕事をすべて行います.
このドキュメント全体にいくつかの例があります.すべて同じ環境を仮定してい
ます.我々は,ライブラリlibhelloを一般的な方法で構築したいと思っ
ています.
libhelloは,共有ライブラリ,スタティックライブラリ,または,その
両方です... libtoolで移植できるホストシステムで利用可能な,あらゆる
ものです.
この章は,libtoolの最初の設計思想を説明します.歴史に興味がなかったり, 一貫した方法で拡張されているlibtoolに対しコードを書きたい場合,つぎの章 へ自由に行ってください.
1995年初頭から,数人の異なるGNU開発者は,パッケージに対する共有ライブラ リのサポートの重要性を認識していました.そのように変更した主な動機は, GNUプログラムでのコードのモジュール化と再利用を(概念的,物理的の両方で) 促進するためです.
そのような要求は,GNUパッケージにライブラリを組み込む方法で,パッケージ インストーラが必要とするあらゆるライブラリ形式が可能な,一般的な方法が必 要だということを意味します.異なるプラットフォームで共有ライブラリを作成 する標準手続きが無いことが問題です.
以下のセクションで,GNUでの共有ライブラリのサポートが直面している重大な 問題と,共有ライブラリのサポートをlibtoolで標準化した方法を概説します.
以下の仕様書が,このシステムの開発評価で使用されました.
以下の問題は,再利用可能なあらゆる共有ライブラリシステム,特にlibtoolで 扱う必要があります.
LD_LIBRARY_PATHが(サポートしている場合は)正し
く設定されている必要があり,そうでなければプログラムの実行に失敗するでしょ
う.
Makefile規則が難しくなります.
Makefileターゲットは,パッケージインストーラに
特定の環境変数(LD_LIBRARY_PATHまたは同等のもの)を設定したり,
ldconfigを実行するよう,警告する必要があります.
libtoolが開発されるまで,多くのフリーソフトウエアパッケージは,独自の 共有ライブラリを構築し,インストールしていました.最初は,既存の機能の再 発明を避けるために,これらのパッケージは調査されました.
さて,これらのパッケージに,libtoolが要求する,共有ライブラリシステム の詳細な文章が無いのは明らかです.そのため,他のパッケージは,影響のため 多少捨てられました.
調査されたそれぞれの実装は,多くの異なるホストシステムに対して,予定して いた仕事をすべて公平に行いました.しかし,一般的に再利用できる要素として 機能するものは,これらの解決法にはなさそうです.
ほとんどのものは,実装が行っていることを正確に理解すること無く使用する (まして,変更する)には複雑すぎ,それらは通常,文章化されていませんでした.
主な困難さは,異なるベンダーはライブラリについて異なる見解を持つこと,そ して,調査したパッケージには,当然動作するという,単一の規範を自 信を持って定めているものが無かったことです.
理想としては,拡張シリーズと既存のライブラリシステムが絶えず動作するよう な編集を実装する標準に,libtoolがなることです.しかし,オペレーティング システム開発者の悪い方法を修正することは簡単な仕事ではなく,人々は,バグ が多く,壊れていて,混乱したオペレーティングシステム上でさえ,今すぐに共 有ライブラリを構築したいと思っていました.
このため,libtoolは独立したシェルスクリプトとして設計されました.それは,
異なるプラットフォーム上のコンパイラスイートを,堅実で強力なインターフェー
スを用いて包み込むことで,Makefileの書き手を悩ませるライブラリ構
築での問題と矛盾から隔離しています.
運が良ければ,libtoolは役に立ちGNUコミュニティで使用され,そして,それを 書くとき学んだ教訓は,将来のライブラリシステムの設計に採用されるでしょう.
最初は,ライブラリのオブジェクト形式の任意の数をサポートするように libtool は設計されました.その後,libtoolはより多くのプラットフォームに 移植され,新しいパラダイムは,ライブラリとプログラムの間の関係を記述する ため,徐々に開発されました.
要約すると,"ライブラリは複数のエントリポイントと,より正式に定義された インターフェースがあるプログラムです."
libtoolのバージョン0.7は,この新しいパラダイムを反映するため,完全に再設 計され書き換えられました.今のところ成功しているようです.libtoolは,以 前よりより単純になり,より役に立ちます.
libtoolパラダイムを導入する最善の方法は,それぞれの例を用い,既存のライ ブラリシステムのパラダイムと比較することです.それは新しい考え方なので吸 収するまで少し時間がかかるかもしれませんが,理解したとき世界がより単純化 されるでしょう.
libtoolが人生をより単純にする方法が分かるまで,独自のパッケージでlibtool を使用することを話す意味がありません.この章の例は,標準的なライブラリの 構築処理と,libtoolの処理を,2つの異なるプラットフォームで比較することで, 主な特徴を紹介します.
a23
burger
独自のプラットフォームの例をこれに続けることができ,それは,libtoolでイ ンストールされた,前もってコンフィグレーションされたlibtoolスクリプトを 用います(see Configuring).
以下の例のソースファイルは,libtool配布物のdemoサブディレクトリか
ら持ってきました.ファイルfoo.cとhello.cからライブラリ
libhelloを構築していると考えてください.
foo.cソースファイルがcos数学ライブラリ関数を使用していて,
それは通常,Cライブラリではなく単独の数学ライブラリで見つかることに注意
してください(see Trig Functions).そのため,foo.oやfoo.lo
を実行形式やライブラリにリンクするときは,常にリンク行の最後に-lm
を加える必要があります(see Inter-library dependencies).
同じ規則は,標準Cライブラリに無い関数を使用するとき,常に当てはまります ... これらのオブジェクトに対しリンクするときは,適切な -lnameフラグをリンク行の終りに加える必要があります.
ライブラリをビルドした後,libhelloに対してmain.oをリンクす
ることでプログラムを作成したいと思います.
ソースファイルからオブジェクトファイルを作成するため,コンパイラは`-c'フ ラグ(とその他の必要なあらゆるフラグ)とともに呼び出されます.
burger$ gcc -g -O -c main.c burger$
上記のコンパイラコマンドは,ソースファイルmain.cからオブジェクト
ファイルmain.oを生成します.
ほとんどのライブラリシステムに対し,スタティックライブラリの一部となるオ ブジェクトファイルを作成することは,実行可能な形式にリンクされるオブジェ クトファイルを作成することと同じくらい単純です.
burger$ gcc -g -O -c foo.c burger$ gcc -g -O -c hello.c burger$
しかし,共有ライブラリはposition-independent code(PIC)のみから構築 されます.そのため,標準のposition-dependent codeではなくPICを生成するよ うにコンパイラに伝えるため,特定のフラグを渡す必要があります.
これはライブラリ実装の詳細なので,libtoolは別々の(.oの代わりに
.loで終わる)ライブラリオブジェクトファイルを用いて,複雑なPICコン
パイラフラグを隠します.共有ライブラリがない(または,特定のPICフラグがな
い)システムでは,これらのライブラリオブジェクトファイルは"標準の"オブ
ジェクトファイルと同じです.
foo.cとhello.cに対するライブラリオブジェクトファイルを作成
するため,単純に標準のコンパイルコマンドを引数として,libtoolを呼び出し
てください(see Compile mode).
a23$ libtool gcc -g -O -c foo.c gcc -g -O -c foo.c echo timestamp > foo.lo a23$ libtool gcc -g -O -c hello.c gcc -g -O -c hello.c echo timestamp > hello.lo a23$
libtoolがそれぞれの呼び出しに対し,2つのファイルを作成することに注意し
てください..loファイルはライブラリオブジェクトで,それは共有ライ
ブラリに構築され,.oファイルは標準的なオブジェクトファイルです.
a23では,スタティックライブラリのみサポートされているので,ライブ
ラリオブジェクトはタイムスタンプのみです.
共有ライブラリのあるシステムでは,ライブラリオブジェクトと標準オブジェク トが異なるように,libtoolはPIC生成フラグをコンパイルコマンドに自動的に挿 入します.
burger$ libtool gcc -g -O -c foo.c gcc -g -O -c -fPIC -DPIC foo.c mv -f foo.o foo.lo gcc -g -O -c foo.c >/dev/null 2>&1 burger$ libtool gcc -g -O -c hello.c gcc -g -O -c -fPIC -DPIC hello.c mv -f hello.o hello.lo gcc -g -O -c hello.c >/dev/null 2>&1 burger$
2番目に実行されるGCCがその出力を破棄していることに注意してください.こ れは,コンパイラの警告がうるさく重複しないために行われます.
libtoolを用いない場合,スタティックライブラリを作成するため,プログラマ
はarコマンドを呼び出していました.
burger$ ar cru libhello.a hello.o foo.o burger$
しかしもちろん,それだけではあまりに単純すぎて,多くのシステムでは(それ
以上のカルマや何かを与えるため)ranlibコマンドを結果として生成され
たライブラリ上で実行する必要があります.
burger$ ranlib libhello.a burger$
libtoolの"ライブラリはプログラム"というアプローチで与えられるこの作業
に対し,Cコンパイラを使用することは,より自然に感じられます.そのため,
共有ライブラリが無いプラットフォームでは,libtoolは単純にシステムの
ar(そして可能ならranlib)コマンドのラッパーとして動作します.
再びlibtoolライブラリ名を標準の名前(.a接尾子の代わりに.la
接尾子を持ちます)と異なるものとします.libtoolの引数はコンパイラで
libhello.laという名の実行形式を生成するために使用したのと同じもの
です(see Link mode).
a23$ libtool gcc -g -O -o libhello.la foo.o hello.o
libtool: cannot build libtool library `libhello.la' from non-libtool \
objects
a23$
あぁ!libtoolは通常のエラーを得てしまった... ライブラリオブジェクト の代わりに,標準のオブジェクトからライブラリを構築しています.これはスタ ティックライブラリでは問題ありませんが,共有ライブラリシステムでは非常に 重要です.
そのため,今回はライブラリオブジェクトファイルを用いて,もう一度試してみ
ましょう.foo.cがcos数学ライブラリを使用しているので,コマ
ンドラインに-lmを加える必要があることも忘れないでください
(see Using libtool).
共有ライブラリを構築するその他の複雑なことは,(最終的に)インストールされ
るディレクトリパス(この場合は,/usr/local/lib)
1
を指定する必要があることです.
a23$ libtool gcc -g -O -o libhello.la foo.lo hello.lo \
-rpath /usr/local/lib -lm
mkdir .libs
ar cru .libs/libhello.a foo.o hello.o
ranlib .libs/libhello.a
creating libhello.la
a23$
さて,共有ライブラリのプラットフォーム上で同じトリックを試してみましょう.
burger$ libtool gcc -g -O -o libhello.la foo.lo hello.lo \
-rpath /usr/local/lib -lm
mkdir .libs
ld -Bshareable -o .libs/libhello.so.0.0 foo.lo hello.lo -lm
ar cru .libs/libhello.a foo.o hello.o
ranlib .libs/libhello.a
creating libhello.la
burger$
さてそれはかなり賢いです... libtoolは共有ライブラリを作成するため,
スタティックライブラリと同様に,曖昧なldコマンドを実行しただけで
す.
libtoolが現在のディレクトリではなく,.libsサブディレクト
リに,予備のファイルを作成する方法に注意してください.この機能は構築ディ
レクトリをきれいにするのをより簡単にするためと,たまたまlibtoolの使用を
忘れていて他のプログラムを実行するとき,確実に手ひどく失敗させるのに役立
ちます.
ライブラリを,実行形式とリンクする前に,インストールする(永久に位
置する場所にそれを配置する)場所を選択した場合,リンクするためにlibtoolを
使用する必要はありません.ライブラリの位置を指定するため,単純に適切な
-Lと-lフラグを使用してください.
システムのリンカによっては結果として生じる実行形式に,共有ライブラリの完 全なディレクトリ名の符号化を強要するものもあります.libtoolは永久に配置 されるディレクトリ名のみインストールされた実行形式に書き込むことを確実に するため,特別な魔法でこの設計ミスに関して動作する必要があります.
このバグの重要性は,見落としてはなりません.それによるプログラムの暴走は 明白ではありません.それはセキュリティホールを作成し,さらに悪いことには, パッケージのインストール後にライブラリソースコードを編集した場合,インス トールされたプログラムの動作を変更してしまうでしょう!
そのため,インストールする前にライブラリとプログラムをリンクさせたい場合, リンクするためにlibtoolを使用する必要があります.
ここにインストールされていないライブラリとリンクする古い方法があります.
burger$ gcc -g -O -o hell.old main.o libhello.a -lm burger$
libtoolの方法はほとんど同じです2(see Link mode).
a23$ libtool gcc -g -O -o hell main.o libhello.la -lm gcc -g -O -o hell main.o ./.libs/libhello.a -lm a23$
真実としてはあまりに単純に見えます.libtoolが行うことは,
libhello.laを./.libs/libhello.aに変換することがす
べてですが,a23は共有ライブラリがないことを忘れないでください.
burgerでは,状況が異なります.
burger$ libtool gcc -g -O -o hell main.o libhello.la -lm gcc -g -O -o .libs/hell main.o -L./.libs -R/usr/local/lib -lhello -lm creating hell burger$
さて,libhello.laが既にインストールされていると仮定し,新しいプロ
グラムをそれとリンクしたいとします.自分でそれがある場所を探し,以下を実
行します.
burger$ gcc -g -O -o test test.o -L/usr/local/lib -lhello
しかし,/usr/local/libが標準のライブラリ検索パスに無い場合,
testを実行することはできません.しかし,既にインストールされてい
るlibtoolライブラリとリンクするためlibtoolを使用する場合,それは The
Right Thing (TM)となります.
burger$ libtool gcc -g -O -o test test.o /usr/local/lib/libhello.la gcc -g -O -o .libs/test test.o -Wl,--rpath -Wl,/usr/local/lib /usr/local/lib/libhello.a -lm creating test burger$
libtoolが,ライブラリlibhello.laが依存している-lm同様,必要なラン
タイムパスフラグを加えていることに注意してください.いいですね,ふっふ?
libtoolがラッパースクリプトを作成したので,インストールとデバッグにも libtoolを使用したほうがいいでしょう.しかし,プログラムはインストールさ れていないlibtoolライブラリには全く依存しないので,ラッパースクリプトを 用いない場合でも,それはおそらく有用でしょう.この場合はラッパースクリプ トの作成を避けるため,おそらくより賢くlibtoolを作成できたでしょうが,こ れは読者の演習として残しておきます.
実行形式hellは,実際には.libsサブディレクトリに作
成されることに注意してください.そして,ラッパースクリプトは現在のディレ
クトリに作成されます.
NetBSD 1.2では,libtoolは,-R/usr/local/libコンパイラフラグを使用
して,libhelloのディレクトリのインストールを符号化します.そして,
ラッパースクリプトは,正しくインストールされるまで実行形式が正しい
(./.libsにある)共有ライブラリを見つけることを保証します.
2つの異なるプログラムを比較してみましょう.
burger$ time ./hell.old
Welcome to GNU Hell!
** This is not GNU Hello. There is no built-in mail reader. **
0.21 real 0.02 user 0.08 sys
burger$ time ./hell
Welcome to GNU Hell!
** This is not GNU Hello. There is no built-in mail reader. **
0.63 real 0.09 user 0.59 sys
burger$
ラッパースクリプトは実行にかなりかかりますが,共有ライブラリがインストー ルされていなくても,少なくとも結果は正しくなります.
そのため,共有ライブラリが生じると仮定すると,保存スペース全体ははどうなっ ているのでしょう?
burger$ ls -l hell.old libhello.a -rwxr-xr-x 1 gord gord 15481 Nov 14 12:11 hell.old -rw-r--r-- 1 gord gord 4274 Nov 13 18:02 libhello.a burger$ ls -l .libs/hell .libs/libhello.* -rwxr-xr-x 1 gord gord 11647 Nov 14 12:10 .libs/hell -rw-r--r-- 1 gord gord 4274 Nov 13 18:44 .libs/libhello.a -rwxr-xr-x 1 gord gord 12205 Nov 13 18:44 .libs/libhello.so.0.0 burger$
さて,それは吸収されます.おそらく,私はこのプロジェクトを破壊し,作成中 の籠を取り上げたほうがいいでしょう.
実際,それは重要な点を証明します.共有ライブラリは,それが(関連する)複雑
さのため,オーバーへッドを招きます.この状況では,ダイナミックの価値は8
キロバイトで,報酬は約4キロバイトです.そのため,少なくとも2,3以上のプ
ログラムとリンクするまで,共有されるlibhelloを維持することは利点
ではありません.
hellが複雑なプログラムの場合,システムにインストールする前にそれ
のテストとデバッグを間違いなく行いたいでしょう.上記のセクションで,
libtoolラッパースクリプトが,プログラムを直接実行することを可能にする方
法を見ましたが,残念ながら,このメカニズムはデバッガを妨げます.
burger$ gdb hell GDB is free software and you are welcome to distribute copies of it under certain conditions; type "show copying" to see the conditions. There is no warranty for GDB; type "show warranty" for details. GDB 4.16 (i386-unknown-netbsd), (C) 1996 Free Software Foundation, Inc. "hell": not in executable format: File format not recognized (gdb) quit burger$
残念です.GDBは実行形式がある場所が分からないので動作しません.そのため, もう一度実行形式でGDBを呼び出してみてください.
burger$ gdb .libs/hell trick:/home/src/libtool/demo$ gdb .libs/hell GDB is free software and you are welcome to distribute copies of it under certain conditions; type "show copying" to see the conditions. There is no warranty for GDB; type "show warranty" for details. GDB 4.16 (i386-unknown-netbsd), (C) 1996 Free Software Foundation, Inc. (gdb) break main Breakpoint 1 at 0x8048547: file main.c, line 29. (gdb) run Starting program: /home/src/libtool/demo/.libs/hell /home/src/libtool/demo/.libs/hell: can't load library 'libhello.so.2' Program exited with code 020. (gdb) quit burger$
あぁ.さて,GDBは,hellがリンクしている共有ライブラリを見つけるこ
とができないため文句を言いました.そのため,正しいライブラリパスを設定し
て,デバッガを実行するため,libtoolを使う必要があります.幸い,
.libsディレクトリを完全に忘れて,そのままの実行形式のラッ
パーで実行可能です(see Execute mode).
burger$ libtool gdb hell
GDB is free software and you are welcome to distribute copies of it
under certain conditions; type "show copying" to see the conditions.
There is no warranty for GDB; type "show warranty" for details.
GDB 4.16 (i386-unknown-netbsd), (C) 1996 Free Software Foundation, Inc.
(gdb) break main
Breakpoint 1 at 0x8048547: file main.c, line 29.
(gdb) run
Starting program: /home/src/libtool/demo/.libs/hell
Breakpoint 1, main (argc=1, argv=0xbffffc40) at main.c:29
29 printf ("Welcome to GNU Hell!\n");
(gdb) quit
The program is running. Quit anyway (and kill it)? (y or n) y
burger$
libtoolが無いシステムでライブラリをインストールすることは,全く簡単です ... それらをその場所にコピーするだけです.3
burger$ su Password: ******** burger# cp libhello.a /usr/local/lib/libhello.a burger#
おっと,ranlibコマンドを忘れないでください.
burger# ranlib /usr/local/lib/libhello.a burger#
libtoolのインストールは,同様に全く単純です.通常使用する,
installやcpコマンドをそのまま使用してください
(see Install mode).
a23# libtool cp libhello.la /usr/local/lib/libhello.la cp libhello.la /usr/local/lib/libhello.la cp .libs/libhello.a /usr/local/lib/libhello.a ranlib /usr/local/lib/libhello.a a23#
アンインストールでlibtoolを助け(see Uninstall mode),リンクし
(see Linking executables),dlopenでプログラムを助ける
(see Dlopened modules)ため,libtoolのライブラリlibhello.laも
インストールされることに注意してください.
ここに,共有ライブラリの例があります.
burger# libtool install -c libhello.la /usr/local/lib/libhello.la install -c .libs/libhello.so.0.0 /usr/local/lib/libhello.so.0.0 install -c libhello.la /usr/local/lib/libhello.la install -c .libs/libhello.a /usr/local/lib/libhello.a ranlib /usr/local/lib/libhello.a burger#
ライブラリインストール時にBSD互換のinstallプログラムを使用する場合,
-s(シンボルを切り捨てる)フラグを指定すると安全です.libtool は
-sフラグを無視するか,ライブラリからデバッグとコンパイラシンボル
のみを切り捨てるプログラムを実行します.
ライブラリを一度配置すると,使用する前に必要な追加のコンフィグレーション
を行います.最初に構築時に使用した-rpathフラグと同じ場所に,ライ
ブラリが実際にインストールされていることを確かめる必要があります.
そして,libtool -n --finish libdirを実行すると,行うことの
ヒントが与えられます(see Finish mode).
burger# libtool -n --finish /usr/local/lib
PATH="$PATH:/sbin" ldconfig -m /usr/local/lib
-----------------------------------------------------------------
Libraries have been installed in:
/usr/local/lib
To link against installed libraries in a given directory, LIBDIR,
you must use the `-LLIBDIR' flag during linking.
You will also need to do one of the following:
- add LIBDIR to the `LD_LIBRARY_PATH' environment variable
during execution
- add LIBDIR to the `LD_RUN_PATH' environment variable
during linking
- use the `-RLIBDIR' linker flag
See any operating system documentation about shared libraries for
more information, such as the ld and ld.so manual pages.
-----------------------------------------------------------------
burger#
これらのステップを完了した後,インストールされたライブラリを使用開始でき ます.作成されたライブラリに依存する実行形式もインストールできます.
インストールされていないlibtoolライブラリに対して実行形式をリンクするた めにlibtoolを使用した場合(see Linking executables),ライブラリをイン ストールした後で,実行形式をインストールするためlibtoolを使用する必要が あります.
そして,Ultrixの例を実行します.
a23# libtool install -c hell /usr/local/bin/hell install -c hell /usr/local/bin/hell a23#
共有ライブラリシステムでは,libtoolはラッパースクリプトを無視し,正しい バイナリをインストールします.
burger# libtool install -c hell /usr/local/bin/hell install -c .libs/hell /usr/local/bin/hell burger#
libtoolの旨味を知って,arとranlibの愚かさへなぜ戻るのでしょ
う?さて,決して共有されるはずがないスタティックアーカイブをつくることが
望ましいときもあります.最もよくあるケースは,複数の異なるプログラムを構
築するために使用する,オブジェクトファイルの集まりを持っているときです.
個々のプログラムに対し,すべてのオブジェクトファイルをリストアップする代
わりに,それらのオブジェクトから"便利なライブラリ"を作成し,ライブラリ
とプログラムをリンクすることが可能です.この技術は,他のディレクトリのラ
イブラリへのリンクをサポートするので,他のディレクトリのソースから構築さ
れるオブジェクトファイルをリンクするサポートが欠けている,GNU automakeを
補うためによく使用されます.この制限は,リリース1.4までのGNU automakeに
当てはまります.より新しいリリースは,他のディレクトリのソースをサポート
するでしょう.
この便利なライブラリとプログラムをリンクしたいだけの場合,完全にlibtool
を無視し,古いarとranlibコマンド(や,対応するGNU automake
_LIBRARIES規則)が使用可能です.(おそらく使用したくはないでしょう
が)libtoolを使用して,便利なライブラリをインストールすることさえ可能です.
burger$ libtool ./install-sh -c libhello.a /local/lib/libhello.a ./install-sh -c libhello.a /local/lib/libhello.a ranlib /local/lib/libhello.a burger$
スタティックライブラリのインストールにlibtoolを使用すると,ライブラリが
(-sフラグを使用したインストーラの場合のように)偶然切り取られるこ
とから守り,自動的に実行される正しいranlibコマンドと同様になりま
す.
しかし,libtoolライブラリは単にオブジェクトファイルの集合以上です.それ
らは古いアーカイブにはない,ライブラリの依存情報も運ぶことが可能です.
libtoolの静的な便利なライブラリを作成したい場合,スタティックライブラリ
のみに興味があることを示すため,-rpathフラグを省略し
-staticを使用することができます.そのようなスタティックライブラリ
とリンクするとき,libtoolは実際にすべてのオブジェクトファイルと依存する
ライブラリをプログラムにリンクします.
-rpathと-staticの両方を省略した場合,libtoolは,他の
libtoolライブラリで,共有ライブラリの作成にすら使用可能なlibtoolの便利な
ライブラリを作成します.静的な場合のように,ライブラリは一組のオブジェク
トファイルと依存するライブラリの別名として動作しますが,この場合,オブジェ
クトファイルは共有ライブラリに含まれるほうが適しています.しかし,直接ま
たは間接的に,単一のプログラムやライブラリに単一の便利なライブラリをリン
クしないように注意して下さい.さもなければ,シンボル再定義に関するエラー
を得るでしょう.
GNU automakeを使用するとき,-rpathオプションがリンク時に渡されな
いように,便利なライブラリに対するlib_LTLIBRARIESの代わりに
noinst_LTLIBRARIESを使用した方が良いでしょう.
経験的に,最大一つのlibtoolライブラリにlibtoolの便利なライブラリをリンク し,プログラムにはリンクせず,libtoolの便利なスタティックライブラリを一 つのプログラムにのみリンクし,それは,ライブラリ依存情報を便利なスタティッ クライブラリのユーザに運ぶことが必要な場合のみです.
静的なリンクが適している,その他の一般的な状況は,独立したバイナリを作成
するときです.リンクにlibtoolを使用し,-all-staticフラグを加えて
ください.
libtoolの呼び出しlibtoolプログラムは以下の構文を持ちます.
libtool [option]... [mode-arg]...
そして,以下のオプションを受け入れます.
--config
--debug
less(やmore)にパイプしたり,ファイルにリダイ
レクトしたいかもしれません.
-n
--dry-run
--features
--finish
--mode=finishと同じです.
--help
--mode=modeが指定された
場合,modeの詳細へルプを表示します.
--mode=mode
modeが指定された場合,それは以下の一つにする必要があります.
compile
execute
finish
install
link
uninstall
clean
--version
mode-argsは引数の変数の数で,処理モードの選択に依存します.一般的 に,それぞれのmode-argは,libtool自身ではなく,libtoolが呼び出すプ ログラムで解釈されます.
コンパイルモードに対し,mode-argsは,`標準的な'オブジェクト
ファイルを作成するとき使用するコンパイルコマンドです.これらの引数は,C
コンパイラの名前で始まり,オブジェクトファイルのみを作成するための
-cコンパイラフラグを含みます.
libtoolは,ソースファイル名からディレクトリ要素を削除して出力ファイル名
を決定し,ソースコードの接尾子(例えば,Cソースコードに対する.c)を
ライブラリオブジェクト接尾子.loに置換します.
共有ライブラリの構築の場合は,必要なPIC生成フラグがコンパイルコマンドに
置換されます.-Wc,flagと-Xcompiler flagを使用
したり,-Wl,flagと-Xlinker flagを使用したりし
て,それぞれ,コンパイラとリンカに指定したフラグを渡すことが可能です.
-staticオプションが与えられた場合は,libtoolが
--disable-staticでコンフィグレーションされていた場合でも,
.oファイルが構築されてます.
-oオプションが,現在は完全にサポートされていることに注意してくだ
さい.それは,(オブジェクトのロックと移動によって)それがサポートされてい
ないプラットフォームでエミュレートされているので,Makefileを少し編集する
だけでlibtoolの使用は本当に簡単です.入力例です.
libtool gcc -c foo/x.c -o foo/x.loこれは期待したことを行います.
しかし,コンパイラが-cと-oをサポートしていない場合,既存の
./x.oを上書きせずにfoo/x.cをコンパイルすることが不可能なこ
とに注意してください.そのため,ソースファイル./x.cがある場合,
./x.o(や./x.lo)が,サブディレクトリのあらゆるx.loの
後で再作成されることを確実にするため,Makefileに依存性の導入を必
ず行ってください.
x.o x.lo: foo/x.lo bar/x.loこれは,プログラムやライブラリを作成するため,一時的に壊れた
x.oの
使用を試みないことを確実にします.それは,-cと-oを同時にサ
ポートするプラットフォームで,不必要な再コンパイルを引き起こすかもしれま
せんが,それは,そうでないものに対して安全にする唯一の方法です.
リンクモードは,(ライブラリオブジェクトを含む)オブジェクトファイル と,その他のライブラリや作成された実行可能なプログラムをリンクします.
mode-argsは,いくつかのオブジェクトファイルから(-oフラグを
用いた)出力ファイルを作成するためにCコンパイラが使用するコマンドから成り
立ちます.
以下のmode-argsの組は特別に扱われます.
-all-static
-avoid-version
-dlopen file
-staticや
-all-staticでリンクされている場合,-dlpreopen fileと
同じです.それ以外では効果はありません.fileがselfの場合,
-export-dynamicを可能にする,または,-dlpreopen selfに後退
することにより,libtoolはプログラムがそれ自身をdlopen可能であるこ
とを確かめます.
-dlpreopen file
selfの場合,プログラムのシンボル自身がlt_preloaded_symbols
に加えられます.fileがforceの場合,libtoolは,
lt_preloaded_symbolsが空であろうがなかろうが,常に定義済で
あることを確実にします.
-export-dynamic
dlsymで解決されることを許可しま
す(see Dlopened modules).
-export-symbols symfile
.symで終わるべきで,一行毎に一
シンボル名を含める必要があります.このオプションは効果がないプラットフォー
ムがあります.デフォルトですべてのシンボルがエクスポートされます.
-export-symbols-regex regex
-export-symbolsと同じです.デフォルトですべてのシンボルがエクスポー
トされます.
-Llibdir
-lname
libname
を要求します.このオプションはoutput-fileが実行形式でないときも要
求されます.
-module
-no-fast-install
-no-install
-no-undefined
-o output-file
-release release
-version-infoフラグを使用してく
ださい(see Versioning).
-rpath libdir
-R libdir
-static
-version-info current[:revision[:age]]
-releaseを参照してください.
-Wl,flag
-Xlinker flag
output-fileが.laで終わる場合,libtoolライブラリが作成され,
それはライブラリオブジェクト(.loファイル)からのみ作成される必要が
あります.-rpathオプションは要求されません.現在の実装では,
libtoolライブラリが他のインストールされていないlibtoolライブラリに依存す
ることはできません(see Inter-library dependencies).
output-fileが.aで終わる場合,標準的なライブラリはar
と,おそらくranlibを使用して作成されます.
output-fileが.oや.loで終わる場合,リロード可能なオブ
ジェクトファイルは,(通常ld -rを用いて)入力ファイルから作成されま
す.この手法は部分的なリンクと呼ばれることが多いです.
それ以外の場合,実行可能なプログラムが作成されます.
実行モードに対し,ライブラリパスは自動的に設定され,プログラムは
実行されます.
mode-argsの最初は,プログラム名として扱われ,残りはプログラムの引 数となります.
以下のmode-argsの組は特別に扱われます.
-dlopen file
このモードは,あらゆる-dlopenフラグによって,ライブラリパス環境変
数を設定します.
すべてのargsがlibtoolの実行形式のラッパーの場合,それらは対応する インストールされていないバイナリの名前に変換され,それらが要求するすべて のライブラリディレクトリがライブラリパスに加えられます.
インストールモードでは,libtoolはmode-argsを,cpで始
まるインストールコマンドやBSD互換のinstallプログラムとして解釈し
ます.
mode-argsの残りは,そのコマンドの引数として解釈されます.
コマンドが実行され,特権の不要な必要なインストール後のコマンドも完全に実 行されます.
フィニッシュモードは,ユーザプログラムにlibtoolライブラリを配置し, リンクできるよう,システム管理者のインストールを助けます.
それぞれのmode-argはライブラリのディレクトリの名前として解釈されま
す.このコマンドの実行は,--dry-runオプションが役に立つように,スー
パーユーザの特権を要求するかもしれません.
アンインストールモードはインストールされているライブラリ,実行形式, そしてオブジェクトを削除します.
mode-argの最初はファイルの削除に使用するプログラム名(通常は
/bin/rm)です.
残りのmode-argsは,(`-'で始まる)削除プログラムに対するフラグ,また は削除するファイル名です.
クリーンモードはアンインストールされたライブラリ,実行形式,オブジェ クト,そして,それらに関連があるlibtoolの一時ファイルを削除します.
最初のmode-argは,ファイルを削除するために使用するプログラムの名前
(通常は/bin/rm)です.
残りのmode-argsは削除プログラムに対する(`-'で始まる)フラグ,または 削除するファイル名です.
この章は,ユーザが混乱せずに共有ライブラリをインストールできるように,パッ ケージとlibtoolの統合方法を記述します.
Makefile rules for libtool.
Makefile規則を書くlibtoolは,完全にAutomake(see Top)と統合されていて,それはAutomake version 1.2から開始し ました.
通常のMakefile(やMakefile.in)で,libtoolを使用したい場合,
独自のものとなります.Automake 1.2を使用せず,パッケージにlibtoolの組み
込み方を知らない場合,以下の一つが必要です.
Makefile規則の手での書き方を学んでください.複雑なときもあります
が,古いライブラリをコンパイルするための規則を書けるぐらいの知識がある場
合,libtoolライブラリに対する新しい規則の理解は可能でしょう(ヒント:
libtool 配布物のdemoサブディレクトリのMakefile.inを調べて
ください... 特に,それがAutomakeによってMakefile.amから自動的
に生成されたことに注意してください).
libtoolライブラリのサポートは,LTLIBRARIESプライマリの下で実装さ
れました.
ここに,libtool配布物のdemoサブディレクトリの,Automake
Makefile.amからの例がいくつかあります.
最初に,プログラムをlibtoolライブラリとリンクするため,
program_LDADD変数のみを使用してください.
bin_PROGRAMS = hell hell.debug # Build hell from main.c and libhello.la hell_SOURCES = main.c hell_LDADD = libhello.la # Create an easier-to-debug version of hell. hell_debug_SOURCES = main.c hell_debug_LDADD = libhello.la hell_debug_LDFLAGS = -static
フラグ-dlopenと-dlpreopen(see Link mode)は,
program_LDADD変数で,より適切になります.残念ながら,リリース1.4ま
でのGNU automakeは,program_LDADD変数でこれらのフラグを受け入れな
いため,以下で代用します.
program_LDADD = "-dlopen" libfoo.la program_DEPENDENCIES = libfoo.la
configure.inのAC_SUBSTで,変数DLOPENと
DLPREOPENを設定し,program_LDADDでの明確なフラグ
-dlopenと-dlpreopenに対する置換物として,@DLOPEN@
と@DLPREOPEN@を使用します.Automakeは,依存性から
AC_SUBSTされた変数を捨てるので,program_LDADDのこれらのフ
ラグを受け入れたとき,それは正確に期待したように動作します.
(インストールされていない共有libtoolライブラリとのリンクを避けるため
-staticを使用するような)programをリンクしている間,libtool
に渡したいあらゆるフラグを詰め込むため,program_LDFLAGS変数を使用
することも可能です.
libtoolライブラリを構築することは,ほとんど冒険です...
-version-info(see Versioning)オプションをlibtoolに渡すため,
libhello_la_LDFLAGSを使用することに注意してください.
# Build a libtool library, libhello.la for installation in libdir. lib_LTLIBRARIES = libhello.la libhello_la_SOURCES = hello.c foo.c libhello_la_LDFLAGS = -version-info 3:12:1
-rpathオプションは,(noinst_LTLIBRARIESとしてリストアップ
されるライブラリ以外)Automakeにより自動的に渡されるので,指定する必要は
ありません.
詳細は,See A Shared Library.
libtoolは,共有ライブラリを作成し適切なものにリンクするため,コンパイラセット とオペレーティングシステムの詳細な知識を必要とします.libtool配布物をイ ンストールするとき,システム特有のlibtoolスクリプトはバイナリディレクト リにインストールされます.
しかし,独自のパッケージとともにlibtoolを配布するとき (see Distributing),パッケージをコンパイルするために使用されるコンパ イラセットとオペレーティングシステムを,常に知っているわけではありません.
このため,libtoolを使用する前にコンフィグレーションする必要があり
ます.この考えは,GNU configureスクリプトを使用するものに似ていま
す.configureは,システムの特徴に対しいくつものテストを行い,
Makefiles(と,おそらくconfig.hヘッダファイル)を生成し,そ
の後,makeを実行しパケージを構築することができます.
libtoolは,インストーラのホストマシンに対するlibtoolスクリプトを生成する
ために,独自のテストをconfigureスクリプトに加えます.
libtool in configure.in.
AC_PROG_LIBTOOLマクロGNU Autoconf(やAutomake)を使用している場合,AC_PROG_LIBTOOLの呼び
出しをconfigure.inに加える必要があります.このマクロは,
生成されたlibtoolスクリプトがホストの特徴を理解できるようにするため,
多くの新しいテストをconfigureスクリプトに加えます.
| AC_PROG_LIBTOOL | Macro |
| AM_PROG_LIBTOOL | Macro |
--enable-sharedと--disable-sharedのconfigureフラグ
に対するサポートを加えます.4 AM_PROG_LIBTOOLは,このマクロに対する古い名前で,しばらくは
サポートされますが,やめた方がいいです.
デフォルトで,このマクロは,利用可能な場合は共有ライブラリを開始し,共有
ライブラリと衝突しない場合はスタティックライブラリも可能とします.これら
のデフォルトは, # Turn off shared libraries during beta-testing, since they # make the build process take too long. AC_DISABLE_SHARED AC_PROG_LIBTOOL ユーザは,パッケージ名を元に構築される,共有またはスタティックライブラリ
を選択するため, trick$ ./configure --enable-shared=bfd,gdb 一般的に, パッケージ名 このマクロは,シェル変数LIBTOOL_DEPSも設定し,それで,libtoolスク
リプトが時代遅れになった場合の自動的な更新に使用できるようになります.そ
うするために AC_PROG_LIBTOOL AC_SUBST(LIBTOOL_DEPS) そして, LIBTOOL_DEPS = @LIBTOOL_DEPS@
libtool: $(LIBTOOL_DEPS)
$(SHELL) ./config.status --recheck
GNU automakeを使用してる場合,automakeが面倒をみるので,指示の省略が可能
です. |
| AC_LIBTOOL_DLOPEN | Macro |
dlopenサポートの調査を可能にします.パッケージで-dlopenと
-dlpreopenフラグを使用する場合,このマクロ使用すべきで,そうしな
い場合,libtoolはシステムがdlopenをサポートしていないと仮定します.マク
ロはAC_PROG_LIBTOOLの前で呼び出す必要があります.
|
| AC_LIBTOOL_WIN32_DLL | Macro |
このマクロは,win32プラットフォームでクリーンなdllを構築するために移植す
る場合,使用する必要があります.通常,これは,あらゆるライブラリデータ項
目を__declspec(dllexport)でエクスポートし,
__declspec(dllimport)でインポートすることを意味します.このマクロ
が使用されていない場合,libtoolはパッケージライブラリがクリーンなdllでは
なく,win32ホストでのスタティックライブラリのみを構築すると仮定します.
このマクロは |
| AC_DISABLE_FAST_INSTALL | Macro |
AC_PROG_LIBTOOLのデフォルトの動作を,高速インストールに対する最適
化を不可能にするよう変更します.ユーザはこのデフォルトを,プラットフォー
ムのサポートに依存して,--enable-fast-installを指定することで優先
させることができます.
|
| AC_DISABLE_SHARED | Macro |
| AM_DISABLE_SHARED | Macro |
AC_PROG_LIBTOOLのデフォルトの動作を,共有ライブラリを利用不可能に
変更します.ユーザはこのデフォルトを,--enable-sharedを指定するこ
とで優先させることができます.
|
| AC_DISABLE_STATIC | Macro |
| AM_DISABLE_STATIC | Macro |
AC_PROG_LIBTOOLのデフォルトの動作を,スタティックライブラリを利用
不可能に変更します.ユーザはこのデフォルトを,--enable-staticを指
定することで優先させることができます.
|
AC_PROG_LIBTOOL内のテストは,以下の環境変数も認識します.
| CC | Variable |
生成されたlibtoolが使用するCコンパイラ.これが設定されていない場
合,AC_PROG_LIBTOOLはgccやccを探します.
|
| CFLAGS | Variable |
標準的なオブジェクトファイルを生成するために使用するコンパイラフラグ.こ
れが設定されていない場合,AC_PROG_LIBTOOLはそのようなフラグを全く
使用しません.それは,AC_PROG_LIBTOOLがテストを実行する方法にのみ
効果があり,生成されたlibtoolには効果はありません.
|
| CPPFLAGS | Variable |
Cプリプロセッサフラグ.これが設定されていない場合,
AC_PROG_LIBTOOLはそのようなフラグを全く使用しません.それは,
AC_PROG_LIBTOOLがテストを実行する方法にのみ効果があり,生成された
libtoolには効果はありません.
|
| LD | Variable |
(生成されたlibtoolが要求する場合は)システムリンカ.これが設定され
ていない場合,AC_PROG_LIBTOOLは,CCで使用されるリンカが何か
を判別しようとします.
|
| LDFLAGS | Variable |
プログラムをリンクするときAC_PROG_LIBTOOL5が使用する
フラグ.これが設定されていない場合,AC_PROG_LIBTOOLはそのようなフ
ラグを全く使用しません.それは,AC_PROG_LIBTOOLがテストを実行する
方法にのみ効果があり,生成されたlibtoolには効果はありません.
|
| LIBS | Variable |
プログラムのリンク時にAC_PROG_LIBTOOLが使用するライブラリです.こ
れが設定されていない場合,AC_PROG_LIBTOOLはそのようなフラグを使用
しません.それはltconfigの実行テストにのみに効果があり,生成され
たlibtoolには効果はありません.
|
| NM | Variable |
使用するプログラムで,nmの調査ではありません.
|
| RANLIB | Variable |
使用するプログラムで,ranlibの調査ではありません.
|
| LN_S | Variable |
プログラムのリンクを作成するコマンドで,可能な場合はソフトリンク,それ以
外ではハードリンクです.この変数が設定されていない場合,
AC_PROG_LIBTOOLは適切なプログラムを調査します.
|
| DLLTOOL | Variable |
使用するプログラムで,dlltoolの調査ではありません.
Cygwin/MS-Windowsでのみ意味があります.
|
| OBJDUMP | Variable |
使用するプログラムで,objdumpの調査ではありません.
Cygwin/MS-Windowsでのみ意味があります.
|
| AS | Variable |
使用するプログラムで,asの調査ではありません.しばらくは,
Cygwin/MS-Windows でのみ使用されます.
|
libtoolizeプログラムを呼び出すとき(see Invoking libtoolize),
それはAC_PROG_LIBTOOLの定義が見つかる場所を伝えます.Automakeを使
用している場合,aclocalプログラムは自動的に,configureスク
リプトにAC_PROG_LIBTOOLサポートをconfigureスクリプトに加え
ます.
それにもかかわらず,acinclude.m4にlibtool.m4のコピーを含め
ることは賢明で,そのため,aclocal.m4とconfigureがとある理
由で再構築された場合も,適切なlibtoolマクロが使用されます.代わりに,ユー
ザがlibtool.m4の互換バージョンをインストールしていて,
aclocalにアクセス可能なことを期待します.これは,バージョンが一致
しない場合,不運なエラーを導くかもしれません.
libtoolを使用するため,パッケージに以下のファイルを含める必要があります.
config.guess
config.sub
ltmain.sh
libtoolスクリプト自身はパッケージに含まないことに注意してください. See Configuring.
手動でこれらのファイルをパッケージにコピーするより,libtoolizeプ
ログラムを使用した方がよいでしょう.
libtoolize command line options.
libtoolizeの呼び出しlibtoolizeプログラムは,libtoolサポートをパッケージに追加する標準
的な方法を提供します.将来は,より良い調査の使用法や,より簡単にlibtool
を作成する特徴を実装するかもしれません.
libtoolizeプログラムは以下の構文です.
libtoolize [option]...
そして,以下のオプションを受け入れます.
--automake
libtoolize --automakeは,AC_PROG_LIBTOOLが
configure.inにあるとき,Automakeがlibtoolファイルをパッケージに追
加するために使用します.
--copy
-c
--debug
less(やmore)にパイプしたり,ファイルにリダ
イレクトしたいかもしれません.
--dry-run
-n
--force
-f
libtoolizeは既存
のファイルを上書きしません.
--help
--ltdl
--ltdl-tar
--version
libtoolizeのバージョン情報を出力し終了します.
libtoolizeが,パッケージのconfigure.inで,明確な
AC_CONFIG_AUX_DIRの呼び出しを検出した場合(see Input),指定されたディレクトリ
にファイルを配置します.
libtoolizeは,パッケージにlibtoolサポートを加えるヒントも同様に表
示します.
.oマクロAutoconfパッケージは,テストを実行するいくつかのマクロをもたらし,それは, オブジェクトファイル名に対応して変数を設定します.libtoolオブジェクトに 対応する名前を使用する必要があるときもあります.
ここにlibtoolオブジェクトがリストアップする変数名があります.
| LTALLOCA | Variable |
AC_FUNC_ALLOCAで置換されます(see Particular Functions).空,またはalloca.loを含みます.
|
| LTLIBOBJS | Variable |
AC_REPLACE_FUNCSとその他の関数で置換されます(see Generic Functions).
|
残念ながら,安定版のリリースのAutoconf(これを書いている時期は,2.13)は,
libtoolでこれらの変数を提供する方法が全くありません.そのため,それに依
存して,パッケージのconfigure.inでAC_OUTPUTを呼び出す前に,
以下のコードの実装を使用してください.
LTLIBOBJS=`echo "$LIBOBJS" | sed 's/\.[^.]* /.lo /g;s/\.[^.]*$/.lo/'` AC_SUBST(LTLIBOBJS) LTALLOCA=`echo "$ALLOCA" | sed 's/\.[^.]* /.lo /g;s/\.[^.]*$/.lo/'` AC_SUBST(LTALLOCA) AC_OUTPUT(...)
パッケージを開発しているとき,パッケージを--disable-sharedフラグ
でコンフィグレーションしたり,AC_DISABLE_SHARED Autoconfマクロ
(see The AC_PROG_LIBTOOL macro)を使用して,
AC_PROG_LIBTOOLのデフォルトに優先することに価値があることもよくあ
ります.これは,libtoolが共有ライブラリを構築することを避け,それには,
いくつかの利点があります.
パッケージのREADMEに,他の開発者に--disable-sharedで時間を
稼げることを知らせるため,ちょっとした注意を書きたいかもしれません.以下
の例の注意は,GIMP6
配布物のREADMEから持ってきました.
The GIMP uses GNU Libtool in order to build shared libraries on a variety of systems. While this is very nice for making usable binaries, it can be a pain when trying to debug a program. For that reason, compilation of shared libraries can be turned off by specifying the--disable-sharedoption toconfigure.
共有ライブラリで導入された発行物で,最も難しいものは,実行時の依存の作成
と解決です.プログラムとライブラリの依存は,sedのような単一の名前
の用語で,よく記述されます.そのため"libtoolはsedに依存する"と告げ,そ
れで十分目的を果たせます.
しかし,規則的にインターフェースが変更されるとき,我々はより具体的に告げ る必要があります."Gnus 5.1はEmacs 19.28以上を要求する."ここでは,名 前からなるインターフェースの記述と"バージョンナンバー"です.
種類の説明はいくつかの目的において十分でないことすらあります.Emacs 20で 変更された場合,Gnus 5.1を破壊するのに十分ではないでしょうか?
同じ問題は,共有ライブラリでも存在します.我々は,プログラムが必要として いるインターフェースを提供するライブラリのみとリンクされることを,ダイナ ミックリンカが保証できるように,プログラムが依存する共有ライブラリを記述 するために,通常のバージョン管理システムが必要です.
ライブラリのインターフェースは,以下の何か(またはそれ以上)でしょう.
静的な関数は,ライブラリのユーザが直接利用不可能なので,インターフェース に数えられないことに注意してください.
libtoolは独自の形式的なバージョン管理システムがあります.それは,あまり 柔軟ではありませんが,強力なバージョン管理システムで,確かに最も単純です.
ライブラリとは,整数で任意に表示できるインターフェースのいくつかの組を エクスポートするものだと考えて下さい.プログラムがライブラリとリンクされ るとき,これらのインターフェースのサブセットを利用するかもしれません.
プログラムが使用するインターフェースのlibtoolの記述は単純です.それは, 結果のバイナリにある最大と最小のインターフェースの番号を符号化します (first-interface, last-interface).
ダイナミックリンカは,ライブラリがfirst-interfaceと last-interfaceの間のすべてのインターフェースの番号をサポー トする場合,プログラムがライブラリとリンク可能なことを保証します.
libtoolの移植性の要求が,実際に必要と言うよりは厳密なので,問題を生じる 可能性があることに注意してください.
さて,libhelloがインターフェースの5,16,17,18,と19をサポートし,
libtoolはlibhelloをtestにリンクするとき使用されると仮定し
ます.
libtoolはtestに数字5と19を符号化し,ダイナミックリンカは,5と19の
間のすべてのインターフェースをサポートしているライブラリのみと,
testをリンクします.そのため,ダイナミックリンカはlibhello
とtestをリンクすることを拒否します!
この問題を排除するために,libtoolはライブラリは,連続したインターフェー
ス番号を宣言することのみ可能としています.そのため,libhelloは,
16 から19までのインターフェースをサポートすることを宣言するのが精一杯で
す.そして,ダイナミックリンカは,libhelloをtestとリンクし
ます.
そのため,libtoolライブラリバージョンは,3つの整数で宣言されます.
current - ageから
currentまでの番号の範囲で,すべてのインターフェース番号を実
装しています.
2つのライブラリが,個別のcurrentとageを持つ場合,ダイナミッ クリンカは,より大きいrevision番号を選択します.
libtoolのバージョン管理システムを使用したい場合,リンクモード
(see Link mode)の時に,-version-infoフラグを使用して,libtool
にバージョン情報を指定する必要があります.
このフラグは,current[:revision[:age]]の形式の
引数を受け入れます.そして,-version-info 3:12:1を渡すと,
currentを3,revisionを12,そしてageを1に設定します.
revisionやageが省略された場合,デフォルトは0になります.また, ageはcurrentインターフェース番号以下にする必要があることに注 意してください.
ここに,ライブラリバージョン情報を更新する助けとなる規則の集合があります.
0:0:0で始めて
ください.
c:r:aは
c:r+1:aとなります).
パッケージのリリース番号に対応するように,インターフェース番号を設定する
試みは決してしないでください.これは,ライブラリバージョ
ンの目的の誤解を促進する悪習にすぎません.その代わり,-release
フラグ(see Release numbers)を使用しますが,パッケージが他のリリース
とバイナリ互換でないことを警告されます.
プログラムをライブラリにリンクしたいユーザに明確になるように,パッケージ リリース名を共有ライブラリに符号化したいこともよくあります.この便利さは, 特にGNU/Linuxで使用されます.
trick$ ls /usr/lib/libbfd* /usr/lib/libbfd.a /usr/lib/libbfd.so.2.7.0.2 /usr/lib/libbfd.so trick$
trickとして,/usr/lib/libbfd.soはlibbfd.so.2.7.0.2
へのシンボリックリンクで,それはbinutils-2.7.0.2の一部として配布
されています.
ライブラリインターフェースは,リリース番号のように,滅多に同時に変更され す,ライブラリ接尾子はすべてのプラットフォームを跨り,すべて同じではない ので,残念ながらこの便利さはlibtoolのライブラリバージョンの情報の考えと 直接衝突します.
そのため,両方の見方に適応するため,-version-infoを使用したくない
ライブラリに対し,リリース情報を設定するにあたり,-releaseフラグ
を使用することができます.libbfdの例では,libtoolが使用する次のリ
リースは,-release 2.9.0で構築されるべきで,それは,GNU/Linuxで,
以下のファイルを生成します.
trick$ ls /usr/lib/libbfd* /usr/lib/libbfd-2.9.0.so /usr/lib/libbfd.a /usr/lib/libbfd.so trick$
この場合,/usr/lib/libbfd.soはlibbfd-2.9.0.soへのシンボリッ
クリンクです.これはbinutils-2.9.0を扱っているユーザにとって,バー
ジョン情報のlibtoolの考えに妥協することなく,明白になります.
このオプションはライブラリ名を編集することに注意し,過去のライブラリリリー
スとのバイナリ互換を壊したくない場合は使用しないでください.一般的に,パッ
ケージの内部ライブラリや,大変頻繁に変更されるインターフェースを持つ物に
対してのみ-releaseを使用してください.
良いライブラリインターフェースと書くことは,多くの経験とライブラリが解決 する問題への完全な理解が必要です.
良いインターフェースを設計した場合,頻繁に変更する必要がなく,ドキュメン トを更新し続ける必要がなく,ユーザはライブラリの使用方法を何度も学習する 必要がありません.
ここにライブラリインターフェースの設計に関するヒントの短いリストがあり, それは仕事上で役立つでしょう.
これは,本質的にオブジェクト指向のシステムで抽象的なデータ型と継承を使用
するのと同じです.
staticキーワード(または等価物)の使用
移植性の高いCヘッダファイルを書くことは難しく,それは異なる形式のコンパ イラで読まれる可能性があるためです.
extern "C"ディレクティブで宣言する必要があります.libtoolでC++の
使用に関連したその他の問題は,See C++ libraries.
#includeしたときの不必要な警告を避ける
ため,行う方が良いでしょう.
これらの複雑さは,上記それぞれのコンパイラを利用可能にするため,ライブラ リインファーフェースヘッダで,いくつかのCプリプロセッサの魔法を使用する 必要があることを意味します.
libtool配布物のdemoサブディレクトリのfoo.hは,安全にシステ
ムディレクトリにインストール可能な,ヘッダファイルの書き方の例を提供しま
す.
ここに,そのファイルの関連する部分があります.
/* BEGIN_C_DECLS should be used at the beginning of your declarations,
so that C++ compilers don't mangle their names. Use END_C_DECLS at
the end of C declarations. */
#undef BEGIN_C_DECLS
#undef END_C_DECLS
#ifdef __cplusplus
# define BEGIN_C_DECLS extern "C" {
# define END_C_DECLS }
#else
# define BEGIN_C_DECLS /* empty */
# define END_C_DECLS /* empty */
#endif
/* PARAMS is a macro used to wrap function prototypes, so that
compilers that don't understand ANSI C prototypes still work,
and ANSI C compilers can issue warnings about type mismatches. */
#undef PARAMS
#if defined (__STDC__) || defined (_AIX) \
|| (defined (__mips) && defined (_SYSTYPE_SVR4)) \
|| defined(WIN32) || defined(__cplusplus)
# define PARAMS(protos) protos
#else
# define PARAMS(protos) ()
#endif
これらのマクロは,以下のようにfoo.hで使用されます.
#ifndef FOO_H #define FOO_H 1 /* The above macro definitions. */ #include "..." BEGIN_C_DECLS int foo PARAMS((void)); int hello PARAMS((void)); END_C_DECLS #endif /* !FOO_H */
#ifndef FOO_Hが,foo.hの本体を,与えられたコンパイルで一回
以上読み込むことを避けることに注意してください.
また,BEGIN_C_DECLS/END_C_DECLSの組の外側に行くはずのもの
のみ,#include行にあります.厳密にいうと,それは,保護が必要なCの
シンボル名ですが,ヘッダの内容の中心部分のあたりに,これらのマクロの単一
の組がある場合,ヘッダファイルはより管理可能になります.
PARAMS,BEGIN_C_DECLS,そしてEND_C_DECLSのこれらの
定義を独自のヘッダで使用すべきです.そして,C++,ANSI,そして非ANSIのコ
ンパイラ7で有効なヘッダファイルを作成するために,それらを
使用することが可能となります.
移植可能なコードをネイティブに書かないでください,上記のヒントに続けるこ とで,最も明白な問題を無くすことに役立ちますが,明らかに別の微妙な問題が あります.以下の問題に対処する必要があるかもしれません.
void *を常にサポートする
わけではなく,そこではchar *を使用する必要があります.
const,signedそしてsignedキーワードは,サポートされ
ていないコンパイラもあり,特にpre-ANSIコンパイラがあげられます.
long double型は,多くのコンパイラでサポートされていません.
定義では,すべての共有ライブラリシステムは,シンボル解決が実行時まで延期 されるので,実行形式をライブラリに依存させる方法を提供します.
ライブラリ内部の依存性は,他のライブラリに依存するライブラリにあり
ます.例えば,libtoolライブラリlibhelloがcos関数を使用する
場合,それはlibmに対するライブラリ内部の依存性があり,数学ライブ
ラリがcosを実装しています.
共有ライブラリシステムには,内部で一貫した方法で,この機能を提供するもの もあります.これらのシステムは,潜在的に無限長の依存性の連鎖を認めます.
しかし,ほとんどの共有ライブラリのシステムは,単一レベルの依存のみを認め るという制限があります.これらのシステムでは,プログラムは共有ライブラリ に依存しますが,共有ライブラリは他の共有ライブラリに依存しません.
あらゆるイベントで,ライブラリ内部の依存性を宣言するため,libtoolは単純
なメカニズムを提供します.独自のライブラリに依存するすべてのライブラリ
libnameに対しライブラリを作成するとき,対応する
-lnameオプションをリンク行に単純に加えます.libmに依
存するlibhelloの例を構築してみます.
burger$ libtool gcc -g -O -o libhello.la foo.lo hello.lo \
-rpath /usr/local/lib -lm
burger$
プログラムをlibhelloに対しリンクするとき,-lオプションを再
び指定する必要はありません.すべて必要なライブラリが見つかることを保証す
るため,libtoolはそれを行います.この制約は,静的なライブラリシステムと,
単純な動的ライブラリシステムとの互換性を保つために必要です.
AIXのように,この柔軟性さえ許可されないプラットフォームもあります.共有
ライブラリを構築するため,それは完全に自己内蔵型である必要があり(すなわ
ち,.loファイルや-lで指定されたライブラリでシンボルが見つ
かるもののみを参照する),-no-undefinedフラグを指定する必要がありま
す.デフォルトで,libtoolはこの種のプラットフォームではスタティックライ
ブラリのみを構築します.
1.2以前のlibtoolのリリースのコードにおける,単純な考えのライブラリ内部の 依存性の追跡は,ライブラリを他のライブラリとリンク可能なときが明白でない ため不可能で,複雑な異常終了が発生します.この概念のより複雑な実装は,リ リース1.3の前に再導入されましたが,libtoolがサポートするすべてのプラット フォームに移植されませんでした.デフォルトで,保守的な動作は,ライブラリ が他のライブラリとリンクすることを避け,プログラムがリンクされるときのみ に,その内部依存性が導入されます.
ダイナミックリンクの議論では,用語が2つの異なる概念の言及で使用さ れるので,混乱することがあります.
dlopen8のような関数の呼び出しで,
それは,ユーザが指定したモジュールを実行時に任意にロードします.この形式
のダイナミックリンクは,アプリケーションで明示的に制御されます.
混乱を軽減するため,このマニュアルは2番目の形式のダイナミックリンクを dlopenモジュールとして言及します.
dlopenモジュールの主な利点は,プログラムを拡張するために,インタプリタ言 語を使用するのではなく,コンパイルされたオブジェクトコードにアクセスする 能力です.実際,dlopenは,言語を拡張する効果的な方法を提供するため,イン タプリタ言語でよく使用されます.
バージョン1.4の現在は,libtoolはdlopenされるモジュールのサポー
トを提供します.しかし,パッケージがそのようなサポートを行うことを,
configure.inで,マクロAC_LIBTOOL_DLOPENを使用して指示した
方が良いでしょう.このマクロが使用されない(またはAC_PROG_LIBTOOL
の後で使用される)場合,libtoolはdlopenメカニズムが利用不可能と仮
定し,シミュレーションを試みます.
この章ではdlopenでアクセス可能なモジュールを生成するため,dlopenアプリケー ション開発者がlibtoolを使用する方法を議論します.
dlopen.
オペレーティングシステムには,プログラムシンボルをdlsym(またはそ
の透過)関数を用いて動的に解決するために,特定のもので指定する必要がある
ものもあります.
libtoolは,-export-dynamicと-moduleリンクフラグを提供し
(see Link mode),それはこの宣言を行います.他のモジュールやdlopenさ
れているライブラリをdlopenするアプリケーションプログラムをリンクする場合,
これらのフラグを使用する必要があります.
例えば,後でアプリケーションにdlopenされる共有ライブラリlibhello
を構築したい場合,他のリンクオプションに-moduleを加えます.
burger$ libtool gcc -module -o libhello.la foo.lo \
hello.lo -rpath /usr/local/lib -lm
burger$
実行形式からのシンボルが,dlopenしたいライブラリの未解決の参照を
満足させる必要がある場合,フラグ-export-dynamicを使用する必要があ
ります.dlopenを呼び出す実行形式をリンクするとき,-export-dynamic
を使用してください.
burger$ libtool gcc -export-dynamic -o hell-dlopener main.o burger$
libtoolは,dlopenするlibtoolオブジェクトとlibtoolライブラリファイルに対
し,たとえdlopenとdlsym関数が無いプラットフォームで
も,そのシンボルが解決できるように,特別のサポートを提供します.
"laziness"の増加順にプログラムにコードをロードする,以下の別の方法を考 慮します.
libtoolは,コンパイル時にオブジェクトファイルをプログラムにリンクし,プ
ログラムのシンボルテーブルを表現するデータ構造を作成することで,スタティッ
クなプラットフォームで-dlopenオプションをエミュレートします.
この特徴を使用するため,プログラムのリンク時(see Link mode)に
-dlopenや-dlpreopenフラグを使用することで,アプリケーショ
ンでdlopenしたいオブジェクトを宣言する必要があります.
| struct lt_dlsymlist { const char *name; lt_ptr address; } | Structure |
name属性は,"fprintf"のような,シンボル名のNULL終端されてい
る文字列です.address属性は,&fprintfのような対応するオブジェ
クトへの一般的なポインタです.
|
| const lt_dlsymlist * lt_preloaded_symbols | Variable |
lt_symbol構造体の配列で,プログラムにリンクされる,プリロードされ
ているすべてのシンボルを表現します.それぞれの-dlpreloadedファイ
ルに対し,ファイルのnameを用いた要素と,0のaddressが
あり,このファイルからエクスポートされるすべてのシンボルが続きます.実行
形式自身に対し,特別の名前@PROGRAM@が使用されます.最後の要素は,
nameと0のaddressを持ちます.
|
ドル記号のような,ANSI Cでは有効ではない識別子を許可するコンパイラもあり ます.libtoolはANSI Cで有効なシンボル(最初がASCII文字またはアンダースコ アで,0以上のASCII文字,数字,そしてアンダースコアが続くもの)のみ認識す るので,非ASCIIシンボルはlt_preloaded_symbolsに出現しません.
-moduleを用いてライブラリがリンクされた後,dlopen可能になります.
残念ながら ライブラリ名が変更されるため,パッケージでdlopenの正しいファ
イルを決定する必要があります.
最も率直で柔軟な実装は,インストールされた.laファイルを探し,以下
の行を検索することで実行時に決定することです.
# The name that we can dlopen.
dlname='dlname'
dlnameが空の場合,ライブラリはdlopenされません.それ以外では,それ
でライブラリのdlnameを与えます.そのため,ライブラリが
/usr/local/lib/libhello.laにインストールされていて,dlname
がlibhello.so.3の場合,/usr/local/lib/libhello.so.3が
dlopenされます.
プログラムがこのアプローチを行っている場合,ライブラリが最終的にインストー
ルされるディレクトリと同じように,LD_LIBRARY_PATH9環境変数でリストアッ
プされているディレクトリで検索します.この変数(または同等物)を検索するこ
とで,インストール前でも,プログラムがlibtoolを使用してリンクし提供され
ているdlopenモジュールを見つけることを保証します.
以下の問題は,libtoolのdlopenサポートを使用しても解決しません.
dlopenファミリーのラッパー関数を書くことを必要とし,それは,与え
られたプラットフォームでdlopenがサポートされていないまたは利用不可能なと
きの,パッケージ特有のトリックです.
dlopenファミリーの実装には大きな違いがあります.同じ関数名
を用いないプラットフォーム(特にHP-UXではshl_loadファミリーを用い
ます)さえ存在します.
dlopenに渡す正しいモジュール名を発見す
るために,カスタムの検索関数を書く必要があります.
libtoolは,libltdlと呼ばれる小さなライブラリを提供し,それは,
dlopenライブラリの様々な困難をプログラマから隠すことを目指します.それは,
dlopenの機能で必要とされるアプリケーションとともに配布可能な,ヘッダファ
イルと小さなCソースファイルから成り立ちます.libltdlサービスの単
純な実装に対し,あまりに制限が多いダイナミックリンカをもつプラットフォー
ム上では,GNU DLDを要求したり,libtoolのdlpreopenメカニズムを用いてダイ
ナミックリンクをエミュレートするだけのものもあります.
libltdlは,現在以下のダイナミックリンクメカニズムをサポートします.
dlopen (Solaris,Linux,そして様々なBSD)
shl_load (HP-UX)
LoadLibrary (Win16とWin32)
load_add_on (BeOS)
以下の例外で,libltdlはGNUライブラリ公有使用許諾書の条件下でライセンスさ れています.
GNU Lesser General Public Licenseの特別な例外として,GNU libtoolを使用し て構築されるプログラムやライブラリの一部としてこのファイルを配布する場合, プログラムの残りに対して使用する配布条件と同じにして,それを含めることが できます.
dlopened.
libltdl APIは,強力なSolarisとLinuxのdlopenインターフェースに似ていて, それは,非常に簡単ですが強力です.
プログラムでlibltdlを使用するために,ヘッダファイルltdl.hをインク
ルードする必要があります.
#include <ltdl.h>
libltdlの前回のリリースでは,POSIX名前空間の慣習に違反していたシン
ボルを,いくつか使用していました.これらのシンボルは,現在反対され,ここ
で記述されるように置換されました.古い反対されているシンボル名に依存した
コードがある場合,ltdl.hをインクルードする前に
LT_NON_POSIX_NAMESPACEを定義すると,変換されたマクロが提供されま
す.使用するシンボルの組が何であっても,新しいAPIは前回のものとバイナリ
互換ではないので,このバージョンのlibltdlを使用するため,アプリケーショ
ンを再コンパイルする必要があるでしょう.
libltdlがスレッドセーフでない,すなわち,マルチスレッドアプリケーション
は,libtoolに対しミューテックスを使用する必要があることに注意してくださ
い.それは,GNU/Linuxのglibc 2.0のRTLD_LAZYを用いたdlopen
が(デフォルトでlibtoolを使用します),スレッドセーフではないことが報告さ
れていますが,この問題は,glibc 2.1でおそらく修正されるでしょ.一方,
RTLD_NOWは,FreeBSD上のマルチスレッドアプリケーションで問題が生じ
たと報告されています.これらの問題に関する作業は,読者の演習として残って
います.貢献は,きっと歓迎されます.
以下の型はltdl.hで定義されています.
| lt_ptr | Type |
lt_ptrは,汎用ポインタです.
|
| lt_dlhandle | Type |
lt_dlhandleはモジュール"ハンドル"です.すべてのlt_dlopenされるモ
ジュールはそれに関連付けされたハンドルがあります.
|
| lt_dlsymlist | Type |
lt_dlsymlistはdlpreopenされるモジュールのシンボルリストです.この
構造体は,see Dlpreopeningで記述されます.
|
libltdlは以下の関数を提供します.
| int lt_dlinit (void) | Function |
| libltdlを初期化します.この関数は,libltdl使用する前に呼び出す必要があり, 複数回呼び出すことが可能です.成功したら0,それ以外ではエラーの番号を返 します. |
| int lt_dlexit (void) | Function |
libltdlを終了し,すべてのモジュールを閉じます.この関数は,
lt_dlinitが正常に呼び出された回数と同じだけ呼び出されたとき,
libltdlを終了するだけです.成功したら0,それ以外ではエラーの番号を返しま
す.
|
| lt_dlhandle lt_dlopen (const char *filename) | Function |
ファイル名filenameを用いてモジュールを開き,そのハンドルを返します.
lt_dlopenは,libtoolダイナミックモジュール,プリロードされたスタ
ティックモジュール,プログラム自身,そしてネイティブなダイナミックライブ
ラリを開くことが可能です.
モジュール内の未解決のシンボルは,それが依存する(まだ実装されていない)ラ
イブラリと,前もってdlopenされたモジュールを用いて解決されます.このモ
ジュールを使用している実行形式が filenameが libltdlがライブラリを見つけられず,ファイル名filenameがディレクト リコンポーネントを持たない場合,それは,以下の検索パスを(以下の順番で), さらにモジュールを検索します.
それぞれの検索パスは,例えば 同じモジュールが複数回ロードされた場合,同じハンドルが返されます.あらゆ
る原因で |
| lt_dlhandle lt_dlopenext (const char *filename) | Function |
ファイル名に異なるファイル名の拡張子を追加を試みる以外は,
lt_dlopenと同じです.ファイル名filenameを持つファイルが見つ
からない場合,libltdlは,以下の拡張子の追加を試みます.
この探索作戦は,本来のダイナミックライブラリの命名規則を知らないプログラ
ムが,そのようなライブラリを,libtoolモジュールと同様に,透過的に
|
| int lt_dlclose (lt_dlhandle handle) | Function |
| モジュールhandleの参照カウントを減らします.ゼロになったり,このモ ジュールに依存する他のモジュールがない場合,モジュールはアンロードされま す.成功時には0を返します. |
| lt_ptr lt_dlsym (lt_dlhandle handle, const char *name) | Function |
モジュールhandle内のアドレスを返し,そこでは,ヌルで終端された文字
列nameで与えられるシンボルがロードされています.シンボルが見つから
ない場合はNULLを返します.
|
| const char * lt_dlerror (void) | Function |
libltdlのあらゆる関数から発生した最も新しいエラーを記述する,可読性の高
い文字列を返します.初期化からまたは最後に呼び出されてからエラーが発生し
ていない場合,NULLを返します.
|
| int lt_dlpreload (const lt_dlsymlist *preloaded) | Function |
プリロードされているモジュールpreloadedのリストを登録します.
preloadedがNULLの場合,lt_dlpreload_defaultで設定さ
れているリスト以外の,これまで登録されているすべてのシンボルリストが検出
されます.成功時には0を返します.
|
| int lt_dlpreload_default (const lt_dlsymlist *preloaded) | Function |
プリロードされているモジュールリストのデフォルトをpreloadedに設定
し,それはlt_dlpreloadで検出されません.この関数は,
lt_dlinitを使用して初期化されるためにlibltdlを要求しないこ
とと,デフォルトでプリロードされるモジュールを登録するためにプログラムで
使用できることに注意してください.この関数を直接呼び出す代わりに,ほとん
どのプログラムはマクロLTDL_SET_PRELOADED_SYMBOLSを使用します.
成功時には0を返します. |
| LTDL_SET_PRELOADED_SYMBOLS() | Macro |
プリロードされるシンボルのデフォルトリストを設定します.プリロードされる
libltdlのモジュールを初期化するために,プログラムで使用した方が良いでしょ
う.
#include <ltdl.h>
int main() {
/* ... */
LTDL_SET_PRELOADED_SYMBOLS();
/* ... */
}
|
| int lt_dladdsearchdir (const char *search_dir) | Function |
| 検索ディレクトリsearch_dirをユーザー定義のライブラリ検索パスに追加 します.成功時には0を返します. |
| int lt_dlsetsearchpath (const char *search_path) | Function |
| 現在のユーザ定義のライブラリ検索パスをsearch_pathで置換し,それは コロンで分けられた絶対的なディレクトリのリストにする必要があります.成功 時には0を返します. |
| const char * lt_dlgetsearchpath (void) | Function |
| 現在のユーザ定義のライブラリ検索パスを返します. |
| int lt_dlmakeresident (lt_dlhandle handle) | Function |
モジュールをlt_dlcloseできないように印を付けます.モジュールがプ
ロジェクトの中心部の機能を実装している場合,削除されるとコードが壊れるの
で,これは役に立つはずです.成功すると0を返します.
実行しているバイナリに対するhandleを取得するために |
| int lt_dlisresident (lt_dlhandle handle) | Function |
特定のモジュールが常駐しているように印が付いているかどうか調査し,その場
合は1を返し,それ以外では0を返します.この関数の実行中にエラーがある場合,
-1 が返され,lt_dlerrorを用いて回収されるエラーメッセージが設定さ
れます.
|
| lt_ptr (*) (size_t @var{size}) lt_dlmalloc | Variable |
| void (*) (lt_ptr @var{ptr}) lt_dlfree | Variable |
これらの変数は,デフォルトでmallocとfreeに設定されますが,
同等の機能を提供する他の関数に設定可能です.しかし,
lt_dlpreopen_defaultやマクロLTDL_SET_PRELOADED_SYMBOLS以外
のあらゆるlibltdl関数の呼び出し後に,その値を編集すべきではありません.
|
dlopen可能なモジュールの作成libtoolモジュールは,いくつかの例外はありますが,通常のlibtoolライブラリ に似ています.
libtoolの-moduleスイッチを用いて,モジュールとリンクする必要があ
り,そして,dlopenをサポートしていないプラットフォームでlibtoolが
dlpreopenできるよう,-dlopen modulename.laを用いてモジュールを
dlopenするために,あらゆるプログラムとリンクすべきです.モジュールが,あ
らゆる他のライブラリに依存する場合,モジュールとリンクするときや,それを
dlopenするプログラムをリンクするとき,それらを確実に指定してください.特
定のモジュールに対しsee Versioningを使用禁止にしたい場合,
-avoid-versionスイッチを用いてリンクすべきです.libtoolモジュール
は,"lib"接頭辞が不要なことに注意してください.しかし,automake 1.4やそ
れ以降のものは,そのようなモジュールの構築が必要です.
通常,その内部を知る必要なしにプログラムがdlopenできるよう,一組のモジュー
ルは同じインターフェース提供し,すなわち同じシンボルをエクスポートします.
すべてのエクスポートされたシンボルで,シンボルの衝突を避けるため,
"modulename_LTX_"を前置する必要があります(modulenameはモジュール
名です).内部シンボルは,例えば"_modulename_"を前置するといった,他のモ
ジュールと衝突しないような方法で命名する必要があります.一回以上宣言され
た,同じシンボルを持つことをサポートするシステムもありますが,それは通常
移植性がなく,そのようなモジュールをdlpreopenすることを不可能にします.
libltdlは,シンボルの本当の名前を得るとき,自動的に接頭辞を切り取ります.
さらに,非libtoolモジュールもdlopenできるよう,接頭辞を使用していないモ
ジュールをサポートします.
foo1.cは移植可能なlibtoolモジュールの例です.エクスポートされたシ
ンボルは"foo1_LTX_",内部シンボルは"_foo1_"が前置されています.コードの
可読性を高めるため,エイリアスは最初に定義されています.
/* aliases for the exported symbols */
#define foo foo1_LTX_foo
#define bar foo1_LTX_bar
/* a global variable definition */
int bar = 1;
/* a private function */
int _foo1_helper() {
return bar;
}
/* an exported function */
int foo() {
return _foo1_helper();
}
Makefile.amは,モジュールfoo1.laを構築するのに必要な規則を
含みます.
... lib_LTLIBRARIES = foo1.la foo1_la_SOURCES = foo1.c foo1_la_LDFLAGS = -module ...
lt_dlmutex_register()関数を使用し,適切なコールバック関数の定義を
提供することで,libltdlをマルチスレッド環境で使用することが可能です.
| void lt_dlmutex_lock (void) | Type |
|
これは,ミューテックスロックが必要なlibltdlの実装コードの部分の,最初に
呼び出される関数のアドレスを持っている,関数のポインタ型です.
libltdlは本質的に再帰的なので,これらのコールバック関数によって使用され るロックメカニズムがリエントリー可能であることは重要で,そうでなければ, おかしな問題が発生します. |
| void lt_dlmutex_unlock (void) | Type |
| アンロック関数に一致する型です. |
| void lt_dlmutex_seterror (const char *error); | Type |
libltdl APIの関数の多くは,エラーを発生したクライアントを示す,特殊
な戻り値をとります.通常(シングルスレッドアプリケーションでは),内部から
回収することができるエラーを記述する文字列は,lt_dlerror()に保存
されます.
この形式の関数は,それがマルチスレッドのコンテクストで動作するように,ラ イブラリに登録される必要があります.関数は,スレッドローカルストレージに 渡されるあらゆるエラーメッセージを保存すべきです. |
| const char * lt_dlmutex_geterror (void) | Type |
|
スレッドローカルのストレージに,最後にエラーメッセージを保存したものに関
連するコールバック関数に一致する型です.
正しく登録されたとき,この関数は,クライアントに対するエラーメッセージを
回収するために全てのスレッドから |
| int lt_dlmutex_register (lt_dlmutex_lock *lock, lt_dlmutex_unlock *unlock, lt_dlmutex_set_error *seterror, lt_dlmutex_geterror *geterror) | Function |
libltdlのマルチスレッドの準備で,上記のそれぞれの関数の型を登録するため
に,この関数を使用してください.全ての引数は,有効なNULLでない関
数アドレスにする必要があり,また,そうでない場合は,シングルスレッドオペ
レーションへの戻り値として,全てNULLにする必要があります.
|
libltdlが管理している,それぞれのロードされたモジュールに関する内部情報 には,ユーザが利用可能なものもあり,それはこの構造体の形式です.
| struct lt_dlinfo { char *filename; char *name; int ref_count; } | Type |
lt_dlinfoは,モジュールの情報を保存するために使用されます.
filename属性は,NULLで終端された,実際のモジュールファイル
名の文字列です.モジュールがlibtoolモジュールの場合,nameはそのモ
ジュール名(例えば,"dir/libfoo.la"に対する"libfoo")で,そ
れ以外ではNULLに設定されます.ref_count属性は,現在ロードさ
れている同じモジュールの回数を記述する参照カウンタです.
|
以下の関数は,与えられたhandleに対するこの構造体のlibltdlの内部の コピーへのポインタを返します.
| const lt_dlinfo * lt_dlgetinfo (lt_dlhandle handle) | Function |
モジュールhandleに関するいくつかの情報を含む構造体の,ポインタを返
します.構造体の内容は編集してはなりません.失敗時にはNULLが返り
ます.
|
さらに,ロードした全てのモジュールのハンドルリストを保つ手助けをするため に,これらの関数で,ロードされているモジュールのlibltdlのリスト全体を繰 り返すことが可能となります.
| int lt_dlforeach (int (*func) (lt_dlhandle handle, lt_ptr data), lt_ptr data) | Function |
ロードされているそれぞれのモジュールに対し関数funcを呼び出します.
引数のhandleは,ロードされているモジュールのハンドルの一つで,
dataは,lt_dlforeachに渡すdata引数です.funcが
ハンドルの一つに対し,ゼロでない値を返すとすぐに,lt_dlforeachは
funcの呼び出しを停止し,直ちに1を返します.それ以外は0が返ります.
|
| lt_dlhandle lt_dlhandle_next (lt_dlhandle place) | Function |
placeがNULLの場合は,リスト内の最初のハンドルを返し,そして
順番に次ものを呼び出すことで,ロードされているモジュール全体を繰り返しま
す.placeが,ロードされているモジュールリスト内の最後の要素の場合,
この関数はNULLを返します.
|
もちろん,アプリケーションの効果に対し,それぞれのハンドルに関連付けする 必要がある他のデータがある場合,libltdlで管理されるリストと平行して,ロー ドされたモジュールハンドルの、独自のリストの管理が必要でしょう。しかし, アプリケーションデータに,個別のモジュールハンドルを,ロードされたものと して関連付けさせるために,以下のAPIの呼び出しを使用する場合,実際に はそうする必要はありません。最初に,前もって保存したデータを回収するため に後で利用する,libltdlからのユニークな呼び出しidを取得する必要がありま す。これで,ロードされているモジュールに対する独自のデータを,個別に保存 したい異なるライブラリが,もう一つの(ライブラリ)のデータへのインターフェー スなしでそれを行うことが可能となります。
| lt_dlcaller_id | Type |
| 個別のデータセットのキーを保つ,透過でない型です. |
| lt_dlcaller_id lt_dlcaller_register (void) | Function |
| モジュールデータ毎に個別のセットを,保存し回収するためのユニークなキーを 取得するために,これを使用してください. |
| lt_ptr lt_dlcaller_set_data (lt_dlcaller_id key, lt_dlhandle handle, lt_ptr data) | Function |
後で回収するために,keyとhandleにユニークに関連付けされたデー
タのセットとして,dataを設定します.この関数は,以前に関連付けされ
たkeyとhandleがある場合は,そのdataを返します.0の結果
は,前回のエラー(が存在する場合)は,診断結果がlt_dlerror()で利用
可能であることを示している可能性があります.
例えば,いくつかの関連データを正しく削除するために,以下のようにします. lt_ptr stale = lt_dlcaller_set_data (key, handle, 0);
if (stale == NULL)
{
char *error_msg = lt_dlerror ();
if (error_msg != NULL)
{
my_error_handler (error_msg);
return STATUS_FAILED;
}
}
else
{
free (stale);
}
|
| lt_ptr lt_dlcaller_get_data (lt_dlcaller_id key, lt_dlhandle handle) | Function |
keyとhandleに関連付けされているdataのアドレス,または,
無い場合はNULLを返します.
|
ここまでの関数は,アプリケーションにロードされたりアンロードされたりした
モジュールを追跡させる必要なしで,オペレーションの検索と適用を実装するた
めに,lt_dlforeachと組み合わせることが可能です.
int
my_dlcaller_callback (lt_dlhandle handle, lt_ptr key_ptr)
{
struct my_module_data *my_data;
my_data = lt_dlcaller_get_data (handle, (lt_dlcaller_id) *key_ptr);
return process (my_data);
}
int
my_dlcaller_foreach (lt_dlcaller_id key)
{
lt_dlforeach (my_dlcaller_callback, (lt_ptr) &key);
}
モジュールにアクセスするためのlibltdlの多くの方法は,プロジェクトの目的
に十分でないときもあります.独自のローダを書き,lt_dlopenが利用で
きるように,libltdlでそれを登録することが可能です.
ローダを書くことは,lt_dlopen,lt_dlsymそして
lt_dlcloseで呼び出し可能な,少なくとも3つの関数を書くことを必要と
します.オプションで,lt_dlexitが実行されるときクリーンアップ処理
を実行する終了関数と,lt_dlsymに渡されるあらゆるシンボルに前置さ
れるシンボルの前置文字を提供することも可能です.これらの関数は,以下の関
数のポインタ型に一致する必要があり,その後,それらを
lt_user_dlloaderの代わりに関連付けし,登録することが可能です.
ローダの登録には,lt_dlloader_findが認識でき,
lt_dlloader_removeで削除できるように,それに対する名前を選択する
ことが必要です.選択した名前はユニークである必要があり,libltdlの組み込
みローダで既に使用しているものはいけません.
libdldがインストールされている場合は,
GNU dldローダ.
lt_dlopenのための
ローダ.
前置される"dl"は,libltdlの将来のバージョンで提供されるローダとして予約 されているので,独自のローダ名に使用すべきではありません.
以下の型は,ltdl.hで定義されています.
| lt_module | Type |
lt_moduleはモジュール依存のdlloaderです.ダイナミックモジュールロー
ダの拡張は,これらの低レベルの型を使用して通信します.
|
| lt_dlloader | Type |
lt_dlloaderはモジュールローダの型に対するハンドルです.
|
| lt_dlloader_data | Type |
lt_dlloader_dataはローダのインスタンスデータに対して使用されます.
|
| struct lt_user_dlloader {const char *sym_prefix; lt_module_open *module_open;lt_module_close *module_close; lt_find_sym *find_sym; lt_dlloader_exit *dlloader_exit; lt_dlloader_data dlloader_data; } | Type |
ダイナミックモジュールを開くために新しい方法を定義したくて,それを使用し
たlt_dlopen APIがある場合,これらの構造体のインスタンスを作
成し,それをlt_dlloader_addに渡す必要があります.好みの
dlloader_dataフィールドで渡すことが可能で,それは,関数ポインタフィー
ルドで指定されている,それぞれの関数への最初のパラメータの値として戻りま
す.
|
| lt_module lt_module_open (lt_user_data loader_data, const char *filename) | Type |
lt_dlloaderモジュールローダに対するローダ関数の型です.
struct lt_user_dlloader構造体のdlloader_dataフィールドに設定され
る値は,loader_dataパラメータで,この関数に渡されます.そのような
関数の実装は,指名されたモジュールのロードを試み,関連する
lt_module_closeとlt_sym_find関数のポインタに渡すのに適切な
lt_moduleを返すべきです.関数が失敗した場合はNULLを返し,
lt_dlseterrorを用いてエラーメッセージを設定すべきです.
|
| int lt_module_close (lt_dlloader_data loader_data, lt_module module) | Type |
ユーザが定義したモジュールローダに対するアンローダの型です.そのような関
数の実装は,moduleモジュールに結び付けられたあらゆるリソースの解放
を試み,それから,それをメモリからアンロードすべきです.
lt_module_closeとlt_sym_find関数のポインタに渡すのに適切理
由があり関数が失敗した場合,lt_dlseterrorを用いてエラーメッセージ
を設定し,ゼロ以外を返すべきです.
|
| lt_ptr lt_find_sym (lt_user_data loader_data, lt_module module, const char *symbol) | Type |
ユーザが定義したモジュールローダに対する,シンボルルックアップ関数の型で
す.そのような関数の実装は,モジュールmodule内の指名された
symbolのアドレスを返す,もしくは,検査が失敗した場合は,エラーメッ
セージをlt_dlseterrorで設定し,NULLを返すべきです.
|
| int lt_dlloader_exit (lt_user_data loader_data) | Type |
ユーザが定義したモジュールローダに対する,finalisation関数の型です.その
ような関数の実装は,ローダに関連するあらゆるリソースを解放すべきで,それ
にはlt_user_dlloaderのdlloader_dataフィールド内部にあるユー
ザが指定したあらゆるデータを含みます.NULLでない場合は,関数は
lt_dlexitとlt_dlloader_removeから呼び出されます.
|
例えば,以下のようにします.
int
register_myloader (void)
{
lt_user_dlloader dlloader;
/* User modules are responsible for their own initialisation. */
if (myloader_init () != 0)
return MYLOADER_INIT_ERROR;
dlloader.sym_prefix = NULL;
dlloader.module_open = myloader_open;
dlloader.module_close = myloader_close;
dlloader.find_sym = myloader_find_sym.
dlloader.dlloader_exit = myloader_exit;
dlloader.dlloader_data = (lt_user_data)myloader_function;
/* Add my loader as the default module loader. */
if (lt_dlloader_add (lt_dlloader_next (NULL), &dlloader, "myloader") != 0)
return ERROR;
return OK;
}
ローダに対する必要な初期化がある場合は,ローダが登録される前に手動で実行 する必要があることに注意してください - libltdlはユーザローダの初期化を 扱いません.
Finalisationはlibltdlで扱われますが,dlloader_exitのコール
バックが初期化フェーズの間に要求された,あらゆるリソースを解放することを
確かめることは重要です.
libltdlは,独自のモジュールローダを書くために,以下の関数を提供します.
| int lt_dlloader_add (lt_dlloader *place, lt_user_dlloader *dlloader, const char *loader_name) | Function |
新しいモジュールローダを全てのローダリストに加え,それは,(placeが
NULLの場合は)最後のローダとして,それ以外ではplaceとして渡
されたローダの直前に加えます.loader_nameは,新しく登録されたロー
ダが渡された場合,lt_dlloader_nameを返します,これらの
loader_nameは,ユニークである必要があり,そうでない場合は,
lt_dlloader_removeとlt_dlloader_findは動作不可能です.成功
に対し0を返します.
{
/* Make myloader be the last one. */
if (lt_dlloader_add (NULL, myloader) != 0)
perror (lt_dlerror ());
}
|
| int lt_dlloader_remove (const char *loader_name) | Function |
ユニークな名前loader_nameで識別されているローダを削除します.これ
が成功可能となる前に,指名されたローダにより開かれている全てのモジュール
を,閉じておく必要があります.成功に対し0を返し,それ以外では,エラーメッ
セージがlt_dlerrorから取得可能です.
{
/* Remove myloader. */
if (lt_dlloader_remove ("myloader") != 0)
perror (lt_dlerror ());
}
|
| lt_dlloader * lt_dlloader_next (lt_dlloader *place) | Function |
ローダモジュール全体を繰り返し,それは,placeがNULLの場合,
最初のローダを返し,順番に次を呼び出すことで行います.ハンドルは,
lt_dlloader_add用です.
{
/* Make myloader be the first one. */
if (lt_dlloader_add (lt_dlloader_next (NULL), myloader) != 0)
return ERROR;
}
|
| lt_dlloader * lt_dlloader_find (const char *loader_name) | Function |
loader_name識別しに一致する最初のローダを返し,識別子が見つからな
い場合はNULLを返します.
libltdl自身で使用可能な識別子は,ホストアーキテクチャがサポートしている 場合は,dlopen10, dld,そしてdlpreloadです. {
/* Add a user loader as the next module loader to be tried if
the standard dlopen loader were to fail when lt_dlopening. */
if (lt_dlloader_add (lt_dlloader_find ("dlopen"), myloader) != 0)
return ERROR;
}
|
| const char * lt_dlloader_name (lt_dlloader *place) | Function |
lt_dlloader_nextやlt_dlloader_findで取得される,
PLACEの識別名を返します.この関数が失敗する場合,NULLを返し,
lt_dlerrorで回収するためのエラーを設定します.
|
| lt_user_data * lt_dlloader_data (lt_dlloader *place) | Function |
lt_dlloader_nextやlt_dlloader_findで取得される,
PLACEのアドレスを返します.この関数が失敗する場合,NULLを返
し,lt_dlerrorで回収するためのエラーを設定します.
|
| int lt_dladderror (const char *diagnostic) | Function |
この関数で,独自のエラーメッセージをlt_dlerrorに組み込むことが可
能となります.lt_dlerrorで返すための適切な診断メッセージ内のパス
と,lt_dlseterrorで使用されるエラー識別子が返されます.
識別子の割り当てが失敗した場合,この関数は-1を返します. int myerror = lt_dladderror ("Doh!");
if (myerror < 0)
perror (lt_dlerror ());
|
| int lt_dlseterror (int errorcode) | Function |
独自のモジュールローダを書くとき,lt_dlerrorインターフェースを通
じて伝搬されるように,エラーを発生させるために,この関数を使用すべきです.
libltdlで使用される標準エラーの全ては,ltdl.hで宣言されていて,そ
うでなければ,lt_dladderrorを用いて独自に書き加えることが可能です.
if (lt_dlseterror (LTDL_ERROR_NO_MEMORY) != 0) perror (lt_dlerror ()); |
libltdlはlibtoolとともにインストールされるのですが,libtoolやlibltdlをイ
ンストールしていないパッケージユーザの利便性のため,パッケージの配布物に
libltdlを含めたいと思うかもしれません.この場合,手動でパッケージに加え
るltdlオブジェクト,または,使用したいlibltdlの特色を決定する必要
があります.それは,便利なライブラリやインストール可能なlibtoolライブラ
リです.
libltdlをッケージに加える最も簡単な方法は,ソースファイルの
ltdl.cとltdl.hをパッケージのソースディレクトリにコピーし,
ソースの残りと一緒にリンクすることです.これの手助けをするため,autoconf
のm4マクロがltdl.m4で利用可能です.autoconfを実行する前に,それら
がaclocal.m4で利用可能かどうかを確かめる必要があります -
automakeを使用している場合はltdl.m4の内容をacinclude.m4に
加え,そうでない場合はaclocal.m4に加えます.マクロを利用可能にし
た後,ltdl.oを正しく構築するために必要なコンフィグレーション時の
調査を実行するため,AC_LIB_LTDLマクロの呼び出しを,パッケージの
configure.inに加える必要があります.インストールされているlibltdl
やlibltdlに依存しているライブラリと,パケージのバイナリをリンクしようと
する場合,この手法には問題があります.シンボルの二重定義の問題があるかも
しれません.
便利なライブラリの利点の一つはインストールされていないということなので,
libtoolを使用するという事実はユーザにとって明白ではなく,ユーザが以前に
インストールしているlibtoolのバージョンを上書きしません.一方,(例えば,
バグフィックスといった)理由があり,libltdlをアップグレードしたい場合,イ
ンストールされているバージョンのlibtoolを置き換える代わりに,パッケージ
を再コンパイルする必要があります.しかし,プログラムやライブラリが以前に
インストールされているバージョンのlibltdlを使用しているライブラリとリン
クする場合,リンカエラーが発生し実行時にクラッシュするかもしれません.も
う一つの問題は,一つ以上のlibtoolライブラリへ便利なライブラリをリンクで
きないことで,複製されたのシンボルを得る可能性があるので,そのときは,こ
れらのライブラリを用いた単一のプログラムとリンクしてください.一般的に,
libtoolを使用している他のライブラリに依存しないプログラムでは,便利なラ
イブラリを問題なく使用可能です.libltdlのこの特徴を利用可能にするため,
AC_LIBLTDL_CONVENIENCE行をconfigure.inに,
AC_PROG_LIBTOOLの前に加えた方が良いでしょう.
インストール可能なバージョンのlibltdlを選択するために,マクロ
AC_LIBLTDL_INSTALLABLEの呼び出しをconfigure.inに,
AC_PROG_LIBTOOLの前に加えた方が良いでしょう.このマクロは,
libltdlが既にインストールされているかどうか調査し,そうでない場合,構築
しインストールされるパッケージlibltdlを埋め込むことを要求します.しかし,
バージョン調査は実行されないことに注意してください.ユーザは,コンフィグ
レーションスイッチ--enable-ltdl-installを使用することで,他のバー
ジョンの存在に関係なく,テストを優先し,埋め込まれたlibtoolをインストー
ルする必要があるか決定することができます.
libtoolをパッケージに埋め込むため,libtoolizeコマンドラインに
--ltdlのみ加えてください.それで,パッケージのサブディレクトリ
libltdlにlibtoolのソースをコピーします.どちらのマクロも,
libltdlディレクトリの位置を指定する,追加の引数を受け入れます.デ
フォルトで,どちらのマクロも${top_srcdir}/libltdlを仮定します.
どのマクロを使用しても,configure.inはAC_CONFIG_SUBDIRSを
使用して,libltdlをコンフィグレーションし,Makefileが,例えば,
automakeのSUBDIRSを使用して,libtoolのディレクトリでサブmakeを開始
することを確実にするのはあなたです.どちらのマクロも,libltdlでリンクす
るために使用するリンクフラグのシェル変数LIBLTDLと,ltdl.hを
インクルードするプログラムをコンパイルするために使用するプリプロセッサフ
ラグINCLTDLを定義します.この変数がMakefileで利用可能にする
ことを確実にするためAC_SUBSTを使用したり,デフォルトで
AC_SUBSTされる,LIBSとCPPFLAGSのような変数に加えるの
はあなた次第です.
便利なlibltdlを使用している場合,LIBLTDLは便利なlibltdlのバージョ
ンに対するパス名で,INCLTDLはlibltdlを含むディレクトリが続く
-Iになり,どちらも${top_builddir}/,または,
${top_srcdir}/で,それぞれ始まります.
インストールされているlibltdlのバージョンを要求し,それが見つかった場合
11,LIBLTDLは-lltdl
に,INCLTDLは空に設定されます(それは,libltdlがライブラリパスにあ
る場合,ltdl.hがインクルードパスのどこかにあるという,暗黙の仮定
です).インストール可能なlibltdlのバージョンを構築する必要がある場合,
${top_builddir}/で始まるそのパス名は,LIBLTDLに保存され,
INCLTDLは便利なライブラリの場合と同様に設定されます.
そのため,libltdlとプログラムをリンクしたいとき,libtoolを使用して,
$(INCLTDL)を用いてコンパイルし,$(LIBLTDL)を用いてリンクし,
インストールされた,または,インストール可能な便利なライブラリにしてくだ
さい.
おそらくAC_LIBTOOL_DLOPENもconfigure.inに,
AC_PROG_LIBTOOLの前に加えた方が良く,そうしない場合は,
libtoolはdlopenメカニズムがサポートされていないと仮定し,おそらく希望し
ていないdlpreopenに逆戻りします.
libltdlとプログラムをリンクするとき,-staticや-all-static
スイッチの使用を避けてください.dlopen関数はスタティックリンクに対して利
用可能でない可能性があるので,これはすべてのプラットフォームで動作するわ
けではありません.
以下の例は,パッケージに便利なlibltdlを埋め込む方法を示します.インストー
ル可能な変形を使用するために,AC_LIBLTDL_CONVENIENCEを
AC_LIBLTDL_INSTALLABLEで置換してください.我々は,libltdlが
libtoolize --ltdlを使用して埋め込まれていると仮定しています.
configure.inです.
... dnl Enable building of the convenience library dnl and set LIBLTDL accordingly AC_LIBLTDL_CONVENIENCE dnl Substitute INCLTDL and LIBLTDL in the Makefiles AC_SUBST(INCLTDL) AC_SUBST(LIBLTDL) dnl Check for dlopen support AC_LIBTOOL_DLOPEN dnl Configure libtool AC_PROG_LIBTOOL dnl Configure libltdl AC_CONFIG_SUBDIRS(libltdl) ...
Makefile.amです.
... SUBDIRS = libltdl INCLUDES = $(INCLTDL) myprog_LDFLAGS = -export-dynamic # The quotes around -dlopen below fool automake <= 1.4 into accepting it myprog_LDADD = $(LIBLTDL) "-dlopen" self "-dlopen" foo1.la myprog_DEPENDENCIES = $(LIBLTDL) foo1.la ...
libtoolは最初に,C言語での共有ライブラリを書くことに対するサポートを加え るために実装されました.しかし,時間が経ち,プログラマが好みのプログラム 言語での共有ライブラリの便利さを自由に得られるように,libtoolは他の言語 と統合されています.
この章は,libtoolが他の言語と相互作用する方法と,Cを用いない場合に必要と される特記事項を記述します.
C++コードのライブラリを作成することは,そのオブジェクトファイルがCのもの と3つの点で異なっているだけので,かなり簡単な処理になります.
ldを直接呼び出すべ
きではなく,その代わりにC++コンパイラを使用するべきだということを意味し
ます.
ldを実行すること
は,失敗すると思われます.しかし,C++コンパイラを直接実行することは,ラ
イブラリ内部の依存に関係する問題に至る可能性があります.
結論として,libtoolはC++ライブラリに対する一般的な使用のための準備ができ ていません.標準Cコンパイラでコンパイルする場合は,"初期化要素は一定で はない"というエラーの原因となる,あらゆるグローバルまたはスタティック変 数の初期化を避けるべきです.
この問題に関して動作する他の方法もありますが,それらはこのマニュアルの範 囲を越えています.
さらに,C++コンパイラがデフォルトでリンクするC++ 標準ライブラリと,リン クコマンドラインの明示的なリストは,コンフィグレーション時に分かった方が 良いでしょう.たぶん将来,libtoolはこの仕事を単独で可能となるでしょう.
libtoolは,コンスタントに開発されていて,現在のオペレーティングシステム で最新を保つよう変更します.libtoolがプラットフォーム上で思ったように動 作しない場合,問題点と解決方法を決定する助けとなる,この章を読んだ方が良 いでしょう.
libtoolは,その能力をテストし,libtoolプログラムの明らかなバグを報告する, プログラムの独自のセットとともにあります.これらのテストは,libtoolの過 去の問題と他のオペレーティングシステム内の既知の欠陥を基にして,絶えず進 化もしています.
INSTALLファイルに記述されているように,libtoolの構築後,基本的な
機能要求に合っていることを確めるために,make checkを実行することが
可能です.
ここに,テストスイートの現在のプログラムと,それらがテストするもののリスト があります.
cdemo-conf.test
cdemo-exec.test
cdemo-make.test
cdemo-static.test
cdemo-shared.test
cdemoサブディレクトリが,正
しくコンフィグレーションされ,構築されることを知るために調査します.
cdemoサブディレクトリは,libtoolの便利なライブラリのデモンストレー
ションをふくみ,それは,構築時に共有ライブラリの作成を可能とするメカニズ
ム,コンポーネントが,それが共有ライブラリでも,プログラムや他のライブラ
リと遅れてリンクされることを可能とする方法です.
cdemo-make.testとcdemo-exec.testのテストは,3つの異なる
libtoolコンフィグレーションで,3回実行されます.cdemo-conf.test
は,スタティックライブラリと共有ライブラリの両方を構築するために(両方サ
ポートしているプラットフォームではデフォルトです)cdemo/libtoolを
コンフィグレーションし,cdemo-static.testはスタティックライブラリ
のみ構築し(--disable-shared),そしてcdemo-shared.testは共
有ライブラリのみ構築します(--disable-static).
demo-conf.test
demo-exec.test
demo-inst.test
demo-make.test
demo-unst.test
demo-static.test
demo-shared.test
demo-nofast.test
demo-pic.test
demo-nopic.test
demoサブディレクトリが,コン
フィグレーション,構築,インストール,そしてアンインストールが正しくでき
ることを知るために調査します.
demoサブディレクトリは,libtoolを使用する平凡なパッケージのデモン
ストレーションを含みます.テストのdemo-make.test,
demo-exec.test,demo-inst.test,そして
demo-unst.testは,4つの異なるlibtoolのコンフィグレーションの下で,
4回実行されます.demo-conf.testは,スタティックと共有の両方のラ
イブラリを構築するためにdemo/libtoolをコンフィグレーションし,
demo-static.testは,スタティックライブラリのみ構築し
(--disable-shared),そしてdemo-shared.testは,共有ライブラ
リのみを構築します(--disable-static).demo-nofast.testは,
高速インストールモードを使用禁止にするために
(--enable-fast-install=no),demo/libtoolをコンフィグレーショ
ンします.demo-pic.testは,PICコードを構築したいときは
(--with-pic),非PICコードを構築したいときは(--without-pic)
にするように,demo/libtoolをコンフィグレーションします.
deplibs.test
deplibs_check_methodを使用します.このテストは,libtoolの
deplibs_check_methodが正しく動作するかどうか調査します.
hardcode.test
build-relink.test
noinst-link.test
depdemo-conf.test
depdemo-exec.test
depdemo-inst.test
depdemo-make.test
depdemo-unst.test
depdemo-static.test
depdemo-shared.test
depdemo-nofast.test
depdemoサブディレクトリの,
コンフィグレーション,構築,インストール,そしてアンインストールを,正し
く行えることを判定するための調査を行います.
depdemoサブディレクトリは,libtoolに依存する内部ライブラリのデモ
ンストレーションを含みます.このテストプログラムは,いくつかの交互依存し
ているライブラリをリンクします.
テストの,depdemo-make.test,depdemo-exec.test,
depdemo-inst.test,そしてdepdemo-unst.testは,4つの異なる
libtoolのコンフィグレーションの下で,4回実行されます.
depdemo-conf.testは,スタティックと共有の両方のライブラリを構築す
るために,depdemo/libtoolをコンフィグレーションし,
depdemo-static.testはスタティックライブラリのみ構築し
(--disable-shared),depdemo-shared.testは共有ライブラリの
み構築します(--disable-static).depdemo-nofast.testは高速
インストールモード(--enable-fast-install=no)を利用不可能にするた
めに,depdemo/libtoolをコンフィグレーションします.
mdemo-conf.test
mdemo-exec.test
mdemo-inst.test
mdemo-make.test
mdemo-unst.test
mdemo-static.test
mdemo-shared.test
mdemoサブディレクトリが,コ
ンフィグレーション,構築,インストール,そしてアンインストールが正しくで
きることを知るために調査します.
mdemoサブディレクトリは,libtoolと,システム非依存のモジュールロー
ドのための,dlopenラッパーlibltdlを使用するパッケージのデモンスト
レーションを含みます.ライブラリlibltdlは,様々なプラットフォーム
(Linux,Solaris,HP/UX等)に対する,dlpreopenモジュールに対するサポートを
含む(see Dlpreopening)dlopenラッパーを提供します.
テストのmdemo-make.test,mdemo-exec.test,
mdemo-inst.test,そしてmdemo-unst.testは,3つの異なる
libtoolのコンフィグレーションの下で,3回実行されます.
mdemo-conf.testは,スタティックと共有の両方のライブラリを構築する
ためにmdemo/libtoolをコンフィグレーションし,
mdemo-static.testは,スタティックライブラリのみ構築し
(--disable-shared),そしてmdemo-shared.testは,共有ライブ
ラリのみを構築します(--disable-static).
dryrun.test
--dry-runモードが正しく働くかどうかを調査
します.
assign.test
link.test
link-2.test
.loで終わるファイルがプログラムファイルに直接リンク
されないことを確かめます.
nomode.test
quote.test
sh.test
suffix.test
.c以外の接尾子で終わるかもしれません.このテスト
は,サポートするすべてのファイル形式に対する接尾子を扱うこと可能で,接尾
子が不当なときは失敗することを確認します.
上記のそれぞれのテストは,make checkを実行するとき出力を生成しない
ように設計されています.それぞれのプログラムの終了ステータスで,テストが
成功しなかったかどうかをMakefileに伝えます.
テストが失敗した場合,それはlibtool内のプログラムエラー,またはプログラ ム自身のエラーのどちらかが存在することを意味します.
特定のテストを調査するために,通常のプログラムで行うように,直接実行する ことが可能です.テストがこの方法で呼び出されたとき,それは,問題を決定す るのに役に立ちそうな出力を生成します.
テストプログラムに出力を生成させるもうひとつの方法は,実行前に
VERBOSE環境変数をyesに設定することです.例えば,env
VERBOSE=yes make checkですべてのテストが実行され,それぞれについてデバッ
グ情報の表示が得られます.
libtoolにバグを発見したと考えた場合,もう一度考えたほうが良いでしょう. libtool管理者は,責任転嫁(または"バグを通過させる"かもしれません)で有 名です12.libtoolは,共有ライブラリの実装で 既知の欠陥を修正するために開発されたので,libtoolのバグのほとんどは,あ る程度は,他のオペレーティングシステムのバグになります.しかし,libtool の管理者は,他人のバギーなオペレーティングシステムに対するサポートを加え ることを,確かに楽しんでいます.[Texinfoでウインクしている笑顔を表示する, いい方法があれば良いのですが.]
libtoolの純粋なバグは,シェルスクリプトの移植性の問題,ドキュメントのエ ラー,そしてテストスイートの失敗(see Libtool test suite)を含みます.
最初に,問題と考えられる動作が,既に特徴として言及されていないことを確か めるために,ドキュメントとへルプ画面を調査してください.
そして,バグを報告することに関するEmacsガイド(see Bugs)を読んでください.リストアップされている 詳細は,Emacs特有のものもありますが,基本的な原則は一般的なものです.
最終的に,テストスイートの出力(see When tests fail),バグを再生成す るのに必要なすべての詳細,そして,動作がバグだと考えられる理由の概要のよ うな,適切なあらゆる事実とともにthe libtool bug reporting address bug-libtool@gnu.orgにバグの報告を送っ てください.サブジェクト行に,単語"libtool"と,同様に使用しているバー ジョンナンバー(それは,ltconfig --versionの入力で分かります)が含ま れていることを確認してください.
この章は,libtool管理者が見つける重要な情報を含みます.新しいシステムへ の移植や,独自のlibtoolを書くことを考慮しない場合,役に立たないでしょう.
サポートされていないシステムへのlibtoolの移植に乗り出す前に,既存の仕事 と重複していないことを確認するために,the libtool mailing list libtool@gnu.orgに電子メールを送る 価値はあります.
移植の文章が見つからない場合,文句を言ってください! パッチを含む苦情と 文章やlibtool自身の改良は十分に歓迎されます.
新たな移植の必要性が明らかになると,通常,以下の情報が必要となります.
config.guessの出力が必要です.
ldとccに対するmanページ
ld.so,rtld,または,その同等物のmanページ
ldconfigやその同等物のmanページ
Bourneシェルプログラムの方法を知っている場合,完全に自分で移植することが 可能です.それ以外の場合,関連する作業を行う腕のある人を探す必要がありま す.libtoolメーリングリストの人々は,新たな移植への援助を志願する意思が あるので,彼らに情報を送ることができます.
独自に移植するためには,プラットフォーム特有のコンフィグレーションプロセ
スの変更を行うため,libtool.m4マクロを明確に修正する必要がありま
す.PORTMEキーワードに対するファイルを検索する必要があり,それで,
変更に必要なヒントを得られるでしょう.一般的に,呼び出されるものは,適切
なコンフィグレーション変数の編集です(see libtool script contents).
最善策は,既にサポートされている良く似たシステムを見つけ,変更の基本とす
ることです.しかし,システムが他のサポートされているシステムと,大きく異
なる場合や,新しいコンフィグレーション変数を加え,それに応じて
ltmain.inスクリプトを変更する必要がある場合もあります.欲しいもの
を達成するための,最も効果的な方法の助言がある可能性があるので,
ltmain.inを変更する前に,メーリングリストに書いて確認してください.
バージョン1.2c以降,libtoolは,Toshio Kuratomi badger@prtr-13.ucsc.eduのパッチのおかげで,ライブラリ内部の依存 性を可能とする機能が再導入されてるプラットフォームもあります.パッチに含 まれるメッセージの短いバージョンメッセージが,ここにあります.
基本的な体系はこのようになります.libtool.m4で,libtoolを書いてい
る人は,$deplibsが$archive_cmdsのどこかに含まれていること,
また,変数$deplibs_check_methodと,deplibs_check_methodが
ファイルマジックの場合は$file_magic_cmdが設定されていることを確認
します.
deplibs_check_methodは,以下の5つの内の一つのはずです.
file_magic [regex]
$file_magic_cmdを実行し,egrepを使用した
regexに一致することを調査します.file_magic_test_fileが
libtool.m4によって設定されているとき,正規表現がその出力と一致す
るかどうかを検証し,それ以外ではユーザが警告を受けるようにするため,それ
は$file_magic_cmdへの引数として使用されます.
test_compile
lddの出力でリストアップされていることを調査します.それは
現在,使用されておらず,将来は打ち切る可能性があります.
pass_all
none
archive_cmdsは,す
べてのプラットフォームでdeplibsを含むはずですが,deplibは必要がなければ
使用されません.
unknown
libtool.m4で優先されない場合,すべてのシステムでデフォルトです.
それはnoneと同じですが,正しい値が何か,我々が本当に知らないこと
を文章化していて,我々はそれを改善するパッチを歓迎します.
ltmain.inで,我々は本当に一生懸命作業しました.それは,
(libname_spec等の評価を使用するための変数を設定/リリース行う)小さな初期
化と移植,そして使用するメソッドを決定するケース文です.これは,実際には
コードです... もう少し凝縮できれば良かったのですが,関数呼び出しを用い
ずにできるとは思えませんでした.私はほとんどの(ループの外に出す等の)最適
化を行いましたが,余分なものがあるかもしれません.前に進めていく内にやめ
るべきだと考えていたことは,明白な最適化を考える前に,発見したあらゆるバ
グに対して作業することでした.
この表は,共有ライブラリのサポートを謡っているプラットフォームで, libtoolがテストされたことが分かっている最後の時期を記述しています.
-------------------------------------------------------
標準的なホスト名 コンパイラ libtool 結果
(ツールのバージョン) リリース
-------------------------------------------------------
alpha-dec-osf5.1 cc 1.3e ok (1.910)
alpha-dec-osf4.0f gcc 1.3e ok (1.910)
alpha-dec-osf4.0f cc 1.3e ok (1.910)
alpha-dec-osf3.2 gcc 0.8 ok
alpha-dec-osf3.2 cc 0.8 ok
alpha-dec-osf2.1 gcc 1.2f NS
alpha*-unknown-linux-gnu gcc 1.3b ok
(egcs-1.1.2, GNU ld 2.9.1.0.23)
hppa2.0w-hp-hpux11.00 cc 1.2f ok
hppa2.0-hp-hpux10.20 cc 1.3.2 ok
hppa1.1-hp-hpux10.20 gcc 1.2f ok
hppa1.1-hp-hpux10.20 cc 1.3c ok (1.821)
hppa1.1-hp-hpux10.10 gcc 1.2f ok
hppa1.1-hp-hpux10.10 cc 1.2f ok
hppa1.1-hp-hpux9.07 gcc 1.2f ok
hppa1.1-hp-hpux9.07 cc 1.2f ok
hppa1.1-hp-hpux9.05 gcc 1.2f ok
hppa1.1-hp-hpux9.05 cc 1.2f ok
hppa1.1-hp-hpux9.01 gcc 1.2f ok
hppa1.1-hp-hpux9.01 cc 1.2f ok
i*86-*-beos gcc 1.2f ok
i*86-*-bsdi4.0.1 gcc 1.3c ok
(gcc-2.7.2.1)
i*86-*-bsdi4.0 gcc 1.2f ok
i*86-*-bsdi3.1 gcc 1.2e NS
i*86-*-bsdi3.0 gcc 1.2e NS
i*86-*-bsdi2.1 gcc 1.2e NS
i*86-pc-cygwin gcc 1.3b NS
(egcs-1.1 stock b20.1 compiler)
i*86-*-dguxR4.20MU01 gcc 1.2 ok
i*86-*-freebsd4.3 gcc 1.3e ok (1.912)
i*86-*-freebsdelf4.0 gcc 1.3c ok
(egcs-1.1.2)
i*86-*-freebsdelf3.2 gcc 1.3c ok
(gcc-2.7.2.1)
i*86-*-freebsdelf3.1 gcc 1.3c ok
(gcc-2.7.2.1)
i*86-*-freebsdelf3.0 gcc 1.3c ok
i*86-*-freebsd3.0 gcc 1.2e ok
i*86-*-freebsd2.2.8 gcc 1.3c ok
(gcc-2.7.2.1)
i*86-*-freebsd2.2.6 gcc 1.3b ok
(egcs-1.1 & gcc-2.7.2.1, native ld)
i*86-*-freebsd2.1.5 gcc 0.5 ok
i*86-*-netbsd1.5 gcc 1.3e ok (1.901)
(egcs-1.1.2)
i*86-*-netbsd1.4 gcc 1.3c ok
(egcs-1.1.1)
i*86-*-netbsd1.4.3A gcc 1.3e ok (1.901)
i*86-*-netbsd1.3.3 gcc 1.3c ok
(gcc-2.7.2.2+myc2)
i*86-*-netbsd1.3.2 gcc 1.2e ok
i*86-*-netbsd1.3I gcc 1.2e ok
(egcs 1.1?)
i*86-*-netbsd1.2 gcc 0.9g ok
i*86-*-linux-gnu gcc 1.3e ok (1.901)
(Red Hat 7.0, gcc "2.96")
i*86-*-linux-gnu gcc 1.3e ok (1.911)
(SuSE 7.0, gcc 2.95.2)
i*86-*-linux-gnulibc1 gcc 1.2f ok
i*86-*-openbsd2.5 gcc 1.3c ok
(gcc-2.8.1)
i*86-*-openbsd2.4 gcc 1.3c ok
(gcc-2.8.1)
i*86-*-solaris2.7 gcc 1.3b ok
(egcs-1.1.2, native ld)
i*86-*-solaris2.6 gcc 1.2f ok
i*86-*-solaris2.5.1 gcc 1.2f ok
i*86-ncr-sysv4.3.03 gcc 1.2f ok
i*86-ncr-sysv4.3.03 cc 1.2e ok
(cc -Hnocopyr)
i*86-pc-sco3.2v5.0.5 cc 1.3c ok
i*86-pc-sco3.2v5.0.5 gcc 1.3c ok
(gcc 95q4c)
i*86-pc-sco3.2v5.0.5 gcc 1.3c ok
(egcs-1.1.2)
i*86-sco-sysv5uw7.1.1 gcc 1.3e ok (1.901)
(gcc-2.95.2, SCO linker)
i*86-UnixWare7.1.0-sysv5 cc 1.3c ok
i*86-UnixWare7.1.0-sysv5 gcc 1.3c ok
(egcs-1.1.1)
m68k-next-nextstep3 gcc 1.2f NS
m68k-sun-sunos4.1.1 gcc 1.2f NS
(gcc-2.5.7)
m88k-dg-dguxR4.12TMU01 gcc 1.2 ok
m88k-motorola-sysv4 gcc 1.3 ok
(egcs-1.1.2)
mips-sgi-irix6.5 gcc 1.2f ok
(gcc-2.8.1)
mips-sgi-irix6.4 gcc 1.2f ok
mips-sgi-irix6.3 gcc 1.3b ok
(egcs-1.1.2, native ld)
mips-sgi-irix6.3 cc 1.3b ok
(cc 7.0)
mips-sgi-irix6.2 gcc 1.2f ok
mips-sgi-irix6.2 cc 0.9 ok
mips-sgi-irix5.3 gcc 1.2f ok
(egcs-1.1.1)
mips-sgi-irix5.3 gcc 1.2f NS
(gcc-2.6.3)
mips-sgi-irix5.3 cc 0.8 ok
mips-sgi-irix5.2 gcc 1.3b ok
(egcs-1.1.2, native ld)
mips-sgi-irix5.2 cc 1.3b ok
(cc 3.18)
mips-sni-sysv4 cc 1.3.5 ok
(Siemens C-compiler)
mips-sni-sysv4 gcc 1.3.5 ok
(gcc-2.7.2.3, GNU assembler 2.8.1, native ld)
mipsel-unknown-openbsd2.1 gcc 1.0 ok
powerpc-ibm-aix4.3.1.0 gcc 1.2f ok
(egcs-1.1.1)
powerpc-ibm-aix4.2.1.0 gcc 1.2f ok
(egcs-1.1.1)
powerpc-ibm-aix4.1.5.0 gcc 1.2f ok
(egcs-1.1.1)
powerpc-ibm-aix4.1.5.0 gcc 1.2f NS
(gcc-2.8.1)
powerpc-ibm-aix4.1.4.0 gcc 1.0 ok
powerpc-ibm-aix4.1.4.0 xlc 1.0i ok
rs6000-ibm-aix4.1.5.0 gcc 1.2f ok
(gcc-2.7.2)
rs6000-ibm-aix4.1.4.0 gcc 1.2f ok
(gcc-2.7.2)
rs6000-ibm-aix3.2.5 gcc 1.0i ok
rs6000-ibm-aix3.2.5 xlc 1.0i ok
sparc-sun-solaris2.8 gcc 1.3e ok (1.913)
(gcc-2.95.3 & native ld)
sparc-sun-solaris2.7 gcc 1.3e ok (1.913)
(gcc-2.95.3 & native ld)
sparc-sun-solaris2.6 gcc 1.3e ok (1.913)
(gcc-2.95.3 & native ld)
sparc-sun-solaris2.5.1 gcc 1.3e ok (1.911)
sparc-sun-solaris2.5 gcc 1.3b ok
(egcs-1.1.2, GNU ld 2.9.1 & native ld)
sparc-sun-solaris2.5 cc 1.3b ok
(SC 3.0.1)
sparc-sun-solaris2.4 gcc 1.0a ok
sparc-sun-solaris2.4 cc 1.0a ok
sparc-sun-solaris2.3 gcc 1.2f ok
sparc-sun-sunos4.1.4 gcc 1.2f ok
sparc-sun-sunos4.1.4 cc 1.0f ok
sparc-sun-sunos4.1.3_U1 gcc 1.2f ok
sparc-sun-sunos4.1.3C gcc 1.2f ok
sparc-sun-sunos4.1.3 gcc 1.3b ok
(egcs-1.1.2, GNU ld 2.9.1 & native ld)
sparc-sun-sunos4.1.3 cc 1.3b ok
sparc-unknown-bsdi4.0 gcc 1.2c ok
sparc-unknown-linux-gnulibc1 gcc 1.2f ok
sparc-unknown-linux-gnu gcc 1.3b ok
(egcs-1.1.2, GNU ld 2.9.1.0.23)
sparc64-unknown-linux-gnu gcc 1.2f ok
注意:
- "ok" は,"すべてのテストを通過した"ことを意味します.
- "NS" は,"共有に失敗"("Not Shared")を意味しますが,
スタティックライブラリはOKです.
注:ベンダー配布されているHP-UXのsed(1)プログラムは,ひどく壊れて
いて,libtoolの要求を処理することができないため,ユーザは異常の問題を報
告する可能性があります.これらのシステムで動作する(GNU sed)のよう
なsedをインストールする以外に,回避方法はありません.
注:ベンダー配布されているNCR MP-RAS ccプログラムは,標準エラーに
著作権を出力し,conftest.errの大きさのテストで混乱します.回避方
法は,configureを実行するとき,CC='cc -Hnocopyr'を用いて
CC を指定します.
このセクションは,libtoolの管理者の健康に捧げます.それは,libtoolが使用 するプログラム,システムごとの違い,そしてテストの方法を記述します.
libtoolはシェルスクリプトなので,最初から最後まで読むだけで理解すること は難しいはずです.このセクションは,libtoolが特定の方法で行う理由の理解 を助けます.スクリプト自身が組み合わされているので,libtoolの改善や,独 自に書く方法の,より良いセンスが必要でしょう.
以下は,価値のある文章の参照リストです.
http://techpubs.sgi.com/cgi-bin/infosrch.cgi?cmd=browse&db=man>で見
つかります.
http://www.sun.com/service/online/free.html>)とドキュメントサーバ
(<http://docs.sun.com/>).
http://tru64unix.compaq.com/faqs/publications/pub_page/doc_list.html>)
にあり,C++ドキュメントは
(<http://tru64unix.compaq.com/cplus/docs/index.htm>)です.
http://docs.hp.com/index.html>)にオンラインドキュ
メントがあります.
http://www.rs6000.ibm.com/resource/aix_resource/Pubs/>)にオン
ラインドキュメントがあります.
libtoolに影響するコンパイラの特徴は,PICオブジェクトを生成するための(存 在する場合は)必要なフラグのみです.一般的に,Cコンパイラが特定のPICフラ グをサポートする場合,あらゆる派生的なコンパイラは同じフラグをサポートし ます.この規則に対し,注目すべき若干の例外があるまでは,このセクションで はCコンパイラのみを説明します.
プラットフォームに関係なく,以下のCコンパイラは,標準のコマンドライオプ ションがあります.
gcc
-fpicや-fPICフラグは,位置に依存しないコードを生成するため
に使用可能です.-fPICは動作するコードを生成することを保証しますが,
m68k,m88k,そしてSparcチップ上ではコードは遅くなります.しかし,これら
のチップで-fpicを使用すると,共有ライブラリでの自由なサイズが強制
的に制限されます.
バンドルされているオペレーティングシステムにより,このサブセクションの残 りでコンパイラをリストアップします.
aix3*
aix4*
hpux10*
+Zを使用してください.
osf3*
solaris2*
-KPICを使用してください.
sunos4*
-PICを使用してください.
すべての既知のシステム上で,リロード可能なオブジェクトはld -r -o output.o input1.o input2.oを実行することで生成可能で す.このリロード可能なオブジェクトは,他のオブジェクトと完全な同義語とし て扱うことが可能です.
ほとんどの近代的なプラットフォームでは,依存するライブラリがリストアップ される順序は,オブジェクトの生成で影響がありません.理論上,シンボルを提 供している,それらのライブラリの後にリストアップされている,その他のライ ブラリに足りないシンボルを提供するライブラリを要求するプラットフォームが あります.
特に,一組のスタティックアーカイブのそれぞれが,他のシンボルのいくつかを 解決する場合,それらのアーカイブの前後両方に他のものをリストアップするこ とが必要かもしれません.複製されたライブラリはリンク行から削除されるので, libtoolは,現在この状況に十分に対処していません.
正しくリンクされたオブジェクトを生成するために,ライブラリを複数回リスト アップすることを要求するホストで開発していることが分かった場合,以下のよ うにして,libtoolの除去アルゴリズムを無効にすることが可能です.
$ libtool ... -lfoo -lbar -Wl,-lfoo
すべての既知のシステム上で,スタティックライブラリの構築は,ar cru
libname.a obj1.o obj2.o ...の実行で完成するはずで,
そこでは,.aファイルは出力ライブラリで,それぞれの.oファイ
ルはオブジェクトファイルです.
すべての既知のシステム上で,ranlibという名のプログラムがある場合,
リンクする前にranlib libname.aコマンドを用いて,作成されるラ
イブラリを"祝福"するために使用する必要があります.Irixのように,代わり
にar tsを使用するシステムもあります.
libtoolスクリプトの内容バージョン1.4からは,libtoolスクリプトはconfigureによって
生成されます(see Configuring.以前のバージョンでは,ltconfig
と呼ばれるへルパースクリプトを呼び出すことで,configureはそれを達
成していました.libtoolのバージョン0.7から1.0までは,このスクリプトは,
単純にシェル変数を設定し,libtoolのバックエンドのltmain.shの源と
なっていました.libtoolバージョン1.1から1.3までのltconfigは,
ltmain.shの内容を,生成されたlibtoolにインライン化し,それ
は多くのシステムでパフォーマンスを改善しました.ltconfigが実行す
るために使用するテストは,現在libtool.m4にあり,そこで我々は
Autoconfを使用して書くことが可能となっています.これは,インライン化され
たltmain.shの実行時の動作に有利で,そして,管理が必要な生
のシェルコードの量をかなり取り除くことで,構築時間を短くする改善を行いま
した.
遅延評価に対するシェルコマンドを持つ変数の命名に使用される規則は,有効な
単一行のシェルスクリプトが必要とされるところで接尾子_cmd,複数行
のシェルスクリプトが遅延評価可能なところで接尾子_cmdsを
使用することです.規則では,_cmds変数は,必要なところで,~
文字で評価ユニットを区切ります.
ここに,それぞれのコンフィグレーション変数と,ltmain.shで使用法の
リストがあります(see Configuring).
| AR | Variable |
| システムライブラリアーカイバの名前です. |
| CC | Variable |
| libtoolをコンフィグレーションするために使用するCコンパイラの名前です. |
| LD | Variable |
| リロード可能なリンクとおそらく共有ライブラリに対し,libtoolが内部で使用 するリンカの名前です. |
| NM | Variable |
BSD互換のnmプログラムの名前で,それは以下の書式の一つで,大域的な
シンボルを生成します.
address C global-variable-name address D global-variable-name address T global-function-name |
| RANLIB | Variable |
| 存在する場合,ranlibプログラムの名前を設定します. |
| allow_undefined_flag | Variable |
結果として生じる共有ライブラリに,未解決のシンボルがあることを宣言するた
めに,archive_cmdsで使用されるフラグです.そのようなフラグが不要
な場合は空です.ライブラリで定義されていないシンボルを参照して,共有ライ
ブラリを生成する方法がない場合,unsupportedを設定します.
|
| always_export_symbols | Variable |
アーカイブとリンクする前に,export_symbols_cmdsを使用してエクスポー
トされるシンボルのリストを,libtoolが自動的に生成するかどうかです.
yesまたはnoに設定します.デフォルトはnoです.
|
| archive_cmds | Variable |
| archive_expsym_cmds | Variable |
| old_archive_cmds | Variable |
それぞれ,共有ライブラリ,-export-symbolsを用いた共有ライブラリ,
そしてスタティックライブラリを生成するために使用するコマンドです.
|
| old_archive_from_new_cmds | Variable |
共有ライブラリがスタティックライブラリに依存する場合,
old_archive_from_new_cmdsはスタティックライブラリを生成するために
使用するコマンドを含みます.この変数が空の場合,old_archive_cmds
は使用されません.
|
| old_archive_from_expsyms_cmds | Variable |
スタティックライブラリが,共有ライブラリで正しくリンクするために,エクス
ポートシンボルリストから作成される必要がある場合,
old_archive_from_expsyms_cmdsは,そのスタティックライブラリを作成
するために必要なコマンドを含みます.これらのコマンドが実行されるとき,変
数sonameは,共有ライブラリの名前を疑問符の中に含み,
$objdir/$newlibは,これらのコマンドが構築する静的ライブラリのパス
を含みます.これらのコマンドを実行した後,libtoolは,sonameの代わ
りに$objdir/$newlibに対してリンクするための処理を行います.
|
| build_libtool_libs | Variable |
このシステムで,libtoolが共有ライブラリを構築できるかどうかです.
yesまたはnoに設定します.
|
| build_old_libs | Variable |
このシステムで,libtoolがスタティックライブラリを構築できるかどうかです.
yesまたはnoに設定します.
|
| compiler_c_o | Variable |
コンパイラが,同時に-cと-oオプションをサポートするかどうか
です.yesまたはnoに設定します.
|
| compiler_o_lo | Variable |
コンパイラが,直接".lo"ファイルへのコンパイルをサポートするかどうかで,
例えば,オブジェクトファイルが,接尾子".o"を持つ必要があるかどうかです.
yesまたはnoに設定します.
|
| dlopen_support | Variable |
プラットフォームで,dlopenをサポートするかどうかです.yes
またはnoに設定します.
|
| dlopen_self | Variable |
実行形式自身がdlopen可能かどうかです.yesまたはno
に設定します.
|
| dlopen_self_static | Variable |
静的にリンクされているとき(-all-static),実行形式自身が
dlopen可能かどうかです.yesまたはnoに設定します.
|
| echo | Variable |
バックスラッシュをエスケープ文字と解釈しないechoプログラムです.
|
| exclude_expsyms | Variable |
| プリリードされているシンボルにリストアップされないシンボルのリストです. |
| export_dynamic_flag_spec | Variable |
| dlopenされる共有ライブラリが,プログラムで定義されているシンボルへの参照 を可能にするコンパイラリンクフラグです. |
| export_symbols_cmds | Variable |
| libobjsからファイルexport_symbolsへエクスポートされたシンボ ルを抽出するコマンドです. |
| extract_expsyms_cmds | Variable |
共有ライブラリからエクスポートされたシンボルリストを抽出するコマンドです.
これらのコマンドは,ファイル$objdir/$soname-defが無い場合に実行さ
れ,old_archive_from_expsyms_cmdsが使用するため,エクスポートされ
たシンボル名をそのファイルに書き出します.
|
| fast_install | Variable |
libtoolが特権を与えるのを,インストール者または開発者のどちらかに決定し
ます.ビルドツリーでインストール者がプログラムを滅多に実行せず,開発者は
滅多にインストールしないしないと仮定します.これは,
shlibpath_overrides_runpathがyesでないプラットフォーム上で
のみ意味があるので,この場合,fast_installはneedless設定さ
れます.fast_installがyesに設定される場合,libtoolはインス
トールされたライブラリを検索するプログラムを作成し,プログラムがビルドツ
リーで実行される場合,まだインストールされていないライブラリを使用するた
め,要求があれば,新しいコピーがリンクされます.noに設定されてい
る場合,libtoolは,まだインストールされていないライブラリを使用するプロ
グラムを作成し,インストール時にプログラムの新しいコピーをリンクします.
デフォルト値はyesまたはneedlessで,それは,プラットフォー
ムとコンフィグレーションフラグに依存し,コンフィグレーションフラグ
--disable-fast-installを用いると,yesからnoに切り替
えられます.
|
| finish_cmds | Variable |
| 指定されたディレクトリで共有ライブラリを見つける方法を,ダイナミックリン カに伝えるコマンドです. |
| finish_eval | Variable |
| コマンドが表示されない以外,finish_cmdsと同じです. |
| fix_srcfile_path | Variable |
| コンパイラに対するシェル変数$srcfileを修正する表現です. |
| global_symbol_pipe | Variable |
NMの出力を受け,Cの名前が続く生のシンボルのリストを生成するパイプ
ラインです.例えば,以下のようになります.
$ eval "$NM progname | $global_symbol_pipe" D symbol1 C-symbol1 T symbol2 C-symbol2 C symbol3 C-symbol3 ... $ 最初の列は,(いくつかのプラットフォーム上でコードからデータを伝えるため に使用される)シンボル形式を含みますが,その意味はシステムに依存します. |
| global_symbol_to_cdecl | Variable |
| global_symbol_pipeの出力を厳密なC宣言に変換するパイプラインです. HP/UXのような,リンカがコードとデータを区別するプラットフォームでは,デー タシンボルはそのように宣言され,コードシンボルは関数として宣言されます. 気にしないプラットフォームではすべてがデータと仮定されます. |
| hardcode_action | Variable |
immediateまたはrelinkのいずれかで,共有ライブラリパスがイ
ンストールされる前に実行形式にハードコードされるか,または,再リンクする
必要があるかに依存します.
|
| hardcode_direct | Variable |
hardcode_libdir_flag_specが指定されたとき,
(dir/libname.aのような)コマンド行でライブラリが直接し
ていされる場合,リンカがディレクトリをハードコードするかどうかに依存し,
yesまたはnoに設定します.
|
| hardcode_into_libs | Variable |
ライブラリ内の実行パスのハードコードをプラットフォームがサポートするかど
うかです.可能な場合,プログラムのリンクはより単純になりますが,ライブラ
リはインストール時に再リンクが必要です.yesまたはnoに設定
します.
|
| hardcode_libdir_flag_spec | Variable |
| 実行時に,共有ライブラリに対しダイナミックリンカがlibdirを検索する ために,バイナリにlibdir変数をハードコードするためのフラグです.空 の場合,libtoolは他のハードコーディングメカニズムの使用を試みます. |
| hardcode_libdir_separator | Variable |
| コンパイラが単一のhardcode_libdir_flagのみ受け入れる場合,この変数 はそのフラグに対する複数の引数を分ける文字列を含みます. |
| hardcode_minus_L | Variable |
hardcode_libdir_flag_specが指定されたとき,結果として生じる実行形
式に-Lフラグで指定されるディレクトリを,リンカがハードコードする
かどうかに依存し,yesまたはnoに設定します.
|
| hardcode_shlibpath_var | Variable |
hardcode_libdir_flag_specが指定されたとき,結果として生じる実行形
式に$shlibpath_varの内容を書き込むことで,リンカがディレクトリを
ハードコードするかどうかに依存し,yesまたはnoに設定します.
$shlibpath_varで指定されたディレクトリが,リンク時ではなく実行時
に検索される場合,unsupportedに設定します.
|
| host | Variable |
| host_alias | Variable |
| 情報を目的として,libtoolがコンフィグレーションされたシステムの指定され た標準名に設定します. |
| include_expsyms | Variable |
| export_symbolsの使用時に,常にエクスポートされる必要があるシンボル のリストです. |
| libext | Variable |
| 標準的な,古いアーカイブの接尾子(通常は"a")です. |
| libname_spec | Variable |
ライブラリ名の接頭辞の書式です.Unixシステムでは,スタティックライブラリ
はlibname.aと呼ばれますが,(OS/2やMS-DOSのような)システムで
は,ライブラリはname.aのみで呼ばれることもあります.
|
| library_names_spec | Variable |
共有ライブラリ名のリストです.最初はファイル名で,残りはファイルへのシン
ボリックリンクです.リスト内の名前は,-lnameで与えられたと
きリンカが見つけるファイル名です.
|
| link_all_deplibs | Variable |
libtoolが,全ての依存するプログラムに対しプログラムをリンクする必要があ
るかどうかです.yesまたはnoに設定します.デフォルトは
unknownで,それはyesと同じです.
|
| link_static_flag | Variable |
| ダイナミックリンクを避けるために使用する(Cコンパイラに渡す)リンカフラグ です. |
| need_lib_prefix | Variable |
自動的にモジュール名に'lib'接尾子を付けるかどうかです.yesまたは
noに設定します.デフォルトで,それはunknownになり,それは
yesと同じ意味ですが,本当に確かめたわけではないことを告げています.
yesはdlopenと'lib'接頭辞がないライブラリにリンク可能なこと
を意味し,すなわち,それはhardcode_directをyesにすることを
要求します.
|
| need_version | Variable |
バージョン管理がライブラリに必要とされるかどうかで,すなわち,ダイナミッ
クリンカが,すべてのライブラリに対しバージョンの接尾子を必要とするかどう
かです.yesまたはnoに設定します.デフォルトで,それは
unknownで,それはyesと同じ意味を持ちますが,それを実際に確
かめていないことを告げています.
|
| need_locks | Variable |
同時にコンパイルするとき,衝突を避けるためにファイルをロックする必要があ
るかどうかです.yesまたはnoに設定します.
|
| no_builtin_flag | Variable |
charとして外部グローバルシンボルを宣言することと衝突する組み込み
関数を,利用不可能にするコンパイラフラグです.
|
| no_undefined_flag | Variable |
結果として生じる共有ライブラリに,未解決のシンボルがないことを宣言するた
めの,archive_cmdsで使用されるフラグです.
|
| objdir | Variable |
| 一時的なlibtoolファイルが含まれるディレクトリ名です. |
| objext | Variable |
| 標準的なオブジェクトファイルの接尾子(通常は"o")です. |
| pic_flag | Variable |
| ライブラリオブジェクトファイルを構築するための,あらゆる追加のコンパイル フラグです. |
| postinstall_cmds | Variable |
| old_postinstall_cmds | Variable |
| それぞれ,共有またはスタティックライブラリをインストールした後に実行する コマンドです. |
| postuninstall_cmds | Variable |
| old_postuninstall_cmds | Variable |
| それぞれ,共有またはスタティックライブラリをアンインストールした後に実行 するコマンドです. |
| reload_cmds | Variable |
| reload_flag | Variable |
| リロード可能なオブジェクトを作成するコマンドです. |
| runpath_var | Variable |
| 結果として生じる実行形式内にハードコードするディレクトリをリンカに伝える 環境変数です. |
| shlibpath_overrides_runpath | Variable |
環境変数でプログラムのハードコードされたライブラリ検索パスを優先可能かど
うかを示します.これがnoに設定されている場合,libtoolはビルドツリー
にプログラムのコピーを2つ作成する必要がある可能性があり,一つはインストー
ルされ,もう一つはビルドツリーのみで実行されます.これらのコピーのどちら
かが作成されるとき,fast_installの値に依存します.デフォルト値は
unknownで,それはnoと同じです.
|
| shlibpath_var | Variable |
| ダイナミックリンカに共有ライブラリを探す場所を伝える環境変数です. |
| soname_spec | Variable |
| 共有ライブラリがファイルの本当の名前と異なる場合,その中に符号化されたコー ドされた名前です. |
| striplib | Variable |
| old_striplib | Variable |
共有(striplib)やスタティック(old_striplib)のライブラリをス
トリップするコマンドです.これらの変数が空の場合,インストールモードのス
トリップフラグは,ライブラリに対し無視されます(see Install mode).
|
| sys_lib_dlsearch_path_spec | Variable |
| 実行時にライブラリの検索パスを取得する表現です.このリストに現れるディレ クトリが実行形式にハードコードされることは決してありません. |
| sys_lib_search_path_spec | Variable |
コンパイル時にライブラリの検索パスを取得する表現です.この変数は,特定の
ライブラリが共有かスタティックかをテストする必要があるとき,libtoolが使
用します.shlibpath_varでリストアップされるディレクトリは,このリ
ストに自動的に現れ,ライブラリ検索パスを拡張するためにこの変数を使用する
リンカもあるので,毎回(すなわち,コンフィグレーション時以外)libtoolは実
行します.リンカは-Lのような検索パス引数も切り替えます.
|
| thread_safe_flag_spec | Variable |
| スレッドセーフなライブラリを生成するために使用する(Cコンパイラに渡す)リ ンカフラグです. |
| version_type | Variable |
ライブラリバージョンナンバーの形式です.libtool,
freebsd-aout,freebsd-elf,irix,linux,
osf,sunos,windows,またはnoneの一つです.
|
| whole_archive_flag_spec | Variable |
| 便利なアーカイバから共有ライブラリを生成するコンパイラフラグです. |
| wl | Variable |
libtoolが直接リンカにフラグを渡すことを可能とするCコンパイラフラグです.
${wl}some-flagとして使用されます.
|
_cmdsや_evalで終わる変数は,~で分けられた,順番に
evalされるコマンドのリストを含みます.ゼロ以外の終了ステータスを
返すコマンドがある場合,libtoolは一般的にエラーメッセージとともに終了し
ます.
_specで終わる変数は,libtoolで使用される前にevalされます.
ここに,簡単にメンテナーシップを作成するために使用することが可能な,いく つかの手段があります.
--config,
--debug,または--featuresフラグを使用したかどうかを尋ねて
ください.これらのフラグは,中古の調査を信頼しなければならない代わりに,
情報を直接得る手助けとなるものです.
ltmain.inを変更するたび毎に再コンフィグレーションする代わりに,
PATHに永久的なlibtoolスクリプトを持ち続け,それは直接
ltmain.inの元となります.
以下のステップは,そのようなスクリプトを作成する方法を記述し,そこでは
/home/src/libtoolはlibtoolソースツリーを含むディレクトリ,
/home/src/libtool/libtoolはプラットフォームに対し以前にコンフィグ
レーションしたlibtooolスクリプト,そして~/binはPATHにあるディ
レクトリです.
trick$ cd ~/bin trick$ sed '/^# ltmain\.sh/q' /home/src/libtool/libtool > libtool trick$ echo '. /home/src/libtool/ltmain.in' >> libtool trick$ chmod +x libtool trick$ libtool --version ltmain.sh (GNU @PACKAGE@) @VERSION@@TIMESTAMP@ trick$
libtool --versionコマンドの最終的な出力は,ltmain.inスクリ
プトが直接使用されていることを示します.configureを再実行する必要
なく新しい変更をテストするため,すぐに,~/bin/libtoolや
/home/src/libtool/ltmain.inを編集してください.
Version 1.1, March 2000
Copyright (C) 2000 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
The purpose of this License is to make a manual, textbook, or other written document "free" in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others.
This License is a kind of "copyleft", which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software.
We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.
This License applies to any manual or other work that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. The "Document", below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as "you".
A "Modified Version" of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language.
A "Secondary Section" is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (For example, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.
The "Invariant Sections" are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License.
The "Cover Texts" are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License.
A "Transparent" copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, whose contents can be viewed and edited directly and straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup has been designed to thwart or discourage subsequent modification by readers is not Transparent. A copy that is not "Transparent" is called "Opaque".
Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML designed for human modification. Opaque formats include PostScript, PDF, proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML produced by some word processors for output purposes only.
The "Title Page" means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, "Title Page" means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text.
You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.
You may also lend copies, under the same conditions stated above, and you may publicly display copies.
If you publish printed copies of the Document numbering more than 100, and the Document's license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects.
If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.
If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a publicly-accessible computer-network location containing a complete Transparent copy of the Document, free of added material, which the general network-using public has access to download anonymously at no charge using public-standard network protocols. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.
It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.
You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:
If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles.
You may add a section entitled "Endorsements", provided it contains nothing but endorsements of your Modified Version by various parties-for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.
You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.
The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.
You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice.
The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.
In the combination, you must combine any sections entitled "History" in the various original documents, forming one section entitled "History"; likewise combine any sections entitled "Acknowledgements", and any sections entitled "Dedications". You must delete all sections entitled "Endorsements."
You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.
You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.
A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, does not as a whole count as a Modified Version of the Document, provided no compilation copyright is claimed for the compilation. Such a compilation is called an "aggregate", and this License does not apply to the other self-contained works thus compiled with the Document, on account of their being thus compiled, if they are not themselves derivative works of the Document.
If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one quarter of the entire aggregate, the Document's Cover Texts may be placed on covers that surround only the Document within the aggregate. Otherwise they must appear on covers around the whole aggregate.
Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License provided that you also include the original English version of this License. In case of a disagreement between the translation and the original English version of this License, the original English version will prevail.
You may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See http://www.gnu.org/copyleft/.
Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License "or any later version" applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation.
To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page:
Copyright (c) YEAR YOUR NAME. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. A copy of the license is included in the section entitled "GNU Free Documentation License".
If you have no Invariant Sections, write "with no Invariant Sections" instead of saying which ones are invariant. If you have no Front-Cover Texts, write "no Front-Cover Texts" instead of "Front-Cover Texts being LIST"; likewise for Back-Cover Texts.
If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.
.la files: Linking libraries
.libs subdirectory: Linking libraries
.lo files: Creating object files
AC_CONFIG_AUX_DIR: Invoking libtoolize
AC_DISABLE_FAST_INSTALL: AC_PROG_LIBTOOL
AC_DISABLE_SHARED: AC_PROG_LIBTOOL
AC_DISABLE_STATIC: AC_PROG_LIBTOOL
AC_FUNC_ALLOCA: Autoconf .o macros
AC_LIBTOOL_DLOPEN: AC_PROG_LIBTOOL
AC_LIBTOOL_WIN32_DLL: AC_PROG_LIBTOOL
AC_PROG_LIBTOOL: AC_PROG_LIBTOOL
AC_REPLACE_FUNCS: Autoconf .o macros
aclocal: AC_PROG_LIBTOOL
allow_undefined_flag: libtool script contents
always_export_symbols: libtool script contents
AM_DISABLE_SHARED: AC_PROG_LIBTOOL
AM_DISABLE_STATIC: AC_PROG_LIBTOOL
AM_PROG_LIBTOOL: AC_PROG_LIBTOOL
AR: libtool script contents
ar: Linking libraries
archive_cmds: libtool script contents
archive_expsym_cmds: libtool script contents
AS: AC_PROG_LIBTOOL
assign.test: Test descriptions
build-relink.test: Test descriptions
build_libtool_libs: libtool script contents
build_old_libs: libtool script contents
CC: libtool script contents, AC_PROG_LIBTOOL
cdemo-conf.test: Test descriptions
cdemo-exec.test: Test descriptions
cdemo-make.test: Test descriptions
cdemo-shared.test: Test descriptions
cdemo-static.test: Test descriptions
CFLAGS: AC_PROG_LIBTOOL
compiler_c_o: libtool script contents
compiler_o_lo: libtool script contents
config.guess: Distributing
config.sub: Distributing
CPPFLAGS: AC_PROG_LIBTOOL
demo-conf.test: Test descriptions
demo-exec.test: Test descriptions
demo-inst.test: Test descriptions
demo-make.test: Test descriptions
demo-nofast.test: Test descriptions
demo-nopic.test: Test descriptions
demo-pic.test: Test descriptions
demo-shared.test: Test descriptions
demo-static.test: Test descriptions
demo-unst.test: Test descriptions
depdemo-conf.test: Test descriptions
depdemo-exec.test: Test descriptions
depdemo-inst.test: Test descriptions
depdemo-make.test: Test descriptions
depdemo-nofast.test: Test descriptions
depdemo-shared.test: Test descriptions
depdemo-static.test: Test descriptions
depdemo-unst.test: Test descriptions
deplibs.test: Test descriptions
deplibs_check_method: Porting inter-library dependencies
dlclose: Using libltdl, Dlopened modules
dlerror: Using libltdl
DLLTOOL: AC_PROG_LIBTOOL
dlopen: Using libltdl, Dlopened modules
dlopen_self: libtool script contents
dlopen_self_static: libtool script contents
dlopen_support: libtool script contents
dlsym: Using libltdl, Dlopened modules
dryrun.test: Test descriptions
echo: libtool script contents
exclude_expsyms: libtool script contents
export_dynamic_flag_spec: libtool script contents
export_symbols_cmds: libtool script contents
extract_expsyms_cmds: libtool script contents
fast_install: libtool script contents
file_magic: Porting inter-library dependencies
file_magic_cmd: Porting inter-library dependencies
file_magic_test_file: Porting inter-library dependencies
finish_cmds: libtool script contents
finish_eval: libtool script contents
fix_srcfile_path: libtool script contents
global_symbol_pipe: libtool script contents
global_symbol_to_cdecl: libtool script contents
hardcode.test: Test descriptions
hardcode_action: libtool script contents
hardcode_direct: libtool script contents
hardcode_into_libs: libtool script contents
hardcode_libdir_flag_spec: libtool script contents
hardcode_libdir_separator: libtool script contents
hardcode_minus_L: libtool script contents
hardcode_shlibpath_var: libtool script contents
host: libtool script contents
host_alias: libtool script contents
include_expsyms: libtool script contents
install: Installing libraries
LD: libtool script contents, AC_PROG_LIBTOOL
LDFLAGS: AC_PROG_LIBTOOL
libext: libtool script contents
libltdl: Using libltdl
libname_spec: libtool script contents
library_names_spec: libtool script contents
LIBS: AC_PROG_LIBTOOL
libtool: Invoking libtool
libtoolize: Invoking libtoolize
link-2.test: Test descriptions
link.test: Test descriptions
link_all_deplibs: libtool script contents
link_static_flag: libtool script contents
LN_S: AC_PROG_LIBTOOL
lt_dladderror: Module loaders for libltdl
lt_dladdsearchdir: Libltdl interface
lt_dlcaller_get_data: User defined module data
lt_dlcaller_id: User defined module data
lt_dlcaller_register: User defined module data
lt_dlcaller_set_data: User defined module data
lt_dlclose: Libltdl interface
lt_dlerror: Libltdl interface
lt_dlexit: Libltdl interface
lt_dlforeach: User defined module data
lt_dlfree: Libltdl interface
lt_dlgetinfo: User defined module data
lt_dlgetsearchpath: Libltdl interface
lt_dlhandle: Libltdl interface
lt_dlhandle_next: User defined module data
lt_dlinfo: User defined module data
lt_dlinit: Libltdl interface
lt_dlisresident: Libltdl interface
lt_dlloader: Module loaders for libltdl
lt_dlloader_add: Module loaders for libltdl
lt_dlloader_data: Module loaders for libltdl
lt_dlloader_exit: Module loaders for libltdl
lt_dlloader_find: Module loaders for libltdl
lt_dlloader_name: Module loaders for libltdl
lt_dlloader_next: Module loaders for libltdl
lt_dlloader_remove: Module loaders for libltdl
lt_dlmakeresident: Libltdl interface
lt_dlmalloc: Libltdl interface
lt_dlmutex_geterror: Thread Saftey in libltdl
lt_dlmutex_lock: Thread Saftey in libltdl
lt_dlmutex_register: Thread Saftey in libltdl
lt_dlmutex_seterror: Thread Saftey in libltdl
lt_dlmutex_unlock: Thread Saftey in libltdl
lt_dlopen: Libltdl interface
lt_dlopenext: Libltdl interface
lt_dlpreload: Libltdl interface
lt_dlpreload_default: Libltdl interface
lt_dlseterror: Module loaders for libltdl
lt_dlsetsearchpath: Libltdl interface
lt_dlsym: Libltdl interface
lt_dlsymlist: Libltdl interface, Dlpreopening
lt_find_sym: Module loaders for libltdl
lt_module: Module loaders for libltdl
lt_module_close: Module loaders for libltdl
lt_module_open: Module loaders for libltdl
lt_preloaded_symbols: Dlpreopening
lt_ptr: Libltdl interface
lt_user_dlloader: Module loaders for libltdl
LTALLOCA: Autoconf .o macros
LTDL_SET_PRELOADED_SYMBOLS: Libltdl interface
LTLIBOBJS: Autoconf .o macros
LTLIBRARIES: Using Automake
ltmain.sh: Distributing
mdemo-conf.test: Test descriptions
mdemo-exec.test: Test descriptions
mdemo-inst.test: Test descriptions
mdemo-make.test: Test descriptions
mdemo-shared.test: Test descriptions
mdemo-static.test: Test descriptions
mdemo-unst.test: Test descriptions
need_lib_prefix: libtool script contents
need_locks: libtool script contents
need_version: libtool script contents
NM: libtool script contents, AC_PROG_LIBTOOL
no_builtin_flag: libtool script contents
no_undefined_flag: libtool script contents
noinst-link.test: Test descriptions
nomode.test: Test descriptions
none: Porting inter-library dependencies
objdir: libtool script contents
OBJDUMP: AC_PROG_LIBTOOL
objext: libtool script contents
old_archive_cmds: libtool script contents
old_archive_from_expsyms_cmds: libtool script contents
old_archive_from_new_cmds: libtool script contents
old_postinstall_cmds: libtool script contents
old_postuninstall_cmds: libtool script contents
old_striplib: libtool script contents
pass_all: Porting inter-library dependencies
pic_flag: libtool script contents
postinstall_cmds: libtool script contents
postuninstall_cmds: libtool script contents
quote.test: Test descriptions
RANLIB: libtool script contents, AC_PROG_LIBTOOL
ranlib: Linking libraries
reload_cmds: libtool script contents
reload_flag: libtool script contents
runpath_var: libtool script contents
sh.test: Test descriptions
shl_load: Using libltdl, Dlopened modules
shlibpath_overrides_runpath: libtool script contents
shlibpath_var: libtool script contents
soname_spec: libtool script contents
strip: Installing libraries
striplib: libtool script contents
su: Installing libraries
suffix.test: Test descriptions
sys_lib_dlsearch_path_spec: libtool script contents
sys_lib_search_path_spec: libtool script contents
test_compile: Porting inter-library dependencies
thread_safe_flag_spec: libtool script contents
unknown: Porting inter-library dependencies
version_type: libtool script contents
whole_archive_flag_spec: libtool script contents
wl: libtool script contents
libtoolの呼び出し
rpathを指定しない場合,libtoolは便利なアーカイブを構築
しますが,それは共有ライブラリではありません(see Static libraries).
しかし,インストールされていな
いlibtoolライブラリにリンクするために,-Lや-lフラグの使用
を避けたほうがいいでしょう..laファイルに対する,
../intl/libintl.laのような相対パスのみを指定してください.これは,
インストールされていない共有ライブラリに対しリンクするとき,あらゆる曖昧
さを取り除くため決定された設計です.
ライブラリを偶然 でもシンボルを切り捨てないでください,そうすると使用不可能になります.
AC_PROG_LIBTOOLは,
Makefile.inでのMakefile変数のtop_builddirの定義を要
求します.Automakeはこれを自動的に行いますが,Autoconfユーザは,構築ディ
レクトリのトップへの相対パス(例えば,../..)を設定する必要がありま
す.
訳注:原文は
ltconfigだが,多分AC_PROG_LIBTOOLだと思います.
思い切りが良くない人のためのGNU Image
Manipulation Programです.<http://www.gimp.org/>を参照してください.
我々は,__P,__BEGIN_DECLSそして
__END_DECLSの使用を推奨していました.アンダースコアで始まるシンボ
ル(とプリプロセッサマクロさえも)がコンパイラの使用で予約されているので,
悪いアドバイスでした.
HP-UXでは異なり,
shl_loadという名の関数が使用されます.
AIXで
のLIBPATHとHP-UXでのSHLIB_PATHです.
これは,モジュールをロードしているAPI
に依存します - 例えば,shl_loadとLoadLibraryです
たとえ,libltdlがインストールされていても,libltdlがCライブラ
リ以外のライブラリが提供するシンボルに依存する場合,
AC_LIBLTDL_INSTALLABLEは検出に失敗する可能性があります.この場合,
libltdlの構築とインストールは不必要です.
訳注:原文では,passing the buck(責任転嫁)とpassing the bug(バグを通過させる)をかけています
PowerPCとRS/6000チップ(powerpc-*-*,
powerpcle-*-*,そしてrs6000-*-*)に対しコンパイルされている
すべてのコードは,オペレーティングシステムやコンパイラスイートに関係なく
位置に依存しません.そのため,"標準オブジェクト"はこれらのシステムの共
有ライブラリの構築で使用され,特別なPICコンパイラフラグは要求されません.