2016-12-26時点でのDebian GNU/Linux sidでの話です。
以前、GNU Autotoolsを使ってWindows用バイナリーをビルドする方法を紹介しましたが、ここで紹介するのはCMakeを使う方法です。
CMakeでクロスコンパイルする方法はcmake-toolchains(7)に説明があります。CMakeはクロスコンパイル用にCMAKE_TOOLCHAIN_FILEという変数を用意しています。前述のドキュメントはこの変数を使う方法を説明しています。
ただ、ファイルを作るのは少し面倒なので、ここではコマンドラインオプションでWindows用バイナリーをビルドする方法を紹介します。
用意するもの
Debian GNU/Linux上でWindows用バイナリをビルドするためにはクロスコンパイルする必要があります。そのためにMinGW-w64を使います。MinGW-w64はGCCでWindows用バイナリをビルドするために必要なヘッダーファイルやライブラリなど一式を提供します。
cmakeパッケージとmingw-w64パッケージをインストールします。wineパッケージは動作確認用です。
% sudo apt install -V cmake mingw-w64 wine
準備はこれで完了です。
ビルド
ここではCMakeでのビルドに対応しているGroongaをクロスコンパイルします。
まず、ソースコードをダウンロードして展開します。
% wget http://packages.groonga.org/source/groonga/groonga-6.1.1.tar.gz
% tar xvf groonga-6.1.1.tar.gz
% cd groonga-6.1.1
CMakeを使うときはソースコードのあるディレクトリーではなく別のディレクトリーをビルドディレクトリーにすることが多いですが、ここでは説明を簡単にするためにソースコードのあるディレクトリーを使います。
GNU Autotoolsのときは--host=x86_64-w64-mingw32を指定するだけであとはいい感じに設定してくれますが、CMakeは次のようにいくつかのパラメーターを指定します。この中でクロスコンパイルに直接関係ないパラメーターはCMAKE_INSTALL_PREFIXだけです。これはインストール先を変更するために指定しているだけです。
% PKG_CONFIG_LIBDIR=/tmp/local.windows/lib/pkgconfig \
cmake \
-DCMAKE_INSTALL_PREFIX=/tmp/local.windows \
-DCMAKE_SYSTEM_NAME=Windows \
-DCMAKE_SYSTEM_PROCESSOR=x64 \
-DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc \
-DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++ \
-DCMAKE_RC_COMPILER=x86_64-w64-mingw32-windres
各パラーメーターについて説明します。
-
PKG_CONFIG_LIBDIR:pkg-configが.pcファイルを検索するときに使うパス。通常は(LIBDIRではなく)PKG_CONFIG_PATHを指定するが、クロスコンパイルのときはPKG_CONFIG_LIBDIRを指定して、ビルド環境(この場合はDebian GNU/Linux)の.pcファイルを一切検索しないようにする。 -
CMAKE_SYSTEM_NAME:Windowsを指定するとCMakeに組み込まれているWindows用のビルドの設定を使ってくれる。(/usr/share/cmake-3.7/Modules/Platform/Windows.cmakeなどを使ってくれる。)CMAKE_SYSTEM_NAMEを設定するときはあわせてCMAKE_SYSTEM_VERSIONも設定するべきだが、MinGW-w64でクロスコンパイルするときはCMAKE_SYSTEM_VERSIONを使っていなそうなので省略している。 -
CMAKE_SYSTEM_PROCESSOR: 32bitのバイナリーをビルドするか64bitのバイナリーをビルドするかを指定する。32bitならx86で64bitならx64になる。ここではx64を指定しているので64bitのバイナリーをビルドする。 -
CMAKE_C_COMPILER: MinGW-w64が提供するgccのコマンド名を指定する。PATHが通っていない場合はフルパスで指定する。 -
CMAKE_CXX_COMPILER: MinGW-w64が提供するg++のコマンド名を指定する。PATHが通っていない場合はフルパスで指定する。 -
CMAKE_RC_COMPILER: MinGW-w64が提供するwindresのコマンド名を指定する。PATHが通っていない場合はフルパスで指定する。.rcファイルを使わない場合は指定しなくても大丈夫。
CMAKE_FIND_ROOT_PATH_MODE_PROGRAMなども指定した方が間違ってビルド環境にあるプログラムやライブラリーなどを見つけてしまわなくてよいのですが、Groongaのようにpkg-configを使っている場合は設定しなくても大丈夫です。
あとはmakeでビルドできます。
% make
make installするとCMAKE_INSTALL_PREFIXで指定したディレクトリー以下にインストールされます。
% make install
Wineを使うとDebian GNU/Linux上でインストールしたバイナリーで動作確認できます。Groongaのようにg++を利用している場合はlibstdc++-6.dllとlibgcc_s_seh-1(sehはStructured Exception Handlingの略)がないとバイナリーを実行できません。動作確認する前に${CMAKE_INSTALL_PREFIX}/bin/以下にこれらのDLLをコピーします。
% cd /tmp/local.windows/bin
% cp $(x86_64-w64-mingw32-g++ -print-file-name=libstdc++-6.dll) ./
% cp $(x86_64-w64-mingw32-g++ -print-file-name=libgcc_s_seh-1.dll) ./
これで動作確認できます。
% wine groonga.exe --version
Groonga 6.1.1 [Windows,x64,utf8,match-escalation-threshold=0,nfkc,onigmo]
configure options: <>
CPackを使えばビルドしたバイナリーを含むアーカイブを作成することができます。PGroongaはCPackを使ってバイナリー入りアーカイブを作成しています。
CMakeLists.txtにCPackの設定がある場合は次のようにすればアーカイブを作成できます。
% make package
まとめ
Groongaを例にしてDebian GNU/Linux上でCMakeを使ってWindows用のバイナリーをビルドする方法を紹介しました。CMakeを使っているプロダクトをクロスコンパイルしたいときは参考にしてください。