All Projects → crazy-max → goreleaser-xx

crazy-max / goreleaser-xx

Licence: MIT license
Cross compilation helper for GoReleaser

Programming Languages

go
31211 projects - #10 most used programming language
Dockerfile
14818 projects
HCL
1544 projects

Projects that are alternatives of or similar to goreleaser-xx

bake-action
GitHub Action to use Docker Buildx Bake as a high-level build command
Stars: ✭ 52 (+52.94%)
Mutual labels:  bake, buildx
aseprite-macos-buildsh
Automated script to create latest release app (either beta, or release whichever is newer) of Aseprite for macOS
Stars: ✭ 143 (+320.59%)
Mutual labels:  build-tool
Etlegacy
ET: Legacy is an open source project based on the code of Wolfenstein: Enemy Territory which was released in 2010 under the terms of the GPLv3 license.
Stars: ✭ 212 (+523.53%)
Mutual labels:  multi-platform
millw
Mill Wrapper Script
Stars: ✭ 40 (+17.65%)
Mutual labels:  build-tool
Panda3d
Powerful, mature open-source cross-platform game engine for Python and C++, developed by Disney and CMU
Stars: ✭ 3,035 (+8826.47%)
Mutual labels:  multi-platform
cacheify
Browserify transform wrapper that caches the transforms between runs to improve performance
Stars: ✭ 30 (-11.76%)
Mutual labels:  build-tool
Flaxengine
Flax Engine – multi-platform 3D game engine
Stars: ✭ 3,127 (+9097.06%)
Mutual labels:  multi-platform
next-boilerplate
☶ The easiest way to create a Next app by running one command.
Stars: ✭ 65 (+91.18%)
Mutual labels:  build-tool
DialogHost.Avalonia
AvaloniaUI control that provides a simple way to display a dialog with information or prompt the user when information is needed
Stars: ✭ 92 (+170.59%)
Mutual labels:  multi-platform
proot-static-build
Build static variants of PRoot
Stars: ✭ 63 (+85.29%)
Mutual labels:  build-tool
Examples wxWidgets
Shows how to use wxWidgets controls only by programming code (c++17).
Stars: ✭ 116 (+241.18%)
Mutual labels:  multi-platform
Tdesktop
Telegram Desktop messaging app
Stars: ✭ 17,508 (+51394.12%)
Mutual labels:  multi-platform
ocsigen-start
Ocsigen-start: an Eliom application skeleton ready to use to build your own application with users, (pre)registration, notifications, etc.
Stars: ✭ 70 (+105.88%)
Mutual labels:  multi-platform
Libuiohook
A multi-platform C library to provide global keyboard and mouse hooks from userland.
Stars: ✭ 237 (+597.06%)
Mutual labels:  multi-platform
rush-cli
⚡ A new and improved way of building MIT AI2 extensions.
Stars: ✭ 31 (-8.82%)
Mutual labels:  build-tool
Esenthelengine
Full Source of Esenthel Engine and its Tools
Stars: ✭ 204 (+500%)
Mutual labels:  multi-platform
tag-push-action
Github action to copy/retag multiarch images from one registry to another
Stars: ✭ 23 (-32.35%)
Mutual labels:  buildx
makeme
Embedthis MakeMe
Stars: ✭ 26 (-23.53%)
Mutual labels:  build-tool
docker-firefox-syncserver
Firefox Sync Server Docker image
Stars: ✭ 169 (+397.06%)
Mutual labels:  multi-platform
cmake-d
cmake for D2
Stars: ✭ 57 (+67.65%)
Mutual labels:  build-tool

goreleaser-xx

GitHub release Build Status Docker Stars Docker Pulls Go Report Card

About

goreleaser-xx is a small CLI wrapper for GoReleaser and available as a lightweight and multi-platform scratch Docker image to ease the integration and cross compilation in a Dockerfile for your Go projects.

Building yasu with goreleaser-xx


Features

  • Handle --platform in your Dockerfile for multi-platform support
  • Build into any architecture
  • Handle C and C++ compilers (CGO)
  • Translation of platform ARGs in the global scope into Go compiler's target
  • Auto generation of .goreleaser.yml config based on target architecture
  • Demo projects

Image

Registry Image
Docker Hub crazymax/goreleaser-xx
GitHub Container Registry ghcr.io/crazy-max/goreleaser-xx

Following platforms for this image are available:

