     [file libtool-v.texi not included]

このファイルは，GNU Libtool VERSIONを説明します．

Copyright (C) 1996-2000 Free Software Foundation, Inc.

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 no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts.  A copy of the license is included in the section entitled "GNU Free Documentation License".

Shared library support for GNU
******************************

このファイルはGNU Libtoolの説明で，それは，パッケージ開発者が一般的な共有ライブラリを提供可能とするスクリプトです．このエディションはバージョン VERSIONを説明します．

libtoolを用いた問題の報告方法の情報は，see Reporting bugs.

はじめに
****

これまで，ソースコードパッケージの開発者が共有ライブラリの力を利用したい場合，パッケージを実行するそれぞれのプラットフォームに対し，カスタムサポートコードを書く必要がありました．パッケージインストーラが構築されるライブラリの種類を選択できるように，コンフィグレーションインターフェースを設計する必要もありました．

GNU Libtoolは，一つのスクリプトで，プラットフォーム特有の依存とユーザインターフェースの両方をカプセル化することで，開発者の仕事を単純にします．それぞれのホスト形式の完全な機能を一般的なインタフェースを通して利用できるようにGNU Libtoolは設計されていますが，やっかいな癖はプログラマから隠されます．

GNU Libtoolの一貫したインターフェースは再保証されます... ユーザは好みのソースコードパッケージを共有ライブラリに構築するため，曖昧なドキュメントを読む必要がありません．それらはパッケージのconfigureスクリプト(または同等品)を実行し，libtoolはいやな仕事をすべて行います．

このドキュメント全体にいくつかの例があります．すべて同じ環境を仮定しています．我々は，ライブラリlibhelloを一般的な方法で構築したいと思っています．

libhelloは，共有ライブラリ，スタティックライブラリ，または，その両方です... libtoolで移植できるホストシステムで利用可能な，あらゆるものです．

この章は，libtoolの最初の設計思想を説明します．歴史に興味がなかったり，一貫した方法で拡張されているlibtoolに対しコードを書きたい場合，つぎの章へ自由に行ってください．

libtoolを書いた動機
=============

1995年初頭から，数人の異なるGNU開発者は，パッケージに対する共有ライブラリのサポートの重要性を認識していました．そのように変更した主な動機は， GNUプログラムでのコードのモジュール化と再利用を(概念的，物理的の両方で) 促進するためです．

そのような要求は，GNUパッケージにライブラリを組み込む方法で，パッケージインストーラが必要とするあらゆるライブラリ形式が可能な，一般的な方法が必要だということを意味します．異なるプラットフォームで共有ライブラリを作成する標準手続きが無いことが問題です．

以下のセクションで，GNUでの共有ライブラリのサポートが直面している重大な問題と，共有ライブラリのサポートをlibtoolで標準化した方法を概説します．

以下の仕様書が，このシステムの開発評価で使用されました．

 1. システムはできる限り簡潔である必要があります．

 2. システムはGNU管理者がより簡単に使用できるよう，GNU AutoconfとAutomakeユーティリティと完全に統合する必要があります．しかし，GNUパッケージ以外でも使用できるように，これらのツールを要求してはなりません．

 3. 他の(GNUでない)アーキテクチャとツールへの移植が望まれます．

問題の実装
=====

以下の問題は，再利用可能なあらゆる共有ライブラリシステム，特にlibtoolで扱う必要があります．

 1. パッケージのインストーラは，構築されるライブラリの種類を制御可能であるべきです．

 2. インストールされていないライブラリと動的にリンクされるプログラムの実行を巧妙に行うはずです．LD_LIBRARY_PATHが(サポートしている場合は)正しく設定されている必要があり，そうでなければプログラムの実行に失敗するでしょう．

 3. システムは，共有ライブラリをサポートしていないホストでさえ，堅実に処理する必要があります．

 4. 共有ライブラリを構築するとき必要なコマンドは，ホスト毎に大きく異なる可能性があります．これらは，コンフィグレーション時に一定の方法で決定する必要があります．

 5. インストールされる共有ライブラリの接尾子が常に明白なわけではありません．通常，ファイル名は，ホスト毎に同じだということを仮定されるので， Makefile規則が難しくなります．

 6. 共有ライブラリをその場でアップグレード可能なように，システムは，単純なライブラリバージョンナンバーの抽象化が必要です．バイナリ互換を最大にするため，ライブラリへのインターフェースの設計方法は，プログラマに伝えられるべきです．

 7. インストールするMakefileターゲットは，パッケージインストーラに特定の環境変数(LD_LIBRARY_PATHまたは同等のもの)を設定したり， ldconfigを実行するよう，警告する必要があります．

その他の実装
======

libtoolが開発されるまで，多くのフリーソフトウエアパッケージは，独自の共有ライブラリを構築し，インストールしていました．最初は，既存の機能の再発明を避けるために，これらのパッケージは調査されました．

さて，これらのパッケージに，libtoolが要求する，共有ライブラリシステムの詳細な文章が無いのは明らかです．そのため，他のパッケージは，影響のため多少捨てられました．

その他の実装の近代的な解析
=============

調査されたそれぞれの実装は，多くの異なるホストシステムに対して，予定していた仕事をすべて公平に行いました．しかし，一般的に再利用できる要素として機能するものは，これらの解決法にはなさそうです．

ほとんどのものは，実装が行っていることを正確に理解すること無く使用する (まして，変更する)には複雑すぎ，それらは通常，文章化されていませんでした．

主な困難さは，異なるベンダーはライブラリについて異なる見解を持つこと，そして，調査したパッケージには，当然動作するという，単一の規範を自信を持って定めているものが無かったことです．

理想としては，拡張シリーズと既存のライブラリシステムが絶えず動作するような編集を実装する標準に，libtoolがなることです．しかし，オペレーティングシステム開発者の悪い方法を修正することは簡単な仕事ではなく，人々は，バグが多く，壊れていて，混乱したオペレーティングシステム上でさえ，今すぐに共有ライブラリを構築したいと思っていました．

このため，libtoolは独立したシェルスクリプトとして設計されました．それは，異なるプラットフォーム上のコンパイラスイートを，堅実で強力なインターフェースを用いて包み込むことで，Makefileの書き手を悩ませるライブラリ構築での問題と矛盾から隔離しています．

運が良ければ，libtoolは役に立ちGNUコミュニティで使用され，そして，それを書くとき学んだ教訓は，将来のライブラリシステムの設計に採用されるでしょう．

libtoolのパラダイム
*************

最初は，ライブラリのオブジェクト形式の任意の数をサポートするように libtool は設計されました．その後，libtoolはより多くのプラットフォームに移植され，新しいパラダイムは，ライブラリとプログラムの間の関係を記述するため，徐々に開発されました．

要約すると，``ライブラリは複数のエントリポイントと，より正式に定義されたインターフェースがあるプログラムです．''

libtoolのバージョン0.7は，この新しいパラダイムを反映するため，完全に再設計され書き換えられました．今のところ成功しているようです．libtoolは，以前よりより単純になり，より役に立ちます．

libtoolパラダイムを導入する最善の方法は，それぞれの例を用い，既存のライブラリシステムのパラダイムと比較することです．それは新しい考え方なので吸収するまで少し時間がかかるかもしれませんが，理解したとき世界がより単純化されるでしょう．

libtoolの使用
**********

libtoolが人生をより単純にする方法が分かるまで，独自のパッケージでlibtool を使用することを話す意味がありません．この章の例は，標準的なライブラリの構築処理と，libtoolの処理を，2つの異なるプラットフォームで比較することで，主な特徴を紹介します．

a23
     スタティックライブラリのみのUltrix 4.2プラットフォーム．

burger
     共有ライブラリを持つ，NetBSD/i386 1.2プラットフォーム．

独自のプラットフォームの例をこれに続けることができ，それは，libtoolでインストールされた，前もってコンフィグレーションされたlibtoolスクリプトを用います(see Configuring)．

以下の例のソースファイルは，libtool配布物のdemoサブディレクトリから持ってきました．ファイルfoo.cとhello.cからライブラリ libhelloを構築していると考えてください．

foo.cソースファイルがcos数学ライブラリ関数を使用していて，それは通常，Cライブラリではなく単独の数学ライブラリで見つかることに注意してください(see Trigonometric Functions (The GNU C Library Reference Manual))．そのため，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がそれぞれの呼び出しに対し，２つのファイルを作成することに注意してください．.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$

