Skip to content

Commit

Permalink
Build Linux binaries with musl
Browse files Browse the repository at this point in the history
When I tried to build with "normal" glibc, I got weird errors on old/new glibc.

Instead of building with glibc, which limits us with compatibility and weird issues, let's build with
musl, which will always produce 100% static library.

(Musl is a libc alternative. The good thing is musl is statically linked
and can cross-compile relatively easily.)

The actual hard work is building all these musl cross-compilers;
luckily, Rust people already did that for Rust :) we can steal that and reuse.

Note that this all works on both AMD and ARM hosts, as both the musl cross-compilers images
and the go images are published for both.
  • Loading branch information
igor-hnizdo committed Sep 7, 2022
1 parent 5d72637 commit 24d8150
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 15 deletions.
11 changes: 11 additions & 0 deletions release/linux/Dockerfile.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM messense/rust-musl-cross:aarch64-musl AS go-arm64-musl
COPY --from=golang:1.19.1 /usr/local/go/ /usr/local/go/
ENV TREZORD_BUILD=go-arm64-musl

FROM messense/rust-musl-cross:i686-musl AS go-386-musl
COPY --from=golang:1.19.1 /usr/local/go/ /usr/local/go/
ENV TREZORD_BUILD=go-386-musl

FROM messense/rust-musl-cross:x86_64-musl AS go-amd64-musl
COPY --from=golang:1.19.1 /usr/local/go/ /usr/local/go/
ENV TREZORD_BUILD=go-amd64-musl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# initialize from the image

FROM fedora:32
FROM fedora:36

# update package repositories

Expand Down
35 changes: 21 additions & 14 deletions release/linux/Makefile
Original file line number Diff line number Diff line change
@@ -1,33 +1,40 @@
PLATFORM = linux
VOL_MOUNT = -v $(shell pwd):/release
IMAGETAG = trezord-go-build-env-$(PLATFORM)

IMPORT_PATH = ../..
IMAGETAG_PACKAGE = trezord-go-package-env-$(PLATFORM)
IMAGETAG_BUILD = trezord-go-build-env-$(PLATFORM)

IMPORT_PATH = $(shell realpath ../..)

all: clean .package

clean:
$(info Cleaning...)
rm -rf build

.binary:
$(info Building with xgo ...)
.binary: .docker-image-build
$(info Building with musl crosbuild ...)
mkdir -p build
xgo -targets=linux/386,linux/amd64,linux/arm64 $(IMPORT_PATH)
mv -f trezord-go-linux-386 build/trezord-linux-386
mv -f trezord-go-linux-amd64 build/trezord-linux-amd64
mv -f trezord-go-linux-arm64 build/trezord-linux-arm64
docker run -it --rm -v $(IMPORT_PATH):/trezord -w /trezord $(IMAGETAG_BUILD)-arm64 /trezord/release/linux/build.sh
docker run -it --rm -v $(IMPORT_PATH):/trezord -w /trezord $(IMAGETAG_BUILD)-386 /trezord/release/linux/build.sh
docker run -it --rm -v $(IMPORT_PATH):/trezord -w /trezord $(IMAGETAG_BUILD)-amd64 /trezord/release/linux/build.sh
cp ../../VERSION build

.package: .binary .docker-image
.package: .binary .docker-image-package
$(info Packaging ...)
docker run -i -t $(VOL_MOUNT) $(IMAGETAG) /release/release.sh linux-386
docker run -i -t $(VOL_MOUNT) $(IMAGETAG) /release/release.sh linux-amd64
docker run -i -t $(VOL_MOUNT) $(IMAGETAG) /release/release.sh linux-arm64
docker run -i -t $(VOL_MOUNT) $(IMAGETAG_PACKAGE) /release/release.sh linux-386
docker run -i -t $(VOL_MOUNT) $(IMAGETAG_PACKAGE) /release/release.sh linux-amd64
docker run -i -t $(VOL_MOUNT) $(IMAGETAG_PACKAGE) /release/release.sh linux-arm64

.docker-image-build:
$(info Preparing docker images for build ...)
docker build -t $(IMAGETAG_BUILD)-arm64 . -f Dockerfile.build --target go-arm64-musl
docker build -t $(IMAGETAG_BUILD)-amd64 . -f Dockerfile.build --target go-amd64-musl
docker build -t $(IMAGETAG_BUILD)-386 . -f Dockerfile.build --target go-386-musl

.docker-image:
.docker-image-package:
$(info Preparing docker image ...)
docker build -t $(IMAGETAG) .
docker build -t $(IMAGETAG_PACKAGE) . -f Dockerfile.package

shell: .docker-image
docker run -i -t $(VOL_MOUNT) $(IMAGETAG) /bin/bash
Expand Down
29 changes: 29 additions & 0 deletions release/linux/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/sh

set -ex
PATH=$PATH:/usr/local/go/bin

case $TREZORD_BUILD in
"go-arm64-musl")
CGO_ENABLED=1 CC="/usr/local/musl/bin/aarch64-unknown-linux-musl-gcc" GOARCH=arm64 \
go build --ldflags '-linkmode external -extldflags "-static" -extld /usr/local/musl/bin/aarch64-unknown-linux-musl-gcc' \
-o release/linux/build/trezord-linux-arm64
;;

"go-386-musl")
CGO_ENABLED=1 CC="/usr/local/musl/bin/i686-unknown-linux-musl-gcc" GOARCH=386 \
go build --ldflags '-linkmode external -extldflags "-static" -extld /usr/local/musl/bin/i686-unknown-linux-musl-gcc' \
-o release/linux/build/trezord-linux-386
;;

"go-amd64-musl")
CGO_ENABLED=1 CC="/usr/local/musl/bin/x86_64-unknown-linux-musl-gcc" GOARCH=amd64 \
go build --ldflags '-linkmode external -extldflags "-static" -extld /usr/local/musl/bin/x86_64-unknown-linux-musl-gcc' \
-o release/linux/build/trezord-linux-amd64
;;

*)
echo -n "unknown build"
exit 1
;;
esac

0 comments on commit 24d8150

Please sign in to comment.