Jay Taylor's notes
back to listing indexCross compilation with Go 1.5 | Dave Cheney
[web search]Dave Cheney
The acme of foolishness
Cross compilation with Go 1.5
Now that Go 1.5 is out, lots of gophers are excited to try the much improved cross compilation support. For some background on the changes to the cross compilation story you can read my previous post, or Rakyll’s excellent follow up piece.
I’ll assume that you are using the binary version of Go 1.5, as distributed from the Go website. If you are using Go 1.5 from your operating system’s distribution, or homebrew, the process will be the same, however paths may differ slightly.
How to cross compile
To cross compile a Go program using Go 1.5 the process is as follows:
- set
GOOS
andGOARCH
to be the values for the target operating system and architecture. - run
go build -v YOURPACKAGE
If the compile is successful you’ll have a binary called YOURPACKAGE
(possibly with a .exe
extension if you’re targeting Windows) in your current working directory.
-o
may be used to alter the name and destination of your binary, but remember that go build takes a value that is relative to your $GOPATH/src
, not your working directory, so changing directories then executing the go build
command is also an option.
Example
I prefer to combine the two steps outlined above into one, like this:
% env GOOS=linux GOARCH=arm go build -v github.com/constabulary/gb/cmd/gb runtime sync/atomic ... github.com/constabulary/gb github.com/constabulary/gb/cmd github.com/constabulary/gb/cmd/gb % file ./gb ./gb: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped
and that’s all there is to it.
Using go build vs go install
When cross compiling, you should use go build
, not go install
. This is the one of the few cases where go build
is preferable to go install
.
The reason for this is go install
always caches compiled packages, .a
files, into the pkg/
directory that matches the root of the source code.
For example, if you are building $GOPATH/src/github.com/lib/pq
, then the compiled package will be installed into $GOPATH/pkg/$GOOS_$GOARCH/github.com/lib/pq.a
.
This logic also holds true for the standard library, which lives in /usr/local/go/src
, so will be compiled to /usr/local/go/pkg/$GOOS_$GOARCH
. This is a problem, because when cross compiling the go
tool needs to rebuild the standard library for your target, but the binary distribution expects that /usr/local/go
is not writeable.
Using go build
rather that go install
is the solution here, because go build
builds, then throws away most of the result (rather than caching it for later), leaving you with the final binary in the current directory, which is most likely writeable by you.
Ugh, this is really slow!
In the procedure described above, cross compilation always rebuilds that standard library for the target every time. Depending on your workflow this is either not an issue, or a really big issue. If it’s the latter then I recommend you remove the binary distribution and build from source into a path that is writeable by you, then you’ll have the full gamut of go
commands available to you.
Cross compilation support in gb is being actively developed and will not have this restriction.
What about GOARM?
The go
tool chooses a reasonable value for GOARM
by default. You should not change this unless you have a good reason.
But but, what about GOARM=7?
Sure, knock yourself out, but that means your program won’t run on all models of the Raspberry Pi. The difference between GOARM=6
(the default) and GOARM=7
is enabling a few more floating point registers, and a few more operations that allow floating point double values to be passed to and from the ARMv7 (VPFv3) floating point co processor more efficiently. IMO, with the current Go 1.5 arm compiler, it’s not worth the bother.
Hear me speak
In April I will be speaking at GopherChina in Beijing and GoCon in Tokyo.
In May I'll be talking about Go design at Yow! West 2016.
Recent Posts
Categories
Archives
- April 2016
- March 2016
- February 2016
- January 2016
- December 2015
- November 2015
- October 2015
- September 2015
- August 2015
- July 2015
- June 2015
- May 2015
- March 2015
- February 2015
- January 2015
- December 2014
- November 2014
- October 2014
- September 2014
- August 2014
- July 2014
- June 2014
- May 2014
- April 2014
- March 2014
- February 2014
- January 2014
- December 2013
- November 2013
- October 2013
- September 2013
- August 2013
- July 2013
- June 2013
- May 2013
- April 2013
- January 2013
- December 2012
- November 2012
- October 2012
- September 2012
- August 2012
- February 2012
- January 2012
- November 2011
- October 2011
- August 2011
- July 2011
- June 2011
- May 2011
- April 2011
- March 2011
- February 2011
- November 2010
- October 2010
Elsewhere
License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.