Windows上で動作する実行形式は基本的にはWindows上でビルドされるが、GNU/Linux上でMinGWと呼ばれるツール群のクロスコンパイラを用いてビルドすることもできる。
ここではDebian/Ubuntuで簡単に導入可能なパッケージを用いたコンパイル作業についてを扱う。他のディストリでも同様のパッケージが提供される場合があるが、コマンド名や一部ファイルの配置場所が異なる可能性がある。
本記事で扱うパッケージでインストールされるのは本家MinGWではなく、2007年にWin64や追加APIのサポートを目的として派生した “mingw-w64” と呼ばれるプロジェクトが配布しているバージョンとなる。 “w64” と付いているが、Win64専用というわけではなく、Win32にも対応している。
インストールするためのメタパッケージ
プロジェクト名でもある “mingw-w64” という名前のパッケージを選択してインストールすることで、Win32とWin64のどちらのアーキテクチャの実行形式も作成できるようになる。Windows API(DirectX含む)についての開発ファイルもインストールされる。
プログラミング言語のサポートについては基本的にC言語とC++言語のみとなるが、AdaとFortranの2つ[1]については推奨パッケージとして同時にインストールされる場合がある。
Objective-C系のサポートについては
- gobjc-mingw-w64 (Objective-C)
- gobjc++-mingw-w64 (Objective-C++)
パッケージを別途選択・インストールすることで対応できる。
各コンパイラのコマンド名
以下の表に各コンパイラのコマンド名をまとめている。
(x86_32やx86_64のアーキテクチャにおける)GNU/LinuxのGCCでは-m32
や-m64
といったオプションで出力ファイルの “x86_32向けかx86_64向けか” を指定することができるが、このパッケージ群では(そうした仕組みではなく)コマンド名によって対象のアーキテクチャが決まる。
コマンド名 | 対象言語 | 出力 |
---|---|---|
x86_64-w64-mingw32-gcc | C | Win64 |
x86_64-w64-mingw32-g++ | C++ | |
x86_64-w64-mingw32-gnat | Ada | |
x86_64-w64-mingw32-gfortran | Fortran | |
x86_64-w64-mingw32-windres | リソース | |
i686-w64-mingw32-gcc | C | Win32 |
i686-w64-mingw32-g++ | C++ | |
i686-w64-mingw32-gnat | Ada | |
i686-w64-mingw32-gfortran | Fortran | |
i686-w64-mingw32-windres | リソース |
コマンド名の最初の部分が対象アーキテクチャを示し、"w64-mingw32" の後ろの部分は(クロスコンパイラではない、通常の)GCCと同様に対象言語を示している。
各コマンドは末尾に “-posix” が付いたものと “-win32” が付いたものが存在し、前者はスレッドにpthreadが使用できるもので後者はWindows APIのスレッド機能を用いるものとなる。速度に関しては後者のほうが高速とされる。末尾なしのコマンド(上の表に示したもの)はシンボリックリンクとなっており、手元のUbuntu 15.04では “-win32” が付いたほうを指し示している(変更可)。
mingw-w64 3.2.0時点ではpthread版のコンパイラが出力した実行ファイルは動作時にlibwinpthread-1.dll
に依存する。libwinpthread-1.dll
は以下の場所にあるので、ここから実行ファイルのあるディレクトリなどにコピーする必要がある。
- Win64版:
/usr/x86_64-w64-mingw32/lib/
- Win32版:
/usr/i686-w64-mingw32/lib/
この “winpthreads” ライブラリはMITライセンスと一部に修正(三条項)BSDライセンスが使用されており、制約は少ない。
C++言語などのコンパイラ使用時の注意点
C++コンパイラでコンパイル処理を行った実行ファイルはGCC 4.9系時点では以下のDLL(ランタイムライブラリの類)に依存する。
libstdc++-6.dll
libgcc_s_seh-1.dll
これらのファイルは
- Win64 + pthread版:
/usr/lib/gcc/x86_64-w64-mingw32/4.9-posix/
- Win64 + Winスレッド版:
/usr/lib/gcc/x86_64-w64-mingw32/4.9-win32/
- Win32 + pthread版:
/usr/lib/gcc/i686-w64-mingw32/4.9-posix/
- Win32 + Winスレッド版:
/usr/lib/gcc/i686-w64-mingw32/4.9-win32/
に存在するので、コンパイラが出力した実行ファイルのあるディレクトリなどにコピーする。その際、 “posix” と “win32” のDLLは混ぜないように注意する。
他の言語でも、例えばFortranの場合は前述のディレクトリ内の
libgfortran-3.dll
libquadmath-0.dll
[2]libgcc_s_seh-1.dll
が必要になる。
こうしたDLLをコピーする代わりにライブラリを静的リンクする(埋め込む)方法もあり、C++言語の場合はリンク時に “-static-libstdc++ -static-libgcc
” オプションを付ける。
Fortran(でlibquadmath-0.dll
が必要な場合)では “-static-libgfortran -static-libgcc -static-libquadmath
” というオプションを付けたいところだが静的リンクするためのオプションは利用できない。
ただ、同URLの記述を参考に
$ x86_64-w64-mingw32-gcc test.f95 -o test.exe -static-libgcc -Wl,-Bstatic -lgfortran -lquadmath -Wl,-Bdynamic -lm
のようにして静的リンクすることはできる。
GCCランタイムライブラリのライセンスの扱いについて
GCC関係のランタイムライブラリ(GCCが生成した機械語形式のファイルが自動的に依存するもの)の使用については、コンパイルされるプログラムのライセンスに関わらずGCCランタイムライブラリ例外によって許可されている。
コンパイル時にGCCがどのように利用されたかが条件として関わってくる点には注意が必要だが、GCCに含まれるコンパイラをそのまま用いている分には問題はない。
GCCに付属するあるライブラリのライセンスはまだ変更されていません。これらのライブラリはGCCが生成するオブジェクトコードによって自動的に使われます。そのため、これらのライブラリが単にGPLの条項だけで配布された場合、GCCが生成するすべてのオブジェクトコードが同じ条項で配布されなければならないでしょう。しかし、FSFは、開発者がGCCのライブラリを、どのようなプログラムに対しても、そのライセンスにかかわらず使うことを許すことを、だいぶ前に決めました。(中略)GCCランタイムライブラリ例外がカバーするのは、そのライセンスヘッダに例外が適用されると述べられた告知があるすべてのファイルです。これには、libgcc, libstdc++, libfortran, libgomp, libdecnumber, libgcov とGCCで配布されるそのほかのライブラリが含まれます。
ただしlibquadmath[3]についてはLGPLライセンスとなっており、ランタイムライブラリ例外についての記述もないため、configure
スクリプトに--disable-libquadmath-support
オプション[4]を付けずにビルドされた[5]GCCでFortranのプログラムをコンパイルする場合、出力された機械語ファイルはLGPLライセンスのライブラリにリンクしていることになるため、同ライセンスの制約を受ける(将来同ライブラリのライセンスが変更されれば制約はなくなると思われる)。
- mingw-w64 3.2.0
- GCC 4.9.2