Cross Platform compile Go Quadrans from Source¶
Note: All of these and much more have been merged into the project Makefile. You can cross build via make gqdc-<os>-<platform>
without needing to know any of these details from below.
Developers usually have a preferred platform that they feel most comfortable working in, with all the necessary tools, libraries and environments set up for an optimal workflow. However, there’s often need to build for either a different CPU architecture, or an entirely different operating system; but maintaining a development environment for each and switching between the them quickly becomes unwieldy.
Here we present a very simple way to cross compile Quadrans to various operating systems and architectures using a minimal set of prerequisites and a completely containerized approach, guaranteeing that your development environment remains clean even after the complex requirements and mechanisms of a cross compilation.
The currently supported target platforms are:
32 bit, 64 bit and ARMv5+ Linux
32 bit and 64 bit Darwin (Mac OSX)
32 bit and 64 bit Windows
Please note, that cross compilation does not replace a release build. Although resulting binaries can usually run perfectly on the desired platform, compiling on a native system with the specialized tools provided by the official vendor can often result in more a finely optimized code.
Cross compilation environment¶
Although the go-quadrans
project is written in Go, it does include a bit of C code shared between all implementations to ensure that all perform equally well, including a dependency to the GNU Multiple Precision Arithmetic Library. Because of these, Go cannot by itself compile to a different platform than the host. To overcome this limitation, we will use xgo
, a Go cross compiler package based on Docker containers that has been architected specifically to allow both embedded C snippets as well as simpler external C dependencies during compilation.
The xgo
project has two simple dependencies: Docker (to ensure that the build environment is completely contained) and Go. On most platforms these should be available from the official package repositories. For manually installing them, please consult their install guides at Docker and Go respectively. This guide assumes that these two dependencies are met.
To install and/or update xgo, simply type:
$ go get -u github.com/karalabe/xgo
You can test whether xgo
is functioning correctly by requesting it to cross compile itself and verifying that all cross compilations succeeded or not.
$ xgo github.com/karalabe/xgo
...
$ ls -al
-rwxr-xr-x 1 root root 2353212 Sep 14 16:45 xgo-darwin-386
-rwxr-xr-x 1 root root 2906128 Sep 14 16:45 xgo-darwin-amd64
-rwxr-xr-x 1 root root 2388288 Sep 14 16:45 xgo-linux-386
-rwxr-xr-x 1 root root 2960560 Sep 14 16:45 xgo-linux-amd64
-rwxr-xr-x 1 root root 2437864 Sep 14 16:45 xgo-linux-arm
-rwxr-xr-x 1 root root 2551808 Sep 14 16:45 xgo-windows-386.exe
-rwxr-xr-x 1 root root 3130368 Sep 14 16:45 xgo-windows-amd64.exe
Building Quadrans¶
Cross compiling Quadrans is analogous to the above example, but an additional flags is required to satisfy the dependencies:
--deps
is used to inject arbitrary C dependency packages and pre-build them
Injecting the GNU Arithmetic Library dependency and selecting gqdc
would be:
$ xgo --deps=https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2 \
github.com/quadrans/go-quadrans/cmd/gqdc
...
$ ls -al
-rwxr-xr-x 1 root root 14373980 Sep 14 17:59 gqdc-darwin-386
-rwxr-xr-x 1 root root 17373676 Sep 14 17:59 gqdc-darwin-amd64
-rwxr-xr-x 1 root root 21098910 Sep 14 17:59 gqdc-linux-386
-rwxr-xr-x 1 root root 25049693 Sep 14 17:59 gqdc-linux-amd64
-rwxr-xr-x 1 root root 20573442 Sep 14 17:59 gqdc-linux-arm64
-rwxr-xr-x 1 root root 20578535 Sep 14 17:59 gqdc-linux-arm-7
-rwxr-xr-x 1 root root 16351260 Sep 14 17:59 gqdc-windows-386.exe
-rwxr-xr-x 1 root root 19418071 Sep 14 17:59 gqdc-windows-amd64.exe
As the cross compiler needs to build all the dependencies as well as the main project itself for each platform, it may take a while for the build to complete (approximately 3-4 minutes on a Core i7 3770K machine).
Building locally¶
If you would like to cross compile your local development version, simply specify a local path (starting with .
or /
), and xgo
will use all local code from GOPATH
, only downloading missing dependencies. In such a case of course, the --branch
, --remote
and --pkg
arguments are no-op:
$ xgo --deps=https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2 \
./cmd/gqdc
Using the Makefile¶
Having understood the gist of xgo
based cross compilation, you do not need to actually memorize and maintain these commands, as they have been incorporated into the official Makefile and can be invoked with a trivial make
request:
make gqdc-cross
: Cross compiles to every supported OS and architecturemake gqdc-<os>
: Cross compiles supported architectures of a particular OS (e.g.linux
)make gqdc-<os>-<arch>
: Cross compiles to a specific OS/architecture (e.g.linux
,arm
)
We advise using the make
based commands opposed to manually invoking xgo
as we do maintain the Makefile actively whereas we cannot guarantee that this document will be always readily updated to latest advancements.
Tuning the cross builds¶
A few of the xgo
build options have also been surfaced directly into the Makefile to allow fine tuning builds to work around either upstream Go issues, or to enable some fancier mechanics.
make ... GO=<go>
: Use a specific Go runtime (e.g.1.5.1
,1.5-develop
,develop
)make ... MODE=<mode>
: Build a specific target type (e.g.exe
,c-archive
).
Please note that these are not yet fully finalized, so they may or may not change in the future as our code and the Go runtime features change.