libtoolは,`libltdl'と呼ばれる小さなライブラリを提供し,それは, dlopenライブラリの様々な困難をプログラマから隠すことを目指します.それ は,dlopenの機能で必要とされるアプリケーションとともに配布可能な,ヘッ ダファイルと小さなCソースファイルから成り立ちます.`libltdl'サー ビスの単純な実装に対し,あまりに制限が多いダイナミックリンカをもつプラッ トフォーム上では,GNU DLDを要求したり,libtoolのdlpreopenメカニズムを 用いてダイナミックリンクをエミュレートするだけのものもあります.
libltdlは,現在以下のダイナミックリンクメカニズムをサポートします.
dlopen (Solaris,Linux,そして様々なBSD)
shl_load (HP-UX)
LoadLibrary (Win16とWin32)
load_add_on (BeOS)
以下の例外で,libltdlはGNUライブラリ公有使用許諾書の条件下でライセンス されています.
GNU Lesser General Public Licenseの特別な例外として,GNU libtoolを使用 してビルドされるプログラムやライブラリの一部としてこのファイルを配布す る場合,プログラムの残りに対して使用する配布条件と同じものにして,それ を含めることができます.
libltdl APIは,強力なSolarisとLinuxのdlopenインターフェースに似ていて, それは,非常に簡単ですが強力です.
プログラムでlibltdlを使用するために,ヘッダファイル`ltdl.h'をイン クルードする必要があります.
#include <ltdl.h>
libltdlの前回のリリースでは,POSIX名前空間の慣習に違反していたシ ンボルをいくつか使用していました.これらのシンボルの使用は,現在では非 難されるので,ここで記述されるように置換されました.古い非難されそうな シンボル名に依存したコードがある場合,`ltdl.h'をインクルードする 前に`LT_NON_POSIX_NAMESPACE'を定義すると,変換されたマクロが提供 されます.使用するシンボルの組が何であっても,新しいAPIは前回のものと バイナリ互換ではないので,このバージョンのlibltdlを使用するため,アプ リケーションを再コンパイルする必要があるでしょう.
libltdlがスレッドセーフでない,すなわち,マルチスレッドアプリケーショ
ンは,libtoolに対しミューテックスを使用する必要があることに注意してく
ださい.それは,GNU/Linuxのglibc 2.0の`RTLD_LAZY'を用いた
dlopenが(デフォルトでlibtoolを使用します),スレッドセーフではな
いことが報告されていますが,この問題は,glibc 2.1でおそらく修正される
でしょ.一方,`RTLD_NOW'は,FreeBSD上のマルチスレッドアプリケーショ
ンで問題が生じたと報告されています.これらの問題に関する作業は,読者の
演習として残っています.貢献は,きっと歓迎されます.
以下の型は`ltdl.h'で定義されています.
lt_ptrは,汎用ポインタです.
lt_dlhandleはモジュール"ハンドル"です.すべてのlt_dlopenされる
モジュールはそれに関連付けされたハンドルがあります.
lt_dlsymlistはdlpreopenされるモジュールのシンボルリストです.こ
の構造体は,see section dlopenで記述されます.
libltdlは以下の関数を提供します.
lt_dlinitが正常に呼び出された回数と同じだけ呼び出されたとき,
libltdlを終了するだけです.成功したら0,それ以外ではエラーの番号を返し
ます.
lt_dlopenは,libtoolダイナミックモジュール,プリロードされ
たスタティックモジュール,プログラム自身,そしてネイティブなダイナミッ
クライブラリを開くことが可能です.
モジュール内の未解決のシンボルは,それが依存する(まだ実装されていない)
ライブラリと,前もってdlopenされたモジュールを用いて解決されます.この
モジュールを使用している実行形式が-export-dynamicフラグでリンク
されている場合,実行形式の大域的なシンボルもモジュール内の参照の解決に
使用されます.
filenameがNULLでプログラムが-export-dynamicや
-dlopen selfを用いてリンクされている場合,lt_dlopenはプ
ログラム自身のハンドルを返し,それはそのシンボルのアクセスに使用可能で
す.
libltdlがライブラリを見つけられず,ファイル名filenameがディレク トリコンポーネントを持たない場合,それは,以下の検索パスを(以下の順番 で),さらにモジュールを検索します.
lt_dlsetsearchpath,
lt_dladdsearchdir,そしてlt_dlinsertsearchdirを用いたプ
ログラムで変更可能です.
それぞれの検索パスは,例えば"/usr/lib/mypkg:/lib/foo"のように,
コロンで分離された絶対的なディレクトリのリストにする必要があります.
同じモジュールが複数回ロードされた場合,同じハンドルが返されます.あら
ゆる原因でlt_dlopenが失敗した場合,NULLが返されます.
lt_dlopenと同じです.ファイル名filenameを持つファイルが見
つからない場合,libltdlは,以下の拡張子の追加を試みます.
この探索手法は,本来のダイナミックライブラリの命名規則を知らないプログ
ラムが,そのようなライブラリを,libtoolモジュールと同様に,透過的に
dlopenすることを可能にするために設計されています.
NULLを返します.
NULLを返します.
NULLの場合,lt_dlpreload_defaultで設定
されているリスト以外の,これまで登録されているすべてのシンボルリストが
検出されます.成功時には0を返します.
lt_dlpreloadで検出されません.この関数は,
lt_dlinitを使用して初期化されるためにlibltdlを要求しない
ことと,デフォルトでプリロードされるモジュールを登録するためにプログラ
ムで使用できることに注意してください.この関数を直接呼び出す代わりに,
ほとんどのプログラムはマクロLTDL_SET_PRELOADED_SYMBOLSを使用し
ます.
成功時には0を返します.
#include <ltdl.h>
int main() {
/* ... */
LTDL_SET_PRELOADED_SYMBOLS();
/* ... */
}
lt_dladdsearchdirが呼び出されたのと同様に後
置します.成功時には0を返します.
lt_dlopenが調査する標準的な場所をすべて検索します.この関数は,
これらの呼び出しの一つでもゼロ以外の値が返されるまで,またはファイルが
亡くなるまで,search_pathで見つかったそれぞれのファイルに対し,
funcを呼び出し続けます.`lt_dlforeachfile'は最後の
funcの呼び出しの返り値を返します.
例えば,最初のベクトル(配列)のアドレスを保持しているdataを使用し ているファイルの,順番になっているargvのようなベクトル(配列)を構 築するために,funcを定義することも可能です.
実行しているバイナリに対するhandleを取得するために `lt_dlopen (NULL)'を使用する場合,そのハンドルは常駐しているよう な印が常に付き,したがってうまく`lt_dlclose'することができません.
lt_dlerrorを用いて回収されるエラーメッセー
ジが設定されます.
mallocとfreeに設定されますが,
同等の機能を提供する他の関数に設定可能です.しかし,
lt_dlpreopen_defaultやマクロLTDL_SET_PRELOADED_SYMBOLS以
外のあらゆるlibltdl関数の呼び出し後に,その値を編集すべきではありませ
ん.
dlopen可能なモジュールの作成libtoolモジュールは,いくつかの例外はありますが,通常のlibtoolライブラ リに似ています.
libtoolの`-module'スイッチを用いて,モジュールとリンクする必要が あり,そして,dlopenをサポートしていないプラットフォームでlibtoolが dlpreopenできるよう,`-dlopen modulename.la'を用いてモジュールを dlopenするために,あらゆるプログラムとリンクすべきです.モジュールが, あらゆる他のライブラリに依存する場合,モジュールとリンクするときや,そ れをdlopenするプログラムをリンクするとき,それらを確実に指定してくださ い.特定のモジュールに対しsee section ライブラリインターフェースのバージョンを使用禁止にしたい場合, `-avoid-version'スイッチを用いてリンクすべきです.libtoolモジュー ルは,"lib"接頭辞が不要なことに注意してください.しかし,automake 1.4 やそれ以降のものは,そのようなモジュールのビルドが必要です.
通常,その内部を知る必要なしにプログラムがdlopenできるよう,一組のモ ジュールは同じインターフェース提供し,すなわち同じシンボルをエクスポー トします.すべてのエクスポートされたシンボルで,シンボルの衝突を避ける ため,"modulename_LTX_"を前置する必要があります(`modulename'はモ ジュール名です).内部シンボルは,例えば"_modulename_"を前置するといっ た,他のモジュールと衝突しないような方法で命名する必要があります.一回 以上宣言された,同じシンボルを持つことをサポートするシステムもあります がそれは通常移植性がなく,そのようなモジュールをdlpreopenすることを不 可能にします.libltdlは,シンボルの本当の名前を得るとき,自動的に接頭 辞を切り取ります.さらに,非libtoolモジュールもdlopenできるよう,接頭 辞を使用していないモジュールをサポートします.
`foo1.c'は移植可能なlibtoolモジュールの例です.エクスポートされた シンボルは"foo1_LTX_",内部シンボルは"_foo1_"が前置されています.コー ドの可読性を高めるため,エイリアスは最初に定義されています.
/* aliases for the exported symbols */
#define foo foo1_LTX_foo
#define bar foo1_LTX_bar
/* a global variable definition */
int bar = 1;
/* a private function */
int _foo1_helper() {
return bar;
}
/* an exported function */
int foo() {
return _foo1_helper();
}
`Makefile.am'は,モジュール`foo1.la'をビルドするのに必要な規 則を含んでいます.
... lib_LTLIBRARIES = foo1.la foo1_la_SOURCES = foo1.c foo1_la_LDFLAGS = -module ...
lt_dlmutex_register()関数を使用し,適切なコールバック関数の定義
を提供することで,libltdlをマルチスレッド環境で使用することが可能です.
libltdlは本質的に再帰的なので,これらのコールバック関数によって使用さ れるロックメカニズムが再入可能であることは重要で,そうでなければ,おか しな問題が発生します.
lt_dlerror()
に保存されます.
この形式の関数は,それがマルチスレッドのコンテクストで動作するように, ライブラリに登録される必要があります.関数は,スレッドローカルストレー ジに渡されるあらゆるエラーメッセージを保存すべきです.
正しく登録されたとき,クライアントに対するエラーメッセージを回収するた
めに,全てのスレッドからlt_dlerror())によって,この関数は使用さ
れます.
NULLでな
い関数アドレスにする必要があり,また,そうでない場合は,シングルスレッ
ドオペレーションへの返り値として,全てNULLにする必要があります.
libltdlが管理している,それぞれのロードされたモジュールに関する内部情 報には,ユーザが利用可能なものもあり,それは以下のような構造体の形式で す.
lt_dlinfoは,モジュールの情報を保存するために使用されます.
filename属性は,NULLで終端された,実際のモジュールファイ
ル名の文字列です.モジュールがlibtoolモジュールの場合,nameはそ
のモジュール名(例えば,"dir/libfoo.la"に対する"libfoo")
で,それ以外ではNULLに設定されます.ref_count属性は,現在
ロードされている同じモジュールの回数を記述する参照カウンタです.
以下の関数は,与えられたhandleに対するこの構造体のlibltdlの内部 のコピーへのポインタを返します.
NULLが
返ります.
さらに,ロードした全てのモジュールのハンドルリストを保持する手助けをす るために,これらの関数で,ロードされているモジュールのlibltdlのリスト 全体を繰り返すことが可能となります.
lt_dlforeachに渡すdata引数です.func
がハンドルの一つに対し,ゼロでない値を返すとすぐに,
lt_dlforeachはfuncの呼び出しを停止し,直ちに1を返します.
それ以外は0が返ります.
NULLの場合は,リスト内の最初のハンドルを返し,そし
て順番に次ものを呼び出すことで,ロードされているモジュール全体を繰り返
します.placeが,ロードされているモジュールリスト内の最後の要素
の場合,この関数はNULLを返します.
もちろん,アプリケーションの目的のために,それぞれのハンドルに関連付け する必要があるデータがある場合,libltdlで管理されるリストと平行して, ロードされたモジュールハンドルの独自のリストの管理が必要になります.し かし,個別のモジュールハンドルを用いたアプリケーションデータに,ロード されたものとして関連付けさせるために,以下のAPIの呼び出しを使用す る場合には,実際にはそうする必要はありません.前もって保存したデータを 回収するために後で利用するlibltdlからのユニークな呼び出しidを,最初に 取得する必要があります.これで,ロードされているモジュールに対する独自 のデータを個別に保存したい異なるライブラリが,もう一つの(ライブラリ)の データへのインターフェースなしでそれを行うことが可能となります.
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);
}
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で呼び出し可能な,少なくとも三つの関数を書くことを必
要とします.オプションで,lt_dlexitが実行されるときクリーンアッ
プ処理を実行する終了関数と,lt_dlsymに渡されるあらゆるシンボル
に前置されるシンボルの前置文字を提供することも可能です.これらの関数は,
以下の関数のポインタ型に一致する必要があり,その後,それらを
lt_user_dlloaderの代わりに関連付けし,登録することが可能です.
ローダの登録には,lt_dlloader_findが認識でき,
lt_dlloader_removeで削除できるように,それに対する名前を選択す
ることが必要です.選択した名前はユニークである必要があり,libltdlの組
み込みローダで既に使用しているものはいけません.
lt_dlopenのためのロー
ダ.
前置される"dl"は,libltdlの将来のバージョンで提供されるローダとして予 約されているので,独自のローダ名に使用すべきではありません.
以下の型は,`ltdl.h'で定義されています.
lt_moduleはモジュール依存のdlloaderです.ダイナミックモジュール
ローダの拡張は,これらの低レベルの型を使用して通信を行ないます.
lt_dlloaderはモジュールローダの型に対するハンドルです.
lt_user_dataはローダのインスタンスデータに対して使用されます.
lt_dlopen APIがある場合,これらの構造体のインスタンス
を作成し,それをlt_dlloader_addに渡す必要があります.好みの
dlloader_dataフィールドで渡すことが可能で,それは,関数ポインタ
フィールドで指定されている,それぞれの関数への最初のパラメータの値とし
て返されます.
lt_dlloaderモジュールローダに対するローダ関数の型です.
struct lt_user_dlloader構造体のdlloader_dataフィールドに設定さ
れる値は,loader_dataパラメータで,この関数に渡されます.そのよ
うな関数の実装は,指名されたモジュールのロードを試み,関連する
lt_module_closeとlt_sym_find関数のポインタに渡すのに適切
なlt_moduleを返すべきです.関数が失敗した場合はNULLを返
し,lt_dlseterrorを用いてエラーメッセージを設定すべきです.
lt_dlseterrorを用いてエラーメッセージを設定し,ゼ
ロ以外を返すべきです.
lt_dlseterrorで設定し,NULLを返すべきです.
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はユーザローダの初期 化を扱いません.
終了はlibltdlで扱われますが,dlloader_exitのコールバック
が初期化フェーズの間に要求された,あらゆるリソースを解放することを確か
めることは重要です.
libltdlは,独自のモジュールローダを書くために,以下の関数を提供します.
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 ());
}
lt_dlerrorから取得可能です.
{
/* Remove myloader. */
if (lt_dlloader_remove ("myloader") != 0)
perror (lt_dlerror ());
}
NULLの場合
は最初のローダを返し,順番に次を呼び出すことで行います.ハンドルは,
lt_dlloader_add用です.
{
/* Make myloader be the first one. */
if (lt_dlloader_add (lt_dlloader_next (NULL), myloader) != 0)
return ERROR;
}
NULLを返します.
libltdl自身で使用可能な識別子は,ホストアーキテクチャがサポートしてい る場合はdlopen(10),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;
}
lt_dlloader_nextやlt_dlloader_findで取得される,
PLACEの識別名を返します.この関数が失敗する場合,NULLを返
し,lt_dlerrorで回収するためのエラーを設定します.
lt_dlloader_nextやlt_dlloader_findで取得される,
PLACEのアドレスを返します.この関数が失敗する場合,NULLを
返し,lt_dlerrorで回収するためのエラーを設定します.
lt_dlerrorに組み込むことが
可能となります.lt_dlerrorで返すための適切な診断メッセージに渡
すものと,lt_dlseterrorで使用されるエラー識別子が返されます.
識別子の割り当てが失敗した場合,この関数は-1を返します.
int myerror = lt_dladderror ("Doh!");
if (myerror < 0)
perror (lt_dlerror ());
lt_dlerrorインターフェースを
通じて伝搬されるようにエラーを発生させるために,この関数を使用すべきで
す.libltdlで使用される標準エラーの全ては,`ltdl.h'で宣言されてい
て,そうでなければ,lt_dladderrorを用いて独自に書き加えることが
可能です.
if (lt_dlseterror (LTDL_ERROR_NO_MEMORY) != 0) perror (lt_dlerror ());
libltdlはlibtoolとともにインストールされるのですが,libtoolやlibltdlを
インストールしていないパッケージユーザの利便性のため,パッケージの配布
物にlibltdlを含めたいと思うかもしれません.この場合,手動でパッケージ
に加えるltdlオブジェクト,または,使用したいlibltdlの特色を決定
する必要があります.それは,コンビニエンスライブラリやインストール可能
なlibtoolライブラリです.
libltdlをッケージに加える最も簡単な方法は,ソースファイルの
`ltdl.c'と`ltdl.h'をパッケージのソースディレクトリにコピーし,
ソースの残りと一緒にリンクすることです.これの手助けをするため,
autoconfのm4マクロが`ltdl.m4'で利用可能です.autoconfを実行する前
に,それらが`aclocal.m4'で利用可能かどうかを確かめる必要がありま
す -- automakeを使用している場合は`ltdl.m4'の内容を
`acinclude.m4'に加え,そうでない場合は`aclocal.m4'に加えます.
マクロを利用可能にした後,`ltdl.o'を正しくビルドするために必要な
コンフィグレーション時の調査を実行するため,`AC_LIB_LTDL'マクロの
呼び出しを,パッケージの`configure.in'に加える必要があります.イ
ンストールされているlibltdl やlibltdlに依存しているライブラリと,パケー
ジのバイナリをリンクしようとする場合,この手法には問題があります.シン
ボルの二重定義の問題があるかもしれません.
コンビニエンスライブラリの利点の一つは,インストールされていないという ことなので,libtoolを使用するという事実はユーザにとって明白ではなく, ユーザが以前にインストールしているlibtoolのバージョンを上書きしません. 一方,(例えば,バグフィックスといった)理由があって,libltdlをアップグ レードしたい場合,インストールされているバージョンのlibtoolを置き換え る代わりに,パッケージを再コンパイルする必要があります.しかし,プログ ラムやライブラリが以前にインストールされているバージョンのlibltdlを使 用しているライブラリとリンクする場合,リンカエラーが発生し実行時にクラッ シュするかもしれません.もう一つの問題は,一つ以上のlibtoolライブラリ へコンビニエンスライブラリをリンクできないことで,複製されたシンボルを 得る可能性があるので,そのときは,これらのライブラリを用いた単一のプロ グラムとリンクしてください.一般的に,libtoolを使用している他のライブ ラリに依存しないプログラムでは,コンビニエンスライブラリを問題なく使用 可能です.libltdlのこの特徴を利用可能にするため, `AC_LIBLTDL_CONVENIENCE'行を`configure.in'に, `AC_PROG_LIBTOOL'の前に加えた方が良いでしょう.
インストール可能なバージョンのlibltdlを選択するために,マクロ `AC_LIBLTDL_INSTALLABLE'の呼び出しを`configure.in'に, `AC_PROG_LIBTOOL'の前に加えた方が良いでしょう.このマクロ は,libltdlが既にインストールされているかどうか調査し,そうでない場合, ビルドしインストールされるパッケージlibltdlを埋め込むことを要求します. しかし,バージョン調査は実行されないことに注意してください.ユーザは, コンフィグレーションスイッチ`--enable-ltdl-install'を使用すること で,他のバージョンの存在に関係なく,テストを優先し,埋め込まれた libtoolをインストールする必要があるか決定することができます.
libtoolをパッケージに埋め込むため,libtoolizeコマンドラインに
`--ltdl'のみ加えてください.それで,パッケージのサブディレクトリ
`libltdl'にlibtoolのソースをコピーします.どちらのマクロも,
`libltdl'ディレクトリの位置を指定する追加の引数を受け入れます.デ
フォルトで,どちらのマクロも`${top_srcdir}/libltdl'を仮定します.
どのマクロを使用しても,`configure.in'は`AC_CONFIG_SUBDIRS' を使用して,libltdlをコンフィグレーションし,`Makefile'が,例えば, automakeのSUBDIRSを使用して,libtoolのディレクトリでサブmakeを開 始することを確実にするのはあなたです.どちらのマクロも,libltdlでリン クするために使用するリンクフラグのシェル変数LIBLTDLと, `ltdl.h'をインクルードするプログラムをコンパイルするために使用す るプリプロセッサフラグLTDLINCLを定義します.この変数が `Makefile'で利用可能にすることを確実にするため`AC_SUBST'を使 用したり,デフォルトで`AC_SUBST'される,LIBSと CPPFLAGSのような変数に加えるのはあなた次第です.
コンビニエンスlibltdlを使用している場合,LIBLTDLはコンビニエンス libltdlのバージョンに対するパス名で,LTDLINCLはlibltdlを含むディ レクトリが続く`-I'になり,どちらも`${top_builddir}/',また は,`${top_srcdir}/'で,それぞれ始まります.
インストールされているlibltdlのバージョンを要求し,それが見つかった場 合(11),LIBLTDLは `-lltdl'に,LTDLINCLは空に設定されます(それは,libltdlがラ イブラリパスにある場合,`ltdl.h'がインクルードパスのどこかにある という,暗黙の仮定です).インストール可能なlibltdlのバージョンをビルド する必要がある場合,`${top_builddir}/'で始まるそのパス名は, LIBLTDLに保存され,LTDLINCLはコンビニエンスライブラリの場 合と同様に設定されます.
そのため,libltdlとプログラムをリンクしたいときは,それをインストール された,またはインストール可能なコンビニエンスライブラリにし,すなわち, libtoolを使用して,LTDLINCLを用いてコンパイルし, `$(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 LTDLINCL and LIBLTDL in the Makefiles AC_SUBST(LTDLINCL) 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 = $(LTDLINCL) 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 ...
Go to the first, previous, next, last section, table of contents.