$ docker run --rm mplatform/mquery crazymax/goreleaser-xx:latest
Image: crazymax/goreleaser-xx:latest (digest: sha256:c65c481c014abab6d307b190ddf1fcb229a44b6c1845d2f2a53bd06dc0437cd7)
 * Manifest List: Yes (Image type: application/vnd.docker.distribution.manifest.list.v2+json)
 * Supported platforms:
   - linux/386
   - linux/amd64
   - linux/arm/v5
   - linux/arm/v6
   - linux/arm/v7
   - linux/arm64
   - linux/ppc64le
   - linux/riscv64
   - linux/s390x

CLI

docker run --rm -t crazymax/goreleaser-xx:latest goreleaser-xx --help
Flag Env var Description
--debug DEBUG Enable debug (default false)
--git-ref GIT_REF The branch or tag like refs/tags/v1.0.0 (default to your working tree info)
--goreleaser GORELEASER_PATH Set a specific GoReleaser binary to use (default goreleaser)
--config GORELEASER_CONFIG Load GoReleaser configuration from file
--go-binary GORELEASER_GOBINARY Set a specific go binary to use when building (default go)
--name GORELEASER_NAME Project name
--dist GORELEASER_DIST Dist folder where artifact will be stored
--artifacts GORELEASER_ARTIFACTS Types of artifact to create (archive, bin) (default archive)
--main GORELEASER_MAIN Path to main.go file or main package (default .)
--flags GORELEASER_FLAGS Custom flags templates
--asmflags GORELEASER_ASMFLAGS Custom asmflags templates
--gcflags GORELEASER_GCFLAGS Custom gcflags templates
--ldflags GORELEASER_LDFLAGS Custom ldflags templates
--tags GORELEASER_TAGS Custom build tags templates
--files GORELEASER_FILES Additional files/template/globs you want to add to the archive
--replacements GORELEASER_REPLACEMENTS Replacements for GOOS and GOARCH in the archive/binary name
--envs GORELEASER_ENVS Custom environment variables to be set during the build
--pre-hooks GORELEASER_PRE_HOOKS Hooks which will be executed before the build
--post-hooks GORELEASER_POST_HOOKS Hooks which will be executed after the build
--snapshot GORELEASER_SNAPSHOT Run in snapshot mode
--checksum GORELEASER_CHECKSUM Create checksum (default true)

Usage

In order to use it, we will use the docker buildx command in the following examples. Buildx is a Docker component that enables many powerful build features. All builds executed via buildx run with Moby BuildKit builder engine.

Minimal

Here is a minimal Dockerfile to build a Go project using goreleaser-xx:

# syntax=docker/dockerfile:1

FROM --platform=$BUILDPLATFORM crazymax/goreleaser-xx:latest AS goreleaser-xx
FROM --platform=$BUILDPLATFORM golang:1.17-alpine AS base
ENV CGO_ENABLED=0
COPY --from=goreleaser-xx / /
RUN apk add --no-cache git
WORKDIR /src

FROM base AS vendored
RUN --mount=type=bind,source=.,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=.,rw \
  --mount=type=cache,target=/root/.cache \
  --mount=type=cache,target=/go/pkg/mod \
  goreleaser-xx --debug \
    --name="myapp" \
    --dist="/out" \
    --ldflags="-s -w -X 'main.version={{.Version}}'" \
    --files="LICENSE" \
    --files="README.md"

