171 lines
4.3 KiB
Bash
Executable File
171 lines
4.3 KiB
Bash
Executable File
#!/bin/bash
|
|
set -e
|
|
|
|
# nt MUSL static build script
|
|
# Produces build/nt_static_x86_64 or build/nt_static_arm64
|
|
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m'
|
|
|
|
print_status() { echo -e "${BLUE}[INFO]${NC} $1" >&2; }
|
|
print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" >&2; }
|
|
print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" >&2; }
|
|
print_error() { echo -e "${RED}[ERROR]${NC} $1" >&2; }
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
BUILD_DIR="$SCRIPT_DIR/build"
|
|
DOCKERFILE="$SCRIPT_DIR/Dockerfile.alpine-musl"
|
|
TARGET_ARCH=""
|
|
|
|
show_usage() {
|
|
echo "nt static builder"
|
|
echo ""
|
|
echo "USAGE:"
|
|
echo " $0 [--arch <x86_64|arm64>]"
|
|
echo ""
|
|
echo "OPTIONS:"
|
|
echo " --arch <arch> Target architecture: x86_64 or arm64"
|
|
echo " -h, --help Show this help"
|
|
}
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--arch)
|
|
if [[ -z "$2" ]]; then
|
|
print_error "--arch requires a value: x86_64 or arm64"
|
|
exit 1
|
|
fi
|
|
case "$2" in
|
|
x86_64|arm64)
|
|
TARGET_ARCH="$2"
|
|
;;
|
|
*)
|
|
print_error "Unsupported architecture '$2'"
|
|
print_error "Supported values: x86_64, arm64"
|
|
exit 1
|
|
;;
|
|
esac
|
|
shift 2
|
|
;;
|
|
-h|--help)
|
|
show_usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
print_error "Unknown argument '$1'"
|
|
show_usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if ! command -v docker >/dev/null 2>&1; then
|
|
print_error "docker is required"
|
|
exit 1
|
|
fi
|
|
|
|
if ! docker info >/dev/null 2>&1; then
|
|
print_error "docker daemon is not running"
|
|
exit 1
|
|
fi
|
|
|
|
HOST_UNAME="$(uname -m)"
|
|
case "$HOST_UNAME" in
|
|
x86_64)
|
|
HOST_ARCH="x86_64"
|
|
;;
|
|
aarch64|arm64)
|
|
HOST_ARCH="arm64"
|
|
;;
|
|
*)
|
|
HOST_ARCH="unknown"
|
|
;;
|
|
esac
|
|
|
|
if [[ -z "$TARGET_ARCH" ]]; then
|
|
if [[ "$HOST_ARCH" == "unknown" ]]; then
|
|
TARGET_ARCH="x86_64"
|
|
print_warning "Unknown host architecture '$HOST_UNAME'; defaulting target arch to x86_64"
|
|
else
|
|
TARGET_ARCH="$HOST_ARCH"
|
|
fi
|
|
fi
|
|
|
|
case "$TARGET_ARCH" in
|
|
x86_64)
|
|
PLATFORM="linux/amd64"
|
|
OUTPUT_NAME="nt_static_x86_64"
|
|
;;
|
|
arm64)
|
|
PLATFORM="linux/arm64"
|
|
OUTPUT_NAME="nt_static_arm64"
|
|
;;
|
|
*)
|
|
print_error "Unsupported target architecture '$TARGET_ARCH'"
|
|
print_error "Supported values: x86_64, arm64"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
if [[ "$HOST_ARCH" != "unknown" && "$HOST_ARCH" != "$TARGET_ARCH" ]]; then
|
|
print_status "Cross-building from host '$HOST_ARCH' to target '$TARGET_ARCH'"
|
|
if ! docker buildx version >/dev/null 2>&1; then
|
|
print_error "docker buildx is required for cross-architecture builds"
|
|
print_error "Install/enable buildx + binfmt and retry."
|
|
echo "docker run --privileged --rm tonistiigi/binfmt --install arm64" >&2
|
|
exit 1
|
|
fi
|
|
print_success "docker buildx is available"
|
|
|
|
if ! docker run --rm --platform "$PLATFORM" alpine:3.19 /bin/true >/dev/null 2>&1; then
|
|
print_error "Cross-architecture execution is not available (binfmt/QEMU not configured)"
|
|
print_error "Enable binfmt support and retry:"
|
|
echo "docker run --privileged --rm tonistiigi/binfmt --install arm64" >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
mkdir -p "$BUILD_DIR"
|
|
|
|
print_status "Building MUSL static binary for $TARGET_ARCH ($PLATFORM)..."
|
|
(
|
|
cd "$SCRIPT_DIR"
|
|
docker build \
|
|
--platform "$PLATFORM" \
|
|
-f Dockerfile.alpine-musl \
|
|
-t nt-musl-output:latest \
|
|
.
|
|
)
|
|
|
|
print_status "Extracting /nt_static from image..."
|
|
CONTAINER_ID=$(docker create nt-musl-output:latest /nt_static)
|
|
if ! docker cp "$CONTAINER_ID:/nt_static" "$BUILD_DIR/$OUTPUT_NAME"; then
|
|
print_error "Could not copy /nt_static from output image"
|
|
docker rm "$CONTAINER_ID" >/dev/null || true
|
|
exit 1
|
|
fi
|
|
docker rm "$CONTAINER_ID" >/dev/null || true
|
|
chmod +x "$BUILD_DIR/$OUTPUT_NAME"
|
|
|
|
print_status "Verifying binary with ldd/file"
|
|
LDD_OK=false
|
|
LDD_OUTPUT=$(ldd "$BUILD_DIR/$OUTPUT_NAME" 2>&1 || true)
|
|
echo "$LDD_OUTPUT" >&2
|
|
if echo "$LDD_OUTPUT" | grep -q "not a dynamic executable\|statically linked"; then
|
|
LDD_OK=true
|
|
fi
|
|
|
|
FILE_OUTPUT=$(file "$BUILD_DIR/$OUTPUT_NAME" 2>&1 || true)
|
|
echo "$FILE_OUTPUT" >&2
|
|
|
|
if [[ "$LDD_OK" == true ]] || echo "$FILE_OUTPUT" | grep -q "statically linked"; then
|
|
print_success "Binary verified as static: $BUILD_DIR/$OUTPUT_NAME"
|
|
else
|
|
print_warning "Could not conclusively verify static linking"
|
|
fi
|
|
|
|
print_success "Done: $BUILD_DIR/$OUTPUT_NAME"
|