２番目に実行される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) (rpathを指定しない場合，libtoolは便利なアーカイブを構築しますが，それは共有ライブラリではありません(see Static libraries)．) を指定する必要があることです．

     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の方法はほとんど同じです (しかし，インストールされていないlibtoolライブラリにリンクするために，-Lや-lフラグの使用を避けたほうがいいでしょう．.laファイルに対する， ../intl/libintl.laのような相対パスのみを指定してください．これは，インストールされていない共有ライブラリに対しリンクするとき，あらゆる曖昧さを取り除くため決定された設計です．)(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が無いシステムでライブラリをインストールすることは，全く簡単です ... それらをその場所にコピーするだけです． (ライブラリを偶然でもシンボルを切り捨てないでください，そうすると使用不可能になります．)

     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
     libtoolのコンフィグレーション変数を表示し終了します．

--debug
     シェルスクリプトの実行の追跡を標準出力にダンプします．これは多くの出力を生成するので，less(やmore)にパイプしたり，ファイルにリダイレクトしたいかもしれません．

-n
--dry-run
     あらゆるファイルを作成，編集，削除せず，libtoolによりコマンドで実行されるものを表示するだけです．

--features
     基本的なコンフィグレーションオプションを表示します．これは，パッケージが構築するライブラリを，スタティックまたは共有のいずれにするか決定する方法を提供します．

--finish
     --mode=finishと同じです．

--help
     へルプメッセージを表示し終了します．--mode=MODEが指定された場合，MODEの詳細へルプを表示します．

--mode=MODE
     処理モードとしてMODEを使用します．デフォルトで，処理モードは MODE-ARGSから推測されます．

     MODEが指定された場合，それは以下の一つにする必要があります．

     compile
          ソースファイルをlibtoolオブジェクトにコンパイルします．

     execute
          インストールされていない，libtoolが生成したプログラムやライブラリを他のプログラムが使用できるように，自動的にライブラリパスを設定します．

     finish
          libtoolライブラリのシステムへのインストールを完全に行います．

     install
          ライブラリや実行形式をインストールします．

     link
          ライブラリや実行形式を作成します．

     uninstall
          インストールされたライブラリや実行形式を削除します．

     clean
          アンインストールされたライブラリや実行形式を削除します．

--version
     libtoolのバージョン情報を出力し終了します．

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
     OUTPUT-FILEがプログラムの場合，共有ライブラリと全くリンクしません． OUTPUT-FILEがライブラリの場合，スタティックライブラリのみ作成します．

-avoid-version
     ライブラリとモジュールに対しバージョン管理(see Versioning)を避けようとし，すなわち，バージョン情報は保存されず，シンボリックリンクも作成されません．プラットフォームがバージョニングを要求する場合，このオプションは効果がありません．

-dlopen FILE
     ネイティブなdlopenがホストプラットフォームでサポートされていない場合 (see Dlopened modules)や，プログラムが-staticや -all-staticでリンクされている場合，-dlpreopen FILEと同じです．それ以外では効果はありません．FILEがselfの場合， -export-dynamicを可能にする，または，-dlpreopen selfに後退することにより，libtoolはプログラムがそれ自身をdlopen可能であることを確かめます．

-dlpreopen FILE
     FILEを出力プログラムにリンクし，そのシンボルを LT_PRELOADED_SYMBOLSに含めます(see Dlpreopening)．FILEが selfの場合，プログラムのシンボル自身がLT_PRELOADED_SYMBOLS に加えられます．FILEがforceの場合，libtoolは， LT_PRELOADED_SYMBOLSが空であろうがなかろうが，常に定義済であることを確実にします．

-export-dynamic
     OUTPUT-FILEからのシンボルがdlsymで解決されることを許可します(see Dlopened modules)．

-export-symbols SYMFILE
     リンカにSYMFILEでリストアップされているシンボルのみエクスポートするよう伝えます．シンボルファイルは.symで終わるべきで，一行毎に一シンボル名を含める必要があります．このオプションは効果がないプラットフォームがあります．デフォルトですべてのシンボルがエクスポートされます．

-export-symbols-regex REGEX
     正規表現REGEXに一致するシンボルのみエクスポートされる以外， -export-symbolsと同じです．デフォルトですべてのシンボルがエクスポートされます．

-LLIBDIR
     既にインストールされている，要求されるライブラリに対し，LIBDIRを検索します．

-lNAME
     OUTPUT-FILEはインストールされているライブラリlibNAME を要求します．このオプションはOUTPUT-FILEが実行形式でないときも要求されます．

-module
     dlopen可能なライブラリを作成します(see Dlopened modules)．このオプションはプログラムでは動作しません．モジュール名の'lib'の前置は不要です．しかし，名前の破壊を避けるため，'libname'と'name' パッケージで同時に使用してはなりません．

-no-fast-install
     実行形式OUTPUT-FILEの高速インストールモードを利用不可にします．プログラムをインストールする必要がないとき役に立ちます．

-no-install
     インストール不可能で，そのためラップスクリプトが不要な実行形式 OUTPUT-FILEをリンクします．プログラムがビルドツリーでのみ使用される場合，例えば，テストしたり他のファイルを生成するプログラムに対して役に立ちます．

-no-undefined
     OUTPUT-FILEが他のライブラリに依存しないことを宣言します．他のライブラリに依存する共有ライブラリを作成不可能なプラットフォームもあります (see Inter-library dependencies)．

-o OUTPUT-FILE
     指定されたオブジェクトとライブラリからOUTPUT-FILEを作成します．

-release RELEASE
     ユーザが他より新しいバージョンを簡単に伝えられるよう，パッケージのリリースRELEASEで生成されたライブラリを指定します．このフラグを使用する場合，パッケージの２つのリリースがバイナリ互換でないことを警告されます．バイナリ互換が欲しい場合，代わりに-version-infoフラグを使用してください(see Versioning)．

-rpath LIBDIR
     OUTPUT-FILEがライブラリの場合，それは最終的にLIBDIRにインストールされます．OUTPUT-FILEがプログラムの場合，プログラムの実行時のパスをLIBDIRに加えます．

-R LIBDIR
     OUTPUT-FILEがプログラムの場合，プログラムの実行時のパスを LIBDIRに加えます．OUTPUT-FILEがライブラリの場合，ライブラリがプログラムとリンクされるときは，常にLIBDIRが実行時のパスに加えられるように，そのDEPENDENCY_LIBSに-RLIBDIRを加えます．

-static
     OUTPUT-FILEがプログラムの場合，インストールされていない共有ライブラリとリンクしません．OUTPUT-FILEがライブラリの場合，スタティックライブラリのみ作成します．

-version-info CURRENT[:REVISION[:AGE]]
     OUTPUT-FILEがlibtoolライブラリの場合，それを構築するために，バージョン情報CURRENT，REVISION，そしてAGEを使用します (see Versioning)．このフラグをパッケージのリリース情報の指定に使用せず，そのためには-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
     ライブラリパスに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の統合
****************

この章は，ユーザが混乱せずに共有ライブラリをインストールできるように，パッケージとlibtoolの統合方法を記述します．

libtoolに対するMakefile規則を書く
========================

libtoolは，完全にAutomake(see Introduction (The Automake Manual))と統合されていて，それはAutomake version 1.2から開始しました．

通常のMakefile(やMakefile.in)で，libtoolを使用したい場合，独自のものとなります．Automake 1.2を使用せず，パッケージにlibtoolの組み込み方を知らない場合，以下の一つが必要です．

 1. Automake(バージョン1.2以降)を近くのGNUのミラーからダウンロードし，インストールし，その使用を開始してください．

 2. Makefile規則の手での書き方を学んでください．複雑なときもありますが，古いライブラリをコンパイルするための規則を書けるぐらいの知識がある場合，libtoolライブラリに対する新しい規則の理解は可能でしょう(ヒント： libtool 配布物のdemoサブディレクトリのMakefile.inを調べてください... 特に，それがAutomakeによってMakefile.amから自動的に生成されたことに注意してください)．

libtoolと共にAutomakeを使用する
=======================

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_LDFLAGSに加え，PROGRAM_DEPENDENCIESにライブラリをリストアップし，それらが属するこれらのフラグを受け入れるGNU automakeのリリースを待ってください．

  * フラグの回りを引用符で囲みますが，PROGRAM_DEPENDENCIESも設定する必要があります．

          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 The Automake Manual.

libtoolのコンフィグレーション
==================

libtoolは，共有ライブラリを作成し適切なものにリンクするため，コンパイラセットとオペレーティングシステムの詳細な知識を必要とします．libtool配布物をインストールするとき，システム特有のlibtoolスクリプトはバイナリディレクトリにインストールされます．

しかし，独自のパッケージとともにlibtoolを配布するとき (see Distributing)，パッケージをコンパイルするために使用されるコンパイラセットとオペレーティングシステムを，常に知っているわけではありません．

このため，libtoolを使用する前にコンフィグレーションする必要があります．この考えは，GNU configureスクリプトを使用するものに似ています．configureは，システムの特徴に対しいくつものテストを行い， Makefiles(と，おそらくconfig.hヘッダファイル)を生成し，その後，makeを実行しパケージを構築することができます．

libtoolは，インストーラのホストマシンに対するlibtoolスクリプトを生成するために，独自のテストをconfigureスクリプトに加えます．

AC_PROG_LIBTOOLマクロ
------------------

GNU Autoconf(やAutomake)を使用している場合，AC_PROG_LIBTOOLの呼び出しをconfigure.inに加える必要があります．このマクロは，生成されたlibtoolスクリプトがホストの特徴を理解できるようにするため，多くの新しいテストをconfigureスクリプトに加えます．

 -- Macro: AC_PROG_LIBTOOL
 -- Macro: AM_PROG_LIBTOOL
     --enable-sharedと--disable-sharedのconfigureフラグに対するサポートを加えます． (AC_PROG_LIBTOOLは， Makefile.inでのMakefile変数のtop_builddirの定義を要求します．Automakeはこれを自動的に行いますが，Autoconfユーザは，構築ディレクトリのトップへの相対パス(例えば，../..)を設定する必要があります．) AM_PROG_LIBTOOLは，このマクロに対する古い名前で，しばらくはサポートされますが，やめた方がいいです．

     デフォルトで，このマクロは，利用可能な場合は共有ライブラリを開始し，共有ライブラリと衝突しない場合はスタティックライブラリも可能とします．これらのデフォルトは，AC_DISABLE_SHAREDやAC_DISABLE_STATICマクロのどちらかで修正可能です．

          # Turn off shared libraries during beta-testing, since they
          # make the build process take too long.
          AC_DISABLE_SHARED
          AC_PROG_LIBTOOL

     ユーザは，パッケージ名を元に構築される，共有またはスタティックライブラリを選択するため，--enable-sharedと--enable-staticコンフィグレーションフラグで指定を修正できます．例えば，共有するbfdと gdbライブラリを構築し，libg++を共有にしないため，以下の configureスクリプトの実行で，３つすべて可能となります．

          trick$ ./configure --enable-shared=bfd,gdb

     一般的に，--enable-shared=PKGSの指定は，カンマで分けられた PKGSリストに名前があるすべてのパッケージを--enable-sharedで，それ以外のすべてのパッケージを--disable-sharedでコンフィグレーションすること同じです．--enable-static=PKGSフラグは，同様に動作しますが，その場合は--enable-staticと--disable-staticを使用します．同様に，--enable-fast-install=PKGSフラグは適用され，それは，--enable-fast-installと --disable-fast-installを使用します．

     パッケージ名defaultは，PACKAGE環境変数に名前が設定されていない，あらゆるパッケージに一致します．

     このマクロは，シェル変数LIBTOOL_DEPSも設定し，それで，libtoolスクリプトが時代遅れになった場合の自動的な更新に使用できるようになります．そうするためにconfigure.inに以下を加えてください．

          AC_PROG_LIBTOOL
          AC_SUBST(LIBTOOL_DEPS)

     そして，Makefile.inやMakefile.amに，以下を加えてください．

          LIBTOOL_DEPS = @LIBTOOL_DEPS@
          libtool: $(LIBTOOL_DEPS)
                  $(SHELL) ./config.status --recheck

     GNU automakeを使用してる場合，automakeが面倒をみるので，指示の省略が可能です．libtoolでの依存性を明確に作成する必要があります．

 -- Macro: AC_LIBTOOL_DLOPEN
     dlopenサポートの調査を可能にします．パッケージで-dlopenと -dlpreopenフラグを使用する場合，このマクロ使用すべきで，そうしない場合，libtoolはシステムがdlopenをサポートしていないと仮定します．マクロはAC_PROG_LIBTOOLの前で呼び出す必要があります．

 -- Macro: AC_LIBTOOL_WIN32_DLL
     このマクロは，win32プラットフォームでクリーンなdllを構築するために移植する場合，使用する必要があります．通常，これは，あらゆるライブラリデータ項目を__declspec(dllexport)でエクスポートし， __declspec(dllimport)でインポートすることを意味します．このマクロが使用されていない場合，libtoolはパッケージライブラリがクリーンなdllではなく，win32ホストでのスタティックライブラリのみを構築すると仮定します．

     このマクロはAC_PROG_LIBTOOLの前で呼び出す必要があり，パッケージのMakefileでのリンクモードでの準備として，libtoolに -no-undefinedを渡させる必要があります．通常，-no-undefined を渡す場合，すべてのライブラリシンボルが，リンク時には本当に定義されていることを確かめる必要があります！

 -- Macro: AC_DISABLE_FAST_INSTALL
     AC_PROG_LIBTOOLのデフォルトの動作を，高速インストールに対する最適化を不可能にするよう変更します．ユーザはこのデフォルトを，プラットフォームのサポートに依存して，--enable-fast-installを指定することで優先させることができます．

 -- Macro: AC_DISABLE_SHARED
 -- Macro: AM_DISABLE_SHARED
     AC_PROG_LIBTOOLのデフォルトの動作を，共有ライブラリを利用不可能に変更します．ユーザはこのデフォルトを，--enable-sharedを指定することで優先させることができます．

 -- Macro: AC_DISABLE_STATIC
 -- Macro: AM_DISABLE_STATIC
     AC_PROG_LIBTOOLのデフォルトの動作を，スタティックライブラリを利用不可能に変更します．ユーザはこのデフォルトを，--enable-staticを指定することで優先させることができます．

AC_PROG_LIBTOOL内のテストは，以下の環境変数も認識します．

 -- Variable: CC
     生成されたlibtoolが使用するCコンパイラ．これが設定されていない場合，AC_PROG_LIBTOOLはgccやccを探します．

 -- Variable: CFLAGS
     標準的なオブジェクトファイルを生成するために使用するコンパイラフラグ．これが設定されていない場合，AC_PROG_LIBTOOLはそのようなフラグを全く使用しません．それは，AC_PROG_LIBTOOLがテストを実行する方法にのみ効果があり，生成されたlibtoolには効果はありません．

 -- Variable: CPPFLAGS
     Cプリプロセッサフラグ．これが設定されていない場合， AC_PROG_LIBTOOLはそのようなフラグを全く使用しません．それは， AC_PROG_LIBTOOLがテストを実行する方法にのみ効果があり，生成された libtoolには効果はありません．

 -- Variable: LD
     (生成されたlibtoolが要求する場合は)システムリンカ．これが設定されていない場合，AC_PROG_LIBTOOLは，CCで使用されるリンカが何かを判別しようとします．

 -- Variable: LDFLAGS
     プログラムをリンクするときAC_PROG_LIBTOOL (訳注：原文は ltconfigだが，多分AC_PROG_LIBTOOLだと思います．)が使用するフラグ．これが設定されていない場合，AC_PROG_LIBTOOLはそのようなフラグを全く使用しません．それは，AC_PROG_LIBTOOLがテストを実行する方法にのみ効果があり，生成されたlibtoolには効果はありません．

 -- Variable: LIBS
     プログラムのリンク時にAC_PROG_LIBTOOLが使用するライブラリです．これが設定されていない場合，AC_PROG_LIBTOOLはそのようなフラグを使用しません．それはltconfigの実行テストにのみに効果があり，生成されたlibtoolには効果はありません．

 -- Variable: NM
     使用するプログラムで，nmの調査ではありません．

 -- Variable: RANLIB
     使用するプログラムで，ranlibの調査ではありません．

 -- Variable: LN_S
     プログラムのリンクを作成するコマンドで，可能な場合はソフトリンク，それ以外ではハードリンクです．この変数が設定されていない場合， AC_PROG_LIBTOOLは適切なプログラムを調査します．

 -- Variable: DLLTOOL
     使用するプログラムで，dlltoolの調査ではありません． Cygwin/MS-Windowsでのみ意味があります．

 -- Variable: OBJDUMP
     使用するプログラムで，objdumpの調査ではありません． Cygwin/MS-Windowsでのみ意味があります．

 -- Variable: AS
     使用するプログラムで，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を含める
=================

libtoolを使用するため，パッケージに以下のファイルを含める必要があります．

config.guess
     標準的なシステム名の判別を試みます．

config.sub
     標準的なシステム名の評価のサブルーチンスクリプトです．

ltmain.sh
     基本的なlibtool機能を実装する一般的なスクリプトです．

libtoolスクリプト自身はパッケージに含まないことに注意してください． See Configuring.

手動でこれらのファイルをパッケージにコピーするより，libtoolizeプログラムを使用した方がよいでしょう．

libtoolizeの呼び出し
---------------

libtoolizeプログラムは，libtoolサポートをパッケージに追加する標準的な方法を提供します．将来は，より良い調査の使用法や，より簡単にlibtool を作成する特徴を実装するかもしれません．

libtoolizeプログラムは以下の構文です．

     libtoolize [OPTION]...

そして，以下のオプションを受け入れます．

--automake
     静かに動作し，libtoolがサポートされているAutomakeを仮定します．

     libtoolize --automakeは，AC_PROG_LIBTOOLが configure.inにあるとき，Automakeがlibtoolファイルをパッケージに追加するために使用します．

--copy
-c
     libtoolデータディレクトリから，シンボリックリンクを作成するのではなく，ファイルをコピーします．

--debug
     シェルスクリプトの実行の追跡を，標準出力にダンプします．これは大量の出力を生成するため，less(やmore)にパイプしたり，ファイルにリダイレクトしたいかもしれません．

--dry-run
-n
     ファイルシステムを変更するコマンドは実行せず，それらを出力するだけです．

--force
-f
     既存のlibtoolファイルを置換します．デフォルトで，libtoolizeは既存のファイルを上書きしません．

--help
     へルプメッセージを出力し終了します．

--ltdl
     パッケージのサブディレクトリに，libltdlをインストールします．

--ltdl-tar
     ファイルlibltdl.tar.gzをパッケージに追加します．

--version
     libtoolizeのバージョン情報を出力し終了します．

libtoolizeが，パッケージのconfigure.inで，明確な AC_CONFIG_AUX_DIRの呼び出しを検出した場合(see The Autoconf Manual)，指定されたディレクトリにファイルを配置します．

libtoolizeは，パッケージにlibtoolサポートを加えるヒントも同様に表示します．

Autoconfの.oマクロ
--------------

Autoconfパッケージは，テストを実行するいくつかのマクロをもたらし，それは，オブジェクトファイル名に対応して変数を設定します．libtoolオブジェクトに対応する名前を使用する必要があるときもあります．

ここにlibtoolオブジェクトがリストアップする変数名があります．

 -- Variable: LTALLOCA
     AC_FUNC_ALLOCAで置換されます(see The Autoconf Manual)．空，またはalloca.loを含みます．

 -- Variable: LTLIBOBJS
     AC_REPLACE_FUNCSとその他の関数で置換されます(see The Autoconf Manual)．

残念ながら，安定版のリリースの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が共有ライブラリを構築することを避け，それには，いくつかの利点があります．

  * 2回目のコンパイルを速くし，開発サイクルを高速にします．

  * 共有ライブラリによって加えられる複雑さの詳細が不要なので，デバッグがより簡単になります．

  * スタティックのみのプラットフォームでのlibtoolの動作方法が分かります．

パッケージのREADMEに，他の開発者に--disable-sharedで時間を稼げることを知らせるため，ちょっとした注意を書きたいかもしれません．以下の例の注意は，GIMP (思い切りが良くない人のためのGNU Image Manipulation Programです．http://www.gimp.org/を参照してください．) 配布物の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-shared option to configure.

ライブラリインターフェースのバージョン
*******************

共有ライブラリで導入された発行物で，最も難しいものは，実行時の依存の作成と解決です．プログラムとライブラリの依存は，sedのような単一の名前の用語で，よく記述されます．そのため``libtoolはsedに依存する''と告げ，それで十分目的を果たせます．

しかし，規則的にインターフェースが変更されるとき，我々はより具体的に告げる必要があります．``Gnus 5.1はEmacs 19.28以上を要求する．''ここでは，名前からなるインターフェースの記述と``バージョンナンバー''です．

種類の説明はいくつかの目的において十分でないことすらあります．Emacs 20で変更された場合，Gnus 5.1を破壊するのに十分ではないでしょうか？

同じ問題は，共有ライブラリでも存在します．我々は，プログラムが必要としているインターフェースを提供するライブラリのみとリンクされることを，ダイナミックリンカが保証できるように，プログラムが依存する共有ライブラリを記述するために，通常のバージョン管理システムが必要です．

ライブラリインターフェースとは？
================

ライブラリのインターフェースは，以下の何か(またはそれ以上)でしょう．

  * グローバル変数:名前と型

  * グローバル関数:引数の型と数，戻り値の型，関数名

  * 標準入力，標準出力，標準エラー，ファイル形式

  * ソケット，パイプ，プロセス間通信のプロトコル書式

静的な関数は，ライブラリのユーザが直接利用不可能なので，インターフェースに数えられないことに注意してください．

libtoolのバージョン管理システム
===================

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ライブラリバージョンは，３つの整数で宣言されます．

current
     このライブラリで実装されている，最も新しいインターフェース番号．

revision
     CURRENTのインターフェースの実装番号．

age
     このライブラリで実装されている，最新と最古のインターフェースの違い．言い換えると，ライブラリは，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インターフェース番号以下にする必要があることに注意してください．

ここに，ライブラリバージョン情報を更新する助けとなる規則の集合があります．

 1. バージョン情報は，それぞれのlibtoolライブラリに対し0:0:0で始めてください．

 2. ソフトウェアの一般へのリリースの直前にのみ，バージョン情報を更新してください．より頻繁な更新は不要で，現在のインターフェース番号が速くなることを保証するだけです．

 3. 前回の更新から，ライブラりソースコードが完全に変更された場合， REVISIONを増加してください(C:R:Aは C:r+1:Aとなります)．

 4. 前回の更新から，インターフェースが加えられた，削除された，または変更された場合，CURRENTを増加し，REVISIONを0に設定してください．

 5. 前回の一般へのリリースから，あるインターフェースが加えられた場合， AGEを増加してください．

 6. 前回の一般へのリリースから，あるインターフェースが削除された場合， AGEを0に設定してください．

パッケージのリリース番号に対応するように，インターフェース番号を設定する試みは決してしないでください．これは，ライブラリバージョンの目的の誤解を促進する悪習にすぎません．その代わり，-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を使用してください．

インターフェース設計に対する助言
****************

良いライブラリインターフェースと書くことは，多くの経験とライブラリが解決する問題への完全な理解が必要です．

良いインターフェースを設計した場合，頻繁に変更する必要がなく，ドキュメントを更新し続ける必要がなく，ユーザはライブラリの使用方法を何度も学習する必要がありません．

ここにライブラリインターフェースの設計に関するヒントの短いリストがあり，それは仕事上で役立つでしょう．

計画前
     エントリポイントを頻繁に削除する必要がないように，すべてのインターフェースを本当に最小限にするように試みてください．

インターフェースの変更を避ける
     エントリポイントの再設計と変更を地獄のように繰り返すのが好きな人もいます (注意：関数の名前変更はエントリポイントの変更と考えられます)．インターフェースを再設計する必要がある場合，ユーザが既存のコードを書き換える必要がないように，互換機能を残すことを試みてください．

不透明なデータ型の使用
     ライブラリユーザがアクセスするデータ型の定義は，少ないければ少ないほど良いでしょう．可能な場合，一般的な(内部データにキャスト可能な)ポインタを受け入れる関数を設計し，ライブラリユーザが直接データを操作するのを許可するのではなく，アクセスする関数を提供してください．そうすることで，インターフェースを変更せずに，データ構造を変更することが自由になります．

     これは，本質的にオブジェクト指向のシステムで抽象的なデータ型と継承を使用するのと同じです．

ヘッダファイルの使用
     ライブラリのグローバル関数と変数のそれぞれのドキュメントをヘッダファイルに注意して書いていて，ライブラリソースファイルに含めている場合，コンパイラは偶然にインターフェースの変更の有無を知らせるでしょう(see C header files)．

可能な場所でのstaticキーワード(または等価物)の使用
     ライブラリが持つグローバル関数は，減らせば減らすほど，より柔軟に変更できます．スタティック関数と変数は，形式を変更したいとき変更できます... ユーザはそれらにアクセスできず，そのためインターフェースは変更されません．

Cヘッダファイルを書く
===========

移植性の高いCヘッダファイルを書くことは難しく，それは異なる形式のコンパイラで読まれる可能性があるためです．

C++コンパイラ
     C++コンパイラは，Cより強固に形式化されているため，完全なプロトタイプで宣言された関数を要求します．C関数と変数は，名前がおかしくならないように， extern "C"ディレクティブで宣言する必要があります．libtoolでC++の使用に関連したその他の問題は，see C++ libraries.

ANSI Cコンパイラ
     ANSI Cコンパイラは，C++コンパイラほど厳密ではありませんが，関数のプロトタイプは，ヘッダファイルを#includeしたときの不必要な警告を避けるため，行う方が良いでしょう．

非ANSI Cコンパイラ
     Non-ANSIコンパイラは，関数がプロトタイプされている場合，エラーを報告します．

これらの複雑さは，上記それぞれのコンパイラを利用可能にするため，ライブラリインファーフェースヘッダで，いくつかの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のコンパイラ (我々は，__P，__BEGIN_DECLSそして __END_DECLSの使用を推奨していました．アンダースコアで始まるシンボル(とプリプロセッサマクロさえも)がコンパイラの使用で予約されているので，悪いアドバイスでした．)で有効なヘッダファイルを作成するために，それらを使用することが可能となります．

移植可能なコードをネイティブに書かないでください，上記のヒントに続けることで，最も明白な問題を無くすことに役立ちますが，明らかに別の微妙な問題があります．以下の問題に対処する必要があるかもしれません．

  * Pre-ANSIコンパイラは，一般的なポインタ型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がサポートするすべてのプラットフォームに移植されませんでした．デフォルトで，保守的な動作は，ライブラリが他のライブラリとリンクすることを避け，プログラムがリンクされるときのみに，その内部依存性が導入されます．

dlopenモジュール
***********

ダイナミックリンクの議論では，用語が２つの異なる概念の言及で使用されるので，混乱することがあります．

 1. 共有ライブラリに対しプログラムをコンパイルとリンクし，それは，ダイナミックリンカにより実行時に自動的に解決される．この処理では，ダイナミックリンクはアプリケーション透過です．

 2. アプリケーションの，dlopen (HP-UXでは異なり， shl_loadという名の関数が使用されます．)のような関数の呼び出しで，それは，ユーザが指定したモジュールを実行時に任意にロードします．この形式のダイナミックリンクは，アプリケーションで明示的に制御されます．

混乱を軽減するため，このマニュアルは２番目の形式のダイナミックリンクを dlopenモジュールとして言及します．

dlopenモジュールの主な利点は，プログラムを拡張するために，インタプリタ言語を使用するのではなく，コンパイルされたオブジェクトコードにアクセスする能力です．実際，dlopenは，言語を拡張する効果的な方法を提供するため，インタプリタ言語でよく使用されます．

バージョンVERSIONの現在は，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$

dlopen
======

libtoolは，dlopenするlibtoolオブジェクトとlibtoolライブラリファイルに対し，たとえdlopenとdlsym関数が無いプラットフォームでも，そのシンボルが解決できるように，特別のサポートを提供します．

``laziness''の増加順にプログラムにコードをロードする，以下の別の方法を考慮します．

 1. 参照するしないに関わらない，実行形式の一部となるオブジェクトファイルへのリンクです．オブジェクトファイルが見つからない場合，リンカは実行形式の作成を停止します．

 2. 上記のオブジェクトファイルでの未定義の参照を満足させるために，リンク時に検索されるようにするための，リンカに対するスタティックライブラリの宣言です．スタティックライブラリが見つからない場合，リンカは実行形式の作成を停止します．

 3. 上記のファイルでの未定義の参照を満足させるために，実行時に検索されるようにするための，実行時リンクの共有ライブラリの宣言です．共有ライブラリが見つからない場合，ダイナミックリンカは実行形式の作成を停止します．

 4. アプリケーション自身が解決することができるように，参照を動的解決する dlopenモジュールです．モジュールを開くときエラーが発生したり，モジュールが見つからない場合，アプリケーションは壊れることなく回復します．

libtoolは，コンパイル時にオブジェクトファイルをプログラムにリンクし，プログラムのシンボルテーブルを表現するデータ構造を作成することで，スタティックなプラットフォームで-dlopenオプションをエミュレートします．

この特徴を使用するため，プログラムのリンク時(see Link mode)に -dlopenや-dlpreopenフラグを使用することで，アプリケーションでdlopenしたいオブジェクトを宣言する必要があります．

 -- Structure: struct lt_dlsymlist { const char *NAME; lt_ptr ADDRESS; }
     NAME属性は，"fprintf"のような，シンボル名のNULL終端されている文字列です．ADDRESS属性は，&fprintfのような対応するオブジェクトへの一般的なポインタです．

 -- Variable: const lt_dlsymlist * lt_preloaded_symbols
     LT_SYMBOL構造体の配列で，プログラムにリンクされる，プリロードされているすべてのシンボルを表現します．それぞれの-dlpreloadedファイルに対し，ファイルのNAMEを用いた要素と，0のADDRESSがあり，このファイルからエクスポートされるすべてのシンボルが続きます．実行形式自身に対し，特別の名前@PROGRAM@が使用されます．最後の要素は， NAMEと0のADDRESSを持ちます．

ドル記号のような，ANSI Cでは有効ではない識別子を許可するコンパイラもあります．libtoolはANSI Cで有効なシンボル(最初がASCII文字またはアンダースコアで，0以上のASCII文字，数字，そしてアンダースコアが続くもの)のみ認識するので，非ASCIIシンボルはLT_PRELOADED_SYMBOLSに出現しません．

dlopenで正しい名前の検索
===============

-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_PATH (AIXでのLIBPATHとHP-UXでのSHLIB_PATHです．)環境変数でリストアップされているディレクトリで検索します．この変数(または同等物)を検索することで，インストール前でも，プログラムがlibtoolを使用してリンクし提供されているdlopenモジュールを見つけることを保証します．

未解決のdlopenの問題
=============

以下の問題は，libtoolのdlopenサポートを使用しても解決しません．

  * dlopen関数は一般に，共有ライブラリプラットフォームでのみ利用可能です．パッケージをスタティックなプラットフォームに移植したい場合，libltdl (see Using libltdl)を使用する，または，代わりとなる独自のdlopenダイナミックコードを開発する必要があります．最も妥当な解決方法は， dlopenファミリーのラッパー関数を書くことを必要とし，それは，与えられたプラットフォームでdlopenがサポートされていないまたは利用不可能なときの，パッケージ特有のトリックです．

  * 関数のdlopenファミリーの実装には大きな違いがあります．同じ関数名を用いないプラットフォーム(特にHP-UXではshl_loadファミリーを用います)さえ存在します．

  * アプリケーション開発者は，dlopenに渡す正しいモジュール名を発見するために，カスタムの検索関数を書く必要があります．

libltdlの使用
**********

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)

  * GNU DLD (スタティックライブラリに対するダイナミックリンクのエミュレーション)

  * libtoolのdlpreopen (see Dlpreopening)

以下の例外で，libltdlはGNUライブラリ公有使用許諾書の条件下でライセンスされています．

     GNU Lesser General Public Licenseの特別な例外として，GNU libtoolを使用して構築されるプログラムやライブラリの一部としてこのファイルを配布する場合，プログラムの残りに対して使用する配布条件と同じにして，それを含めることができます．

プログラムでのlibltdlの使用法
==================

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で定義されています．

 -- Type: lt_ptr
     lt_ptrは，汎用ポインタです．

 -- Type: lt_dlhandle
     lt_dlhandleはモジュール"ハンドル"です．すべてのlt_dlopenされるモジュールはそれに関連付けされたハンドルがあります．

 -- Type: lt_dlsymlist
     lt_dlsymlistはdlpreopenされるモジュールのシンボルリストです．この構造体は，see Dlpreopeningで記述されます．

libltdlは以下の関数を提供します．

 -- Function: int lt_dlinit (void)
     libltdlを初期化します．この関数は，libltdl使用する前に呼び出す必要があり，複数回呼び出すことが可能です．成功したら0，それ以外ではエラーの番号を返します．

 -- Function: int lt_dlexit (void)
     libltdlを終了し，すべてのモジュールを閉じます．この関数は， lt_dlinitが正常に呼び出された回数と同じだけ呼び出されたとき， libltdlを終了するだけです．成功したら0，それ以外ではエラーの番号を返します．

 -- Function: lt_dlhandle lt_dlopen (const char *FILENAME)
     ファイル名FILENAMEを用いてモジュールを開き，そのハンドルを返します． lt_dlopenは，libtoolダイナミックモジュール，プリロードされたスタティックモジュール，プログラム自身，そしてネイティブなダイナミックライブラリを開くことが可能です．

     モジュール内の未解決のシンボルは，それが依存する(まだ実装されていない)ライブラリと，前もってdlopenされたモジュールを用いて解決されます．このモジュールを使用している実行形式が-export-dynamicフラグでリンクされている場合，実行形式の大域的なシンボルもモジュール内の参照の解決に使用されます．

     FILENAMEがNULLでプログラムが-export-dynamicや -dlopen selfを用いてリンクされている場合，lt_dlopenはプログラム自身のハンドルを返し，それはそのシンボルのアクセスに使用可能です．

     libltdlがライブラリを見つけられず，ファイル名FILENAMEがディレクトリコンポーネントを持たない場合，それは，以下の検索パスを(以下の順番で)，さらにモジュールを検索します．

      1. ユーザ定義の検索パス：

          この検索パスは，関数lt_dlsetsearchpathとlt_dladdsearchdir を用いたプログラムで設定可能です．

      2. libtoolの検索パス：

          システム依存のライブラリ検索パスです(例えば，Linuxでは LD_LIBRARY_PATHになります)．

      3. システムのライブラリ検索パス：

          システム依存のライブラリ検索パスです(例えば，Linuxでは LD_LIBRARY_PATHになります)．

     それぞれの検索パスは，例えば"/usr/lib/mypkg:/lib/foo"のような，コロンで分けられた絶対的なディレクトリのリストにする必要があります．

     同じモジュールが複数回ロードされた場合，同じハンドルが返されます．あらゆる原因でlt_dlopenが失敗した場合，NULLが返されます．

 -- Function: lt_dlhandle lt_dlopenext (const char *FILENAME)
     ファイル名に異なるファイル名の拡張子を追加を試みる以外は， lt_dlopenと同じです．ファイル名FILENAMEを持つファイルが見つからない場合，libltdlは，以下の拡張子の追加を試みます．

      1. libtoolのアーカイブ拡張子.la

      2. ホストプラットフォームの本来のダイナミックライブラリに使用される拡張子で，例えば，.so，.sl等

     この探索作戦は，本来のダイナミックライブラリの命名規則を知らないプログラムが，そのようなライブラリを，libtoolモジュールと同様に，透過的に dlopenすることを可能にするために設計されています．

 -- Function: int lt_dlclose (lt_dlhandle HANDLE)
     モジュールHANDLEの参照カウントを減らします．ゼロになったり，このモジュールに依存する他のモジュールがない場合，モジュールはアンロードされます．成功時には0を返します．

 -- Function: lt_ptr lt_dlsym (lt_dlhandle HANDLE, const char *NAME)
     モジュールHANDLE内のアドレスを返し，そこでは，ヌルで終端された文字列NAMEで与えられるシンボルがロードされています．シンボルが見つからない場合はNULLを返します．

 -- Function: const char *lt_dlerror (void)
     libltdlのあらゆる関数から発生した最も新しいエラーを記述する，可読性の高い文字列を返します．初期化からまたは最後に呼び出されてからエラーが発生していない場合，NULLを返します．

 -- Function: int lt_dlpreload (const lt_dlsymlist *PRELOADED)
     プリロードされているモジュールPRELOADEDのリストを登録します． PRELOADEDがNULLの場合，lt_dlpreload_defaultで設定されているリスト以外の，これまで登録されているすべてのシンボルリストが検出されます．成功時には0を返します．

 -- Function: int lt_dlpreload_default (const lt_dlsymlist *PRELOADED)
     プリロードされているモジュールリストのデフォルトをPRELOADEDに設定し，それはlt_dlpreloadで検出されません．この関数は， lt_dlinitを使用して初期化されるためにlibltdlを要求しないことと，デフォルトでプリロードされるモジュールを登録するためにプログラムで使用できることに注意してください．この関数を直接呼び出す代わりに，ほとんどのプログラムはマクロLTDL_SET_PRELOADED_SYMBOLSを使用します．

     成功時には0を返します．

 -- Macro: LTDL_SET_PRELOADED_SYMBOLS()
     プリロードされるシンボルのデフォルトリストを設定します．プリロードされる libltdlのモジュールを初期化するために，プログラムで使用した方が良いでしょう．

          #include <ltdl.h>

          int main() {
            /* ... */
            LTDL_SET_PRELOADED_SYMBOLS();
            /* ... */
          }

 -- Function: int lt_dladdsearchdir (const char *SEARCH_DIR)
     検索ディレクトリSEARCH_DIRをユーザー定義のライブラリ検索パスに追加します．成功時には0を返します．

 -- Function: int lt_dlsetsearchpath (const char *SEARCH_PATH)
     現在のユーザ定義のライブラリ検索パスをSEARCH_PATHで置換し，それはコロンで分けられた絶対的なディレクトリのリストにする必要があります．成功時には0を返します．

 -- Function: const char *lt_dlgetsearchpath (void)
     現在のユーザ定義のライブラリ検索パスを返します．

 -- Function: int lt_dlmakeresident (lt_dlhandle HANDLE)
     モジュールをlt_dlcloseできないように印を付けます．モジュールがプロジェクトの中心部の機能を実装している場合，削除されるとコードが壊れるので，これは役に立つはずです．成功すると0を返します．

     実行しているバイナリに対するHANDLEを取得するためにlt_dlopen (NULL)を使用する場合，そのハンドルは常駐しているような印が常に付き，したがってうまくlt_dlcloseすることができません．

 -- Function: int lt_dlisresident (lt_dlhandle HANDLE)
     特定のモジュールが常駐しているように印が付いているかどうか調査し，その場合は1を返し，それ以外では0を返します．この関数の実行中にエラーがある場合， -1 が返され，lt_dlerrorを用いて回収されるエラーメッセージが設定されます．

 -- Variable: lt_ptr (*) (size_t SIZE) lt_dlmalloc
 -- Variable: void (*) (lt_ptr PTR) lt_dlfree
     これらの変数は，デフォルトで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
     ...

マルチスレッド環境でのlibtldlの使用
=====================

lt_dlmutex_register()関数を使用し，適切なコールバック関数の定義を提供することで，libltdlをマルチスレッド環境で使用することが可能です．

 -- Type: void lt_dlmutex_lock (void)
     これは，ミューテックスロックが必要なlibltdlの実装コードの部分の，最初に呼び出される関数のアドレスを持っている，関数のポインタ型です．

     libltdlは本質的に再帰的なので，これらのコールバック関数によって使用されるロックメカニズムがリエントリー可能であることは重要で，そうでなければ，おかしな問題が発生します．

 -- Type: void lt_dlmutex_unlock (void)
     アンロック関数に一致する型です．

 -- Type: void lt_dlmutex_seterror (const char *ERROR);
     libltdl APIの関数の多くは，エラーを発生したクライアントを示す，特殊な戻り値をとります．通常(シングルスレッドアプリケーションでは)，内部から回収することができるエラーを記述する文字列は，lt_dlerror()に保存されます．

     この形式の関数は，それがマルチスレッドのコンテクストで動作するように，ライブラリに登録される必要があります．関数は，スレッドローカルストレージに渡されるあらゆるエラーメッセージを保存すべきです．

 -- Type: const char * lt_dlmutex_geterror (void)
     スレッドローカルのストレージに，最後にエラーメッセージを保存したものに関連するコールバック関数に一致する型です．

     正しく登録されたとき，この関数は，クライアントに対するエラーメッセージを回収するために全てのスレッドからlt_dlerror())によって使用されます．

 -- Function: int lt_dlmutex_register (lt_dlmutex_lock *LOCK, lt_dlmutex_unlock *UNLOCK, lt_dlmutex_set_error *SETERROR, lt_dlmutex_geterror *GETERROR)
     libltdlのマルチスレッドの準備で，上記のそれぞれの関数の型を登録するために，この関数を使用してください．全ての引数は，有効なNULLでない関数アドレスにする必要があり，また，そうでない場合は，シングルスレッドオペレーションへの戻り値として，全てNULLにする必要があります．

