xcgo is a maximalist Docker image for cross-compiling and
releasing/distributing CGo-enabled Go/Golang applications. At this time, it can build and dist
macOS, Windows and Linux CGo projects for arch
xcgo has what gophers crave:
OSX SDKCatalina /
macOS 10.15(will build on later versions)
- and a bunch of other stuff.
The primary source of documentation for
xcgo is the wiki.
Start there. There's a companion example project (neilotoole/sqlitr)
that was created explicitly to exhibit
xcgo: it demonstrates pretty much the entire array of
showing how to release to
snap, Docker Hub, GitHub, etc. The
neilotoole/xcgo images are
published to Docker Hub.
Note: No effort has yet been made to provide support for other archs such as
386(or for an OS beyond the typical three), but pull requests are welcome. Note also that no effort has been made to make this image slim.
xcgoby mission is maximalist (it's a 3GB+ image), but I'm sure the
Dockerfilecan be slimmed down. Again, pull requests are welcome.
You can test
$ docker run -it neilotoole/xcgo:latest go version go version go1.17.2 linux/amd64
To play around in the container, launch into a shell:
$ docker run -it neilotoole/xcgo:latest zsh
xcgo doesn't prescribe a particular usage approach. Some possibilities:
- Launch a container shell session, clone your repo, and build (or even edit and do all your work) within the container.
- Mount your local repo into the container, shell in, and build from within the container.
- With local repo mounted, invoke
goreleaser: this is pretty typical.
go build inside container
From inside the docker container, we'll build (
amd64) binaries for macOS, Linux, and Windows.
Shell into the
xcgo container if you haven't already done so:
$ docker run -it neilotoole/xcgo:latest zsh
From inside the container:
$ git clone https://github.com/neilotoole/sqlitr.git && cd sqlitr $ GOOS=darwin GOARCH=amd64 CC=o64-clang CXX=o64-clang++ go build -o dist/darwin_amd64/sqlitr $ GOOS=linux GOARCH=amd64 go build -o dist/linux_amd64/sqlitr $ GOOS=windows GOARCH=amd64 CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ go build -o dist/windows_amd64/sqlitr.exe
You should end up with something like this:
$ tree ./dist ./dist ├── darwin_amd64 │ └── sqlitr ├── linux_amd64 │ └── sqlitr └── windows_amd64 └── sqlitr.exe
Quite possibly you'll want to use
xcgo in conjunction
Again, we'll use
sqlitr to demonstrate. On your local machine, clone the
sqlitr repo, mount it into the
xcgo container and run
$ git clone https://github.com/neilotoole/sqlitr.git && cd sqlitr $ docker run --rm --privileged \ -v $(pwd):/go/src/github.com/neilotoole/sqlitr \ -v /var/run/docker.sock:/var/run/docker.sock \ -w /go/src/github.com/neilotoole/sqlitr \ neilotoole/xcgo:latest goreleaser --snapshot --rm-dist
The above will build that CGo project via
goreleaser with binaries for macOS, Linux, and Windows.
$ tree ./dist ./dist ├── build_linux_linux_amd64 │ └── sqlitr ├── build_macos_darwin_amd64 │ └── sqlitr ├── build_windows_windows_amd64 │ └── sqlitr.exe ├── checksums.txt ├── config.yaml ├── goreleaserdocker393975300 │ ├── Dockerfile │ ├── LICENSE │ ├── README.md │ ├── sqlitr │ └── testdata │ └── example.sqlite ├── sqlitr_v0.1.23-snapshot_darwin_amd64.tar.gz ├── sqlitr_v0.1.23-snapshot_linux_amd64 │ └── prime │ ├── meta │ │ └── snap.yaml │ └── sqlitr ├── sqlitr_v0.1.23-snapshot_linux_amd64.deb ├── sqlitr_v0.1.23-snapshot_linux_amd64.rpm ├── sqlitr_v0.1.23-snapshot_linux_amd64.snap ├── sqlitr_v0.1.23-snapshot_linux_amd64.tar.gz └── sqlitr_v0.1.23-snapshot_windows_amd64.zip
Again, see the wiki for more.
Some params that can be passed to
xcgo (as args to
-e DOCKER_USERNAME=X -e DOCKER_PASSWORD=X
docker login. Supply
-e DOCKER_REGISTRY=Xto use a registry other than Docker Hub.
Used to publish artifacts to GitHub (e.g. by
/.snapcraft.loginis present in the
snapcraftlogin. This enables use of
snapcraft, e.g. by
goreleaserto publish a
-e SNAPCRAFT_LOGIN_FILE=/other/place/.snapcraft.loginto specify an alternative mount location for the login file. See the wiki for more.
See FAQ on wiki.
Comments for related projects are as of
- Official golang image: doesn't support CGo.
- mailchain/goreleaser-xcgo: doesn't support
- docker/golang-cross: doesn't support
- mailchain/goreleaser-xcgo: this was the original fork point for
- tpoechtrager/osxcross: fundamental to macOS capabilities.
- mingw: fundamental to Windows capabilities.
- goreleaser: core to
- docker/golang-cross: much gleaned from here.
- SQLite and mattn/go-sqlite3: the perfect use case, as seen in
xcgo's companion example project neilotoole/sqlitr.
- And many others, see sqlitr/go.mod at a minimum. If anybody has been overlooked, please open an issue.