HOWTO: Cross-compile a Go app for Windows from Linux

I recently needed to test some app on windows, and while cross-compiling in Go is straight-forward, the app had some C code and apparently on Arch Linux the mingw64-gcc package is misconfigured.

After some head scratching I figured out a workaround until the package is fixed (task #4313), you have to link your Go code against ssp.

note this bug is specific to Arch Linux, however other distros might build the toolchain in the same manner.

Building the toolchain:

1. Download and unpack the Go source code:

note this guide assumes $GOROOT is set to /usr/src/go/.

  • Use mercurial (slow) hg clone -u release https://code.google.com/p/go
  • Use the source tarball from golang.org

1a. (optional but recommended) add export PATH="$PATH:$GOROOT/bin" to your ~/.bashrc (or the equivalent file for your shell).

2. Compiling the native toolchain:

3. Compiling the Windows toolchain without CGO:

Repeat with GOARCH=amd64 if you want to build win64 binaries.

4. Compiling the Windows toolchain with CGO support:

  • Install mingw-w64-gcc

Repeat with GOARCH=amd64 CC_FOR_TARGET="x86_64-w64-mingw32-gcc .... if you want to build win64 binaries.

note that once the bug is fixed, you can remove -fno-stack-protector -D_FORTIFY_SOURCE=0 -lssp from CC_FOR_TARGET.

Actually compiling your code to run on windows:

We use the same environment variables from earlier, except we have to replace CC_FOR_TARGET with CC

Code:

Testing:

note that to build native go with cgo you will have to use env CC=gcc go build


3 comments on “HOWTO: Cross-compile a Go app for Windows from Linux”

  1. Great post! I only found it by accident, but you may be able to find a solution to a similar problem. In my case, I'm cross-compiling AND using CGO so I can include C source code in my cross-compiled go program. I thought everything was going perfectly until I hit a wall: there is on way to cross-compile test code (AFAIK).

    Do you have any suggestions?

    Thanks!
    Dave

    1. You can try to compile the test binary and then run it with wine, for example: