Autotools三兄弟の末っ子Libtoolとは何者なのか

このエントリーはKLab Advent Calendar 2015の9日目の記事です。

唐突なタイトルですが、本稿ではLibtoolについて一般人目線での紹介をします。Libtoolは裏方のソフトウェアで、明示的に使ったことがある人はほとんどいないと思います。私自身、今まであまり意識していませんでしたが、改めて調べてみると実は身近な存在だということがわかりました。

AutoconfとAutomake

私が勝手にAutotools三兄弟と呼んでいるのはAutoconfAutomakeLibtoolの3つです。このうちAutoconfとAutomakeは知名度が高いソフトウェアだと言えるのではないでしょうか。これら2つは configure スクリプトと Makefile の生成を手伝ってくれるソフトウェアで、OSSプロジェクトで広く利用されています。

自作ソフトウェアでAutoconfとAutomakeなら使ったことがあるよ、という読者の方もいらっしゃるのではないでしょうか。使い方にかなりクセがありますが、ソフトウェアを様々な環境で動かす場合には便利なツールだと思います。

一方、これら2つに比べるとLibtoolの知名度は非常に低い印象があります。そもそも名前を聞いてもピンとこない方が多いのではないでしょうか。私も少し前までGNU Binutilsの仲間かと思っていました。

Libtoolとは

Libtoolを一言で説明すると、同一のインターフェースから複数環境上での共有ライブラリのビルドを実現するようなツールです。普通はAutoconf/Automakeとセットで利用して、ビルド手順を簡潔に記述するのに利用します。

たとえば、共有ライブラリのビルド時はコンパイラオプションでPIC(Position Independent Code、位置独立コード)の指定を行いますが、そのコンパイラオプションは環境によって変わったりします。また、Mac OS X上では共有ライブラリの拡張子が .so でなく .dylib になるなど、環境ごとにどうでもいい違いがたくさんあったりします。

Libtoolはこうした環境ごとの差異を隠蔽してくれるので、多くのUNIX系OS上で使われるようなOSSプロジェクトでは非常に有用です。逆に、Linux+gcc環境だけで動けばいいような場合は大げさすぎる道具だと言えます。

謎の拡張子.laの正体

さて、ここからが本題です。Linuxディストリビューションでライブラリ類をインストールすると、バイナリパッケージ内に次のようなファイルが含まれていることがあります。

/usr/lib/x86_64-linux-gnu/lib*.a
/usr/lib/x86_64-linux-gnu/lib*.la
/usr/lib/x86_64-linux-gnu/lib*.so

*.a*.so がそれぞれ静的ライブラリと共有ライブラリなのはわかりますが、 *.la は何に使うファイルなのでしょうか?私は以前から疑問に思っていたものの、謎のまま過ごしてきました。

これはLibtoolがライブラリのリンク時に作るファイルで、このライブラリを別バイナリから使うような場合に必要な情報が含まれています。Libtool経由でこのライブラリをリンクすると、このファイルの情報を元に適切なリンクオプションを補ってくれたりするわけです。つまり、このファイルはLibtoolから見ると *.a に準ずるような存在のファイルだと言えます。

他にも、Libtoolを使っていると *.lo というファイルが作られますが、これも同名の *.o に対応するようなファイルで、やはりリンクのための情報を持っていたりします。

Cプログラミングに十分慣れていたとしても、 *.la*.lo などは見覚えのないファイルなので、消していいのか悪いのかなど判断がつかなかったりします。正体がわかっていると *.a*.o と同等だと見なせるので、たとえば .gitignore に追加すべきだという判断もつくわけです。

既存プロジェクトのLibtool対応

実は、Autoconf/Automakeを使ったことがあれば、Libtoolの利用は非常に簡単です。自分のプロジェクトでライブラリの -fPIC をつけるかつけないかの話題から解放されたい!というだけであれば、数行の変更で済んでしまいます。

普段通りに書いた autoconf.ac に下記の1行を追加した上で

AC_PROG_LIBTOOL

Makefile.am のライブラリ関連の指定を次のように書くだけです。

lib_LTLIBRARIES = libfoo.la
libfoo_la_SOURCES = foo.c

こうすると configure スクリプトの --enable-static--enable-shared の指定を反映して静的ライブラリ・共有ライブラリがそれぞれ生成されるようになりますし、自分で明示的に -fPIC-rpath などの設定をする必要もなくなります。このあたりの知識がフワっとしていても正しくライブラリが作れるのは幸せですね(本当はもう少し深掘りしないとなーと思いつつ…)。


@hnw

このブログについて

KLabのゲーム開発・運用で培われた技術や挑戦とそのノウハウを発信します。

おすすめ

合わせて読みたい

このブログについて

KLabのゲーム開発・運用で培われた技術や挑戦とそのノウハウを発信します。