FROM scratch AS artifact
COPY --from=build /out/*.tar.gz /
COPY --from=build /out/*.zip /
  • FROM --platform=$BUILDPLATFORM ... command will pull an image that will always match the native platform of your machine (e.g., linux/amd64). BUILDPLATFORM is part of the ARGs in the global scope.
  • ARG TARGETPLATFORM is 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 --platform flag of buildx so goreleaser-xx will be able to automatically build against the right platform.

More details about multi-platform builds in this blog post.

As you can see goreleaser-xx CLI handles basic GoReleaser build customizations with flags to be able to generate a temp and dynamic .goreleaser.yml configuration, but you can also include your own GoReleaser YAML config.

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 \
  --output "./dist" \
  --target "artifact" .

$ tree ./dist
./dist
├── myapp_v1.0.0-SNAPSHOT-00655a9_linux_amd64.tar.gz
└── myapp_v1.0.0-SNAPSHOT-00655a9_linux_amd64.tar.gz.sha256

Here linux/amd64 arch is used because it's my current platform. If we want to handle more platforms, we need to create a builder instance as building multi-platform is currently only supported when using BuildKit with the docker-container or kubernetes drivers.

# create a builder instance
$ docker buildx create --name "mybuilder" --use

# now build for other platforms
$ docker buildx build \
  --platform "linux/amd64,linux/arm64,linux/arm/v7,windows/amd64,darwin/amd64" \
  --output "./dist" \
  --target "artifact" .

$ tree ./dist
./dist
├── darwin_amd64
│ ├── myapp_v1.0.0-SNAPSHOT-00655a9_darwin_x86_64.tar.gz
│ └── myapp_v1.0.0-SNAPSHOT-00655a9_darwin_x86_64.tar.gz.sha256
├── linux_amd64
│ ├── myapp_v1.0.0-SNAPSHOT-00655a9_linux_x86_64.tar.gz
│ └── myapp_v1.0.0-SNAPSHOT-00655a9_linux_x86_64.tar.gz.sha256
├── linux_arm64
│ ├── myapp_v1.0.0-SNAPSHOT-00655a9_linux_arm64.tar.gz
│ └── myapp_v1.0.0-SNAPSHOT-00655a9_linux_arm64.tar.gz.sha256
├── linux_arm_v7
│ ├── myapp_v1.0.0-SNAPSHOT-00655a9_linux_armv7.tar.gz
│ └── myapp_v1.0.0-SNAPSHOT-00655a9_linux_armv7.tar.gz.sha256
└── windows_amd64
│ ├── myapp_v1.0.0-SNAPSHOT-00655a9_windows_x86_64.tar.gz
│ └── myapp_v1.0.0-SNAPSHOT-00655a9_windows_x86_64.tar.gz.sha256

Multi-platform image

We can enhance the previous example to also create a multi-platform image in addition to the generated artifacts:

# syntax=docker/dockerfile:1

FROM --platform=$BUILDPLATFORM crazymax/goreleaser-xx:latest AS goreleaser-xx
FROM --platform=$BUILDPLATFORM golang:1.17-alpine AS base
ENV CGO_ENABLED=0
COPY --from=goreleaser-xx / /
RUN apk add --no-cache git
WORKDIR /src

FROM base AS vendored
RUN --mount=type=bind,source=.,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=.,rw \
  --mount=type=cache,target=/root/.cache \
  --mount=type=cache,target=/go/pkg/mod \
  goreleaser-xx --debug \
    --name="myapp" \
    --dist="/out" \
    --ldflags="-s -w -X 'main.version={{.Version}}'" \
    --files="LICENSE" \
    --files="README.md"

FROM scratch AS artifact
COPY --from=build /out/*.tar.gz /
COPY --from=build /out/*.zip /

FROM alpine AS image
RUN apk --update --no-cache add ca-certificates openssl
COPY --from=build /usr/local/bin/myapp /usr/local/bin/myapp
EXPOSE 8080
ENTRYPOINT [ "myapp" ]

As you can see, we have added a new stage called image. The artifact of each platform is available with goreleaser-xx in /usr/local/bin/{{ .ProjectName }}{{ .Ext }} (build stage) and will be included in your image stage via COPY --from=build command.

Now let's build, tag and push our multi-platform image with buildx:

docker buildx build \
  --tag "user/myapp:latest" \
  --platform "linux/amd64,linux/arm64,linux/arm/v7" \
  --target "image" \
  --push .

windows/amd64 and darwin/amd64 platforms have been removed here because alpine:3.14 does not support them.

With .goreleaser.yml

You can also use a .goreleaser.yml to configure your build:

env:
  - GO111MODULE=auto

gomod:
  proxy: true

builds:
  - mod_timestamp: '{{ .CommitTimestamp }}'
    flags:
      - -trimpath
    ldflags:
      - -s -w

nfpms:
  - file_name_template: '{{ .ConventionalFileName }}'
    homepage:  https://github.com/user/hello
    description: Hello world
    maintainer: Hello <[email protected]>
    license: MIT
    vendor: HelloWorld
    formats:
      - apk
      - deb
      - rpm
# syntax=docker/dockerfile:1

FROM --platform=$BUILDPLATFORM crazymax/goreleaser-xx:latest AS goreleaser-xx
FROM --platform=$BUILDPLATFORM golang:1.17-alpine AS base
ENV CGO_ENABLED=0
COPY --from=goreleaser-xx / /
RUN apk add --no-cache git
WORKDIR /src

FROM base AS vendored
RUN --mount=type=bind,source=.,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=.,rw \
  --mount=type=cache,target=/root/.cache \
  --mount=type=cache,target=/go/pkg/mod \
  goreleaser-xx --debug \
    --config=".goreleaser.yml" \
    --name="hello" \
    --dist="/out" \
    --main="." \
    --files="README.md"

FROM scratch AS artifact
COPY --from=build /out/*.tar.gz /
COPY --from=build /out/*.zip /

CGO

Here are some examples to use CGO to build your project with goreleaser-xx:

crazy-max/goxx

https://github.com/crazy-max/goxx

# syntax=docker/dockerfile:1

FROM --platform=$BUILDPLATFORM crazymax/goreleaser-xx:latest AS goreleaser-xx
FROM --platform=$BUILDPLATFORM crazymax/osxcross:11.3 AS osxcross
FROM --platform=$BUILDPLATFORM crazymax/goxx:1.17 AS base
COPY --from=osxcross /osxcross /osxcross
COPY --from=goreleaser-xx / /
ENV CGO_ENABLED=1
RUN goxx-apt-get install --no-install-recommends -y git
WORKDIR /src

FROM base AS vendored
RUN --mount=type=bind,source=.,rw \
  --mount=type=cache,target=/go/pkg/mod \
  go mod tidy && go mod download

FROM vendored AS build
ARG TARGETPLATFORM
RUN --mount=type=cache,sharing=private,target=/var/cache/apt \
  --mount=type=cache,sharing=private,target=/var/lib/apt/lists \
  goxx-apt-get install -y binutils gcc g++ pkg-config
RUN --mount=type=bind,source=.,rw \
  --mount=type=cache,target=/root/.cache \
  --mount=type=cache,target=/go/pkg/mod \
  goreleaser-xx --debug \
    --name="myapp" \
    --dist="/out" \
    --ldflags="-s -w -X 'main.version={{.Version}}'" \
    --files="LICENSE" \
    --files="README.md"

FROM scratch AS artifact
COPY --from=build /out/*.tar.gz /
COPY --from=build /out/*.zip /

tonistiigi/xx

https://github.com/tonistiigi/xx

# syntax=docker/dockerfile:1

FROM --platform=$BUILDPLATFORM crazymax/goreleaser-xx:latest AS goreleaser-xx
FROM --platform=$BUILDPLATFORM tonistiigi/xx:1.1.2 AS xx
FROM --platform=$BUILDPLATFORM golang:1.17-alpine AS base
ENV CGO_ENABLED=1
COPY --from=goreleaser-xx / /
COPY --from=xx / /
RUN apk add --no-cache clang git file lld llvm pkgconfig
WORKDIR /src

FROM base AS vendored
RUN --mount=type=bind,source=.,target=/src,rw \
  --mount=type=cache,target=/go/pkg/mod \
  go mod tidy && go mod download

FROM vendored AS build
ARG TARGETPLATFORM
RUN xx-apk add --no-cache gcc musl-dev
# XX_CC_PREFER_STATIC_LINKER prefers ld to lld in ppc64le and 386.
ENV XX_CC_PREFER_STATIC_LINKER=1
RUN --mount=type=bind,source=.,rw \
  --mount=from=crazymax/osxcross:11.3,src=/osxsdk,target=/xx-sdk \
  --mount=type=cache,target=/root/.cache \
  --mount=type=cache,target=/go/pkg/mod \
  goreleaser-xx --debug \
    --go-binary="xx-go" \
    --name="myapp" \
    --dist="/out" \
    --ldflags="-s -w -X 'main.version={{.Version}}'" \
    --files="LICENSE" \
    --files="README.md"

FROM scratch AS artifact
COPY --from=build /out/*.tar.gz /
COPY --from=build /out/*.zip /

Notes

CGO_ENABLED

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.

Build

Everything is dockerized and handled by buildx bake for an agnostic usage of this repo:

git clone https://github.com/crazy-max/goreleaser-xx.git goreleaser-xx
cd goreleaser-xx

# build docker image and output to docker with goreleaser-xx:local tag (default)
docker buildx bake

# build multi-platform image
docker buildx bake image-all

Contributing

Want to contribute? Awesome! The most basic way to show your support is to star the project, or to raise issues. If you want to open a pull request, please read the contributing guidelines.

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.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].