See here for available GOOS
and GOARCH
values.
Since Go version 1.5 cross-compiling of pure Go executables has become very easy. Try it out with the code below. More can be found at this blog post by Dave Cheney.
$ cat hello.go
package main
import "fmt"
func main() {
fmt.Printf("Hello\n")
}
$ GOOS=windows GOARCH=386 go build -o hello.exe hello.go
In cmd.exe instead of PowerShell:
$ set GOOS=windows
$ set GOARCH=386
$ go build -o hello.exe hello.go
You can now run hello.exe
on a Windows machine near you.
Note that the first time you run the command above it will silently rebuild most of standard library, and for this reason will be quite slow. Subsequent builds will be faster due to Go command build caching.
Note also that cgo
is disabled when cross-compiling, so any file that mentions import "C"
will be silently ignored (See https://github.com/golang/go/issues/24068). In order to use cgo, or any of the build modes c-archive
, c-shared
, shared
, plugin
, you need to have a C cross-compiler.
I use linux/386, but, I suspect, this procedure will apply to other host platforms as well.
Preparation (if needed):
sudo apt-get install gcc export go env GOROOT
First step is to build host version of go:
cd $GOROOT/src sudo -E GOOS=windows GOARCH=386 PATH=$PATH ./make.bash
Next you need to build the rest of go compilers and linkers. I have small program to do that:
$ cat ~/bin/buildcmd #!/bin/sh set -e for arch in 8 6; do for cmd in a c g l; do go tool dist install -v cmd/$arch$cmd done done exit 0
Last step is to build Windows versions of standard commands and libraries. I have a small script for that too:
$ cat ~/bin/buildpkg #!/bin/sh if [ -z "$1" ]; then echo 'GOOS is not specified' 1>&2 exit 2 else export GOOS=$1 if [ "$GOOS" = "windows" ]; then export CGO_ENABLED=0 fi fi shift if [ -n "$1" ]; then export GOARCH=$1 fi cd $GOROOT/src go tool dist install -v pkg/runtime go install -v -a std
I run it like that:
$ ~/bin/buildpkg windows 386
to build Windows/386 version of Go commands and packages. You can probably see from my script that I exclude building of any cgo related parts — these will not work for me, since I do not have correspondent gcc cross-compiling tools installed. So I just skip those.
Now we're ready to build our Windows executable:
$ cat hello.go
package main
import "fmt"
func main() {
fmt.Printf("Hello\n")
}
$ GOOS=windows GOARCH=386 go build -o hello.exe hello.go
We just need to find a Windows computer to run our hello.exe
.