ライブラリを実行形式とリンクする前に,インストールする(恒久的な 場所にそれを配置する)場所を選択した場合,リンクするためにlibtoolを使用 する必要はありません.ライブラリの位置を指定するため,単純に適切な ‘-L’と‘-l’フラグを使用してください.
システムのリンカによっては,結果として生じる実行形式に,共有ライブラリ の完全なディレクトリ名の符号化を強要するものもあります.libtoolは,恒 久的なディレクトリ名のみをインストールされた実行形式に書き込むことを確 実にするため,特別な魔法でこの設計ミスに関して動作する必要があります.
このバグの重要性は見落としてはなりません.それによるプログラムの暴走は 明白ではありません.それはセキュリティホールを作成し,さらに悪いことに は,パッケージのインストール後にライブラリソースコードを編集した場合, インストールされたプログラムの動作を変更してしまうでしょう!
そのため,インストールする前にライブラリとプログラムをリンクさせたい場 合,リンクするためにlibtoolを使用する必要があります.
インストールされていないライブラリとリンクする古い方法は,以下のように なります.
burger$ gcc -g -O -o hell.old main.o libhello.a -lm burger$
libtoolの方法は,ほとんど同じです1(see Link mode).
a23$ libtool --mode=link 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 --mode=link 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 --mode=link 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にある)共有ライブラリを見つけることを保証しま す.
二つの異なるプログラムを比較してみましょう.
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$
うーん,だめだなあ2.おそらく, 私はこのプロジェクトを破壊し,作成中のゆりかごを取り上げたほうがいいで しょう.
実際,それは重要なことを証明しています.共有ライブラリには,それが(関 連する)複雑さのため,オーバーへッドをがあります.この状況では,ダイナ ミックの価値は8キロバイトで,報酬は約4キロバイトです.そのため,少なく とも二,三個以上のプログラムとリンクするまで,共有される libhelloを維持することは利点になりません.