【ARM】Go言語のクロスコンパイル

DebianWheezy上でARMプロセッサ向けにクロスコンパイルする方法です。
BeagleBoneBlack(以下BBB)で動作確認まで行います。

hongkong

写真は九龍から眺めた香港の夜景。

Go開発環境の構築

環境はdebian Wheezyです。まずは失敗事例から。
apt-getでGoをインストールします。

# debian
$ sudo apt-get install golang
$ which go
/usr/bin/go

# centos
$ yum install golang
$ go version
go version go1.2.2 linux/amd64

Hello Worldを書きます。

package main

import (
 "fmt"
)

func main(){
  fmt.Println("Hello World")
}

通常のコンパイル(i386)をします。

$ go build sample.go
$ file sample
sample: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, not stripped

ここまでは問題なしです。

クロスコンパイル

続いてクロスコンパイル。toolオプションでコンパイラ群が見えます。

$ cd /usr/share/go/src
$ go tool
8a
8c
8g
8l
addr2line
api
cgo
dist
fix
nm
objdump
pack
pprof
vet
yacc

クロスコンパイラのビルドを行います。

$ sudo GOOS=linux GOARCH=arm ./make.bash 
# Building C bootstrap tool.
cmd/dist
go tool dist: $GOROOT is not set correctly or not exported
    GOROOT=/usr/share/go
    /usr/share/go/include/u.h does not exist

# Building compilers and Go bootstrap tool for host, /.
go tool dist: $GOROOT is not set correctly or not exported
    GOROOT=/usr/share/go
    /usr/share/go/include/u.h does not exist

うーん。たしかに GOROOT に /include/u.h がありません。
詳しく追ってないですが, goのversionが1.0.2なのが原因を掴むヒントかもしれません…

$ go version
go version go1.0.2

ということで, ソースコードからビルドしてみます。

$ sudo apt-get install mercurial
$ hg clone -u release https://code.google.com/p/go

今度は /include/u.h がありました。以下のように環境変数をセットします。

$ export -p
declare -x GOARCH="arm"
declare -x GOOS="linux"
declare -x GOROOT="/root/go/src"

ログインの度に環境変数をセットするのはめんどくさいので.bashrcにでも追加しておきましょう。

# .bashrc
export GOOS=linux GOARCH=arm

今度は上手くいきました。

$ cd src
$ ./make.bash
$ go version
go version go1.2.1
$ go build sample.go 

static-linkedなのでバイナリが1.8MBと大きくなってしまいましたが,BBBで実行できました。

$ file sample 
sample: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, not stripped
$ ./sample 
Hello World

以上です。

* この記事はkarota-projectの活動に関する記事です。