Windows7 64bit版でGo言語のクロスコンパイルを試す

前回のブログの後半に少し書きましたが、私の現在のメイン環境(Windows7 64bit)ではos/userパッケージの関数がそれなりに動作しましたが、WindowsXP 32bit版では正常に動作するか確かめてくてクロスコンパイルを行なってみることにしました。
Go言語では簡単にクロスコンパイルが行えるとのことでしたが、そこはさすがWindows、一筋縄では行かなかったのでその記録を残しておきます。


先人の記録をみると、「GOOS、GOARCH環境変数を設定してbuildするだけ」とあるのでやってみました。
設定すべき値はこちらに書いてあるようです。

$ go version
go version go1.2 windows/amd64
$ set GOOS=windows
$ set GOARCH=386
$ go build -o sample01_windows_386.exe sample01.go
go build runtime: windows/386 must be bootstrapped using make.bat

結果はご覧のとおり、さすがWindows!エラーが出ています。どうやら「Go自体をmakeしろ」と。
そういうならそうしてあげましょう、と、

$ cd \C:\golang\go\src
$ set GOOS=windows
$ set GOARCH=386
$ make
# Building C bootstrap tool.
cmd/dist
'gcc' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

なんと今度はgccが必要だと。


結局WindowsでGoのクロスコンパイルを行うには、

  • gccのインストール
  • Goのmake

が必要になるようです。


ではやってみます。

gccのインストール

とりあえずはgccが動作すれば良さそうなので、MinGWを使用することにします。
64bit版のGoを使用している方は必ずMinGW-gccも64bit版を使用してください。make後ローカル環境が64bit版Goの環境に戻れなくなります。(かもしれません、というかなりました)
ですのでMinGWも64bit版を準備することにします。


Mingw-w64 - GCC for Windows 64 & 32 bits [mingw-w64]のレフトナビからDownloadに移動します。
ページをスクロールしていくと以下の様な場所がありますので、

Windows 64のSourceforge.netリンクをクリックします。
現時点では4.8.2が最新なので、4.8.2→threads-posix→sehと進み、x86_64-4.8.2-release-posix-seh-rt_v3-rev2.7zをダウンロードして保存します。
これをc:\mingw64等に解凍すれば完了です。(必要であれば環境変数にパスを登録してください)
今回はGoのmakeにしか使用しないのでmsys等は不要です。

Goのmake

gccの準備ができたので、Goのmakeにとりかかります。先に試したように、GOOS、GOARCH環境変数を設定してmakeするだけです。

$ cd c:\golang\go\src
$ set path=c:\mingw64\bin;%path%
$ set GOOS=windows
$ set GOARCH=386
$ make
・・・(省略)
Installed Go for windows/386 in c:\golang\go
Installed commands in c:\golang\go\bin

$ go version
go version go1.2 windows/amd64

ローカルの環境はwindows/amd64のままですが、windows/386のコンパイル環境ができあがりました。
64bit版のGoにもかかわらず32bitのgccを使用している場合、makeの一部のフェーズがうまくいかないようで、ローカルも32bitのGoになってしまうことがありました。(私のやり方が悪かっただけかもしれません)

Goでクロスコンパイル

準備もできたのでクロスコンパイルを行います。
linux/386用もコンパイルしています、もちろんlinux/386用にGoをmakeしました)

$ set GOOS=windows
$ set GOARCH=386
$ go build -o sample01_windows_386.exe sample01.go
$
$ set GOOS=linux
$ set GOARCH=386
$ go build -o sample01_linux_386.exe sample01.go
$
$ ls -l
total 2958
-rw-r--r--    1 taknb2   Administ      799 Feb 20 00:38 sample01.go
-rwxr-xr-x    1 taknb2   Administ  1871680 Feb 20 17:53 sample01_linux_386.exe
-rwxr-xr-x    1 taknb2   Administ  1874432 Feb 20 17:50 sample01_windows_386.exe
-rwxr-xr-x    1 taknb2   Administ  2308608 Feb 20 17:31 sample01_windows_amd64.exe

無事に作成できました。できあがったexeは若干サイズが違うようです。
もちろんWindowsXP 32bit、centos4 32bitの環境でもそれぞれ動作しました。
linux用はuser.Currentが定義されていないようです)

まとめ

無事にクロスコンパイルすることができましたが、やはりWindowsでGoをやるには一手間かかるようです。(一度わかってしまえば大したことはないのですが)
ちなみにMacチームは特に問題なくすんなりとできたようです。