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

Commit 13b2ad0

Browse files
author
Paulo Gomes
committed
Release darwin universal static binaries
The changes on static.sh highlight the nuances of compiling for linux and mac, as well as cross compiling on the latter. Signed-off-by: Paulo Gomes <[email protected]>
1 parent 6dbaf6b commit 13b2ad0

File tree

3 files changed

+134
-26
lines changed

3 files changed

+134
-26
lines changed

.github/workflows/build.yaml

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,89 @@ on:
1111
pull_request:
1212
paths-ignore:
1313
- README.md
14+
15+
permissions:
16+
contents: write # needed to write releases
17+
packages: write # needed for ghcr access
18+
1419
jobs:
20+
21+
mac-build:
22+
# This job builds and releases "universal libraries" that are
23+
# supported by both darwin-amd64 and darwin-arm64.
24+
#
25+
# First builds in amd64, then cross-compile in arm64. Later combining
26+
# both outcomes onto a single binary for each static library.
27+
#
28+
# `macos-11` has been picked as support for arm64 was only added on Xcode 12.
29+
# Although some minor versions of Catalina 10.15 can support it, at the time
30+
# of testing, GitHub's macos-10.15 did not seem to.
31+
# Cross-compiling to arm64 on that runner consistently failed.
32+
runs-on: macos-11
33+
steps:
34+
- name: Checkout
35+
uses: actions/checkout@v2
36+
- name: Build universal static libraries for Darwin
37+
run: |
38+
TARGET_DIR=${GITHUB_WORKSPACE}/build/libgit2-darwin-amd64 \
39+
BUILD_ROOT_DIR=${GITHUB_WORKSPACE}/libgit2/build/amd \
40+
./hack/static.sh all
41+
42+
TARGET_DIR=${GITHUB_WORKSPACE}/build/libgit2-darwin-arm64 \
43+
BUILD_ROOT_DIR=${GITHUB_WORKSPACE}/libgit2/build/arm \
44+
TARGET_ARCH=arm64 \
45+
CMAKE_APPLE_SILICON_PROCESSOR=arm64 \
46+
./hack/static.sh all
47+
48+
mkdir -p ./libgit2-darwin/lib
49+
mv ${GITHUB_WORKSPACE}/build/libgit2-darwin-amd64/include ./libgit2-darwin/
50+
mv ${GITHUB_WORKSPACE}/build/libgit2-darwin-amd64/share ./libgit2-darwin/
51+
mv ${GITHUB_WORKSPACE}/build/libgit2-darwin-amd64/lib/cmake ./libgit2-darwin/lib/
52+
mv ${GITHUB_WORKSPACE}/build/libgit2-darwin-amd64/lib/engines-3 ./libgit2-darwin/lib/
53+
mv ${GITHUB_WORKSPACE}/build/libgit2-darwin-amd64/lib/ossl-modules ./libgit2-darwin/lib/
54+
mv ${GITHUB_WORKSPACE}/build/libgit2-darwin-amd64/lib/pkgconfig ./libgit2-darwin/lib/
55+
56+
libtool -static -o ./libgit2-darwin/lib/libcrypto.a \
57+
${GITHUB_WORKSPACE}/build/libgit2-darwin-amd64/lib/libcrypto.a \
58+
${GITHUB_WORKSPACE}/build/libgit2-darwin-arm64/lib/libcrypto.a
59+
libtool -static -o ./libgit2-darwin/lib/libgit2.a \
60+
${GITHUB_WORKSPACE}/build/libgit2-darwin-amd64/lib/libgit2.a \
61+
${GITHUB_WORKSPACE}/build/libgit2-darwin-arm64/lib/libgit2.a
62+
libtool -static -o ./libgit2-darwin/lib/libssh2.a \
63+
${GITHUB_WORKSPACE}/build/libgit2-darwin-amd64/lib/libssh2.a \
64+
${GITHUB_WORKSPACE}/build/libgit2-darwin-arm64/lib/libssh2.a
65+
libtool -static -o ./libgit2-darwin/lib/libssl.a \
66+
${GITHUB_WORKSPACE}/build/libgit2-darwin-amd64/lib/libssl.a \
67+
${GITHUB_WORKSPACE}/build/libgit2-darwin-arm64/lib/libssl.a
68+
libtool -static -o ./libgit2-darwin/lib/libz.a \
69+
${GITHUB_WORKSPACE}/build/libgit2-darwin-amd64/lib/libz.a \
70+
${GITHUB_WORKSPACE}/build/libgit2-darwin-arm64/lib/libz.a
71+
72+
tar -zcvf darwin-libs.tar.gz ./libgit2-darwin
73+
74+
- name: Create Release
75+
if: github.event_name != 'pull_request'
76+
id: create_release
77+
uses: actions/create-release@v1
78+
env:
79+
GITHUB_TOKEN: ${{ github.token }}
80+
with:
81+
release_name: ${{ github.ref }}
82+
tag_name: ${{ github.ref }}
83+
draft: false
84+
prerelease: true
85+
- name: Upload Release Asset
86+
if: github.event_name != 'pull_request'
87+
id: upload-release-asset
88+
uses: actions/upload-release-asset@v1
89+
env:
90+
GITHUB_TOKEN: ${{ github.token }}
91+
with:
92+
upload_url: ${{ steps.create_release.outputs.upload_url }}
93+
asset_path: ./darwin-libs.tar.gz
94+
asset_name: darwin-libs.tar.gz
95+
asset_content_type: application/gzip
96+
1597
build:
1698
runs-on: ubuntu-latest
1799
env:
@@ -55,7 +137,7 @@ jobs:
55137
key: ${{ runner.os }}-buildx-ghcache-${{ github.sha }}
56138
restore-keys: |
57139
${{ runner.os }}-buildx-ghcache-
58-
- run: cat ./hack/Makefile
140+
- run: cat ./hack/static.sh
59141
- name: Build candidate image
60142
id: build_candidate
61143
uses: docker/build-push-action@v2

