Skip to content
This repository was archived by the owner on Dec 16, 2022. It is now read-only.

Commit a05dea1

Browse files
authored
Merge pull request #13 from pjbgf/libgit2-1.1.1-5
Optimise target image for cross compilation
2 parents f79adb7 + c4cd5ea commit a05dea1

File tree

7 files changed

+280
-124
lines changed

7 files changed

+280
-124
lines changed

Dockerfile

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,7 @@ ARG XX_VERSION=1.1.0
55

66
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
77

8-
FROM golang:${GO_VERSION}-${BASE_VARIANT} as gostable
9-
10-
FROM gostable AS go-linux
11-
12-
FROM --platform=$BUILDPLATFORM ${BASE_VARIANT} AS build-deps
8+
FROM --platform=$BUILDPLATFORM ${BASE_VARIANT} AS build-base
139

1410
RUN apk add --no-cache \
1511
bash \
@@ -26,15 +22,10 @@ RUN apk add --no-cache \
2622

2723
COPY --from=xx / /
2824

29-
ARG TARGETPLATFORM
30-
31-
RUN xx-apk add --no-cache \
32-
xx-c-essentials
33-
34-
RUN xx-apk add --no-cache \
35-
xx-cxx-essentials
25+
FROM build-base AS build-cross
3626

3727
ARG TARGETPLATFORM
28+
3829
RUN xx-apk add --no-cache \
3930
build-base \
4031
pkgconfig \
@@ -48,7 +39,6 @@ RUN xx-apk add --no-cache \
4839
WORKDIR /build
4940
COPY hack/static.sh .
5041

51-
ARG TARGETPLATFORM
5242
ENV CC=xx-clang
5343
ENV CXX=xx-clang++
5444

@@ -68,12 +58,25 @@ RUN ./static.sh build_libssh2
6858
RUN ./static.sh build_libgit2
6959

7060

71-
FROM go-${TARGETOS} AS build
61+
# trimmed removes all non necessary files (i.e. openssl binary).
62+
FROM build-cross AS trimmed
7263

73-
# Copy cross-compilation tools
74-
COPY --from=xx / /
75-
# Copy compiled libraries
76-
COPY --from=build-deps /usr/local/ /usr/local/
64+
ARG TARGETPLATFORM
65+
RUN mkdir -p /trimmed/usr/local/$(xx-info triple)/ && \
66+
mkdir -p /trimmed/usr/local/$(xx-info triple)/share
67+
68+
RUN cp -r /usr/local/$(xx-info triple)/lib/ /trimmed/usr/local/$(xx-info triple)/ && \
69+
cp -r /usr/local/$(xx-info triple)/lib64/ /trimmed/usr/local/$(xx-info triple)/ | true && \
70+
cp -r /usr/local/$(xx-info triple)/include/ /trimmed/usr/local/$(xx-info triple)/ && \
71+
cp -r /usr/local/$(xx-info triple)/share/doc/ /trimmed/usr/local/$(xx-info triple)/share/
72+
73+
FROM scratch as libs-arm64
74+
COPY --from=trimmed /trimmed/ /
75+
76+
FROM scratch as libs-amd64
77+
COPY --from=trimmed /trimmed/ /
78+
79+
FROM scratch as libs-armv7
80+
COPY --from=trimmed /trimmed/ /
7781

78-
COPY ./hack/Makefile /Makefile
79-
COPY ./hack/static.sh /static.sh
82+
FROM libs-$TARGETARCH$TARGETVARIANT as libs

Dockerfile.test

Lines changed: 26 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,107 +1,59 @@
1-
# This Dockerfile tests the hack/Makefile output against git2go.
21
ARG BASE_VARIANT=alpine
3-
ARG GO_VERSION=1.17.6
2+
ARG GO_VERSION=1.17
43
ARG XX_VERSION=1.1.0
54

6-
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
7-
8-
FROM golang:${GO_VERSION}-${BASE_VARIANT} as gostable
9-
10-
FROM gostable AS go-linux
11-
12-
FROM --platform=$BUILDPLATFORM ${BASE_VARIANT} AS build-deps
13-
14-
RUN apk add --no-cache \
15-
bash \
16-
curl \
17-
build-base \
18-
linux-headers \
19-
perl \
20-
cmake \
21-
pkgconfig \
22-
gcc \
23-
musl-dev \
24-
clang \
25-
lld
26-
27-
COPY --from=xx / /
5+
ARG LIBGIT2_IMG
6+
ARG LIBGIT2_TAG
287

29-
ARG TARGETPLATFORM
30-
31-
RUN xx-apk add --no-cache \
32-
xx-c-essentials
33-
34-
RUN xx-apk add --no-cache \
35-
xx-cxx-essentials
36-
37-
ARG TARGETPLATFORM
38-
RUN xx-apk add --no-cache \
39-
build-base \
40-
pkgconfig \
41-
gcc \
42-
musl-dev \
43-
clang \
44-
lld \
45-
llvm \
46-
linux-headers
47-
48-
WORKDIR /build
49-
COPY hack/static.sh .
50-
51-
ARG TARGETPLATFORM
52-
ENV CC=xx-clang
53-
ENV CXX=xx-clang++
8+
FROM ${LIBGIT2_IMG}:${LIBGIT2_TAG} AS build-deps
549

55-
RUN CHOST=$(xx-clang --print-target-triple) \
56-
./static.sh build_libz
57-
58-
RUN CHOST=$(xx-clang --print-target-triple) \
59-
./static.sh build_openssl
10+
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
6011

61-
RUN export LIBRARY_PATH="/usr/local/$(xx-info triple)/lib:/usr/local/$(xx-info triple)/lib64:${LIBRARY_PATH}" && \
62-
export PKG_CONFIG_PATH="/usr/local/$(xx-info triple)/lib/pkgconfig:/usr/local/$(xx-info triple)/lib64/pkgconfig" && \
63-
export OPENSSL_ROOT_DIR="/usr/local/$(xx-info triple)" && \
64-
export OPENSSL_CRYPTO_LIBRARY="/usr/local/$(xx-info triple)/lib64" && \
65-
export OPENSSL_INCLUDE_DIR="/usr/local/$(xx-info triple)/include/openssl"
12+
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-${BASE_VARIANT} as gostable
6613

67-
RUN ./static.sh build_libssh2
68-
RUN ./static.sh build_libgit2
14+
FROM gostable AS go-linux
6915

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
7019

71-
FROM go-${TARGETOS} AS build
20+
RUN apk add clang lld pkgconfig
7221

73-
# Copy cross-compilation tools
7422
COPY --from=xx / /
75-
# Copy compiled libraries
76-
COPY --from=build-deps /usr/local/ /usr/local/
7723

78-
RUN apk add clang lld pkgconfig
24+
# build-go-mod can still be cached at build platform architecture.
25+
FROM build-base as build-go-mod
7926

8027
WORKDIR /root/smoketest
8128
COPY tests/smoketest/go.mod .
8229
COPY tests/smoketest/go.sum .
8330
RUN go mod download
8431

32+
# Build stage install per target platform
33+
# dependency and effectively cross compile the application.
34+
FROM build-go-mod as build
35+
8536
ARG TARGETPLATFORM
8637

8738
# Some dependencies have to installed
8839
# for the target platform: https://github.com/tonistiigi/xx#go--cgo
89-
RUN xx-apk add --no-cache \
90-
musl-dev \
91-
gcc
40+
RUN xx-apk add musl-dev gcc clang lld
9241

42+
WORKDIR /root/smoketest
9343

9444
COPY tests/smoketest/main.go .
45+
COPY --from=build-deps /usr/local/ /usr/local/
9546

