日記帳

日記です。

MinGW + MSYS で pkg-config と GLib と gettext をビルド

ちょっと訳あって MinGW + MSYS 環境に pkg-config をインストールしたのでその記録.
忘れたら後で見る用であり,他人が読んで面白い話は特に書いていないのであしからず.

MinGW で pkg-config をビルド

http://pkg-config.freedesktop.org/ からリンクをたどって pkg-config-0.23.tar.gz をダウンロード.

お決まりのパターンで configure && make してみる.

$ tar xfz pkg-config-0.23.tar.gz 
$ cd pkg-config-0.23
$ sh configure --prefix=/mingw
$ make
make  all-recursive
make[1]: Entering directory `/home/sawai/pkg-config-0.23'
Making all in check
make[2]: Entering directory `/home/sawai/pkg-config-0.23/check'
make[2]: Nothing to be done for `all'.
make[2]: Leaving directory `/home/sawai/pkg-config-0.23/check'
make[2]: Entering directory `/home/sawai/pkg-config-0.23'
if gcc -DHAVE_CONFIG_H -I. -I. -I. -DPKG_CONFIG_PC_PATH="\"/mingw/lib/pkgconfig:/mingw/share/pkgconfig\"" -I/mingw/include/glib-2.0 -I/mingw/lib/glib-2.0/include   -g -Wall -O2 -g -O2 -MT pkg.o -MD -MP -MF ".deps/pkg.Tpo" \
  -c -o pkg.o `test -f 'pkg.c' || echo './'`pkg.c; \
then mv -f ".deps/pkg.Tpo" ".deps/pkg.Po"; \
else rm -f ".deps/pkg.Tpo"; exit 1; \
fi
In file included from pkg.c:25:
pkg.h:24:18: glib.h: No such file or directory
In file included from pkg.c:25:
<略>
make[2]: *** [pkg.o] Error 1
make[2]: Leaving directory `/home/sawai/pkg-config-0.23'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/sawai/pkg-config-0.23'
make: *** [all] Error 2

configure は通ったけど make で怒られたですよ.どうやら GLib のヘッダファイルが見付からないらしい.でも pkg-config-0.23/glib-1.2.10 に GLib のソースが入ってるんだし事前にインストールされてなければ同封された GLib をリンクするものなんじゃないかしら… よく解らないので

$ grep glib configure.in

などとして configure.in を読んでみると以下のようになっていた.

case "$host" in
  *-*-mingw*)
    native_win32=yes
  ;;
  *)
    native_win32=no
  ;;
esac
<略>
if test x$native_win32 = xyes; then
  # On Win32, use the normal installed GLib.  Yes, this is a circular
  # dependency. But then, only experienced hackers that presumably can
  # work around that will be building pkg-config and GLib on Win32
  # anyway (especially using the auto*/configure/libtool
  # mechanism). Others use prebuilt versions.
  #
  # These are correct for GLib 2.x
  GLIB_CFLAGS="-I$includedir/glib-2.0 -I$libdir/glib-2.0/include"
  GLIB_LIBS="-L$libdir -lglib-2.0 -liconv -lintl"
  use_installed_glib=yes
else
<略>

MinGW 環境だと同封されている glib-1.2.10 は使わずに必ずインストールされている GLib 2.X 系を使うようになっている.つまり 事前に GLib 2.X 系インストールしておく必要があるということか…

でもコメントを読むと「これは循環依存だ」って書いてある.どういうこと?

MinGW で GLib をビルド

とりあえず GLib をビルドしてみる. http://www.gtk.org/ からリンクをたどって http://ftp.gnome.org/pub/gnome/sources/glib/2.19/ あたりから glib-2.19.4.tar.gz をダウンロード.

$ tar xfz glib-2.19.4.tar.gz
$ cd glib-2.19.4
$ sh configure --prefix=/mingw
<略>
checking for pkg-config... no
configure: error: *** pkg-config not found. See http://www.freedesktop.org/software/pkgconfig/

pkg-config がないって怒られた… pkg-config をビルドするのに GLib が必要で,GLib をビルドするのに pkg-config が必要だと… つまりこれが循環依存ってことか….

依存の循環を断ち切る方法を考えてみる.すぐに思い付くのは以下の2つだ.

  1. pkg-config のバイナリパッケージを用意して GLib をビルドする.
  2. GLib のバイナリパッケージを用意して pkg-config をビルドする.

どちらのバイナリパッケージも http://www.gtk.org/download-windows.html から入手可能だ。

でもよく考えてみると GLib をビルドするのに pkg-config が必要な理由がよくわからない. pkg-config はその実装に GLib を利用しているから依存するのは当然なのだけど.

普通に考えると GLib が他のライブラリに依存していてそのライブラリのチェックに使っているということなんだろう.しかし GLib って割と基礎的な機能を集めたライブラリだしあまり他のライブラリに依存したりしてなかった気がするんだけど…

とりあえず pkg-config が何に使われてるかチェックすればいいよなーってことで以下のような pkg-config をでっち上げて実行権付けてパスの通ったディレクトリに置いておく.

#!/bin/sh
echo pkg-config $* >> /tmp/pkg-config-call.log

置いたら GLib の configure を実行してみる.

