Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions Dockerfile.linux-static-libssh2
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
ARG BASE_IMAGE=debian:bookworm-slim
FROM ${BASE_IMAGE}

RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
cmake \
pkg-config \
ca-certificates \
curl \
git \
libssl-dev \
&& rm -rf /var/lib/apt/lists/*

# Build libssh2 from source as a PIC static archive. apt's libssh2.a is not
# compiled with -fPIC, which prevents linking into libgit2.so. Static linking
# lets us ship one libgit2-<sha>-<openssl-variant>.so per OpenSSL ABI without
# colliding libssh2.so.1 SONAMEs across variants.
ARG LIBSSH2_VERSION=1.11.1
RUN curl -fsSL https://github.com/libssh2/libssh2/releases/download/libssh2-${LIBSSH2_VERSION}/libssh2-${LIBSSH2_VERSION}.tar.gz -o libssh2.tar.gz \
&& tar xf libssh2.tar.gz \
&& cmake -S libssh2-${LIBSSH2_VERSION} -B libssh2-${LIBSSH2_VERSION}/build \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=OFF \
-DCMAKE_POSITION_INDEPENDENT_CODE=ON \
-DCRYPTO_BACKEND=OpenSSL \
-DBUILD_TESTING=OFF \
-DBUILD_EXAMPLES=OFF \
&& cmake --build libssh2-${LIBSSH2_VERSION}/build --target install \
&& rm -rf libssh2-${LIBSSH2_VERSION} libssh2.tar.gz

WORKDIR /nativebinaries
COPY . /nativebinaries/

CMD ["/bin/bash", "-c", "./build.libgit2.sh"]
20 changes: 14 additions & 6 deletions build.libgit2.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ OSXARCHITECTURE=$ARCH

EXTRA_CMAKE_FLAGS=""

# When OPENSSL_VARIANT is set, append it to the libgit2 filename so multiple
# variants can ship side by side and be selected at runtime
# This is only needed to support multiple versions of OpenSSL on Linux
LIBGIT2_FILENAME="git2-$SHORTSHA"
if [[ -n "$OPENSSL_VARIANT" ]]; then
LIBGIT2_FILENAME="$LIBGIT2_FILENAME-$OPENSSL_VARIANT"
fi

if [[ $OS == "Darwin" ]]; then
USEHTTPS="ON"
if [[ $RID == "osx-arm64" ]]; then
Expand All @@ -32,7 +40,7 @@ export _BINPATH=`pwd`
cmake -DCMAKE_BUILD_TYPE:STRING=Release \
-DBUILD_TESTS:BOOL=OFF \
-DUSE_SSH=ON \
-DLIBGIT2_FILENAME=git2-$SHORTSHA \
-DLIBGIT2_FILENAME=$LIBGIT2_FILENAME \
-DCMAKE_OSX_ARCHITECTURES=$OSXARCHITECTURE \
-DUSE_HTTPS=$USEHTTPS \
-DUSE_BUNDLED_ZLIB=ON \
Expand All @@ -56,10 +64,7 @@ fi
rm -rf $PACKAGEPATH/$RID
mkdir -p $PACKAGEPATH/$RID/native

cp libgit2/build/libgit2-$SHORTSHA.$LIBEXT $PACKAGEPATH/$RID/native

# Bundle libssh2 shared library alongside libgit2
LIBGIT2_PATH="$PACKAGEPATH/$RID/native/libgit2-$SHORTSHA.$LIBEXT"
cp libgit2/build/lib$LIBGIT2_FILENAME.$LIBEXT $PACKAGEPATH/$RID/native

if [[ $OS == "Darwin" ]]; then
# We don't run Octopus Server on Mac, so we can avoid the restriction of relying on the system crypto libraries
Expand Down Expand Up @@ -107,8 +112,11 @@ if [[ $OS == "Darwin" ]]; then
for DYLIB in "$NATIVE_DIR"/*.dylib; do
codesign --force --sign - "$DYLIB"
done
elif [[ -n "$OPENSSL_VARIANT" ]]; then
echo "$OPENSSL_VARIANT: libssh2 statically linked into libgit2"
else
# Linux: find libssh2 via ldd
# Linux: bundle the dynamic libssh2 alongside libgit2.
LIBGIT2_PATH="$PACKAGEPATH/$RID/native/lib$LIBGIT2_FILENAME.$LIBEXT"
LIBSSH2_PATH=$(ldd "$LIBGIT2_PATH" | grep libssh2 | awk '{print $3}')
if [[ -z "$LIBSSH2_PATH" ]]; then
echo "ERROR: libgit2 does not appear to link against libssh2"
Expand Down
46 changes: 37 additions & 9 deletions dockerbuild.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,44 @@ else
platform="linux/amd64"
fi

if [[ $RID == linux-musl* ]]; then
dockerfile="Dockerfile.linux-musl"
else
dockerfile="Dockerfile.linux"
fi
build_in_container() {
local tag="$1" dockerfile="$2" variant="$3" base_image="$4"

local build_args=()
if [[ -n "$base_image" ]]; then
build_args+=(--build-arg "BASE_IMAGE=$base_image")
fi

docker buildx build --platform "$platform" --load -t $RID -f $dockerfile .
docker buildx build --platform "$platform" --load -t "$tag" -f "$dockerfile" "${build_args[@]}" .
docker run --platform "$platform" -t -e RID=$RID -e OPENSSL_VARIANT="$variant" --name="$tag" "$tag"
}

docker run --platform "$platform" -t -e RID=$RID --name=$RID $RID
extract_runtimes() {
local tag="$1"
docker cp "$tag":/nativebinaries/nuget.package/runtimes/$RID/native/. nuget.package/runtimes/$RID/native/
docker rm "$tag"
}

docker cp $RID:/nativebinaries/nuget.package/runtimes nuget.package
# Reset the host-side runtime dir so we only ship artifacts produced by this
# invocation. Each extract_runtimes call merges its container's outputs in.
rm -rf nuget.package/runtimes/$RID
mkdir -p nuget.package/runtimes/$RID/native

docker rm $RID
if [[ $RID == linux-musl* ]]; then
build_in_container "$RID" "Dockerfile.linux-musl" "" ""
extract_runtimes "$RID"
elif [[ $RID == linux-ppc64le ]]; then
# debian:bullseye-slim has no ppc64le manifest, so we skip the openssl1.1
# variant on this arch and ship only the default OpenSSL 3 build.
build_in_container "$RID" "Dockerfile.linux" "" ""
extract_runtimes "$RID"
else
# All glibc-based Linux RIDs get two variants:
# 1. Default: built on bookworm against OpenSSL 3, libssh2 bundled as a separate .so
# 2. openssl1.1: built on bullseye against OpenSSL 1.1, libssh2 statically linked
build_in_container "$RID" "Dockerfile.linux" "" ""
extract_runtimes "$RID"

build_in_container "$RID-openssl1.1" "Dockerfile.linux-static-libssh2" "openssl1.1" "debian:bullseye-slim"
extract_runtimes "$RID-openssl1.1"
fi