pkg-config をクロス開発で使う

今更だが、pkg-config をクロス開発用に使ってみた。
(今までは configure をコツコツとハックしていた)

pkg-config は、どのようなライブラリがインストールされているかを教えてくれるツールで、クロス開発における使われ方は、あるライブラリ/アプリケーションのビルドのために、そのライブラリ/アプリケーションが依存するライブラリに関する、コンパイルオプションやリンクオプションの情報を知るために configure が使う。

また、ライブラリ自体が存在するかの確認にも使われる。

クロス開発、と言ったが、このツールはホストマシンで動き、環境変数を与えなければホストマシンの環境を知るために使われる。

例えば、以下は手元の Ubuntu で pkg-config を使った例である:

$ pkg-config --list-all
libpng                      libpng - Loads and saves PNG files
glib-2.0                    GLib - C Utility Library
libpng12                    libpng - Loads and saves PNG files
directfb                    DirectFB - Graphics and windowing library for the Linux frame buffer device

以下のようにすると、そのパッケージのコンパイル・リンクに必要なオプションを知ることが出来る:

$ pkg-config --cflags --libs directfb
-D_REENTRANT -I/usr/local/include/directfb  -L/usr/local/lib -ldirectfb -lfusion -ldirect -lpthread

pkg-config で得られる情報は、Ubuntu なら /usr/lib/pkgconfig/ 以下にある *.pc ファイル、手元の FreeBSD では /usr/local/libdata/pkgconfig 以下にある *.pc ファイルに格納されている。-I/usr/... 以下を見れば分かるとおり、これはホストマシンの ( i386Ubuntu の)環境を指している。

クロス開発用に pkg-config を用いる場合は、環境変数 PKG_CONFIG_LIBDIR を設定すれば良い。
例えば、クロス開発用のインストールディレクトリが ~/microBlaze/lc6/linuxLibs/install だとすると、

$ export PKG_CONFIG_LIBDIR=~/microBlaze/lc6/linuxLibs/install/lib/pkgconfig

とすれば良い。うまくいけば、pkg-config --list-all の結果が変わるはずだ:

$ pkg-config --list-all
directfb          DirectFB - Graphics and windowing library for the Linux framebuffer device
direct            Direct - DirectFB base development library
freetype2         FreeType 2 - A free, high-quality, and portable font engine.
directfb-internal DirectFB-Internal - Third party module support package for DirectFB.
zlib              zlib - zlib compression library
libpng            libpng - Loads and saves PNG files
libpng12          libpng - Loads and saves PNG files
fusion            Fusion IPC - High Level IPC Mechanisms

$ pkg-config --cflags --libs directfb
-D_REENTRANT -I/home/hal/microBlaze/lc6/linuxLibs/install/include/directfb  -L/home/hal/microBlaze/lc6/linuxLibs/install/lib -ldirectfb -lfusion -ldirect -lpthread


メモ:
pkg-config のソースを見たところ、環境変数 PKG_CONFIG_LIBDIR は、デフォルトで検索する .pc ファイルの格納ディレクトリを変更し、PKG_CONFIG_PATH という環境変数は、デフォルトで検索するディレクトリへ、ディレクトリを追加する。
クロス開発する場合は PKG_CONFIG_LIBDIR を必ず指定しなければならない。そうしないと、間違えてホストマシン用のコンパイル・リンクオプションが有効になってしまうことがある。

本家のドキュメントにも、それらしいことが書いてあった:
http://www.freedesktop.org/wiki/Software/pkg-config/CrossCompileProposal

メモ2:
pkg-config の環境をクロス開発用に整えたからといっても、configure の際に色々と問題は起きる。
例えば、DirectFB は libpng の存在チェックに pkg-config を使わず、libpng-config というコマンドを使うので、configure の際に無理やり LIBPNG_CONFIG を設定しないとクロスコンパイル出来ない。
また、libjpeg のように pkg-config 用の .pc ファイルを生成しないライブラリもあるので注意が必要である。
よって、configure のハックは pkg-config を導入しても、必要かもしれない。