@@ -2,14 +2,27 @@ ARG BASE_VARIANT=alpine
2
2
ARG GO_VERSION=1.17
3
3
ARG XX_VERSION=1.1.0
4
4
5
- ARG LIBGIT2_IMG=ghcr.io/fluxcd/golang-with-libgit2
6
- ARG LIBGIT2_TAG=libgit2-1.1.1-4
5
+ ARG LIBGIT2_IMG
6
+ ARG LIBGIT2_TAG
7
7
8
- FROM --platform=linux/amd64 ${LIBGIT2_IMG}:${LIBGIT2_TAG} as build-amd64
9
- FROM --platform=linux/arm64 ${LIBGIT2_IMG}:${LIBGIT2_TAG} as build-arm64
10
- FROM --platform=linux/arm/v7 ${LIBGIT2_IMG}:${LIBGIT2_TAG} as build-armv7
8
+ FROM ${LIBGIT2_IMG}:${LIBGIT2_TAG} AS libgit2-libs
11
9
12
- FROM --platform=$BUILDPLATFORM build-$TARGETARCH$TARGETVARIANT AS build
10
+ FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
11
+
12
+ FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-${BASE_VARIANT} as gostable
13
+
14
+ FROM gostable AS go-linux
15
+
16
+ # Build-base consists of build platform dependencies and xx.
17
+ # These will be used at current arch to yield execute the cross compilations.
18
+ FROM go-${TARGETOS} AS build-base
19
+
20
+ RUN apk add --no-cache clang lld pkgconfig
21
+
22
+ COPY --from=xx / /
23
+
24
+ # build-go-mod can still be cached at build platform architecture.
25
+ FROM build-base as build-go-mod
13
26
14
27
# Configure workspace
15
28
WORKDIR /workspace
@@ -24,26 +37,55 @@ COPY go.sum go.sum
24
37
# Cache modules
25
38
RUN go mod download
26
39
27
- RUN apk add clang lld pkgconfig ca-certificates
40
+ # The musl-tool-chain layer is an adhoc solution
41
+ # for the problem in which xx gets confused during compilation
42
+ # and a) looks for gold linker and then b) cannot find musl's dynamic linker.
43
+ FROM --platform=$BUILDPLATFORM alpine as musl-tool-chain
44
+
45
+ COPY --from=xx / /
46
+
47
+ RUN apk add bash curl tar
48
+
49
+ WORKDIR /workspace
50
+ COPY hack/download-musl.sh .
28
51
29
- # Build the binary
30
- ENV CGO_ENABLED=1
31
52
ARG TARGETPLATFORM
53
+ ARG TARGETARCH
54
+ RUN ROOT_DIR="$(pwd)" TARGET_ARCH="$(xx-info alpine-arch)" ENV_FILE=true \
55
+ ./download-musl.sh
32
56
33
- RUN xx-apk add --no-cache \
34
- musl-dev gcc lld binutils-gold
57
+ # Build stage install per target platform
58
+ # dependency and effectively cross compile the application.
59
+ FROM build-go-mod as build
60
+
61
+ ARG TARGETPLATFORM
62
+
63
+ COPY --from=libgit2-libs /usr/local/ /usr/local/
64
+
65
+ # Some dependencies have to installed
66
+ # for the target platform: https://github.com/tonistiigi/xx#go--cgo
67
+ RUN xx-apk add musl-dev gcc lld
68
+
69
+ WORKDIR /workspace
70
+
71
+ # Copy source code
72
+ COPY main.go main.go
73
+ COPY controllers/ controllers/
74
+ COPY pkg/ pkg/
75
+ COPY internal/ internal/
76
+
77
+ COPY --from=musl-tool-chain /workspace/build /workspace/build
78
+
79
+ ARG TARGETPLATFORM
80
+ ARG TARGETARCH
81
+ ENV CGO_ENABLED=1
35
82
36
- # Performance related changes:
37
- # - Use read-only bind instead of copying go source files.
38
- # - Cache go packages.
39
- RUN --mount=target=. \
40
- --mount=type=cache,target=/root/.cache/go-build \
41
- --mount=type=cache,target=/go/pkg \
42
- export LIBRARY_PATH="/usr/local/$(xx-info triple)/lib:/usr/local/$(xx-info triple)/lib64:${LIBRARY_PATH}" && \
83
+ # Instead of using xx-go, (cross) compile with vanilla go leveraging musl tool chain.
84
+ RUN export $(cat build/musl/$(xx-info alpine-arch).env | xargs) && \
85
+ export LIBRARY_PATH="/usr/local/$(xx-info triple):/usr/local/$(xx-info triple)/lib64" && \
43
86
export PKG_CONFIG_PATH="/usr/local/$(xx-info triple)/lib/pkgconfig:/usr/local/$(xx-info triple)/lib64/pkgconfig" && \
44
- export FLAGS="$(pkg-config --static --libs --cflags libssh2 openssl libgit2)" && \
45
- CGO_LDFLAGS="${FLAGS} -static" \
46
- xx-go build \
87
+ export CGO_LDFLAGS="$(pkg-config --static --libs --cflags libssh2 openssl libgit2) -static" && \
88
+ GOARCH=$TARGETARCH go build \
47
89
-ldflags "-s -w" \
48
90
-tags 'netgo,osusergo,static_build' \
49
91
-o /source-controller -trimpath main.go;
0 commit comments