Skip to content

Instantly share code, notes, and snippets.

@slaveofcode
Forked from steeve/_readme.md
Created April 29, 2020 04:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save slaveofcode/73e181a63852dae23ebd2f75c3f47e03 to your computer and use it in GitHub Desktop.
Save slaveofcode/73e181a63852dae23ebd2f75c3f47e03 to your computer and use it in GitHub Desktop.
How to cross compile Go with CGO programs for a different OS/Arch

How to cross compile Go with CGO programs for a different OS/Arch

It is possible to compile Go programs for a different OS, even though go build says otherwise.

You'll need:

First of all, clone the Go repo and switch to tip:

$ hg clone -u release https://code.google.com/p/go
$ cd go
go$ hg update default

Apply the patch:

go$ curl https://gist.github.com/steeve/6905542/raw/cross_compile_goos.patch | patch -p1
patching file src/cmd/go/build.go

Build Go:

go$ cd src
go/src$ bash all.bash

Now use golang-crosscompiler to build all the toolchains

go$ git clone https://github.com/davecheney/golang-crosscompile.git
go$ source golang-crosscompile/crosscompile.bash
go$ go-crosscompile-build-all
go-crosscompile-build darwin/386
# Building C bootstrap tool.
....
---
Installed Go for windows/amd64 in /usr/local/go
Installed commands in /usr/local/go/bin

Almost there, now a little cmd-fu and you're done. Just set the CC env var to your toolchain's gcc, set the proper GOOS, GOARCH, GOARM (if needed) and finally the proper -extld ldflag.

Cross compiling from darwin/amd64 to windows/386:

$ CC=i586-mingw32-gcc GOOS=windows GOARCH=386 CGO_ENABLED=1 go build -v -o myprogram.exe -ldflags="-extld=$CC"

Cross compiling from darwin/amd64 to linux/amd64:

$ CC=x86_64-pc-linux-gcc GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go build -v -o myprogram -ldflags="-extld=$CC"

Cross compiling from linux/amd64 to linux/arm (in that case a Raspberry Pi):

$ CC=arm-linux-gnueabihf-gcc GOOS=linux GOARCH=arm GOARM=6 CGO_ENABLED=1 go build -v -o myprogram -ldflags="-extld=$CC"
diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go.patched
index 2ce968a..a90044f 100644
--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go.patched
@@ -1921,9 +1921,9 @@ var (
)
func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string, gxxfiles []string) (outGo, outObj []string, err error) {
- if goos != toolGOOS {
- return nil, nil, errors.New("cannot use cgo when compiling for a different operating system")
- }
+ // if goos != toolGOOS {
+ // return nil, nil, errors.New("cannot use cgo when compiling for a different operating system")
+ // }
cgoCPPFLAGS := stringList(envList("CGO_CPPFLAGS"), p.CgoCPPFLAGS)
cgoCFLAGS := stringList(envList("CGO_CFLAGS"), p.CgoCFLAGS)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment