Upgrade libgit2 and fix static builds

* Bump to golang-with-libgit2:1.1.1.6 to speed up build time when cross compiling. Previous version was compiling in emulation mode instead, which added +10x overhead.
* Ensure that make test is executed against the exact same libraries that will be shipped on the built image.
* Simplify Makefile to reduce its complexity.
* Libgit2 behaviour:
    linux-amd64 download static libraries from the official container image.
    linux-arm64 on top of the above, requires static musl tool chain (automatically downloaded).
    darwin-amd64 and darwin-arm64 download universal static libraries for darwin from https://github.com/fluxcd/golang-with-libgit2 releases.

Co-authored-by: Paulo Gomes <paulo.gomes@weave.works>
Signed-off-by: Sanskar Jaiswal <sanskar.jaiswal@weave.works>
This commit is contained in:
Sanskar Jaiswal 2022-02-08 20:11:55 +05:30
parent 7aa9f94037
commit a348d9f394
7 changed files with 372 additions and 72 deletions

View File

@ -30,3 +30,42 @@ jobs:
run: make test
- name: Verify
run: make verify
kind-linux-arm64:
# Hosted on Equinix
# Docs: https://github.com/fluxcd/flux2/tree/main/.github/runners
runs-on: [self-hosted, Linux, ARM64, equinix]
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: 1.17.x
- name: Run tests
run: make test
- name: Verify
run: make verify
# Runs 'make test' on macos-10.15 to assure development environment for
# contributors using MacOS.
darwin-amd64:
runs-on: macos-10.15
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: 1.17.x
- name: Restore Go cache
uses: actions/cache@v1
with:
path: /home/runner/work/_temp/_github_home/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Run tests
run: make test
- name: Verify
run: make verify

1
.gitignore vendored
View File

@ -30,5 +30,4 @@ testbin
*~
# Exclude all libgit2 related files
hack/libgit2/
build/

View File

@ -477,30 +477,35 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
----------------------------------------------------------------------
The regex library (deps/regex/) is licensed under the GNU LGPL
(available at the end of this file).
The bundled PCRE implementation (deps/pcre/) is licensed under the BSD
license.
Definitions for data structures and routines for the regular
expression library.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Copyright (C) 1985,1989-93,1995-98,2000,2001,2002,2003,2005,2006,2008
Free Software Foundation, Inc.
This file is part of the GNU C Library.
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
* Neither the name of the University of Cambridge nor the name of Google
Inc. nor the names of their contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------

View File

@ -3,57 +3,97 @@ ARG GO_VERSION=1.17
ARG XX_VERSION=1.1.0
ARG LIBGIT2_IMG=ghcr.io/fluxcd/golang-with-libgit2
ARG LIBGIT2_TAG=libgit2-1.1.1-4
ARG LIBGIT2_TAG=libgit2-1.1.1-6
FROM --platform=linux/amd64 ${LIBGIT2_IMG}:${LIBGIT2_TAG} as build-amd64
FROM --platform=linux/arm64 ${LIBGIT2_IMG}:${LIBGIT2_TAG} as build-arm64
FROM --platform=linux/arm/v7 ${LIBGIT2_IMG}:${LIBGIT2_TAG} as build-armv7
FROM ${LIBGIT2_IMG}:${LIBGIT2_TAG} AS libgit2-libs
FROM --platform=$BUILDPLATFORM build-$TARGETARCH$TARGETVARIANT AS build
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-${BASE_VARIANT} as gostable
FROM gostable AS go-linux
# Build-base consists of build platform dependencies and xx.
# These will be used at current arch to yield execute the cross compilations.
FROM go-${TARGETOS} AS build-base
RUN apk add --no-cache clang lld pkgconfig
COPY --from=xx / /
# build-go-mod can still be cached at build platform architecture.
FROM build-base as build-go-mod
# Configure workspace
WORKDIR /workspace
# This has its own go.mod, which needs to be present so go mod
# download works.
# Copy api submodule
COPY api/ api/
# Copy modules manifests
COPY go.mod go.mod
COPY go.sum go.sum
# cache deps before building and copying source so that we don't need to re-download as much
# and so that source changes don't invalidate our downloaded layer
# Cache modules
RUN go mod download
RUN apk add clang lld pkgconfig ca-certificates
# The musl-tool-chain layer is an adhoc solution
# for the problem in which xx gets confused during compilation
# and a) looks for gold linker and then b) cannot find musl's dynamic linker.
FROM --platform=$BUILDPLATFORM alpine as musl-tool-chain
COPY --from=xx / /
RUN apk add bash curl tar
WORKDIR /workspace
COPY hack/download-musl.sh .
ARG TARGETPLATFORM
ARG TARGETARCH
RUN ROOT_DIR="$(pwd)" TARGET_ARCH="$(xx-info alpine-arch)" ENV_FILE=true \
./download-musl.sh
# Build stage install per target platform
# dependency and effectively cross compile the application.
FROM build-go-mod as build
ENV CGO_ENABLED=1
ARG TARGETPLATFORM
RUN xx-apk add --no-cache \
musl-dev gcc lld binutils-gold
COPY --from=libgit2-libs /usr/local/ /usr/local/
# Some dependencies have to installed
# for the target platform: https://github.com/tonistiigi/xx#go--cgo
RUN xx-apk add musl-dev gcc lld
WORKDIR /workspace
# Copy source code
COPY main.go main.go
COPY controllers/ controllers/
COPY pkg/ pkg/
COPY --from=musl-tool-chain /workspace/build /workspace/build
ARG TARGETPLATFORM
ARG TARGETARCH
ENV CGO_ENABLED=1
# Performance related changes:
# - Use read-only bind instead of copying go source files.
# - Cache go packages.
RUN --mount=target=. \
--mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg \
export LIBRARY_PATH="/usr/local/$(xx-info triple)/lib:/usr/local/$(xx-info triple)/lib64:${LIBRARY_PATH}" && \
RUN export $(cat build/musl/$(xx-info alpine-arch).env | xargs) && \
export LIBRARY_PATH="/usr/local/$(xx-info triple):/usr/local/$(xx-info triple)/lib64" && \
export PKG_CONFIG_PATH="/usr/local/$(xx-info triple)/lib/pkgconfig:/usr/local/$(xx-info triple)/lib64/pkgconfig" && \
export FLAGS="$(pkg-config --static --libs --cflags libssh2 openssl libgit2)" && \
CGO_LDFLAGS="${FLAGS} -static" \
xx-go build \
export CGO_LDFLAGS="$(pkg-config --static --libs --cflags libssh2 openssl libgit2) -static" && \
GOARCH=$TARGETARCH go build \
-ldflags "-s -w" \
-tags 'netgo,osusergo,static_build' \
-o /image-automation-controller -trimpath \
main.go
-o /image-automation-controller -trimpath main.go;
# Ensure that the binary was cross-compiled correctly to the target platform.
RUN xx-verify --static /image-automation-controller
FROM alpine:3.15
ARG TARGETPLATFORM

107
Makefile
View File

@ -8,7 +8,7 @@ CRD_OPTIONS ?= crd:crdVersions=v1
# Base image used to build the Go binary
LIBGIT2_IMG ?= ghcr.io/fluxcd/golang-with-libgit2
LIBGIT2_TAG ?= libgit2-1.1.1-4
LIBGIT2_TAG ?= libgit2-1.1.1-6
# Allows for defining additional Docker buildx arguments,
# e.g. '--push'.
@ -29,31 +29,73 @@ REFLECTOR_VER ?= v0.16.0
# Repository root based on Git metadata.
REPOSITORY_ROOT := $(shell git rev-parse --show-toplevel)
BUILD_DIR := $(REPOSITORY_ROOT)/build
LIBGIT2_PATH := $(REPOSITORY_ROOT)/build/libgit2
# Other dependency versions
ENVTEST_BIN_VERSION ?= 1.19.2
# Caches libgit2 versions per tag, "forcing" rebuild only when needed.
LIBGIT2_PATH := $(BUILD_DIR)/libgit2/$(LIBGIT2_TAG)
LIBGIT2_LIB_PATH := $(LIBGIT2_PATH)/lib
LIBGIT2_LIB64_PATH := $(LIBGIT2_PATH)/lib64
LIBGIT2 := $(LIBGIT2_LIB_PATH)/libgit2.a
MUSL-CC =
export CGO_ENABLED=1
export LIBRARY_PATH=$(LIBGIT2_LIB_PATH):$(LIBGIT2_LIB64_PATH)
export PKG_CONFIG_PATH=$(LIBGIT2_LIB_PATH)/pkgconfig:$(LIBGIT2_LIB64_PATH)/pkgconfig
export CGO_CFLAGS=-I$(LIBGIT2_PATH)/include
export PKG_CONFIG_PATH=$(LIBGIT2_LIB_PATH)/pkgconfig
export LIBRARY_PATH=$(LIBGIT2_LIB_PATH)
export CGO_CFLAGS=-I$(LIBGIT2_PATH)/include -I$(LIBGIT2_PATH)/include/openssl
# The pkg-config command will yield warning messages until libgit2 is downloaded.
ifeq ($(shell uname -s),Darwin)
export CGO_LDFLAGS=$(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs --static --cflags libssh2 openssl libgit2 2>/dev/null)
GO_STATIC_FLAGS=-ldflags "-s -w" -tags 'netgo,osusergo,static_build'
else
export PKG_CONFIG_PATH:=$(PKG_CONFIG_PATH):$(LIBGIT2_LIB64_PATH)/pkgconfig
export LIBRARY_PATH:=$(LIBRARY_PATH):$(LIBGIT2_LIB64_PATH)
export CGO_LDFLAGS=$(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs --static --cflags libssh2 openssl libgit2 2>/dev/null)
endif
ifeq ($(shell uname -s),Linux)
ifeq ($(shell uname -m),x86_64)
# Linux x86_64 seem to be able to cope with the static libraries
# by having only musl-dev installed, without the need of using musl toolchain.
GO_STATIC_FLAGS=-ldflags "-s -w" -tags 'netgo,osusergo,static_build'
else
MUSL-PREFIX=$(BUILD_DIR)/musl/$(shell uname -m)-linux-musl-native/bin/$(shell uname -m)-linux-musl
MUSL-CC=$(MUSL-PREFIX)-gcc
export CC=$(MUSL-PREFIX)-gcc
export CXX=$(MUSL-PREFIX)-g++
export AR=$(MUSL-PREFIX)-ar
GO_STATIC_FLAGS=-ldflags "-s -w -extldflags \"-static\"" -tags 'netgo,osusergo,static_build'
endif
endif
# API (doc) generation utilities
CONTROLLER_GEN_VERSION ?= v0.7.0
GEN_API_REF_DOCS_VERSION ?= v0.3.0
# If gobin not set, create one on ./build and add to path.
ifeq (,$(shell go env GOBIN))
export GOBIN=$(BUILD_DIR)/gobin
else
export GOBIN=$(shell go env GOBIN)
endif
export PATH:=${GOBIN}:${PATH}
# Architecture to use envtest with
ifeq ($(shell uname -m),x86_64)
ENVTEST_ARCH ?= amd64
else
ENVTEST_ARCH ?= arm64
endif
ifeq ($(shell uname -s),Darwin)
export CGO_LDFLAGS=-L$(LIBGIT2_LIB_PATH) -lssh2 -lssl -lcrypto -lgit2
else
export CGO_LDFLAGS=$(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs --static --cflags libssh2 openssl libgit2)
# Envtest only supports darwin-amd64
ENVTEST_ARCH=amd64
endif
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN))
GOBIN=$(shell go env GOPATH)/bin
else
GOBIN=$(shell go env GOBIN)
endif
TEST_CRDS := controllers/testdata/crds
# Log level for `make run`
@ -88,13 +130,15 @@ ${CACHE}/imagepolicies_${REFLECTOR_VER}.yaml:
curl -s --fail https://raw.githubusercontent.com/fluxcd/image-reflector-controller/${REFLECTOR_VER}/config/crd/bases/image.toolkit.fluxcd.io_imagepolicies.yaml \
-o ${CACHE}/imagepolicies_${REFLECTOR_VER}.yaml
check-deps:
ifeq ($(shell uname -s),Darwin)
if ! command -v pkg-config &> /dev/null; then echo "pkg-config is required"; exit 1; fi
endif
KUBEBUILDER_ASSETS?="$(shell $(ENVTEST) --arch=$(ENVTEST_ARCH) use -i $(ENVTEST_KUBERNETES_VERSION) --bin-dir=$(ENVTEST_ASSETS_DIR) -p path)"
test: $(LIBGIT2) test-api test_deps generate fmt vet manifests api-docs install-envtest ## Run tests
KUBEBUILDER_ASSETS=$(KUBEBUILDER_ASSETS) \
go test ./... \
-ldflags "-s -w" \
-coverprofile cover.out \
-tags 'netgo,osusergo,static_build'
go test $(GO_STATIC_FLAGS) ./... -coverprofile cover.out
test-api: ## Run api tests
cd api; go test ./... -coverprofile cover.out
@ -104,7 +148,7 @@ manager: $(LIBGIT2) generate fmt vet ## Build manager binary
run: $(LIBGIT2) generate fmt vet manifests # Run against the configured Kubernetes cluster in ~/.kube/config
go run ./main.go --log-level=${LOG_LEVEL} --log-encoding=console
go run $(GO_STATIC_FLAGS) ./main.go --log-level=${LOG_LEVEL} --log-encoding=console
install: manifests ## Install CRDs into a cluster
kustomize build config/crd | kubectl apply -f -
@ -159,35 +203,40 @@ docker-deploy: ## Set the Docker image in-cluster
kubectl -n flux-system set image deployment/image-automation-controller manager=$(IMG):$(TAG)
# Find or download controller-gen
CONTROLLER_GEN = $(shell pwd)/bin/controller-gen
CONTROLLER_GEN = $(GOBIN)/controller-gen
.PHONY: controller-gen
controller-gen: ## Download controller-gen locally if necessary.
$(call go-install-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@v0.7.0)
libgit2: $(LIBGIT2) ## Detect or download libgit2 library
$(LIBGIT2):
IMG_TAG=$(LIBGIT2_IMG):$(LIBGIT2_TAG) ./hack/extract-libraries.sh
$(LIBGIT2): $(MUSL-CC)
IMG=$(LIBGIT2_IMG) TAG=$(LIBGIT2_TAG) ./hack/install-libraries.sh
$(MUSL-CC):
ifneq ($(shell uname -s),Darwin)
./hack/download-musl.sh
endif
# Find or download gen-crd-api-reference-docs
GEN_CRD_API_REFERENCE_DOCS = $(shell pwd)/bin/gen-crd-api-reference-docs
GEN_CRD_API_REFERENCE_DOCS = $(GOBIN)/gen-crd-api-reference-docs
.PHONY: gen-crd-api-reference-docs
gen-crd-api-reference-docs:
$(call go-install-tool,$(GEN_CRD_API_REFERENCE_DOCS),github.com/ahmetb/gen-crd-api-reference-docs@v0.3.0)
ENVTEST_ASSETS_DIR=$(shell pwd)/testbin
ENVTEST_ASSETS_DIR=$(BUILD_DIR)/testbin
ENVTEST_KUBERNETES_VERSION?=latest
install-envtest: setup-envtest
mkdir -p ${ENVTEST_ASSETS_DIR}
$(ENVTEST) use $(ENVTEST_KUBERNETES_VERSION) --arch=$(ENVTEST_ARCH) --bin-dir=$(ENVTEST_ASSETS_DIR)
chmod -R u+w $(BUILD_DIR)/testbin
ENVTEST = $(shell pwd)/bin/setup-envtest
ENVTEST = $(GOBIN)/setup-envtest
.PHONY: envtest
setup-envtest: ## Download envtest-setup locally if necessary.
$(call go-install-tool,$(ENVTEST),sigs.k8s.io/controller-runtime/tools/setup-envtest@latest)
# go-install-tool will 'go install' any package $2 and install it to $1.
PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))
define go-install-tool
@[ -f $(1) ] || { \
set -e ;\
@ -195,7 +244,7 @@ TMP_DIR=$$(mktemp -d) ;\
cd $$TMP_DIR ;\
go mod init tmp ;\
echo "Downloading $(2)" ;\
GOBIN=$(PROJECT_DIR)/bin go install $(2) ;\
env -i bash -c "GOBIN=$(GOBIN) PATH=$(PATH) GOPATH=$(shell go env GOPATH) GOCACHE=$(shell go env GOCACHE) go install $(2)" ;\
rm -rf $$TMP_DIR ;\
}
endef