README.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
# golang-with-libgit2
22

3-
This repository contains a `Dockerfile` with two files: `Makefile` and `static.sh`.
3+
This repository contains a `Dockerfile` with the statically built libgit2 and its dependency chain.
4+
5+
The `hack` directory contains two main files: `Makefile` and `static.sh`.
46
Both of which can be used to build the [libgit2][] dependency chain for **AMD64, ARM64 and ARMv7** binaries
57
of Go projects that depend on [git2go][].
68

79
The `Makefile` is useful for development environments and will leverage OS specific packages to build `libgit2`.
810
The `static.sh` will build all `libgit2` dependencies from source using `musl` toolchain. This enables for a full
911
static binary with the freedom of configuring each of the dependencies in chain.
1012

13+
Alternatively, the statically built libraries can be pulling from the produced images for Linux or from the github release artifacts for MacOS.
14+
1115
### :warning: **Public usage discouraged**
1216

1317
The set of dependencies was handpicked for the Flux project, based on the issue list documented below. While this setup
@@ -47,17 +51,14 @@ while testing these against the git2go code before releasing the image.
4751
- [ ] [libgit2/git2go#836](https://github.com/libgit2/git2go/issues/836)
4852
- [ ] [libgit2/git2go#837](https://github.com/libgit2/git2go/issues/837)
4953

50-
---
51-
**NOTE**
5254

53-
The issues above do not affect libgit2 built with `static.sh` as all its
55+
> **NOTE:** The issues above do not affect libgit2 built with `static.sh` as all its
5456
dependencies have been configured to be optimal for its use, as the first supported version of libgit2 is `1.3.0`.
5557

56-
---
5758

5859
## Usage
5960

60-
The [Dockerfile.test](./Dockerfile.test) file provides a working example on how to statically build a golang application that has a dependency to libgit2 and git2go.
61+
The [Dockerfile.test](./Dockerfile.test) file provides a working example on how to statically build a golang application that has a dependency on libgit2 and git2go.
6162

6263
The example will statically build all dependencies based on the versions specified on `static.sh`.
6364
Then statically build the golang application and deploy it into an image based off `gcr.io/distroless/static`.

hack/static.sh

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ TARGET_DIR="${TARGET_DIR:-/usr/local/$(xx-info triple)}"
1414
BUILD_ROOT_DIR="${BUILD_ROOT_DIR:-/build}"
1515
SRC_DIR="${BUILD_ROOT_DIR}/src"
1616

17-
TARGET_ARCH="$(uname -m)"
17+
TARGET_ARCH="${TARGET_ARCH:-$(uname -m)}"
1818
if command -v xx-info; then
1919
TARGET_ARCH="$(xx-info march)"
2020
fi
@@ -59,21 +59,34 @@ function build_openssl(){
5959
export OPENSSL_ROOT_DIR="${TARGET_DIR}"
6060
export OPENSSL_LIBRARIES="${TARGET_DIR}/lib"
6161

62+
export KERNEL_BITS=64
6263
target_arch=""
63-
if [ "${TARGET_ARCH}" = "armv7l" ]; then
64-
# openssl does not have a specific armv7l
65-
# using generic32 instead.
66-
target_arch="linux-generic32"
67-
elif [ "${TARGET_ARCH}" = "arm64" ] || [ "${TARGET_ARCH}" = "aarch64" ]; then
68-
target_arch="linux-aarch64"
69-
elif [ "${TARGET_ARCH}" = "x86_64" ]; then
70-
target_arch="linux-x86_64"
64+
if [[ ! $OSTYPE == darwin* ]]; then
65+
if [ "${TARGET_ARCH}" = "armv7l" ]; then
66+
# openssl does not have a specific armv7l
67+
# using generic32 instead.
68+
target_arch="linux-generic32"
69+
export KERNEL_BITS=32
70+
elif [ "${TARGET_ARCH}" = "arm64" ] || [ "${TARGET_ARCH}" = "aarch64" ]; then
71+
target_arch="linux-aarch64"
72+
elif [ "${TARGET_ARCH}" = "x86_64" ]; then
73+
target_arch="linux-x86_64"
74+
fi
7175
else
72-
echo "Architecture currently not supported: ${TARGET_ARCH}"
73-
exit 1
76+
SUFFIX=""
77+
if [ ! "${TARGET_ARCH}" = "$(uname -m)" ]; then
78+
SUFFIX="-cc"
79+
fi
80+
81+
if [ "${TARGET_ARCH}" = "arm64" ] || [ "${TARGET_ARCH}" = "aarch64" ]; then
82+
target_arch="darwin64-arm64${SUFFIX}"
83+
elif [ "${TARGET_ARCH}" = "x86_64" ]; then
84+
target_arch="darwin64-x86_64${SUFFIX}"
85+
fi
86+
# if none of the above, let openssl figure it out.
7487
fi
7588

76-
./Configure "${target_arch}" threads no-shared zlib -fPIC -DOPENSSL_PIC \
89+
./Configure "${target_arch}" threads no-shared no-stdio no-tests zlib -fPIC -DOPENSSL_PIC \
7790
--prefix="${TARGET_DIR}" \
7891
--with-zlib-include="${TARGET_DIR}/include" \
7992
--with-zlib-lib="${TARGET_DIR}/lib" \
@@ -94,20 +107,28 @@ function build_libssh2(){
94107
pushd build
95108

96109
OPENSSL_LIBRARIES="${TARGET_DIR}/lib"
97-
if [ "${TARGET_ARCH}" = "x86_64" ]; then
110+
if [ "${TARGET_ARCH}" = "x86_64" ] && [[ ! $OSTYPE == darwin* ]]; then
98111
OPENSSL_LIBRARIES="${TARGET_DIR}/lib64"
99112
fi
100113

114+
# Set osx arch only when cross compiling on darwin
115+
if [[ $OSTYPE == darwin* ]] && [ ! "${TARGET_ARCH}" = "$(uname -m)" ]; then
116+
CMAKE_PARAMS=-DCMAKE_OSX_ARCHITECTURES="${TARGET_ARCH}"
117+
fi
101118

119+
# Building examples allow for validating against missing symbols at compilation time.
102120
cmake "${CMAKE_PARAMS}" \
103121
-DCMAKE_C_COMPILER="${C_COMPILER}" \
104122
-DCMAKE_INSTALL_PREFIX="${TARGET_DIR}" \
105-
-DBUILD_SHARED_LIBS=OFF \
106-
-DLINT=OFF \
123+
-DBUILD_SHARED_LIBS:BOOL=OFF \
124+
-DLINT:BOOL=OFF \
125+
-DBUILD_EXAMPLES:BOOL=ON \
126+
-DBUILD_TESTING:BOOL=OFF \
107127
-DCMAKE_C_FLAGS=-fPIC \
108128
-DCRYPTO_BACKEND=OpenSSL \
109-
-DENABLE_ZLIB_COMPRESSION=ON \
129+
-DENABLE_ZLIB_COMPRESSION:BOOL=ON \
110130
-DCMAKE_BUILD_TYPE="RelWithDebInfo" \
131+
-DZLIB_LIBRARY="${TARGET_DIR}/lib/libz.a" \
111132
-DOPENSSL_CRYPTO_LIBRARY="${OPENSSL_LIBRARIES}/libcrypto.a" \
112133
-DOPENSSL_SSL_LIBRARY="${OPENSSL_LIBRARIES}/libssl.a" \
113134
..
@@ -129,17 +150,21 @@ function build_libgit2(){
129150

130151
SSL_LIBRARY="${TARGET_DIR}/lib/libssl.a"
131152
CRYPTO_LIBRARY="${TARGET_DIR}/lib/libcrypto.a"
132-
if [ "${TARGET_ARCH}" = "x86_64" ]; then
153+
if [[ ! $OSTYPE == darwin* ]] && [ "${TARGET_ARCH}" = "x86_64" ]; then
133154
SSL_LIBRARY="${TARGET_DIR}/lib64/libssl.a"
134155
CRYPTO_LIBRARY="${TARGET_DIR}/lib64/libcrypto.a"
135156
fi
136157

158+
# Set osx arch only when cross compiling on darwin
159+
if [[ $OSTYPE == darwin* ]] && [ ! "${TARGET_ARCH}" = "$(uname -m)" ]; then
160+
CMAKE_PARAMS=-DCMAKE_OSX_ARCHITECTURES="${TARGET_ARCH}"
161+
fi
162+
137163
cmake "${CMAKE_PARAMS}" \
138164
-DCMAKE_C_COMPILER="${C_COMPILER}" \
139165
-DCMAKE_INSTALL_PREFIX="${TARGET_DIR}" \
140166
-DTHREADSAFE:BOOL=ON \
141167
-DBUILD_CLAR:BOOL=OFF \
142-
-DBUILD_TESTS:BOOL=OFF \
143168
-DBUILD_SHARED_LIBS=OFF \
144169
-DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON \
145170
-DCMAKE_C_FLAGS=-fPIC \
@@ -151,9 +176,9 @@ function build_libgit2(){
151176
-DREGEX_BACKEND:STRING=builtin \
152177
-DOPENSSL_SSL_LIBRARY="${SSL_LIBRARY}" \
153178
-DOPENSSL_CRYPTO_LIBRARY="${CRYPTO_LIBRARY}" \
154-
-DZLIB_LIBRARY="${TARGET_DIR}/lib/libz.a" \
155179
-DCMAKE_INCLUDE_PATH="${TARGET_DIR}/include" \
156180
-DCMAKE_LIBRARY_PATH="${TARGET_DIR}/lib" \
181+
-DCMAKE_PREFIX_PATH="${TARGET_DIR}" \
157182
-DCMAKE_BUILD_TYPE="RelWithDebInfo" \
158183
..
159184

0 commit comments

Comments
 (0)