$ sh configure --prefix=/mingw
<略>
checking for libintl.h... no
configure: error
*** You must have either have gettext support in your C library, or use the
*** GNU gettext library. (http://www.gnu.org/software/gettext/gettext.html

pkg-config の存在チェックはパスした模様.でも gettext がないって怒られた. Win32 の libc に gettext がないから別途 GNU gettext をインストールする必要があるってことか. configure が途中で止ってしまうと pkg-config の呼出しログが取れないので先に gettext をインストールすることにする.

手元の環境ではインストール済みだったけど必要なら libiconv もインストールするといいかも.

MinGWGNU gettext をビルド

http://www.gnu.org/software/gettext/ からリンクをたどって gettext-0.17.tar.gz をダウンロード.

$ tar xfz gettext-0.17.tar.gz 
$ cd gettext-0.17
$ sh configure --prefix=/mingw
$ make
$ make isntall

ビルドしてインストールする.結構時間がかかったけどこのくらい素直にビルドが通ってくれるとおにーさん嬉しいですよ…

MinGW で GLib をビルド(2)

GNU gettext をインストールしたところで再度 GLib の configure を実行してみる.

$ rm /tmp/pkg-config-call.log
$ sh configure --prefix=/mingw
<略>

とりあえず configure は通ったので pkg-config の呼出しログを見てみる.

$ cat /tmp/pkg-config-call.log
pkg-config --atleast-pkgconfig-version 0.16

あれ? pkg-config が1回しか呼ばれていない…. しかも pkg-config 自体のバージョンチェックをしているだけ…. これって GLib ビルドするのに pkg-config 必要ないってことじゃないか…?

結局また configure を読むことにする.

$ grep '$PKG_CONFIG' configure
  case $PKG_CONFIG in
  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
if test -n "$PKG_CONFIG"; then
  { $as_echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5
$as_echo "$PKG_CONFIG" >&6; }
if test x$PKG_CONFIG = xno ; then
if $PKG_CONFIG --atleast-pkgconfig-version 0.16 ; then
  case $PKG_CONFIG in
  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
if test -n "$PKG_CONFIG"; then
  { $as_echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5
$as_echo "$PKG_CONFIG" >&6; }
  ac_pt_PKG_CONFIG=$PKG_CONFIG
if test -n "$PKG_CONFIG"; then
	if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
 elif test -n "$PKG_CONFIG"; then
    if test -n "$PKG_CONFIG" && \
    { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"libpcre >= \$PCRE_REQUIRED_VERSION\"") >&5
  ($PKG_CONFIG --exists --print-errors "libpcre >= $PCRE_REQUIRED_VERSION") 2>&5
  pkg_cv_PCRE_CFLAGS=`$PKG_CONFIG --cflags "libpcre >= $PCRE_REQUIRED_VERSION" 2>/dev/null`
 elif test -n "$PKG_CONFIG"; then
    if test -n "$PKG_CONFIG" && \
    { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"libpcre >= \$PCRE_REQUIRED_VERSION\"") >&5
  ($PKG_CONFIG --exists --print-errors "libpcre >= $PCRE_REQUIRED_VERSION") 2>&5
  pkg_cv_PCRE_LIBS=`$PKG_CONFIG --libs "libpcre >= $PCRE_REQUIRED_VERSION" 2>/dev/null`
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
	        PCRE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "libpcre >= $PCRE_REQUIRED_VERSION" 2>&1`
	        PCRE_PKG_ERRORS=`$PKG_CONFIG --print-errors "libpcre >= $PCRE_REQUIRED_VERSION" 2>&1`
    if test -n "$PKG_CONFIG" && \
    { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"gtk-doc >= 1.11\"") >&5
  ($PKG_CONFIG --exists --print-errors "gtk-doc >= 1.11") 2>&5

pkg-config を呼び出してるっぽいところを見ると以下のように libpcre をチェックするのに使ってるっぽい.

$PKG_CONFIG --exists --print-errors \"libpcre >= \$PCRE_REQUIRED_VERSION\""

というかそれ以外で呼んでなさそう.しかし GLib は libpcre のソースコードを glib-2.19.4/glib/pcre に同封していてそっちを使う場合は pkg-config を呼ぶことすらないみたい.

結局のところ同封された libpcre を使うことにすれば pkg-config --atleast-pkgconfig-version 0.16 のバージョンチェックさえクリアできればいいことになる.つまり以下のような pkg-config でもでっち上げれば GLib を MinGW でビルドすることはできるってことだ.

#!/bin/sh

なんていうか…馬鹿みたいね…

ということで再度 GLib をビルドしてみる.

$ tar xfz glib-2.19.4.tar.gz
$ cd glib-2.19.4
$ echo "#!/bin/sh" >> pkg-config
$ chmod 755 pkg-config
$ sh configure --prefix=/mingw
$ make
$ make install

MinGW で pkg-config をビルド(2)

これで pkg-config もビルドできるはず.

$ tar xfz pkg-config-0.23.tar.gz 
$ cd pkg-config-0.23
$ sh configure --prefix=/mingw --with-pc-path=/mingw/lib/pkgconfig
$ make
$ make install

ずいぶん遠まわりしたけどようやく pkg-config のビルド完了〜.