71
hack/download-musl.sh Executable file
View File

@ -0,0 +1,71 @@
#!/usr/bin/env bash
set -eoux pipefail
MUSL_X86_64_FILENAME=x86_64-linux-musl-native.tgz
MUSL_X86_64_SHA512=44d441ad9aa11a06feddf3daa4c9f53ad7d9ca37af1f5a61379aca07793703d179410cea723c1b7fca94c4de19a321228bdb3656bc5cbdb5e3bea8e2d6dac6c7
MUSL_AARCH64_FILENAME=aarch64-linux-musl-native.tgz
MUSL_AARCH64_SHA512=16d544e09845c9dbba50f29e0cb04dd661e17eb63c56acad6a67fd2a78aa7596b792477c7177d3cd56d408a27dc291a90507df882f2b099c0f25511ce08fd3b5
MUSL_XX86_64_FILENAME=x86_64-linux-musl-cross.tgz
MUSL_XX86_64_SHA512=52abd1a56e670952116e35d1a62e048a9b6160471d988e16fa0e1611923dd108a581d2e00874af5eb04e4968b1ba32e0eb449a1f15c3e4d5240ebe09caf5a9f3
MUSL_XAARCH64_FILENAME=aarch64-linux-musl-cross.tgz
MUSL_XAARCH64_SHA512=8695ff86979cdf30fbbcd33061711f5b1ebc3c48a87822b9ca56cde6d3a22abd4dab30fdcd1789ac27c6febbaeb9e5bde59d79d66552fae53d54cc1377a19272
MUSL_XARMV7_FILENAME=armv7l-linux-musleabihf-cross.tgz
MUSL_XARMV7_SHA512=1bb399a61da425faac521df9b8d303e60ad101f6c7827469e0b4bc685ce1f3dedc606ac7b1e8e34d79f762a3bfe3e8ab479a97e97d9f36fbd9fc5dc9d7ed6fd1
TARGET_ARCH="${TARGET_ARCH:-$(uname -m)}"
ENV_FILE="${ENV_FILE:-false}"
MUSL_FILENAME=""
MUSL_SHA512=""
ROOT_DIR="${ROOT_DIR:-$(git rev-parse --show-toplevel)}"
MUSL_DIR="${ROOT_DIR}/build/musl"
if [ "${TARGET_ARCH}" = "$(uname -m)" ]; then
MUSL_FILENAME="${MUSL_X86_64_FILENAME}"
MUSL_SHA512="${MUSL_X86_64_SHA512}"
MUSL_PREFIX="${TARGET_ARCH}-linux-musl-native/bin/${TARGET_ARCH}-linux-musl"
if [ "${TARGET_ARCH}" = "arm64" ] || [ "${TARGET_ARCH}" = "aarch64" ]; then
MUSL_FILENAME="${MUSL_AARCH64_FILENAME}"
MUSL_SHA512="${MUSL_AARCH64_SHA512}"
fi
else
MUSL_FILENAME="${MUSL_XX86_64_FILENAME}"
MUSL_SHA512="${MUSL_XX86_64_SHA512}"
MUSL_PREFIX="${TARGET_ARCH}-linux-musl-cross/bin/${TARGET_ARCH}-linux-musl"
if [ "${TARGET_ARCH}" = "arm64" ] || [ "${TARGET_ARCH}" = "aarch64" ]; then
MUSL_FILENAME="${MUSL_XAARCH64_FILENAME}"
MUSL_SHA512="${MUSL_XAARCH64_SHA512}"
elif [ "${TARGET_ARCH}" = "arm" ] || [ "${TARGET_ARCH}" = "armv7" ]; then
MUSL_FILENAME="${MUSL_XARMV7_FILENAME}"
MUSL_SHA512="${MUSL_XARMV7_SHA512}"
MUSL_PREFIX=armv7l-linux-musleabihf-cross/bin/armv7l-linux-musleabihf
fi
fi
mkdir -p "${MUSL_DIR}"
if "${ENV_FILE}"; then
cat<<EOF > "${MUSL_DIR}/${TARGET_ARCH}.env"
CC="$(pwd)/build/musl/${MUSL_PREFIX}-gcc"
CXX="$(pwd)/build/musl/${MUSL_PREFIX}-g++"
AR="$(pwd)/build/musl/${MUSL_PREFIX}-ar"
EOF
fi
MUSL_AARCH64_URL="https://more.musl.cc/11.2.1/x86_64-linux-musl/${MUSL_FILENAME}"
if [ ! -f "${MUSL_DIR}/bin" ]; then
TARGET_FILE="${MUSL_DIR}/${MUSL_FILENAME}"
curl -o "${TARGET_FILE}" -LO "${MUSL_AARCH64_URL}"
if ! echo "${MUSL_SHA512} ${TARGET_FILE}" | sha512sum; then
echo "Checksum failed for ${MUSL_FILENAME}."
rm -rf "${MUSL_DIR}"
exit 1
fi
tar xzf "${TARGET_FILE}" -C "${MUSL_DIR}"
rm "${TARGET_FILE}"
fi

97
hack/install-libraries.sh Executable file
View File

@ -0,0 +1,97 @@
#!/usr/bin/env bash
set -euxo pipefail
IMG="${IMG:-}"
TAG="${TAG:-}"
IMG_TAG="${IMG}:${TAG}"
function extract(){
PLATFORM=$1
DIR=$2
id=$(docker create --platform="${PLATFORM}" "${IMG_TAG}" sh)
docker cp "${id}":/usr/local - > output.tar.gz
docker rm -v "${id}"
tar -xf output.tar.gz "local/${DIR}"
rm output.tar.gz
}
function setup() {
PLATFORM=$1
DIR=$2
extract "${PLATFORM}" "${DIR}"
NEW_DIR="$(/bin/pwd)/build/libgit2/${TAG}"
INSTALLED_DIR="/usr/local/${DIR}"
mv "local/${DIR}" "${TAG}"
rm -rf "local"
mv "${TAG}/" "./build/libgit2"
# Update the prefix paths included in the .pc files.
# This will make it easier to update to the location in which they will be used.
find "${NEW_DIR}" -type f -name "*.pc" | xargs -I {} sed -i "s;${INSTALLED_DIR};${NEW_DIR};g" {}
}
function setup_current() {
if [ -d "./build/libgit2/${TAG}" ]; then
echo "Skipping libgit2 setup as it already exists"
exit 0
fi
mkdir -p "./build/libgit2"
if [[ $OSTYPE == 'darwin'* ]]; then
# For MacOS development environments, download the amd64 static libraries released from from golang-with-libgit2.
curl -o output.tar.gz -LO "https://github.com/fluxcd/golang-with-libgit2/releases/download/${TAG}/darwin-libs.tar.gz"
DIR=libgit2-darwin
NEW_DIR="$(/bin/pwd)/build/libgit2/${TAG}"
INSTALLED_DIR="/Users/runner/work/golang-with-libgit2/golang-with-libgit2/build/${DIR}-amd64"
tar -xf output.tar.gz
rm output.tar.gz
mv "${DIR}" "${TAG}"
mv "${TAG}/" "./build/libgit2"
LIBGIT2_SED="s;-L/Applications/Xcode_.* ;;g"
LIBGIT2PC="$(/bin/pwd)/build/libgit2/${TAG}/lib/pkgconfig/libgit2.pc"
# Some macOS users may override their sed with gsed. If gsed is the PATH, use that instead.
if command -v gsed &> /dev/null; then
# Removes abs path from build machine, and let iconv be resolved automatically by default search paths.
gsed -i "${LIBGIT2_SED}" "${LIBGIT2PC}"
# Update the prefix paths included in the .pc files.
# This will make it easier to update to the location in which they will be used.
# sed has a sight different behaviour in MacOS
find "${NEW_DIR}" -type f -name "*.pc" | xargs -I {} gsed -i "s;${INSTALLED_DIR};${NEW_DIR};g" {}
else
# Removes abs path from build machine, and let iconv be resolved automatically by default search paths.
sed -i "" "${LIBGIT2_SED}" "${LIBGIT2PC}"
# Update the prefix paths included in the .pc files.
# This will make it easier to update to the location in which they will be used.
# sed has a sight different behaviour in MacOS
find "${NEW_DIR}" -type f -name "*.pc" | xargs -I {} sed -i "" "s;${INSTALLED_DIR};${NEW_DIR};g" {}
fi
else
# for linux development environments, use the static libraries from the official container images.
DIR="x86_64-alpine-linux-musl"
PLATFORM="linux/amd64"
if [[ "$(uname -m)" == armv7* ]]; then
DIR="armv7-alpine-linux-musleabihf"
PLATFORM="linux/arm/v7"
elif [ "$(uname -m)" = "arm64" ] || [ "$(uname -m)" = "aarch64" ]; then
DIR="aarch64-alpine-linux-musl"
PLATFORM="linux/arm64"
fi
setup "${PLATFORM}" "${DIR}"
fi
}
setup_current