9647
ENV CGO_ENABLED=1
97-
RUN export LIBRARY_PATH="/usr/local/$(xx-info triple)/lib:/usr/local/$(xx-info triple)/lib64:${LIBRARY_PATH}" && \
48+
RUN export LIBRARY_PATH="/usr/local/$(xx-info triple):/usr/local/$(xx-info triple)/lib64" && \
9849
export PKG_CONFIG_PATH="/usr/local/$(xx-info triple)/lib/pkgconfig:/usr/local/$(xx-info triple)/lib64/pkgconfig" && \
99-
export FLAGS="$(pkg-config --static --libs --cflags libssh2 openssl libgit2)" && \
100-
CGO_LDFLAGS="${FLAGS} -static" \
101-
xx-go build \
50+
export FLAGS="$(pkg-config --static --libs --cflags libssh2 openssl libgit2)" && \
51+
export CGO_LDFLAGS="${FLAGS} -static" && \
52+
xx-go build \
10253
-ldflags "-s -w" \
10354
-tags 'netgo,osusergo,static_build' \
104-
-o static-test-runner -trimpath main.go;
55+
-o static-test-runner -trimpath main.go
56+
10557

10658
# Ensure that the generated binary is valid for the target platform
10759
RUN xx-verify --static static-test-runner
@@ -119,11 +71,4 @@ COPY --from=build \
11971

12072
ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
12173

122-
# To do docker run instead, replace the RUN statement with:
123-
# ENTRYPOINT [ "/root/smoketest/static-test-runner" ]
124-
125-
# The approach below was preferred as it provides a way to
126-
# assert the functionality across the supported architectures
127-
# without any extra steps.
128-
12974
RUN /root/smoketest/static-test-runner

Makefile

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,42 @@
1-
IMG ?= hiddeco/golang-with-libgit2
1+
IMG ?= ghcr.io/fluxcd/golang-with-libgit2
22
TAG ?= latest
3-
STATIC_TEST_TAG := test
43

54
PLATFORMS ?= linux/amd64,linux/arm/v7,linux/arm64
65
BUILD_ARGS ?=
76

7+
REPOSITORY_ROOT := $(shell git rev-parse --show-toplevel)
8+
TARGET_DIR ?= $(REPOSITORY_ROOT)/build/libgit2
9+
BUILD_ROOT_DIR ?= $(REPOSITORY_ROOT)/build/libgit2-src
10+
11+
LIBGIT2_PATH := $(TARGET_DIR)
12+
LIBGIT2_LIB_PATH := $(LIBGIT2_PATH)/lib
13+
LIBGIT2_LIB64_PATH := $(LIBGIT2_PATH)/lib64
14+
LIBGIT2 := $(LIBGIT2_LIB_PATH)/libgit2.a
15+
MUSL-CC =
16+
17+
export CGO_ENABLED=1
18+
export LIBRARY_PATH=$(LIBGIT2_LIB_PATH):$(LIBGIT2_LIB64_PATH)
19+
export PKG_CONFIG_PATH=$(LIBGIT2_LIB_PATH)/pkgconfig:$(LIBGIT2_LIB64_PATH)/pkgconfig
20+
export CGO_CFLAGS=-I$(LIBGIT2_PATH)/include
21+
22+
23+
ifeq ($(shell uname -s),Linux)
24+
export CGO_LDFLAGS=$(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs --static --cflags libssh2 openssl libgit2) -static
25+
else
26+
export CGO_LDFLAGS=$(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs --static --cflags libssh2 openssl libgit2) -Wl,--unresolved-symbols=ignore-in-object-files -Wl,-allow-shlib-undefined -static
27+
endif
28+
29+
ifeq ($(shell uname -s),Linux)
30+
MUSL-PREFIX=$(REPOSITORY_ROOT)/build/musl/$(shell uname -m)-linux-musl-native/bin/$(shell uname -m)-linux-musl
31+
MUSL-CC=$(MUSL-PREFIX)-gcc
32+
export CC=$(MUSL-PREFIX)-gcc
33+
export CXX=$(MUSL-PREFIX)-g++
34+
export AR=$(MUSL-PREFIX)-ar
35+
endif
36+
37+
GO_STATIC_FLAGS=-tags 'netgo,osusergo,static_build'
38+
39+
840
.PHONY: build
941
build:
1042
docker buildx build \
@@ -17,7 +49,9 @@ build:
1749
test:
1850
docker buildx build \
1951
--platform=$(PLATFORMS) \
20-
--tag $(IMG):$(TAG) \
52+
--tag $(IMG):$(TAG)-test \
53+
--build-arg LIBGIT2_IMG=$(IMG) \
54+
--build-arg LIBGIT2_TAG=$(TAG) \
2155
--file Dockerfile.test \
2256
$(BUILD_ARGS) .
2357

@@ -33,3 +67,24 @@ builder:
3367
--use
3468
# install qemu emulators
3569
docker run -it --rm --privileged tonistiigi/binfmt --install all
70+
71+
72+
$(LIBGIT2): $(MUSL-CC)
73+
ifeq ($(shell uname -s),Darwin)
74+
TARGET_DIR=$(TARGET_DIR) BUILD_ROOT_DIR=$(BUILD_ROOT_DIR) \
75+
./hack/static.sh all
76+
else
77+
IMG_TAG=$(IMG):$(TAG) ./hack/extract-libraries.sh
78+
endif
79+
80+
$(MUSL-CC):
81+
ifneq ($(shell uname -s),Darwin)
82+
./hack/download-musl.sh
83+
endif
84+
85+
86+
# dev-test is a smoke test for development environment
87+
# consuming the libraries generated by this project.
88+
dev-test: $(LIBGIT2)
89+
cd tests/smoketest; go vet $(GO_STATIC_FLAGS) ./...
90+
cd tests/smoketest; go run $(GO_STATIC_FLAGS) main.go

hack/download-musl.sh

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/usr/bin/env bash
2+
3+
set -eoux pipefail
4+
5+
MUSL_X86_64_FILENAME=x86_64-linux-musl-native.tgz
6+
MUSL_X86_64_SHA512=44d441ad9aa11a06feddf3daa4c9f53ad7d9ca37af1f5a61379aca07793703d179410cea723c1b7fca94c4de19a321228bdb3656bc5cbdb5e3bea8e2d6dac6c7
7+
MUSL_AARCH64_FILENAME=aarch64-linux-musl-native.tgz
8+
MUSL_AARCH64_SHA512=16d544e09845c9dbba50f29e0cb04dd661e17eb63c56acad6a67fd2a78aa7596b792477c7177d3cd56d408a27dc291a90507df882f2b099c0f25511ce08fd3b5
9+
10+
MUSL_FILENAME="${MUSL_X86_64_FILENAME}"
11+
MUSL_SHA512="${MUSL_X86_64_SHA512}"
12+
if [ "$(uname -m)" = "arm64" ] || [ "$(uname -m)" = "aarch64" ]; then
13+
MUSL_FILENAME="${MUSL_AARCH64_FILENAME}"
14+
MUSL_SHA512="${MUSL_AARCH64_SHA512}"
15+
fi
16+
17+
MUSL_AARCH64_URL="https://more.musl.cc/11.2.1/x86_64-linux-musl/${MUSL_FILENAME}"
18+
19+
ROOT_DIR="$(git rev-parse --show-toplevel)"
20+
MUSL_DIR="${ROOT_DIR}/build/musl"
21+
22+
if [ ! -f "${MUSL_DIR}/bin" ]; then
23+
TARGET_FILE="${MUSL_DIR}/${MUSL_FILENAME}"
24+
mkdir -p "${MUSL_DIR}"
25+
26+
echo "${MUSL_SHA512} ${TARGET_FILE}"
27+
curl -o "${TARGET_FILE}" -LO "${MUSL_AARCH64_URL}"
28+
if ! echo "${MUSL_SHA512} ${TARGET_FILE}" | sha512sum --check; then
29+
echo "Checksum failed for ${MUSL_FILENAME}."
30+
rm -rf "${MUSL_DIR}"
31+
exit 1
32+
fi
33+
34+
tar xzf "${TARGET_FILE}" -C "${MUSL_DIR}"
35+
rm "${TARGET_FILE}"
36+
fi

0 commit comments

Comments
 (0)