152 lines
3.8 KiB
Bash
Executable File
152 lines
3.8 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Build fully static MUSL binary for nsigner using Alpine Docker
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
BUILD_DIR="$SCRIPT_DIR/build"
|
|
DOCKERFILE="$SCRIPT_DIR/Dockerfile.alpine-musl"
|
|
|
|
TARGET_ARCH=""
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--arch)
|
|
if [[ -z "${2:-}" ]]; then
|
|
echo "ERROR: --arch requires a value"
|
|
echo "Usage: $0 [--arch <x86_64|arm64|armv7>]"
|
|
exit 1
|
|
fi
|
|
case "$2" in
|
|
x86_64|arm64|armv7)
|
|
TARGET_ARCH="$2"
|
|
;;
|
|
*)
|
|
echo "ERROR: Unsupported architecture '$2'"
|
|
echo "Supported values: x86_64, arm64, armv7"
|
|
exit 1
|
|
;;
|
|
esac
|
|
shift 2
|
|
;;
|
|
*)
|
|
echo "ERROR: Unknown argument '$1'"
|
|
echo "Usage: $0 [--arch <x86_64|arm64|armv7>]"
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if ! command -v docker >/dev/null 2>&1; then
|
|
echo "ERROR: Docker is not installed or not in PATH"
|
|
exit 1
|
|
fi
|
|
|
|
if ! docker info >/dev/null 2>&1; then
|
|
echo "ERROR: Docker daemon is not running or user lacks permissions"
|
|
exit 1
|
|
fi
|
|
|
|
HOST_UNAME="$(uname -m)"
|
|
case "$HOST_UNAME" in
|
|
x86_64)
|
|
HOST_ARCH="x86_64"
|
|
;;
|
|
aarch64|arm64)
|
|
HOST_ARCH="arm64"
|
|
;;
|
|
armv7l|armv7)
|
|
HOST_ARCH="armv7"
|
|
;;
|
|
*)
|
|
HOST_ARCH="x86_64"
|
|
;;
|
|
esac
|
|
|
|
ARCH="${TARGET_ARCH:-$HOST_ARCH}"
|
|
|
|
case "$ARCH" in
|
|
x86_64)
|
|
PLATFORM="linux/amd64"
|
|
OUTPUT_NAME="nsigner_static_x86_64"
|
|
;;
|
|
arm64)
|
|
PLATFORM="linux/arm64"
|
|
OUTPUT_NAME="nsigner_static_arm64"
|
|
;;
|
|
armv7)
|
|
PLATFORM="linux/arm/v7"
|
|
OUTPUT_NAME="nsigner_static_armv7"
|
|
;;
|
|
*)
|
|
echo "ERROR: Unsupported target architecture '$ARCH'"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
mkdir -p "$BUILD_DIR"
|
|
|
|
IMAGE_TAG="nsigner-static-builder:${ARCH}"
|
|
CONTAINER_NAME=""
|
|
cleanup() {
|
|
if [[ -n "$CONTAINER_NAME" ]]; then
|
|
docker rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true
|
|
fi
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
echo "=========================================="
|
|
echo "nsigner static build"
|
|
echo "=========================================="
|
|
echo "Project root: $SCRIPT_DIR"
|
|
echo "Dockerfile: $DOCKERFILE"
|
|
echo "Platform: $PLATFORM"
|
|
echo "Output: $BUILD_DIR/$OUTPUT_NAME"
|
|
echo ""
|
|
|
|
if [ "$ARCH" != "$HOST_ARCH" ]; then
|
|
echo "[0/3] Preparing buildx + QEMU for cross-architecture build"
|
|
if ! docker buildx inspect >/dev/null 2>&1; then
|
|
echo "ERROR: docker buildx is not available"
|
|
exit 1
|
|
fi
|
|
docker run --privileged --rm tonistiigi/binfmt --install all >/dev/null
|
|
|
|
if ! docker buildx inspect nsigner-builder >/dev/null 2>&1; then
|
|
docker buildx create --name nsigner-builder --driver docker-container --use >/dev/null
|
|
else
|
|
docker buildx use nsigner-builder >/dev/null
|
|
fi
|
|
docker buildx inspect --bootstrap >/dev/null
|
|
fi
|
|
|
|
echo "[1/3] Building builder stage from project root context"
|
|
docker buildx build \
|
|
--platform "$PLATFORM" \
|
|
--target builder \
|
|
-f "$DOCKERFILE" \
|
|
-t "$IMAGE_TAG" \
|
|
--load \
|
|
"$SCRIPT_DIR"
|
|
|
|
echo "[2/3] Extracting static binary"
|
|
CONTAINER_NAME="$(docker create "$IMAGE_TAG")"
|
|
docker cp "$CONTAINER_NAME:/build/nsigner_static" "$BUILD_DIR/$OUTPUT_NAME"
|
|
chmod +x "$BUILD_DIR/$OUTPUT_NAME"
|
|
strip "$BUILD_DIR/$OUTPUT_NAME" >/dev/null 2>&1 || true
|
|
|
|
echo "[3/3] Verifying static binary"
|
|
file "$BUILD_DIR/$OUTPUT_NAME"
|
|
|
|
LDD_OUTPUT="$(ldd "$BUILD_DIR/$OUTPUT_NAME" 2>&1 || true)"
|
|
echo "$LDD_OUTPUT"
|
|
if echo "$LDD_OUTPUT" | grep -Eq "not a dynamic executable|statically linked"; then
|
|
echo "Static check: PASS"
|
|
else
|
|
echo "Static check: WARNING (verify manually)"
|
|
fi
|
|
|
|
echo ""
|
|
echo "Build complete: $BUILD_DIR/$OUTPUT_NAME"
|