I am trying to cross-compile a go app on OSX to build binaries for windows and linux. I have read everything what I could find on the net. Closest example that I have found has been published on (apart from many unfinished discussions on go-nuts mailing list):
http://solovyov.net/en/2012/03/09/cross-compiling-go/
yet it does not work on my installation. I have go 1.0.2. As 1.0.2 is quite recent it looks to me that all above examples do not apply to this version.
Tried to do ./make.bash --no-clean
with ENV vars set to 386/windows, it does build go, however it builds go for my installation which is darwin/amd64
and completely ignores what is set in ENV that suppose to build different compiler.
Any advises how it can be done (if it can be done at all)?
I needed CGO enabled while compiling for windows from my mac since I had imported the https://github.com/mattn/go-sqlite3 and it needed it. Compiling according to other answers gave me and error:
If you're like me and you have to compile with CGO. This is what I did:
1.We're going to cross compile for windows with a CGO dependent library. First we need a cross compiler installed like
mingw-w64
This will probably install it here
/usr/local/opt/mingw-w64/bin/
.2.Just like other answers we first need to add our windows arch to our go compiler toolchain now. Compiling a compiler needs a compiler (weird sentence) compiling go compiler needs a separate pre-built compiler. We can download a prebuilt binary or build from source in a folder eg:
~/Documents/go
now we can improve our Go compiler, according to top answer but this time withCGO_ENABLED=1
and our separate prebuilt compilerGOROOT_BOOTSTRAP
(Pooya is my username):3.Now while compiling our Go code use
mingw
to compile our go file targeting windows with CGO enabled:With Go 1.5 they seem to have improved the cross compilation process, meaning it is built in now. No
./make.bash
-ing orbrew
-ing required. The process is described here but for the TLDR-ers (like me) out there: you just set theGOOS
and theGOARCH
environment variables and run the go build.For the even lazier copy-pasters (like me) out there, do something like this if you're on a *nix system:
You even learned the
env
trick, which let you set environment variables for that command only, completely free of charge.Thanks to kind and patient help from golang-nuts, recipe is the following:
1) One needs to compile Go compiler for different target platforms and architectures. This is done from src folder in go installation. In my case Go installation is located in
/usr/local/go
thus to compile a compiler you need to issuemake
utility. Before doing this you need to know some caveats.There is an issue about CGO library when cross compiling so it is needed to disable CGO library.
Compiling is done by changing location to source dir, since compiling has to be done in that folder
then compile the Go compiler:
You need to repeat this step for each OS and Architecture you wish to cross compile by changing the GOOS and GOARCH parameters.
If you are working in user mode as I do, sudo is needed because Go compiler is in the system dir. Otherwise you need to be logged in as super user. On Mac you may need to enable/configure SU access (it is not available by default), but if you have managed to install Go you possibly already have root access.
2) Once you have all cross compilers built, you can happily cross compile your application by using the following settings for example:
Change the GOOS and GOARCH to targets you wish to build.
If you encounter problems with CGO include CGO_ENABLED=0 in the command line. Also note that binaries for linux and mac have no extension so you may add extension for the sake of having different files. -o switch instructs Go to make output file similar to old compilers for c/c++ thus above used appname.linux can be any other extension.
You can do this pretty easily using Docker, so no extra libs required. Just run this command:
You can find more details in this post: https://medium.com/iron-io-blog/how-to-cross-compile-go-programs-using-docker-beaa102a316d
If you use Homebrew on OS X, then you have a simpler solution:
or..
Use
reinstall
if you already havego
installed.The process of creating executables for many platforms can be a little tedious, so I suggest to use a script:
I checked this script on OSX only
gist - go-executable-build.sh