ロードされたモジュールに関連するデータ
===================

libltdlが管理している，それぞれのロードされたモジュールに関する内部情報には，ユーザが利用可能なものもあり，それはこの構造体の形式です．

 -- Type: struct lt_dlinfo { char *FILENAME; char *NAME; int REF_COUNT; }
     lt_dlinfoは，モジュールの情報を保存するために使用されます． FILENAME属性は，NULLで終端された，実際のモジュールファイル名の文字列です．モジュールがlibtoolモジュールの場合，NAMEはそのモジュール名(例えば，"dir/libfoo.la"に対する"libfoo")で，それ以外ではNULLに設定されます．REF_COUNT属性は，現在ロードされている同じモジュールの回数を記述する参照カウンタです．

以下の関数は，与えられたHANDLEに対するこの構造体のlibltdlの内部のコピーへのポインタを返します．

 -- Function: const lt_dlinfo * lt_dlgetinfo (lt_dlhandle HANDLE)
     モジュールHANDLEに関するいくつかの情報を含む構造体の，ポインタを返します．構造体の内容は編集してはなりません．失敗時にはNULLが返ります．

さらに，ロードした全てのモジュールのハンドルリストを保つ手助けをするために，これらの関数で，ロードされているモジュールのlibltdlのリスト全体を繰り返すことが可能となります．

 -- Function: int lt_dlforeach (int (*FUNC) (lt_dlhandle HANDLE, lt_ptr DATA), lt_ptr DATA)
     ロードされているそれぞれのモジュールに対し関数FUNCを呼び出します．引数のHANDLEは，ロードされているモジュールのハンドルの一つで， DATAは，lt_dlforeachに渡すDATA引数です．FUNCがハンドルの一つに対し，ゼロでない値を返すとすぐに，lt_dlforeachは FUNCの呼び出しを停止し，直ちに１を返します．それ以外は0が返ります．

 -- Function: lt_dlhandle lt_dlhandle_next (lt_dlhandle place)
     PLACEがNULLの場合は，リスト内の最初のハンドルを返し，そして順番に次ものを呼び出すことで，ロードされているモジュール全体を繰り返します．PLACEが，ロードされているモジュールリスト内の最後の要素の場合，この関数はNULLを返します．

もちろん，アプリケーションの効果に対し，それぞれのハンドルに関連付けする必要がある他のデータがある場合，libltdlで管理されるリストと平行して，ロードされたモジュールハンドルの、独自のリストの管理が必要でしょう。しかし，アプリケーションデータに，個別のモジュールハンドルを，ロードされたものとして関連付けさせるために，以下のAPIの呼び出しを使用する場合，実際にはそうする必要はありません。最初に，前もって保存したデータを回収するために後で利用する，libltdlからのユニークな呼び出しidを取得する必要があります。これで，ロードされているモジュールに対する独自のデータを，個別に保存したい異なるライブラリが，もう一つの(ライブラリ)のデータへのインターフェースなしでそれを行うことが可能となります。

 -- Type: lt_dlcaller_id
     個別のデータセットのキーを保つ，透過でない型です．

 -- Function: lt_dlcaller_id lt_dlcaller_register (void)
     モジュールデータ毎に個別のセットを，保存し回収するためのユニークなキーを取得するために，これを使用してください．

 -- Function: lt_ptr lt_dlcaller_set_data (lt_dlcaller_id KEY, lt_dlhandle HANDLE, lt_ptr DATA)
     後で回収するために，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);
                }

 -- Function: lt_ptr lt_dlcaller_get_data (lt_dlcaller_id KEY, lt_dlhandle HANDLE)
     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の組み込みローダで既に使用しているものはいけません．

"dlopen"
     存在する場合は，システムのダイナミックローダ．

"dld"
     libltdlが構築されたときにlibdldがインストールされている場合は， GNU dldローダ．

"dlpreload"
     前もってロードされているスタティックモジュールのlt_dlopenのためのローダ．

前置される"dl"は，libltdlの将来のバージョンで提供されるローダとして予約されているので，独自のローダ名に使用すべきではありません．

以下の型は，ltdl.hで定義されています．

 -- Type: lt_module
     lt_moduleはモジュール依存のdlloaderです．ダイナミックモジュールローダの拡張は，これらの低レベルの型を使用して通信します．

 -- Type: lt_dlloader
     lt_dlloaderはモジュールローダの型に対するハンドルです．

 -- Type: lt_dlloader_data
     lt_dlloader_dataはローダのインスタンスデータに対して使用されます．

 -- Type: 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; }
     ダイナミックモジュールを開くために新しい方法を定義したくて，それを使用したlt_dlopen APIがある場合，これらの構造体のインスタンスを作成し，それをlt_dlloader_addに渡す必要があります．好みの DLLOADER_DATAフィールドで渡すことが可能で，それは，関数ポインタフィールドで指定されている，それぞれの関数への最初のパラメータの値として戻ります．

 -- Type: lt_module lt_module_open (lt_user_data LOADER_DATA, const char *FILENAME)
     lt_dlloaderモジュールローダに対するローダ関数の型です． struct lt_user_dlloader構造体のdlloader_dataフィールドに設定される値は，LOADER_DATAパラメータで，この関数に渡されます．そのような関数の実装は，指名されたモジュールのロードを試み，関連する lt_module_closeとlt_sym_find関数のポインタに渡すのに適切な lt_moduleを返すべきです．関数が失敗した場合はNULLを返し， lt_dlseterrorを用いてエラーメッセージを設定すべきです．

 -- Type: int lt_module_close (lt_dlloader_data LOADER_DATA, lt_module MODULE)
     ユーザが定義したモジュールローダに対するアンローダの型です．そのような関数の実装は，MODULEモジュールに結び付けられたあらゆるリソースの解放を試み，それから，それをメモリからアンロードすべきです． lt_module_closeとlt_sym_find関数のポインタに渡すのに適切理由があり関数が失敗した場合，lt_dlseterrorを用いてエラーメッセージを設定し，ゼロ以外を返すべきです．

 -- Type: lt_ptr lt_find_sym (lt_user_data LOADER_DATA, lt_module MODULE, const char *SYMBOL)
     ユーザが定義したモジュールローダに対する，シンボルルックアップ関数の型です．そのような関数の実装は，モジュールMODULE内の指名された SYMBOLのアドレスを返す，もしくは，検査が失敗した場合は，エラーメッセージをlt_dlseterrorで設定し，NULLを返すべきです．

 -- Type: int lt_dlloader_exit (lt_user_data LOADER_DATA)
     ユーザが定義したモジュールローダに対する，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は，独自のモジュールローダを書くために，以下の関数を提供します．

 -- Function: int lt_dlloader_add (lt_dlloader *PLACE, lt_user_dlloader *DLLOADER, const char *LOADER_NAME)
     新しいモジュールローダを全てのローダリストに加え，それは，(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 ());
          }

 -- Function: int lt_dlloader_remove (const char *LOADER_NAME)
     ユニークな名前LOADER_NAMEで識別されているローダを削除します．これが成功可能となる前に，指名されたローダにより開かれている全てのモジュールを，閉じておく必要があります．成功に対し0を返し，それ以外では，エラーメッセージがlt_dlerrorから取得可能です．

          {
            /* Remove myloader. */
            if (lt_dlloader_remove ("myloader") != 0)
              perror (lt_dlerror ());
          }

 -- Function: lt_dlloader *lt_dlloader_next (lt_dlloader *PLACE)
     ローダモジュール全体を繰り返し，それは，PLACEがNULLの場合，最初のローダを返し，順番に次を呼び出すことで行います．ハンドルは， lt_dlloader_add用です．

          {
            /* Make myloader be the first one. */
            if (lt_dlloader_add (lt_dlloader_next (NULL), myloader) != 0)
              return ERROR;
          }

 -- Function: lt_dlloader *lt_dlloader_find (const char *LOADER_NAME)
     LOADER_NAME識別しに一致する最初のローダを返し，識別子が見つからない場合はNULLを返します．

     libltdl自身で使用可能な識別子は，ホストアーキテクチャがサポートしている場合は，dlopen (これは，モジュールをロードしているAPI に依存します -- 例えば，shl_loadとLoadLibraryです)， 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;
          }

 -- Function: const char *lt_dlloader_name (lt_dlloader *PLACE)
     lt_dlloader_nextやlt_dlloader_findで取得される， PLACEの識別名を返します．この関数が失敗する場合，NULLを返し， lt_dlerrorで回収するためのエラーを設定します．

 -- Function: lt_user_data *lt_dlloader_data (lt_dlloader *PLACE)
     lt_dlloader_nextやlt_dlloader_findで取得される， PLACEのアドレスを返します．この関数が失敗する場合，NULLを返し，lt_dlerrorで回収するためのエラーを設定します．

ユーザモジュールローダでのエラー処理
------------------

 -- Function: int lt_dladderror (const char *DIAGNOSTIC)
     この関数で，独自のエラーメッセージをlt_dlerrorに組み込むことが可能となります．lt_dlerrorで返すための適切な診断メッセージ内のパスと，lt_dlseterrorで使用されるエラー識別子が返されます．

     識別子の割り当てが失敗した場合，この関数は-1を返します．

          int myerror = lt_dladderror ("Doh!");
          if (myerror < 0)
            perror (lt_dlerror ());

 -- Function: int lt_dlseterror (int ERRORCODE)
     独自のモジュールローダを書くとき，lt_dlerrorインターフェースを通じて伝搬されるように，エラーを発生させるために，この関数を使用すべきです． libltdlで使用される標準エラーの全ては，ltdl.hで宣言されていて，そうでなければ，lt_dladderrorを用いて独自に書き加えることが可能です．

          if (lt_dlseterror (LTDL_ERROR_NO_MEMORY) != 0)
            perror (lt_dlerror ());

パッケージとともにlibltdlを配布する方法
=======================

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のバージョンを要求し，それが見つかった場合 (たとえ，libltdlがインストールされていても，libltdlがCライブラリ以外のライブラリが提供するシンボルに依存する場合， AC_LIBLTDL_INSTALLABLEは検出に失敗する可能性があります．この場合， libltdlの構築とインストールは不必要です．)，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の使用
****************

libtoolは最初に，C言語での共有ライブラリを書くことに対するサポートを加えるために実装されました．しかし，時間が経ち，プログラマが好みのプログラム言語での共有ライブラリの便利さを自由に得られるように，libtoolは他の言語と統合されています．

この章は，libtoolが他の言語と相互作用する方法と，Cを用いない場合に必要とされる特記事項を記述します．

C++に対するライブラリを書く
===============

C++コードのライブラリを作成することは，そのオブジェクトファイルがCのものと３つの点で異なっているだけので，かなり簡単な処理になります．

 1. 名前をmangleするため，C++ライブラリはC++コンパイラで作成されたものだけ利用可能です．この決定は，コンストラクタ，例外処理，そしてRTTIのような機能の実装との衝突からユーザを守るため，C++の設計者によってなされました．

 2. システムによっては，C++コンパイラは，ダイナミックリンカが動的(すなわち実行時)に初期化を実行することを，特別な動作として考慮する必要があります．これは，そのようなライブラリとリンクするため，ldを直接呼び出すべきではなく，その代わりにC++コンパイラを使用するべきだということを意味します．

 3. C++コンパイラは，いくつかの標準C++ライブラリとデフォルトでリンクしますが， libtoolは，これらのライブラリがどれかを知らないため，それに対してリンクする方法を調査するため，ライブラリ内部の依存の解析さえ実行できません．それゆえ，C++プログラムやライブラリとリンクするためldを実行することは，失敗すると思われます．しかし，C++コンパイラを直接実行することは，ライブラリ内部の依存に関係する問題に至る可能性があります．

結論として，libtoolはC++ライブラリに対する一般的な使用のための準備ができていません．標準Cコンパイラでコンパイルする場合は，``初期化要素は一定ではない''というエラーの原因となる，あらゆるグローバルまたはスタティック変数の初期化を避けるべきです．

この問題に関して動作する他の方法もありますが，それらはこのマニュアルの範囲を越えています．

さらに，C++コンパイラがデフォルトでリンクするC++ 標準ライブラリと，リンクコマンドラインの明示的なリストは，コンフィグレーション時に分かった方が良いでしょう．たぶん将来，libtoolはこの仕事を単独で可能となるでしょう．

トラブルシューティング
***********

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
     これらのプログラムは，libtool配布物のcdemoサブディレクトリが，正しくコンフィグレーションされ，構築されることを知るために調査します．

     cdemoサブディレクトリは，libtoolの便利なライブラリのデモンストレーションをふくみ，それは，構築時に共有ライブラリの作成を可能とするメカニズム，コンポーネントが，それが共有ライブラリでも，プログラムや他のライブラリと遅れてリンクされることを可能とする方法です．

     cdemo-make.testとcdemo-exec.testのテストは，３つの異なる libtoolコンフィグレーションで，３回実行されます．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
     これらのプログラムは，libtool配布物のdemoサブディレクトリが，コンフィグレーション，構築，インストール，そしてアンインストールが正しくできることを知るために調査します．

     demoサブディレクトリは，libtoolを使用する平凡なパッケージのデモンストレーションを含みます．テストのdemo-make.test， demo-exec.test，demo-inst.test，そして demo-unst.testは，４つの異なるlibtoolのコンフィグレーションの下で，４回実行されます．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
     スタティックライブラリを共有ライブラリにリンク不可能なシステムもたくさんあります．そのような場合を避けるため，libtoolは deplibs_check_methodを使用します．このテストは，libtoolの deplibs_check_methodが正しく動作するかどうか調査します．

hardcode.test
     共有ライブラリを持つすべてのシステムで，実行形式に対しリンクされるライブラリの位置が実行形式の内部に符号化されるはずですsee Linking executables．このテストは，システムリンカがライブラリの位置をハードコードし，libtool自身のリンカの動作方法の概念と一致することを保証する条件を調査します．

build-relink.test
     変数SHLIBPATH_OVERRIDES_RUNPATHが正しく設定されているかどうか調査します．テストが失敗し，VERBOSEが設定されている場合，それは変数を設定する必要がないことを示します．

noinst-link.test
     libtoolが，たった今構築されたライブラリにリンクする方が良い時，以前にインストールされているバージョンにリンクしようとしないかどうか調査します．

depdemo-conf.test
depdemo-exec.test
depdemo-inst.test
depdemo-make.test
depdemo-unst.test
depdemo-static.test
depdemo-shared.test
depdemo-nofast.test
     これらのプログラムは，libtool配布物のdepdemoサブディレクトリの，コンフィグレーション，構築，インストール，そしてアンインストールを，正しく行えることを判定するための調査を行います．

     depdemoサブディレクトリは，libtoolに依存する内部ライブラリのデモンストレーションを含みます．このテストプログラムは，いくつかの交互依存しているライブラリをリンクします．

     テストの，depdemo-make.test，depdemo-exec.test， depdemo-inst.test，そしてdepdemo-unst.testは，４つの異なる libtoolのコンフィグレーションの下で，４回実行されます． 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
     これらのプログラムは，libtool配布物の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は，３つの異なる libtoolのコンフィグレーションの下で，３回実行されます． mdemo-conf.testは，スタティックと共有の両方のライブラリを構築するためにmdemo/libtoolをコンフィグレーションし， mdemo-static.testは，スタティックライブラリのみ構築し (--disable-shared)，そしてmdemo-shared.testは，共有ライブラリのみを構築します(--disable-static)．

dryrun.test
     このテストは，libtoolの--dry-runモードが正しく働くかどうかを調査します．

assign.test
     libtoolスクリプト内の割り当てられている同じ行で，停止したり，続けたりしないかどうか調査します．

link.test
     このテストは，libtoolでないスタティックライブラリに対する直接的なリンクが正しく動作することを保証します．

link-2.test
     このテストは，.loで終わるファイルがプログラムファイルに直接リンクされないことを確かめます．

nomode.test
     実際にlibtoolの助けが可能かどうか調査します．

quote.test
     このプログラムはlibtoolのメタ文字を引用符で囲むことを調査します．

