はじめに
UNIX系のフリーソフトウェアはMinGW-w64でビルドすることでWindows上で使えるものも多いですが、Windows上でのMinGW-w64およびMSYS2を使ったビルドは、UNIX系OS上でのセルフビルドと比べて非常に遅いという問題があります。こういった問題はUNIX系OS上でWindows向けにクロスビルドすることで改善することができますが、様々な環境変数やオプションを指定する必要があり、ビルド方法が煩雑になります。また、どちらでビルドするにしても、依存するライブラリについて一つ一つWindows用SDKを用意する必要があり、それらを手動で用意するのも骨が折れます。特に全ての依存ライブラリを自分でビルドしたい場合、ソースコードに手を入れなければならないことも多く、非常に手間がかかります。GNOMEプロジェクトで開発されているJHBuildというビルドシステムを使うことである程度は解決することができますが、Windowsについてはサポートが十分ではなく、素直にビルドが通らないことも多いようです。
これまでは真面目に調べたことがなかったこともあり、なかなか定番と言えるWindows向けクロスビルドシステムが存在しないなと思っていたのですが、最近になってMXE(M cross environment)というクロスビルドシステムの存在を知ったので、紹介致します。
MXEの概要
MXE(M cross environment)はUNIX系OS上からWindowsへのクロスビルドに特化したビルドシステムのようです。このようなビルド環境に特化しているため、サポートされているホストおよびターゲットであれば、ほぼノートラブルでビルドを完了できます。
ビルドシステムはGNU Makefile形式のみで記述されているためシンプルで理解しやすく、新たなパッケージを追加するのも比較的容易です。標準で収録されているソフトウェアはGTKやQt、SDLといったGUI系のものがメインで、非GUI系のものは手薄いという印象です。詳細はMXE: List of Packagesに記載されています。
ビルド環境の準備
MXEを動かすのに必要なソフトウェア一式はMXE: Requirementsに記載されています。
例えばDebianやUbuntuの場合には以下のコマンドで必要なソフトウェア一式をインストールできます。
$ sudo apt install \
autoconf \
automake \
autopoint \
bash \
bison \
bzip2 \
flex \
g++ \
g++-multilib \
gettext \
git \
gperf \
intltool \
libc6-dev-i386 \
libgdk-pixbuf2.0-dev \
libltdl-dev \
libssl-dev \
libtool-bin \
libxml-parser-perl \
lzip \
make \
openssl \
p7zip-full \
patch \
perl \
pkg-config \
python \
ruby \
sed \
unzip \
wget \
xz-utils
DebianやUbuntuではMinGW-w64もapt
コマンドでインストールできますが、MXEの場合はMXEでビルドしたMinGW-w64が使用されるため、インストールする必要は無いようです。
次に、MXEをcloneします。
$ git clone https://github.com/mxe/mxe.git
cloneしたディレクトリに移動し、以下のコマンドを実行することで、要求されるソフトウェアが揃っているか否かをチェックすることができます。
$ make check-requirements
この際、トップディレクトリにビルド設定が記載された settings.mk というファイルが生成されます。 必要に応じて、ビルド前に編集しておくと良いでしょう。
# This is a template of configuration file for MXE. See
# docs/index.html for more extensive documentations.
# This variable controls the number of compilation processes
# within one package ("intra-package parallelism").
#JOBS :=
# This variable controls where intermediate files are created
# this is necessary when compiling inside a virtualbox shared
# directory. Some commands like strip fail in there with Protocol error
# default is the current directory
#MXE_TMP := /tmp
# This variable controls the targets that will build.
#MXE_TARGETS := i686-w64-mingw32.static i686-w64-mingw32.shared x86_64-w64-mingw32.static x86_64-w64-mingw32.shared
# This variable controls which plugins are in use.
# See plugins/README.md for further information.
#override MXE_PLUGIN_DIRS += plugins/apps plugins/native
# This variable controls the download mirror for SourceForge,
# when it is used. Enabling the value below means auto.
#SOURCEFORGE_MIRROR := downloads.sourceforge.net
# The three lines below makes `make` build these "local
# packages" instead of all packages.
#LOCAL_PKG_LIST := boost curl file flac lzo pthreads vorbis wxwidgets
#.DEFAULT_GOAL := local-pkg-list
#local-pkg-list: $(LOCAL_PKG_LIST)
例えば、MXE_TARGETS
を省略すると、デフォルトはi686-w64-mingw32.static
になるようですので、ターゲットをx86_64
にしたい場合や、各種ライブラリを共有ライブラリとしてビルドしたい場合などは事前の設定が必要です。
例:
MXE_TARGETS := x86_64-w64-mingw32.shared
ビルド方法
ビルドは単純で、
$ make レシピ名
でビルドできます。例えばGTK3をビルドした場合は
$ make gtk3
とするだけで、依存ライブラリを含めたソースパッケージのダウンロードやビルドが自動的に実行されます。ビルドされたソフトウェアはデフォルトでは./usr/[ターゲット名]
以下にインストールされるようです。
新たなソフトウェアの追加方法
MXEの各パッケージ向けMakefileはsrcディレクトリ下に[パッケージ名].mkの名前で用意されています。 拡張子が.mkのファイルは自動的に認識されるので、新たなソフトウェアは同様の方法で追加することができます。
また、前述のsetting.mkに以下のような設定があることからもわかるように
# This variable controls which plugins are in use.
# See plugins/README.md for further information.
#override MXE_PLUGIN_DIRS += plugins/apps plugins/native
MEXにはpluginという仕組みがあり、この仕組みを使って新たなパッケージを追加することもできます。プラグインとは言っても、単に.mkファイルを読み込むディレクトリを追加するだけですので、src以下の.mkファイルと同様に変数やマクロを追加(あるいは上書き)するだけです。詳細は、上記のコメントにもある通りplugins/README.mdに記載されています。
まとめ
UNIX系OS上からWindowsへのクロスビルドに特化したビルドシステムMXE(M cross environment)を紹介しました。
クリアコードが過去に関わった案件で、GTKを使用してマルチプラットフォームアプリケーションを開発されているお客様がおられましたが、ビルドシステムは独自に構築されており、そのメンテナンスに多大なコストがかかっていました。当時MXEのことを知っていれば、開発コスト低減の提案が出来ていたかもしれないな、ということが悔やまれてなりません。