MinGWの(クロス)開発環境の作成


諸般の事情*1から、MinGWのクロス開発環境を作った。
MinGWディストリビューションではgcc3が標準だが、gccの配布は最初からMinGWのサポートを含んでいるため通常のgccを適切にconfigureし、ライブラリを配置すればすぐに利用できる。

基本

パッケージのインストールは依存関係を考慮する必要がある。特に、gccをインストールするまでは順番に注意する。これを書いている段階ではC++コンパイラを含んでいない(今回の目的に不要であるため。実際には、gccC言語のみでインストールしたあとに更にgccをインストールする必要が有るように思われる)。

ディレクトリ構成

ディレクトリ構成において重要なのは、hostと同名のディレクトリを準備する必要が有る点。つまり、

  • /opt/mingw/bin - Linuxで動作するツール
  • /opt/mingw/i386-mingw32msvc - Windows向けのバイナリ(COFF)やヘッダファイル

configureのprefixとして、gccbinutilsは/opt/mingwを指定し、他のライブラリ群は/opt/mingw/i386-mingw32msvcを指定する。Linux側で動作するツールであるところのpkg-configも一旦/opt/mingw/i386-mingw32msvcにインストールすることに注意。

開発ツールのインストール

順番が重要。

  • w32api(ヘッダ)

まず、ヘッダファイル群を準備する。これはbinutilsgccコンパイルよりも前に必要になる。/opt/mingw/i386-mingw32msvc以下に、w32api-3.13-mingw32-src.tar.gzに含まれるincludeとlibを展開する。

  • mingwrt

mingwrt-3.15.1-mingw32.tar.gzを/opt/mingw/i386-mingw32msvc以下に展開する。

適当なbinutilsを取得し、configureしてインストールする。

./configure --prefix=/opt/mingw --target=i386-mingw32msvc \
--with-gcc --with-gnu-ld --with-gnu-as --disable-nls --disable-shared

binutilsLinux側で動作するので--disable-sharedをする必要は無い。単にLD_LIBRARY_PATHを管理するのが面倒なのでこれをしている。
binutilsは--hostではなく--targetを使う。gccも同様。

  • pkg-config

適当なバージョンのpkg-configを取得し、configureしてインストールする。

./configure --prefix=/opt/mingw/i386-mingw32msvc

pkg-configはLinux側で動作するツールだが、一旦mingw側にインストールする。インストール後、適当な名前(例えばi386-mingw32msvc-pkg-config)で/opt/mingw/binにシンボリックリンクを作成する。--hostを指定する必要は無い。pkg-configをWindows側で使うことがないため。

インストールする前に、binutilsに対してPATHを通しておく。

export PATH=/opt/mingw/bin:$PATH

適当なバージョンのgccを取得し、configureしてインストールする。gccのソースツリー上でconfigureするのは好ましくないので、可能な限り適当なディレクトリを横に作ってそこで作業する。

/home/oku/build/gcc-4.3.2/configure --prefix=/opt/mingw --target=i386-mingw32msvc \
--disable-nls --disable-shared --without-x --enable-threads=win32 --disable-win32-registry \
--enable-sjlj-exceptions --enable-languages=c --enable-version-specific-runtime-libs --disable-libgomp

gccも--hostではなく--targetを使う。--hostは生成_した_プログラムが動作する場所の指定で、--targetは生成_する_プログラムが動作する場所の指定となる。

  • w32api(ライブラリ)

他のライブラリをインストールする前に、w32apiをインストールする必要が有る(コンパイラのビルド時にはヘッダファイルしか必要としない - 実際のリンクはプログラムを作るまで発生しないため)。

./configure --prefix=/opt/mingw/i386-mingw32msvc --host=i386-mingw32msvc

各種ライブラリのインストール

多くのパッケージは、MinGWと正常に動作できるが、通常のWindowsユーザの使用するアプリケーションが外部DLLに依存するのは望ましくないので、以下のconfigオプションを標準的に使用する。

./configure --disable-shared --host=i386-mingw32msvc --prefix=/opt/mingw/i386-mingw32msvc

hostに関しては通常の指定だが、--disable-sharedは重要で、これをつけることで生成するライブラリは外部のDLLに依存しなくなる*2SDLやcairoをDLLとして配布することに(少なくともWindows上では)メリットが無いため、このオプションが推奨される。

通常のアプリケーションのコンパイル

システムのpkg-configの代わりに、先にリネームしたi386-mingw32msvc-pkg-configを使う。また、この方法でインストールしたライブラリはpkg-configを適切に記述しないことが多いので必要に応じて修正する。例えばSDLであれば、

$ /opt/mingw/i386-mingw32msvc/bin/pkg-config sdl --libs
-mwindows -L/opt/mingw/i386-mingw32msvc/lib -lmingw32 -lSDLmain -lSDL

のように表示されるが、実際には必要な-lwinmmが抜けている。これはi386-mingw32msvc/lib/pkgconfig/sdl.pcを修正する必要が有る。リンク時に発生するエラーのほとんどはこれが原因なので、関数名でWeb検索したり、i386-mingw32msvc/libをgrepする等の方法で適切なライブラリオプションを探して追加することで解決できることが多い。

*1:"Windows上で正常に動作する"PDFを出力できる簡単なドローソフトが必要になった

*2:正確には、Windowsの各種システムDLLやVisualCのランタイムには依存する。