sh.test
     `test'コマンドがlibtoolに忘れていないか調査します．

suffix.test
     他のプログラミング言語がlibtoolで使用されるとき(see Other languages)，ソースファイルは.c以外の接尾子で終わるかもしれません．このテストは，サポートするすべてのファイル形式に対する接尾子を扱うこと可能で，接尾子が不当なときは失敗することを確認します．

テストが失敗するとき
----------

上記のそれぞれのテストは，make checkを実行するとき出力を生成しないように設計されています．それぞれのプログラムの終了ステータスで，テストが成功しなかったかどうかをMakefileに伝えます．

テストが失敗した場合，それはlibtool内のプログラムエラー，またはプログラム自身のエラーのどちらかが存在することを意味します．

特定のテストを調査するために，通常のプログラムで行うように，直接実行することが可能です．テストがこの方法で呼び出されたとき，それは，問題を決定するのに役に立ちそうな出力を生成します．

テストプログラムに出力を生成させるもうひとつの方法は，実行前に VERBOSE環境変数をyesに設定することです．例えば，env VERBOSE=yes make checkですべてのテストが実行され，それぞれについてデバッグ情報の表示が得られます．

バグの報告
=====

libtoolにバグを発見したと考えた場合，もう一度考えたほうが良いでしょう． libtool管理者は，責任転嫁(または``バグを通過させる''かもしれません)で有名です (訳注：原文では，passing the buck(責任転嫁)とpassing the bug(バグを通過させる)をかけています)．libtoolは，共有ライブラリの実装で既知の欠陥を修正するために開発されたので，libtoolのバグのほとんどは，ある程度は，他のオペレーティングシステムのバグになります．しかし，libtool の管理者は，他人のバギーなオペレーティングシステムに対するサポートを加えることを，確かに楽しんでいます．[Texinfoでウインクしている笑顔を表示する，いい方法があれば良いのですが．]

libtoolの純粋なバグは，シェルスクリプトの移植性の問題，ドキュメントのエラー，そしてテストスイートの失敗(see Libtool test suite)を含みます．

最初に，問題と考えられる動作が，既に特徴として言及されていないことを確かめるために，ドキュメントとへルプ画面を調査してください．

そして，バグを報告することに関するEmacsガイド(see Reporting Bugs (The Emacs Manual))を読んでください．リストアップされている詳細は，Emacs特有のものもありますが，基本的な原則は一般的なものです．

最終的に，テストスイートの出力(see When tests fail)，バグを再生成するのに必要なすべての詳細，そして，動作がバグだと考えられる理由の概要のような，適切なあらゆる事実とともにthe libtool bug reporting address bug-libtool@gnu.orgにバグの報告を送ってください．サブジェクト行に，単語``libtool''と，同様に使用しているバージョンナンバー(それは，ltconfig --versionの入力で分かります)が含まれていることを確認してください．

libtoolの管理用メモ
*************

この章は，libtool管理者が見つける重要な情報を含みます．新しいシステムへの移植や，独自のlibtoolを書くことを考慮しない場合，役に立たないでしょう．

新しいシステムへのlibtoolの移植
===================

サポートされていないシステムへのlibtoolの移植に乗り出す前に，既存の仕事と重複していないことを確認するために，the libtool mailing list libtool@gnu.orgに電子メールを送る価値はあります．

移植の文章が見つからない場合，文句を言ってください！ パッチを含む苦情と文章やlibtool自身の改良は十分に歓迎されます．

情報源
---

新たな移植の必要性が明らかになると，通常，以下の情報が必要となります．

標準的なシステム名
     他のシステムに影響しないようにlibtoolのコンフィグレーション処理を変更可能にするため，このシステムに対するconfig.guessの出力が必要です．

ldとccに対するmanページ
     これらは通常，共有ライブラリを作成するため，共有ライブラリのみにリンクするため，そして，PICを生成するために使用するフラグを記述します．必要な情報を見つけるため，以下の相互参照が必要かもしれません．

ld.so，rtld，または，その同等物のmanページ
     これらは，システムで共有ライブラリがロードされる仕組みを理解するための，有益な情報源です．

ldconfigやその同等物のmanページ
     このページは，通常，共有ライブラリをインストールする方法を記述します．

output from ls -l /lib /usr/lib
     これは，システムの共有ライブラリの命名規則を表示し，それは，シンボリックリンクの名も含みます．

あらゆる追加の文章
     共有ライブラリの構築とインストール方法の特別な文章があるシステムもあります．

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は，以下の５つの内の一つのはずです．

file_magic [REGEX]
     ライブラリリンクパスで正しいlibnameを持つライブラリを探します．そして，ライブラリで$file_magic_cmdを実行し，egrepを使用した REGEXに一致することを調査します．FILE_MAGIC_TEST_FILEが libtool.m4によって設定されているとき，正規表現がその出力と一致するかどうかを検証し，それ以外ではユーザが警告を受けるようにするため，それは$file_magic_cmdへの引数として使用されます．

test_compile
     ライブラリリストの出力以外とプログラムがリンク可能かどうかのみを調査し，それらがlddの出力でリストアップされていることを調査します．それは現在，使用されておらず，将来は打ち切る可能性があります．

pass_all
     調査せず，すべて通過します．例えばDEC OSF/1 3 と 4のような，デフォルトで，コードが位置に依存せず，ライブラリ内部の依存性がダイナミックリンカで適切にサポートされているプラットフォームで，これは動作するでしょう．

none
     deplibsをdeplibs=""に再設定します．そのように，archive_cmdsは，すべてのプラットフォームでdeplibsを含むはずですが，deplibは必要がなければ使用されません．

unknown
     libtool.m4で優先されない場合，すべてのシステムでデフォルトです．それはnoneと同じですが，正しい値が何か，我々が本当に知らないことを文章化していて，我々はそれを改善するパッチを歓迎します．

ltmain.inで，我々は本当に一生懸命作業しました．それは， (libname_spec等の評価を使用するための変数を設定/リリース行う)小さな初期化と移植，そして使用するメソッドを決定するケース文です．これは，実際にはコードです...  もう少し凝縮できれば良かったのですが，関数呼び出しを用いずにできるとは思えませんでした．私はほとんどの(ループの外に出す等の)最適化を行いましたが，余分なものがあるかもしれません．前に進めていく内にやめるべきだと考えていたことは，明白な最適化を考える前に，発見したあらゆるバグに対して作業することでした．

テストされたプラットフォーム
==============

この表は，共有ライブラリのサポートを謡っているプラットフォームで， libtoolがテストされたことが分かっている最後の時期を記述しています．

          [file PLATFORMS-ja not included]

注：ベンダー配布されているHP-UXのsed(1)プログラムは，ひどく壊れていて，libtoolの要求を処理することができないため，ユーザは異常の問題を報告する可能性があります．これらのシステムで動作する(GNU sed)のようなsedをインストールする以外に，回避方法はありません．

注：ベンダー配布されているNCR MP-RAS ccプログラムは，標準エラーに著作権を出力し，conftest.errの大きさのテストで混乱します．回避方法は，configureを実行するとき，CC='cc -Hnocopyr'を用いて CC を指定します．

プラットフォームの癖
==========

このセクションは，libtoolの管理者の健康に捧げます．それは，libtoolが使用するプログラム，システムごとの違い，そしてテストの方法を記述します．

libtoolはシェルスクリプトなので，最初から最後まで読むだけで理解することは難しいはずです．このセクションは，libtoolが特定の方法で行う理由の理解を助けます．スクリプト自身が組み合わされているので，libtoolの改善や，独自に書く方法の，より良いセンスが必要でしょう．

参照
--

以下は，価値のある文章の参照リストです．

  * SGIのIRIXのマニュアルページで，それは http://techpubs.sgi.com/cgi-bin/infosrch.cgi?cmd=browse&db=manで見つかります．

  * Sunのフリーサービス領域 (http://www.sun.com/service/online/free.html)とドキュメントサーバ (http://docs.sun.com/)．

  * CompaqのTru64 UNIXオンラインドキュメントは (http://tru64unix.compaq.com/faqs/publications/pub_page/doc_list.html) にあり，C++ドキュメントは (http://tru64unix.compaq.com/cplus/docs/index.htm)です．

  * Hewlett-Packardは(http://docs.hp.com/index.html)にオンラインドキュメントがあります．

  * IBMは(http://www.rs6000.ibm.com/resource/aix_resource/Pubs/)にオンラインドキュメントがあります．

コンパイラ
-----

libtoolに影響するコンパイラの特徴は，PICオブジェクトを生成するための(存在する場合は)必要なフラグのみです．一般的に，Cコンパイラが特定のPICフラグをサポートする場合，あらゆる派生的なコンパイラは同じフラグをサポートします．この規則に対し，注目すべき若干の例外があるまでは，このセクションではCコンパイラのみを説明します．

プラットフォームに関係なく，以下のCコンパイラは，標準のコマンドライオプションがあります．

gcc

     これはGNU Cコンパイラで，多くのフリーオペレーティングシステム(少し例をあげると，FreeBSD，GNU/Hurd，GNU/Linux，Lites，NetBSD，そしてOpenBSDです) に対する，システムコンパイラでもあります．

     -fpicや-fPICフラグは，位置に依存しないコードを生成するために使用可能です．-fPICは動作するコードを生成することを保証しますが， m68k，m88k，そしてSparcチップ上ではコードは遅くなります．しかし，これらのチップで-fpicを使用すると，共有ライブラリでの自由なサイズが強制的に制限されます．

バンドルされているオペレーティングシステムにより，このサブセクションの残りでコンパイラをリストアップします．

aix3*
aix4*
     AIXはPowerPCとRS/6000チップのみに移植されているので，AIXコンパイラはPIC フラグはありません． (PowerPCとRS/6000チップ(powerpc-*-*， powerpcle-*-*，そしてrs6000-*-*)に対しコンパイルされているすべてのコードは，オペレーティングシステムやコンパイラスイートに関係なく位置に依存しません．そのため，``標準オブジェクト''はこれらのシステムの共有ライブラリの構築で使用され，特別なPICコンパイラフラグは要求されません．)

hpux10*
     PICを生成するために+Zを使用してください．

osf3*
     Digital/UNIX 3.xは，少なくともPowerPCプラットフォームでなければ，PICフラグはありません．

solaris2*
     PICを生成するために-KPICを使用してください．

sunos4*
     PICを生成するために-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)．

 -- Variable: AR
     システムライブラリアーカイバの名前です．

 -- Variable: CC
     libtoolをコンフィグレーションするために使用するCコンパイラの名前です．

 -- Variable: LD
     リロード可能なリンクとおそらく共有ライブラリに対し，libtoolが内部で使用するリンカの名前です．

 -- Variable: NM
     BSD互換のnmプログラムの名前で，それは以下の書式の一つで，大域的なシンボルを生成します．

          ADDRESS C GLOBAL-VARIABLE-NAME
          ADDRESS D GLOBAL-VARIABLE-NAME
          ADDRESS T GLOBAL-FUNCTION-NAME

 -- Variable: RANLIB
     存在する場合，ranlibプログラムの名前を設定します．

 -- Variable: allow_undefined_flag
     結果として生じる共有ライブラリに，未解決のシンボルがあることを宣言するために，archive_cmdsで使用されるフラグです．そのようなフラグが不要な場合は空です．ライブラリで定義されていないシンボルを参照して，共有ライブラリを生成する方法がない場合，unsupportedを設定します．

 -- Variable: always_export_symbols
     アーカイブとリンクする前に，EXPORT_SYMBOLS_CMDSを使用してエクスポートされるシンボルのリストを，libtoolが自動的に生成するかどうかです． yesまたはnoに設定します．デフォルトはnoです．

 -- Variable: archive_cmds
 -- Variable: archive_expsym_cmds
 -- Variable: old_archive_cmds
     それぞれ，共有ライブラリ，-export-symbolsを用いた共有ライブラリ，そしてスタティックライブラリを生成するために使用するコマンドです．

 -- Variable: old_archive_from_new_cmds
     共有ライブラリがスタティックライブラリに依存する場合， old_archive_from_new_cmdsはスタティックライブラリを生成するために使用するコマンドを含みます．この変数が空の場合，old_archive_cmds は使用されません．

 -- Variable: old_archive_from_expsyms_cmds
     スタティックライブラリが，共有ライブラリで正しくリンクするために，エクスポートシンボルリストから作成される必要がある場合， old_archive_from_expsyms_cmdsは，そのスタティックライブラリを作成するために必要なコマンドを含みます．これらのコマンドが実行されるとき，変数SONAMEは，共有ライブラリの名前を疑問符の中に含み， $OBJDIR/$NEWLIBは，これらのコマンドが構築する静的ライブラリのパスを含みます．これらのコマンドを実行した後，libtoolは，SONAMEの代わりに$OBJDIR/$NEWLIBに対してリンクするための処理を行います．

 -- Variable: build_libtool_libs
     このシステムで，libtoolが共有ライブラリを構築できるかどうかです． yesまたはnoに設定します．

 -- Variable: build_old_libs
     このシステムで，libtoolがスタティックライブラリを構築できるかどうかです． yesまたはnoに設定します．

 -- Variable: compiler_c_o
     コンパイラが，同時に-cと-oオプションをサポートするかどうかです．yesまたはnoに設定します．

 -- Variable: compiler_o_lo
     コンパイラが，直接".lo"ファイルへのコンパイルをサポートするかどうかで，例えば，オブジェクトファイルが，接尾子".o"を持つ必要があるかどうかです． yesまたはnoに設定します．

 -- Variable: dlopen_support
     プラットフォームで，dlopenをサポートするかどうかです．yes またはnoに設定します．

 -- Variable: dlopen_self
     実行形式自身がdlopen可能かどうかです．yesまたはno に設定します．

 -- Variable: dlopen_self_static
     静的にリンクされているとき(-all-static)，実行形式自身が dlopen可能かどうかです．yesまたはnoに設定します．

 -- Variable: echo
     バックスラッシュをエスケープ文字と解釈しないechoプログラムです．

 -- Variable: exclude_expsyms
     プリリードされているシンボルにリストアップされないシンボルのリストです．

 -- Variable: export_dynamic_flag_spec
     dlopenされる共有ライブラリが，プログラムで定義されているシンボルへの参照を可能にするコンパイラリンクフラグです．

 -- Variable: export_symbols_cmds
     LIBOBJSからファイルEXPORT_SYMBOLSへエクスポートされたシンボルを抽出するコマンドです．

 -- Variable: extract_expsyms_cmds
     共有ライブラリからエクスポートされたシンボルリストを抽出するコマンドです．これらのコマンドは，ファイル$OBJDIR/$SONAME-DEFが無い場合に実行され，old_archive_from_expsyms_cmdsが使用するため，エクスポートされたシンボル名をそのファイルに書き出します．

 -- Variable: fast_install
     libtoolが特権を与えるのを，インストール者または開発者のどちらかに決定します．ビルドツリーでインストール者がプログラムを滅多に実行せず，開発者は滅多にインストールしないしないと仮定します．これは， SHLIBPATH_OVERRIDES_RUNPATHがyesでないプラットフォーム上でのみ意味があるので，この場合，FAST_INSTALLはneedless設定されます．FAST_INSTALLがyesに設定される場合，libtoolはインストールされたライブラリを検索するプログラムを作成し，プログラムがビルドツリーで実行される場合，まだインストールされていないライブラリを使用するため，要求があれば，新しいコピーがリンクされます．noに設定されている場合，libtoolは，まだインストールされていないライブラリを使用するプログラムを作成し，インストール時にプログラムの新しいコピーをリンクします．デフォルト値はyesまたはneedlessで，それは，プラットフォームとコンフィグレーションフラグに依存し，コンフィグレーションフラグ --disable-fast-installを用いると，yesからnoに切り替えられます．

 -- Variable: finish_cmds
     指定されたディレクトリで共有ライブラリを見つける方法を，ダイナミックリンカに伝えるコマンドです．

 -- Variable: finish_eval
     コマンドが表示されない以外，FINISH_CMDSと同じです．

 -- Variable: fix_srcfile_path
     コンパイラに対するシェル変数$srcfileを修正する表現です．

 -- Variable: global_symbol_pipe
     NMの出力を受け，Cの名前が続く生のシンボルのリストを生成するパイプラインです．例えば，以下のようになります．

          $ eval "$NM progname | $global_symbol_pipe"
          D SYMBOL1 C-SYMBOL1
          T SYMBOL2 C-SYMBOL2
          C SYMBOL3 C-SYMBOL3
          ...
          $

     最初の列は，(いくつかのプラットフォーム上でコードからデータを伝えるために使用される)シンボル形式を含みますが，その意味はシステムに依存します．

 -- Variable: global_symbol_to_cdecl
     GLOBAL_SYMBOL_PIPEの出力を厳密なC宣言に変換するパイプラインです． HP/UXのような，リンカがコードとデータを区別するプラットフォームでは，データシンボルはそのように宣言され，コードシンボルは関数として宣言されます．気にしないプラットフォームではすべてがデータと仮定されます．

 -- Variable: hardcode_action
     immediateまたはrelinkのいずれかで，共有ライブラリパスがインストールされる前に実行形式にハードコードされるか，または，再リンクする必要があるかに依存します．

 -- Variable: hardcode_direct
     HARDCODE_LIBDIR_FLAG_SPECが指定されたとき， (DIR/libNAME.aのような)コマンド行でライブラリが直接していされる場合，リンカがディレクトリをハードコードするかどうかに依存し， yesまたはnoに設定します．

 -- Variable: hardcode_into_libs
     ライブラリ内の実行パスのハードコードをプラットフォームがサポートするかどうかです．可能な場合，プログラムのリンクはより単純になりますが，ライブラリはインストール時に再リンクが必要です．yesまたはnoに設定します．

 -- Variable: hardcode_libdir_flag_spec
     実行時に，共有ライブラリに対しダイナミックリンカがLIBDIRを検索するために，バイナリにLIBDIR変数をハードコードするためのフラグです．空の場合，libtoolは他のハードコーディングメカニズムの使用を試みます．

 -- Variable: hardcode_libdir_separator
     コンパイラが単一のHARDCODE_LIBDIR_FLAGのみ受け入れる場合，この変数はそのフラグに対する複数の引数を分ける文字列を含みます．

 -- Variable: hardcode_minus_L
     HARDCODE_LIBDIR_FLAG_SPECが指定されたとき，結果として生じる実行形式に-Lフラグで指定されるディレクトリを，リンカがハードコードするかどうかに依存し，yesまたはnoに設定します．

 -- Variable: hardcode_shlibpath_var
     HARDCODE_LIBDIR_FLAG_SPECが指定されたとき，結果として生じる実行形式に$shlibpath_varの内容を書き込むことで，リンカがディレクトリをハードコードするかどうかに依存し，yesまたはnoに設定します． $shlibpath_varで指定されたディレクトリが，リンク時ではなく実行時に検索される場合，unsupportedに設定します．

 -- Variable: host
 -- Variable: host_alias
     情報を目的として，libtoolがコンフィグレーションされたシステムの指定された標準名に設定します．

 -- Variable: include_expsyms
     EXPORT_SYMBOLSの使用時に，常にエクスポートされる必要があるシンボルのリストです．

 -- Variable: libext
     標準的な，古いアーカイブの接尾子(通常は"a")です．

 -- Variable: libname_spec
     ライブラリ名の接頭辞の書式です．Unixシステムでは，スタティックライブラリはlibNAME.aと呼ばれますが，(OS/2やMS-DOSのような)システムでは，ライブラリはNAME.aのみで呼ばれることもあります．

 -- Variable: library_names_spec
     共有ライブラリ名のリストです．最初はファイル名で，残りはファイルへのシンボリックリンクです．リスト内の名前は，-lNAMEで与えられたときリンカが見つけるファイル名です．

 -- Variable: link_all_deplibs
     libtoolが，全ての依存するプログラムに対しプログラムをリンクする必要があるかどうかです．yesまたはnoに設定します．デフォルトは unknownで，それはyesと同じです．

 -- Variable: link_static_flag
     ダイナミックリンクを避けるために使用する(Cコンパイラに渡す)リンカフラグです．

 -- Variable: need_lib_prefix
     自動的にモジュール名に'lib'接尾子を付けるかどうかです．yesまたは noに設定します．デフォルトで，それはunknownになり，それは yesと同じ意味ですが，本当に確かめたわけではないことを告げています． yesはdlopenと'lib'接頭辞がないライブラリにリンク可能なことを意味し，すなわち，それはHARDCODE_DIRECTをyesにすることを要求します．

 -- Variable: need_version
     バージョン管理がライブラリに必要とされるかどうかで，すなわち，ダイナミックリンカが，すべてのライブラリに対しバージョンの接尾子を必要とするかどうかです．yesまたはnoに設定します．デフォルトで，それは unknownで，それはyesと同じ意味を持ちますが，それを実際に確かめていないことを告げています．

 -- Variable: need_locks
     同時にコンパイルするとき，衝突を避けるためにファイルをロックする必要があるかどうかです．yesまたはnoに設定します．

 -- Variable: no_builtin_flag
     charとして外部グローバルシンボルを宣言することと衝突する組み込み関数を，利用不可能にするコンパイラフラグです．

 -- Variable: no_undefined_flag
     結果として生じる共有ライブラリに，未解決のシンボルがないことを宣言するための，archive_cmdsで使用されるフラグです．

 -- Variable: objdir
     一時的なlibtoolファイルが含まれるディレクトリ名です．

 -- Variable: objext
     標準的なオブジェクトファイルの接尾子(通常は"o")です．

 -- Variable: 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
     環境変数でプログラムのハードコードされたライブラリ検索パスを優先可能かどうかを示します．これがnoに設定されている場合，libtoolはビルドツリーにプログラムのコピーを２つ作成する必要がある可能性があり，一つはインストールされ，もう一つはビルドツリーのみで実行されます．これらのコピーのどちらかが作成されるとき，fast_installの値に依存します．デフォルト値は unknownで，それはnoと同じです．

 -- Variable: shlibpath_var
     ダイナミックリンカに共有ライブラリを探す場所を伝える環境変数です．

 -- Variable: soname_spec
     共有ライブラリがファイルの本当の名前と異なる場合，その中に符号化されたコードされた名前です．

 -- Variable: striplib
 -- Variable: old_striplib
     共有(striplib)やスタティック(old_striplib)のライブラリをストリップするコマンドです．これらの変数が空の場合，インストールモードのストリップフラグは，ライブラリに対し無視されます(see Install mode)．

 -- Variable: sys_lib_dlsearch_path_spec
     実行時にライブラリの検索パスを取得する表現です．このリストに現れるディレクトリが実行形式にハードコードされることは決してありません．

 -- Variable: sys_lib_search_path_spec
     コンパイル時にライブラリの検索パスを取得する表現です．この変数は，特定のライブラリが共有かスタティックかをテストする必要があるとき，libtoolが使用します．SHLIBPATH_VARでリストアップされるディレクトリは，このリストに自動的に現れ，ライブラリ検索パスを拡張するためにこの変数を使用するリンカもあるので，毎回(すなわち，コンフィグレーション時以外)libtoolは実行します．リンカは-Lのような検索パス引数も切り替えます．

 -- Variable: thread_safe_flag_spec
     スレッドセーフなライブラリを生成するために使用する(Cコンパイラに渡す)リンカフラグです．

 -- Variable: version_type
     ライブラリバージョンナンバーの形式です．libtool， freebsd-aout，freebsd-elf，irix，linux， osf，sunos，windows，またはnoneの一つです．

 -- Variable: whole_archive_flag_spec
     便利なアーカイバから共有ライブラリを生成するコンパイラフラグです．

 -- Variable: wl
     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を編集してください．

     [file fdl.texi not included]