Goコンパイラは単体で別アーキテクチャのバイナリを簡単に出力できる点が素晴らしいですよね。また、C/C++のクロスコンパイラを持っていればcgoが必要な場合でもクロスコンパイルが可能です。
ところで、私は突然Linux/MIPS向けにcgoを利用したくなったのですが、Linux/MIPS向けのC/C++クロスコンパイル環境は手元にありません。どうせ今から環境を作るなら、手元の環境にC/C++クロスコンパイル環境を作るより、Linux/MIPS上にGoコンパイル環境を作った方が楽かもしれません1。
そこで、Linux/MIPS上でGo 1.9をビルドしてみることにしました。手元に適当な実機が無いため、macOS+QEMU上にLinux/MIPS環境を構築し、その上でGoをビルドします。
QEMU上でLinux/MIPSを動かす
まずQEMUをインストールします。
$ brew install qemu
次にLinux/MIPSを用意します。QEMU上でDebianのCD/DVDイメージからインストールすることも可能ですが、今回はAurélien Jarnoさんが配っているQEMU用のイメージを利用します。mipsディレクトリから下記ファイルをダウンロードします。
- debian_wheezy_mips_standard.qcow2
- vmlinux-3.2.0-4-4kc-malta
上記ファイルを同一ディレクトリに置いた上で、下記のようにすれば起動できます。
$ qemu-system-mips -M malta -kernel vmlinux-3.2.0-4-4kc-malta -hda debian_wheezy_mips_standard.qcow2 -append "root=/dev/sda1 console=ttyS0" -nographic
デフォルトではメモリサイズ128Mと小さめなので、-m 512M
などとした方がいいかもしれません。
Goのインストール
まずはmacOS上で、1.4のホスト用bootstrapツールをビルドします。
$ tar xvzf go1.4-bootstrap-20170531.tar.gz
$ mv go go1.4-bootstrap-20170531
$ cd go1.4-bootstrap-20170531/src
$ ./make.bash
(snip)
$ cd ../..
次にGo 1.9ベースでMIPS用のbootstrapツールをビルドします(Goが1.4時点ではMIPS対応していなかったので、回りくどい作り方になります)。
$ tar xvzf go1.9.src.tar.gz
$ mv go go1.9-bootstrap-mips
$ cd go1.9-bootstrap-mips/src
$ GOROOT_BOOTSTRAP=$(pwd)/../../go1.4-bootstrap-20170531 GOOS=linux GOARCH=mips ./bootstrap.bash
(snip)
bootstrap.bash
が成功するとgo-linux-mips-bootstrap.tbz
が作られるので、QEMU上のLinux/MIPSに何らかの方法でコピーします。
以下、Linux/MIPS上で作業します。
# tar xvjf go-linux-mips-bootstrap.tbz
# tar xvzf go1.9.src.tar.gz
# mv go go1.9
# cd go1.9/src
# GOROOT_BOOTSTRAP=$(pwd)/../../go-linux-mips-bootstrap ./all.bash
以上でLinux/MIPS上でGo 1.9がビルドできましたが、全部で8時間くらいかかりました。さすがにQEMUだと遅いですね2。
ホスト側でgo本体のクロスコンパイルもできそうなものですが、実際どうなんでしょう。