|
1 | 1 | # golang-with-libgit2 |
2 | 2 |
|
3 | | -This repository contains a `Dockerfile` which `Makefile` content can be used to build the [libgit2][] dependency |
4 | | -chain for **AMD64, ARM64 and ARMv7** binaries of Go projects that depend on [git2go][]. |
| 3 | +This repository contains a `Dockerfile` with two files: `Makefile` and `static.sh`. |
| 4 | +Both of which can be used to build the [libgit2][] dependency chain for **AMD64, ARM64 and ARMv7** binaries |
| 5 | +of Go projects that depend on [git2go][]. |
| 6 | + |
| 7 | +The `Makefile` is useful for development environments and will leverage OS specific packages to build `libgit2`. |
| 8 | +The `static.sh` will build all `libgit2` dependencies from source using `musl` toolchain. This enables for a full |
| 9 | +static binary with the freedom of configuring each of the dependencies in chain. |
5 | 10 |
|
6 | 11 | ### :warning: **Public usage discouraged** |
7 | 12 |
|
@@ -42,86 +47,20 @@ while testing these against the git2go code before releasing the image. |
42 | 47 | - [ ] [libgit2/git2go#836](https://github.com/libgit2/git2go/issues/836) |
43 | 48 | - [ ] [libgit2/git2go#837](https://github.com/libgit2/git2go/issues/837) |
44 | 49 |
|
45 | | -## Usage |
46 | | - |
47 | | -To make use of the image published by the `Dockerfile`, copy over the `Makefile` from the image as a prerequisite to |
48 | | -your Go build. Once copied over to the image, the set of targets can be used to compile `libgit2` for the |
49 | | -`$BUILDPLATFORM` and/or `$TARGETPLATFORM` (see [example](#Dockerfile-example)). |
50 | | - |
51 | | -### Runtime dependencies |
52 | | - |
53 | | -The following dependencies should be present in the image running the application: |
54 | | - |
55 | | -- `libc6` |
56 | | -- `ca-certificates` |
57 | | -- `zlib1g/bookworm` |
58 | | -- `libssl1.1/bookworm` |
59 | | -- `libssh2-1/bookworm` |
60 | | - |
61 | | -**Note:** at present, all dependencies suffixed with `bookworm` must be installed from Debian's `bookworm` release, |
62 | | -[due to a misconfiguration in `libssh2-1` in earlier versions][libssh2-1-misconfiguration]. |
63 | | - |
64 | | -### `Dockerfile` example |
65 | | - |
66 | | -```Dockerfile |
67 | | -FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx |
68 | | -FROM fluxcd/golang-with-libgit2 as libgit2 |
69 | | - |
70 | | -FROM --platform=$BUILDPLATFORM golang:1.17.6-bullseye as build |
71 | | - |
72 | | -# Copy the build utiltiies |
73 | | -COPY --from=xx / / |
74 | | -COPY --from=libgit2 /Makefile /libgit2/ |
75 | | - |
76 | | -# Install the libgit2 build dependencies |
77 | | -RUN make -C /libgit2 cmake |
78 | | - |
79 | | -ARG TARGETPLATFORM |
80 | | -RUN make -C /libgit2 dependencies |
81 | | - |
82 | | -# Compile and install libgit2 |
83 | | -RUN FLAGS=$(xx-clang --print-cmake-defines) make -C /libgit2 libgit2 \ |
84 | | - && mkdir -p /libgit2/lib/ \ |
85 | | - && cp -d /usr/lib/$(xx-info triple)/libgit2.so* /libgit2/lib/ |
| 50 | +--- |
| 51 | +**NOTE** |
86 | 52 |
|
87 | | -# Configure workspace |
88 | | -WORKDIR /workspace |
| 53 | +The issues above do not affect libgit2 built with `static.sh` as all its |
| 54 | +dependencies have been configured to be optimal for its use, as the first supported version of libgit2 is `1.3.0`. |
89 | 55 |
|
90 | | -# Copy modules manifests |
91 | | -COPY go.mod go.mod |
92 | | -COPY go.sum go.sum |
| 56 | +--- |
93 | 57 |
|
94 | | -# Cache modules |
95 | | -RUN go mod download |
96 | | - |
97 | | -# Copy source code |
98 | | -COPY main.go main.go |
99 | | - |
100 | | -# Build the binary |
101 | | -ENV CGO_ENABLED=1 |
102 | | -ARG TARGETPLATFORM |
103 | | -RUN xx-go build -o app \ |
104 | | - main.go |
105 | | - |
106 | | -FROM debian:bookworm-slim as controller |
107 | | - |
108 | | -# Install runtime dependencies |
109 | | -RUN apt update \ |
110 | | - && apt install -y zlib1g/bookworm libssl1.1 libssh2-1 \ |
111 | | - && apt install -y ca-certificates \ |
112 | | - && apt clean \ |
113 | | - && apt autoremove --purge -y \ |
114 | | - && rm -rf /var/lib/apt/lists/* |
115 | | - |
116 | | -# Copy libgit2.so* |
117 | | -COPY --from=build /libgit2/lib/ /usr/local/lib/ |
118 | | -RUN ldconfig |
| 58 | +## Usage |
119 | 59 |
|
120 | | -# Copy over binary from build |
121 | | -COPY --from=build /workspace/app /usr/local/bin/ |
| 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. |
122 | 61 |
|
123 | | -ENTRYPOINT [ "app" ] |
124 | | -``` |
| 62 | +The example will statically build all dependencies based on the versions specified on `static.sh`. |
| 63 | +Then statically build the golang application and deploy it into an image based off `gcr.io/distroless/static`. |
125 | 64 |
|
126 | 65 | ## Contributing |
127 | 66 |
|
@@ -162,6 +101,34 @@ In case changes happen to the `Dockerfile` while the `libgit2` version does not |
162 | 101 | be suffixed with `-<seq num in range>`. For example, `libgit2-1.1.1-2` for the **third** container image |
163 | 102 | with the same version. |
164 | 103 |
|
| 104 | +### Debugging cross-compilation |
| 105 | + |
| 106 | +Below are a few tips on how to overcome cross-compilation issues: |
| 107 | + |
| 108 | +1) Ensure all qemu emulators are installed: |
| 109 | +```sh |
| 110 | +docker run -it --rm --privileged tonistiigi/binfmt --install all |
| 111 | +``` |
| 112 | + |
| 113 | +2) Check that the generated libraries are aligned with the target architecture: |
| 114 | + |
| 115 | +Leveraging `readelf` from `binutils` (i.e. `apk add binutils`), check the target machine |
| 116 | +architecture: |
| 117 | + |
| 118 | +```sh |
| 119 | +$ readelf -h /usr/local/aarch64-alpine-linux-musl/lib/libcrypto.a | grep Machine |sort -u |
| 120 | + Machine: AArch64 |
| 121 | +$ readelf -h /usr/local/aarch64-alpine-linux-musl/lib/libgit2.a | grep Machine | sort -u |
| 122 | + Machine: AArch64 |
| 123 | +$ readelf -h /usr/local/aarch64-alpine-linux-musl/lib/libssh2.a | grep Machine | sort -u |
| 124 | + Machine: AArch64 |
| 125 | +$ readelf -h /usr/local/aarch64-alpine-linux-musl/lib/libssl.a | grep Machine | sort -u |
| 126 | + Machine: AArch64 |
| 127 | +$ readelf -h /usr/local/aarch64-alpine-linux-musl/lib/libz.a | grep Machine | sort -u |
| 128 | + Machine: AArch64 |
| 129 | +``` |
| 130 | + |
| 131 | + |
165 | 132 | [xx]: https://github.com/tonistiigi/xx |
166 | 133 | [Go container image]: https://hub.docker.com/_/golang |
167 | 134 | [libgit2]: https://github.com/libgit2/libgit2 |
|
0 commit comments