MinGWでのGDCビルド手順
Table of Contents
1 はじめに
GDCはGCCのD言語 フロントエンドです。 sourceforge でのメンテナンスが止まって いたのですが、bitbucket で 引き継ぐ形でメンテナンスが行われ、その後 github に引っ越してメンテナンスされています。 2013年03月現在はtrunkは2.062(MinGW向けは2.060)に追従しており、本家とあまり離れてはいない状況です。
2013年03月時点でも、残念ながらCygwinでのビルドはできませんが、MinGWでのビルドが 可能となっています。ただし、MinGW向けはtrunkとは別にメンテナンスされており、 ベースとなるgccは4.6.xが対象となっています。 ここでは、最新のGDC&GCCに追従すべく敢えてソースからビルドする方法を示してます。
3 必要なファイル
以下のtar-ballを公式ページやWebミラーなどからダウンロードしてください。
3.1 MinGW32 のGDCビルドに必要なファイル
- binutils-2.22.tar.bz2 : binutilsのソース一式
- gcc-4.6.3.tar.bz2 : GCCのソース一式
- GDC-924f4bf0bbde5d425abefb85ebfca08f90ad39a5.zip : GDCのソース一式
- mingwrt-3.20-mingw32-src.tar.gz : MinGW ランタイムソース一式
- w32api-3.17-2-mingw32-src.tar.lzma : w32apiソース一式
- gdc_924f4bf0bb_mingw.patch : 不具合解消パッチ
3.2 MinGW64 のGDCビルドに必要なファイル
- binutils-2.22.tar.bz2 : binutilsのソース一式
- gcc-4.6.3.tar.bz2 : GCCのソース一式
- GDC-924f4bf0bbde5d425abefb85ebfca08f90ad39a5.zip : GDCのソース一式
- mingw64-runtime-tdm64-gcc46-svn4483.tar.lzma : TDM-GCC用MinGW64ランタイムバイナリ
- mingw64-runtime-svn4483-src.zip : TDM-GCC用MinGW64ランタイムソース一式
- gdc_924f4bf0bb_mingw.patch : 不具合解消パッチ
3.3 使用するGDCソースについて
GCCは実際にビルドして特に問題の無かった4.6.3を使用しています。 GDCのソースアーカイブはgithubのGDCページからダウンロードするのですが、 trunkではなくvenix1氏がメンテナンスしているfork版を使用します。 具体的には 924f4bf0bbde5d425abefb85ebfca08f90ad39a5 から、ZIPファイルでダウンロードします。
MinGW向けGDC対応をメインで行っているvenix1氏は、2013/01月時点でも bitbucket のダウンロード ページに実行バイナリを提供してくれています。このバイナリはgcc-4.6.1をベース にビルドしています。これは、MinGWは本家がやっと4.7.xに移行されたという状況なのですが、 MinGWランタイムにTLS関連のパッチが必要という状況もあって、4.7.xにはまだ移行できていない ようです。
また更にややこしい事情があります。 GDCのtrunkは開発中であるgcc-4.8をターゲットとして作業をしています。 そしてtrunkはgcc-4.6.xと4.7.xをサポートから外してしまっています。 ではどうやって4.6.xに対応しているのかと言うと、venix1氏が 外された4.6.xのパッチを復活させつつtrunkとマージしているという事を行っています。 この為、MinGW向けはtrunkに比べて少し遅れて追従している感じになってます。
4 MinGW32 でビルド
例では /mingw/gdc031_2060_463 にインストールするものとしてビルドします。 アーカイブ群は ~/arc の下に、ビルドはカレントディレクトリで行うものとします。
まずはGDCのソース本体を展開します。
unzip ~/arc/GDC-924f4bf0bbde5d425abefb85ebfca08f90ad39a5.zip
cd GDC-924f4bf0bbde5d425abefb85ebfca08f90ad39a5
binutilsをビルドします。
bzip2 -dc ~/arc/binutils-2.22.tar.bz2 | tar xf -
pushd binutils-2.22
patch -p1 < ../patches/tls-binutils-2.21.53-20110731.patch
popd
mkdir build_binutils
pushd build_binutils
../binutils-2.22/configure --build=mingw32 --with-arch=i686 --prefix=/mingw/gdc031_2060_463 --disable-nls --disable-win32-registry
make
make install
popd
gccとgdcをビルドします。
bzip2 -dc ~/arc/gcc-4.6.3.tar.bz2 | tar xf -
./update-gcc.sh --setup ./gcc-4.6.3
pushd gcc-4.6.3
patch -p1 < ../patches/mingw-tls-gcc-4.6.x.patch
patch -p1 < ~/arc/gdc_924f4bf0bb_mingw.patch
popd
mkdir build_gdc
pushd build_gdc
../gcc-4.6.3/configure --build=mingw32 --with-arch=i686 --enable-languages=c,d --prefix=/mingw/gdc031_2060_463 --enable-threads --enable-fully-dynamic-string --enable-libstdcxx-debug --enable-version-specific-runtime-libs --disable-nls --disable-win32-registry --disable-symvers --disable-werror --enable-sjlj-exceptions --with-bugurl=https://bitbucket.org/goshawk/gdc/issue --disable-bootstrap --disable-shared --disable-libgomp --disable-libmudflap
make
make install
popd
MinGWのランタイムライブラリをビルドします。
gzip -dc ~/arc/mingwrt-3.20-mingw32-src.tar.gz | tar xf -
lzma -dc ~/arc/w32api-3.17-2-mingw32-src.tar.lzma | tar xf -
mv w32api-3.17-2-mingw32 w32api
pushd mingwrt-3.20-mingw32
patch -p1 < ../patches/tls-mingwrt-3.20.patch
patch -p1 < ../patches/tlssup.c.patch
./configure --prefix=/mingw/gdc031_2060_463
make
make install
popd
以上で、/mingw/gdc031_2060_463/binにパスを通せばgdcコンパイラが使用できます。
$ gdc -v Using built-in specs. COLLECT_GCC=C:\MinGW\gdc031_2060_463\bin\gdc.exe COLLECT_LTO_WRAPPER=c:/mingw/gdc031_2060_463/bin/../libexec/gcc/mingw32/4.6.3/lto-wrapper.exe Target: mingw32 Configured with: ../gcc-4.6.3/configure --build=mingw32 --with-arch=i686 --enable-languages=c,d --prefix=/mingw/gdc031_2060_463 --enable-threads --enable-fully-dynamic-string --enable-libstdcxx-debug --enable-version-specific-runtime-libs --disable-nls --disable-win32-registry --disable-symvers --disable-werror --enable-sjlj-exceptions --with-bugurl=https://bitbucket.org/goshawk/gdc/issue --disable-bootstrap --disable-shared --disable-libgomp --disable-libmudflap Thread model: win32 gcc version 4.6.3 (GCC)
コマンドラインだけを列記しましたが、gdcのREADMEも読んでみてください (ただし内容が若干古いようです(^^;)。
5 MinGW64 でビルド
MinGW64 でのビルドには TDM-GCC を使用します。 本当は32bitと64bitにマルチ対応できるようなのですが、うまくいかなかったので 64bit専用になります。
例では /mingw/gdc64_031_2060_463 にインストールするものとしてビルドします。 アーカイブ群は ~/arc の下に、ビルドはカレントディレクトリで行うものとします。
まずはMinGW64のランタイムライブラリをインストール先に展開します。
mkdir -p /mingw/gdc64_031_2060_463
pushd /mingw/gdc64_031_2060_463
lzma -dc ~/arc/mingw64-runtime-tdm64-gcc46-svn4483.tar.lzma | tar xf - x86_64-w64-mingw32
popd
GDCのソース本体を展開します。
unzip ~/arc/GDC-924f4bf0bbde5d425abefb85ebfca08f90ad39a5.zip
cd GDC-924f4bf0bbde5d425abefb85ebfca08f90ad39a5
binutilsをビルドします。
bzip2 -dc ~/arc/binutils-2.22.tar.bz2 | tar xf -
pushd binutils-2.22
patch -p1 < ../patches/tls-binutils-2.21.53-20110731.patch
popd
mkdir build_binutils
pushd build_binutils
../binutils-2.22/configure --build=x86_64-w64-mingw32 --with-arch=i686 --prefix=/mingw/gdc64_031_2060_463 --disable-nls --disable-win32-registry
make
make install
popd
gccとgdcをビルドします。
bzip2 -dc ~/arc/gcc-4.6.3.tar.bz2 | tar xf -
./update-gcc.sh --setup ./gcc-4.6.3
pushd gcc-4.6.3
patch -p1 < ../patches/mingw-tls-gcc-4.6.x.patch
patch -p1 < ~/arc/gdc_924f4bf0bb_mingw.patch
popd
mkdir build_gdc
pushd build_gdc
../gcc-4.6.3/configure --build=x86_64-w64-mingw32 --enable-languages=c,d --prefix=/mingw/gdc64_031_2060_463 --enable-threads --enable-fully-dynamic-string --enable-libstdcxx-debug --enable-version-specific-runtime-libs --disable-nls --disable-win32-registry --disable-symvers --disable-werror --enable-sjlj-exceptions --with-bugurl=https://bitbucket.org/goshawk/gdc/issue --disable-bootstrap --disable-shared --disable-libgomp --disable-libmudflap --disable-multilib
make
make install
popd
MinGW64のランタイムライブラリをパッチを当てて再ビルドします。
unzip ~/arc/mingw64-runtime-svn4483-src.zip
pushd mingw64-runtime-svn4483-src
patch -p1 < ../patches/tls-mingw64-runtime.patch
./configure --prefix=/mingw/gdc64_031_2060_463 --build=x86_64-w64-mingw32
make
make install
popd
以上で、/mingw/gdc64_031_2060_463/binにパスを通せばgdcコンパイラが使用できます。
$ gdc -v Using built-in specs. COLLECT_GCC=C:\MinGW64\gdc64_031_2060_463\bin\gdc.exe COLLECT_LTO_WRAPPER=c:/mingw64/gdc64_031_2060_463/bin/../libexec/gcc/x86_64-w64-mingw32/4.6.3/lto-wrapper.exe Target: x86_64-w64-mingw32 Configured with: ../gcc-4.6.3/configure --build=x86_64-w64-mingw32 --enable-languages=c,d --prefix=/mingw/gdc64_031_2060_463 --enable-threads --enable-fully-dynamic-string --enable-libstdcxx-debug --enable-version-specific-runtime-libs --disable-nls --disable-win32-registry --disable-symvers --disable-werror --enable-sjlj-exceptions --with-bugurl=https://bitbucket.org/goshawk/gdc/issue --disable-bootstrap --disable-shared --disable-libgomp --disable-libmudflap --disable-multilib Thread model: win32 gcc version 4.6.3 (GCC)
コンパイラオプションに「-m64」を指定する事でx86_64をターゲットとして コンパイルできます。32bitでコンパイルOKなソースも64bitで結構コンパイルエラー しますので、がんばって直す必要があるでしょう(^^;
6 Cygwinからの使用について
コンパイラを使用するにあたって、MSYSのコンソールはコピペできないとか 色々面倒臭いので、TANEはCygwinから使用しています。 具体的にはCygwinのルートディレクトリ直下に以下のようなシンボリックリンクを 張っています。
$ ls -l /MinGW* lrwxrwxrwx 1 TANE None 17 6月 6 2012 /MinGW -> /cygdrive/c/MinGW lrwxrwxrwx 1 TANE None 19 6月 9 2012 /MinGW64 -> /cygdrive/c/MinGW64
MinGW32のgdcを使用する場合は「/MinGW/gdc031_2060_463/bin:/MinGW/bin:」を現在のパスに追加し、 MinGW64のgdcを使用する場合は「/MinGW64/gdc64_031_2060_463/bin:/MinGW64/bin:」を現在のパスに追加 します。
常にパスに足してしまうとCygwinのgccとかツールを使う時に困る場合があるので、 必要な時だけパスを足して使うという感じです。
7 パッチについて
ビルドしたコンパイラを使用してみたのですが、いくつか不具合に見舞われました。 パッチ gdc_924f4bf0bb_mingw.patchは以下の不具合を解消します/したつもりになってます。
- 2012/12/22時点
D言語ソース内で「2^^18」のようなPow式(累乗)を使用したとき、結果が0となるような アセンブラコードが生成されました。 gcc-4.6.3/gcc/d/dfrontend/constfold.cの一部を少し前のコードに置き換えています。
- 2012/12/22時点
プロセス終了時にSegmentFaultで落ちる場合がある。 gcc-4.6.3/libphobos/libdruntime/gc/gcx.dを少し改造しています。 ただし本当にこれで大丈夫かよくわかってません(^^;
- 2012/12/22時点
リンクにおいて core/sys/windows/mingwex.oに含まれるシンボルと元々のMinGWライブラリ に含まれるシンボルとが衝突する。 gcc-4.6.3/libphobos/libdruntime/Makefile.in から外しました。
- 2012/12/22時点
gdcのビルド途中でエラーしてphobosのビルドに失敗する。 core/sys/freebsd/sys/event.diを gcc-4.6.3/libphobos/libdruntime/Makefile.inから外しました。
2012/12/22時点→ 2013/03/11時点gdcのビルド途中でエラーしてphobosのビルドに失敗する。std/__fileinit.oをgcc-4.6.3/libphobos/Makefile.inから外しました。GDC-924f4bf0bbde5d425abefb85ebfca08f90ad39a5で同様の対処が行われました。
- 2012/12/22時点
std.string.format()での表示が変になりました。 xformat()という名前でリライトが進められているようで、こちらを使用すると 問題なかったことから、 format()とxformat()、sformat()とxsformat()の名前を入れ替えるようような改造を gcc-4.6.3/libphobos/std/string.dに行いました。
- 2013/03/10時点
32bitターゲットでビルドした時にlong型の定数代入が化ける問題がありました。 例えば「long foo = 36000000000 ;」としたコードが「foo = 1640261632;」 として動作してしまいます(64bitの上位32bitが0になっている)。これが原因で std.datetimeがうまく動かないように見えていました。 gcc-4.6.3/gcc/d/d-codegen.ccを改造しましたがstd.regexでワーニングメッセージ が出るようになります。
c:\mingw\gdc031_2060_463\include\d\4.6.3\std\regex.d: In member function 'std.regex.Regex!(char).Regex.lightPostprocess': c:\mingw\gdc031_2060_463\include\d\4.6.3\std\regex.d:2025: warning: comparison always true due to limited range of data type
ワーニングが出ないようにstd.regex.dを直す事はできますが、コンパイラの対応方法が 悪いのかも知れませんのでそのままにしてあります。 64bitターゲットでは問題無いようです。
8 その他
本家のdmdコンパイラはバグの再現性確認程度にしか使用した事がありません。 ライブラリやツールの事が良くわからないからというのが理由です(^^; GDCを使用するメリットは多数ありますが、デメリットも多数存在します。
- メリット
- MinGW用にビルドされたライブラリが使用できる。
- gdbが使用できる。gdb-7.2でD言語がサポートされました。
- デメリット
- DMDサイトなどで書かれている例がそのまま使えない場合がある。
- DMD最新バージョンリリースよりも遅れる。2012年12月時点でもgithubの活動が活発な為、 極端に離れる事にはなってませんが、この先も大丈夫な保証はありません。
- コンパイルが遅い。
- GDCでしか起こらない不具合がありうる。
- MinGWでGDCを使う人が殆ど居ない。この為、なにやら動かなくても ある程度自力解決が求められる。
うーむ、やっぱりまだデメリットの方が多いなぁ(^^; まぁ、「そこに山があるから」という事で。
9 履歴
2011/05/15 : Cygwin用のビルド説明からfork。 2012/03/20 : ページをEmacsのorg-modeを使用して生成してみた。内容は2011/05/15と同じです。 2012/08/11 : 誤記修正。 2012/12/22 : GDC-d16af9d0d8をベースにビルド方法をアップデート。 2012/12/23 : ちょこっと修正。 2013/03/10 : パッチファイル「gdc_d16af9d0d8_mingw.patch」がアップロードされていなかったのに今頃気づいた(滝汗;;;; long型化け対応パッチ「gdc_d16af9d0d8_mingw.patch2」を置いた。 2013/03/11 : GDC-924f4bf0bbをベースにビルド方法をアップデート。