Go Cross Platform Compilation

In previous blogs we have looked at the Go Programming Language and how to Run Go in AWS Lambda. In this blog we will learn how to compile Go code so that it can run on Linux, Mac and Windows.

GOOS and GOARCH

The environment variables GOOS and GOARCH configure the target platform Go will compile to. By default, the GOHOSTOS and GOHOSTARCH, which contain the auto-detected values of the host architecture will be used as the target platform to compile to. Type ‘go env’ to check what the target architecture is.

Mac:

$ go env
...
<span style="color:#008080">GOARCH</span><span style="font-weight:bold">=</span><span style="color:#b84">"amd64"</span>
<span style="color:#008080">GOHOSTARCH</span><span style="font-weight:bold">=</span><span style="color:#b84">"amd64"</span>
<span style="color:#008080">GOHOSTOS</span><span style="font-weight:bold">=</span><span style="color:#b84">"darwin"</span>
<span style="color:#008080">GOOS</span><span style="font-weight:bold">=</span><span style="color:#b84">"darwin"</span>
...

Docker golang:stretch:

root@ccd8f40b9eb7:/go# go env
...
<span style="color:#008080">GOARCH</span><span style="font-weight:bold">=</span><span style="color:#b84">"amd64"</span>
<span style="color:#008080">GOHOSTARCH</span><span style="font-weight:bold">=</span><span style="color:#b84">"amd64"</span>
<span style="color:#008080">GOHOSTOS</span><span style="font-weight:bold">=</span><span style="color:#b84">"linux"</span>
<span style="color:#008080">GOOS</span><span style="font-weight:bold">=</span><span style="color:#b84">"linux"</span>
...

Target Architecture

Go supports a list of platforms, but the most important ones are Linux, Mac and Windows.

Compiling for a platform

To compile for a specific platform, you have to set the GOOS and GOARCH environment variables. Below is a table that shows the available values. Go supports more OS and CPU architectures than the one shown below, but normally you will use these settings the most.

PlatformGOOSGOARCH
Macdarwinamd64
Linuxlinuxamd64
Windowswindowsamd64

Cross Compilation

Lets create a simple ‘helloworld.go’ example and cross compile it to Linux, Mac and Windows.

<span style="font-weight:bold">package</span> main

<span style="font-weight:bold">import</span> (
    <span style="color:#b84">"fmt"</span>
)

<span style="font-weight:bold">func</span> <span style="color:#900;font-weight:bold">main</span>() {
    fmt.<span style="color:#900;font-weight:bold">Println</span>(<span style="color:#b84">"Hello World!"</span>)
}

To compile it type:

$ <span style="color:#008080">GOOS</span><span style="font-weight:bold">=</span>darwin <span style="color:#008080">GOARCH</span><span style="font-weight:bold">=</span>amd64 go build -o helloworld-mac helloworld.go
$ file helloworld-mac
helloworld: Mach-O 64-bit executable x86_64

$ <span style="color:#008080">GOOS</span><span style="font-weight:bold">=</span>linux <span style="color:#008080">GOARCH</span><span style="font-weight:bold">=</span>amd64 go build -o helloworld-linux helloworld.go
$ file helloworld-linux
helloworld-linux: ELF 64-bit LSB executable, x86-64, version <span style="color:#099">1</span> <span style="font-weight:bold">(</span>SYSV<span style="font-weight:bold">)</span>, statically linked, not stripped

$ <span style="color:#008080">GOOS</span><span style="font-weight:bold">=</span>windows <span style="color:#008080">GOARCH</span><span style="font-weight:bold">=</span>amd64 go build -o helloworld-windows.exe helloworld.go
$ file helloworld-windows.exe
helloworld-windows.exe: PE32+ executable <span style="font-weight:bold">(</span>console<span style="font-weight:bold">)</span> x86-64 <span style="font-weight:bold">(</span>stripped to external PDB<span style="font-weight:bold">)</span>, <span style="font-weight:bold">for</span> MS Windows

Running the artifacts

To run the artifacts type:

$ ./helloworld-mac
Hello World!

$ docker run -it -v ~/go:/go ubuntu /bin/bash
root@5ae3f3f473d7:/# /go/helloworld-linux
Hello World!

Conclusion

Programs written in Go can easily be compiled to other platforms like Linux, Mac and Windows by setting the environment variables GOOS and GOARCH. The ‘go build’ command will compile a binary that runs on the configured platform. On Linux and Mac you can check the binary platform with the command ‘file’ that shows the file type and platform architecture that can run the file.

Share this article: Tweet this post / Post on LinkedIn