README
¶
About
This repo contains a Dockerfile for building an image which can be used as a base for building your Go project using CGO. All the necessary Go tool-chains, C/C++ cross-compilers and platform headers/libraries have been assembled into a single Docker container. It also includes the MinGW compiler for windows, and the MacOSX SDK.
Docker image
| Registry | Image |
|---|---|
| Docker Hub | crazymax/goxx |
| GitHub Container Registry | ghcr.io/crazy-max/goxx |
$ docker run --rm mplatform/mquery crazymax/goxx:latest
Image: crazymax/goxx:latest
* Manifest List: Yes
* Supported platforms:
- linux/amd64
- linux/arm64
Platforms available
| Platform | CC |
CXX |
|---|---|---|
darwin/amd64 |
o64-clang |
o64-clang++ |
darwin/arm64 |
o64-clang |
o64-clang++ |
linux/386 |
i686-linux-gnu-gcc |
i686-linux-gnu-g++ |
linux/amd64 |
x86_64-linux-gnu-gcc |
x86_64-linux-gnu-g++ |
linux/arm64 |
aarch64-linux-gnu-gcc |
aarch64-linux-gnu-g++ |
linux/arm/v5 |
arm-linux-gnueabi-gcc |
arm-linux-gnueabi-g++ |
linux/arm/v6 |
arm-linux-gnueabi-gcc |
arm-linux-gnueabi-g++ |
linux/arm/v7 |
arm-linux-gnueabihf-gcc |
arm-linux-gnueabihf-g++ |
linux/mips |
mips-linux-gnu-gcc |
mips-linux-gnu-g++ |
linux/mipsle |
mipsel-linux-gnu-gcc |
mipsel-linux-gnu-g++ |
linux/mips64 |
mips64-linux-gnuabi64-gcc |
mips64-linux-gnuabi64-g++ |
linux/mips64le |
mips64el-linux-gnuabi64-gcc |
mips64el-linux-gnuabi64-g++ |
linux/ppc64le |
powerpc64le-linux-gnu-gcc |
powerpc64le-linux-gnu-g++ |
linux/riscv64 |
riscv64-linux-gnu-gcc |
riscv64-linux-gnu-g++ |
linux/s390x |
s390x-linux-gnu-gcc |
s390x-linux-gnu-g++ |
windows/386 |
i686-w64-mingw32-gcc |
i686-w64-mingw32-g++ |
windows/amd64 |
x86_64-w64-mingw32-gcc |
x86_64-w64-mingw32-g++ |
Usage
In order to use this image effectively, we will use the docker buildx command.
Buildx is a Docker component that enables
many powerful build features. All builds executed via buildx run with
Moby BuildKit builder engine.
# syntax=docker/dockerfile:1.3
FROM --platform=$BUILDPLATFORM crazymax/goxx:1.17 AS base
ENV CGO_ENABLED=1
WORKDIR /src
FROM base AS vendored
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/go/pkg/mod \
go mod tidy && go mod download
FROM vendored AS build
ARG TARGETPLATFORM
RUN --mount=type=bind,source=. \
--mount=type=cache,target=/root/.cache \
--mount=type=cache,target=/go/pkg/mod \
goxx build -o /out/hello ./hello.go
FROM scratch AS artifact
COPY --from=build /out /
FROM scratch
COPY --from=build /out/hello /hello
ENTRYPOINT [ "/hello" ]
FROM --platform=$BUILDPLATFORM ...command will pull an image that will always match the native platform of your machine (e.g.,linux/amd64).BUILDPLATFORMis part of the ARGs in the global scope.ARG TARGETPLATFORMis also an ARG in the global scope that will be set to the platform of the target that will default to your current platform or can be defined via the--platformflag of buildx sogoreleaser-xxwill be able to automatically build against the right platform.
More details about multi-platform builds in this blog post.
Let's run a simple build against the artifact target in our Dockerfile:
# build and output content of the artifact stage that contains the archive in ./dist
docker buildx build \
--platform "linux/amd64,linux/arm64,linux/arm/v7,darwin/amd64" \
--output "./dist" \
--target "artifact" .
$ tree ./dist
./dist
├── darwin_amd64
│ ├── hello
├── linux_amd64
│ ├── hello
├── linux_arm64
│ ├── hello
├── linux_arm_v7
│ ├── hello
You can also create a multi-platform image in addition to the generated artifacts:
docker buildx build \
--platform "linux/amd64,linux/arm64,linux/arm/v7" \
--tag "hello:latest" \
--push .
More examples can be found in the examples folder.
Build
Build goxx yourself using Docker buildx bake:
git clone https://github.com/crazy-max/goxx.git goxx
cd goxx
# Create docker container builder
docker buildx create --name goxx --driver-opt network=host --use
# Create local registry to push the image
docker run -d --name registry -p 5000:5000 registry:2
# Build goxx image and push to local registry
docker buildx bake --set "*.tags=localhost:5000/goxx:latest" --push
# Examples
export GOXX_BASE=localhost:5000/goxx:latest
(cd ./examples/c ; docker buildx bake artifact-all)
(cd ./examples/cpp ; docker buildx bake artifact-all)
(cd ./examples/gorm ; docker buildx bake artifact-all)
Notes
Wrapper
goxx is a simple wrapper for go which will
automatically sets values for GOOS, GOARCH, GOARM, GOMIPS, etc. but also
AR, CC, CXX if building with CGO based on defined ARGs in the global scope
like TARGETPLATFORM.
CGO
By default, CGO is enabled in Go when compiling for native architecture and
disabled when cross-compiling. It's therefore recommended to always set
CGO_ENABLED=0 or CGO_ENABLED=1 when cross-compiling depending on whether
you need to use CGO or not.
Contributing
Want to contribute? Awesome! The most basic way to show your support is to star the project, or to raise issues. You can also support this project by becoming a sponsor on GitHub or by making a Paypal donation to ensure this journey continues indefinitely!
Thanks again for your support, it is much appreciated! 🙏
License
MIT. See LICENSE for more details.