- Restructure Dockerfile.alpine-musl for better layer caching * Build dependencies (secp256k1, libwebsockets) in separate cached layers * Copy submodules before source files to maximize cache hits * Reduce rebuild time from ~2-3 minutes to ~10-15 seconds for source changes - Remove 'musl' from binary names (c_relay_static_x86_64 instead of c_relay_static_musl_x86_64) - Enforce static binary usage in make_and_restart_relay.sh * Remove all fallbacks to regular make builds * Exit with clear error if static binary not found * Ensures JSON1 extension is always available - Fix build_static.sh hanging on ldd check with timeout - Remove sudo usage from build_static.sh (assumes docker group membership) These changes ensure consistent builds with JSON1 support and dramatically improve development iteration speed through intelligent Docker layer caching.
191 lines
5.4 KiB
Bash
Executable File
191 lines
5.4 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Build fully static MUSL binaries for C-Relay using Alpine Docker
|
|
# Produces truly portable binaries with zero runtime dependencies
|
|
|
|
set -e
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
BUILD_DIR="$SCRIPT_DIR/build"
|
|
DOCKERFILE="$SCRIPT_DIR/Dockerfile.alpine-musl"
|
|
|
|
echo "=========================================="
|
|
echo "C-Relay MUSL Static Binary Builder"
|
|
echo "=========================================="
|
|
echo "Project directory: $SCRIPT_DIR"
|
|
echo "Build directory: $BUILD_DIR"
|
|
echo ""
|
|
|
|
# Create build directory
|
|
mkdir -p "$BUILD_DIR"
|
|
|
|
# Check if Docker is available
|
|
if ! command -v docker &> /dev/null; then
|
|
echo "ERROR: Docker is not installed or not in PATH"
|
|
echo ""
|
|
echo "Docker is required to build MUSL static binaries."
|
|
echo "Please install Docker:"
|
|
echo " - Ubuntu/Debian: sudo apt install docker.io"
|
|
echo " - Or visit: https://docs.docker.com/engine/install/"
|
|
echo ""
|
|
exit 1
|
|
fi
|
|
|
|
# Check if Docker daemon is running
|
|
if ! docker info &> /dev/null; then
|
|
echo "ERROR: Docker daemon is not running or user not in docker group"
|
|
echo ""
|
|
echo "Please start Docker and ensure you're in the docker group:"
|
|
echo " - sudo systemctl start docker"
|
|
echo " - sudo usermod -aG docker $USER && newgrp docker"
|
|
echo " - Or start Docker Desktop"
|
|
echo ""
|
|
exit 1
|
|
fi
|
|
|
|
DOCKER_CMD="docker"
|
|
|
|
echo "✓ Docker is available and running"
|
|
echo ""
|
|
|
|
# Detect architecture
|
|
ARCH=$(uname -m)
|
|
case "$ARCH" in
|
|
x86_64)
|
|
PLATFORM="linux/amd64"
|
|
OUTPUT_NAME="c_relay_static_x86_64"
|
|
;;
|
|
aarch64|arm64)
|
|
PLATFORM="linux/arm64"
|
|
OUTPUT_NAME="c_relay_static_arm64"
|
|
;;
|
|
*)
|
|
echo "WARNING: Unknown architecture: $ARCH"
|
|
echo "Defaulting to linux/amd64"
|
|
PLATFORM="linux/amd64"
|
|
OUTPUT_NAME="c_relay_static_${ARCH}"
|
|
;;
|
|
esac
|
|
|
|
echo "Building for platform: $PLATFORM"
|
|
echo "Output binary: $OUTPUT_NAME"
|
|
echo ""
|
|
|
|
# Build the Docker image
|
|
echo "=========================================="
|
|
echo "Step 1: Building Alpine Docker image"
|
|
echo "=========================================="
|
|
echo "This will:"
|
|
echo " - Use Alpine Linux (native MUSL)"
|
|
echo " - Build all dependencies statically"
|
|
echo " - Compile c-relay with full static linking"
|
|
echo ""
|
|
|
|
$DOCKER_CMD build \
|
|
--platform "$PLATFORM" \
|
|
-f "$DOCKERFILE" \
|
|
-t c-relay-musl-builder:latest \
|
|
--progress=plain \
|
|
. || {
|
|
echo ""
|
|
echo "ERROR: Docker build failed"
|
|
echo "Check the output above for details"
|
|
exit 1
|
|
}
|
|
|
|
echo ""
|
|
echo "✓ Docker image built successfully"
|
|
echo ""
|
|
|
|
# Extract the binary from the container
|
|
echo "=========================================="
|
|
echo "Step 2: Extracting static binary"
|
|
echo "=========================================="
|
|
|
|
# Build the builder stage to extract the binary
|
|
$DOCKER_CMD build \
|
|
--platform "$PLATFORM" \
|
|
--target builder \
|
|
-f "$DOCKERFILE" \
|
|
-t c-relay-static-builder-stage:latest \
|
|
. > /dev/null 2>&1
|
|
|
|
# Create a temporary container to copy the binary
|
|
CONTAINER_ID=$($DOCKER_CMD create c-relay-static-builder-stage:latest)
|
|
|
|
# Copy binary from container
|
|
$DOCKER_CMD cp "$CONTAINER_ID:/build/c_relay_static" "$BUILD_DIR/$OUTPUT_NAME" || {
|
|
echo "ERROR: Failed to extract binary from container"
|
|
$DOCKER_CMD rm "$CONTAINER_ID" 2>/dev/null
|
|
exit 1
|
|
}
|
|
|
|
# Clean up container
|
|
$DOCKER_CMD rm "$CONTAINER_ID" > /dev/null
|
|
|
|
echo "✓ Binary extracted to: $BUILD_DIR/$OUTPUT_NAME"
|
|
echo ""
|
|
|
|
# Make binary executable
|
|
chmod +x "$BUILD_DIR/$OUTPUT_NAME"
|
|
|
|
# Verify the binary
|
|
echo "=========================================="
|
|
echo "Step 3: Verifying static binary"
|
|
echo "=========================================="
|
|
echo ""
|
|
|
|
echo "Checking for dynamic dependencies:"
|
|
if LDD_OUTPUT=$(timeout 5 ldd "$BUILD_DIR/$OUTPUT_NAME" 2>&1); then
|
|
if echo "$LDD_OUTPUT" | grep -q "not a dynamic executable"; then
|
|
echo "✓ Binary is fully static (no dynamic dependencies)"
|
|
TRULY_STATIC=true
|
|
elif echo "$LDD_OUTPUT" | grep -q "statically linked"; then
|
|
echo "✓ Binary is statically linked"
|
|
TRULY_STATIC=true
|
|
else
|
|
echo "⚠ WARNING: Binary may have dynamic dependencies:"
|
|
echo "$LDD_OUTPUT"
|
|
TRULY_STATIC=false
|
|
fi
|
|
else
|
|
# ldd failed or timed out - check with file command instead
|
|
if file "$BUILD_DIR/$OUTPUT_NAME" | grep -q "statically linked"; then
|
|
echo "✓ Binary is statically linked (verified with file command)"
|
|
TRULY_STATIC=true
|
|
else
|
|
echo "⚠ Could not verify static linking (ldd check failed)"
|
|
TRULY_STATIC=false
|
|
fi
|
|
fi
|
|
echo ""
|
|
|
|
echo "File size: $(ls -lh "$BUILD_DIR/$OUTPUT_NAME" | awk '{print $5}')"
|
|
echo ""
|
|
|
|
# Test if binary runs
|
|
echo "Testing binary execution:"
|
|
if "$BUILD_DIR/$OUTPUT_NAME" --version 2>&1 | head -5; then
|
|
echo "✓ Binary executes successfully"
|
|
else
|
|
echo "⚠ Binary execution test failed (this may be normal if --version is not supported)"
|
|
fi
|
|
echo ""
|
|
|
|
# Summary
|
|
echo "=========================================="
|
|
echo "Build Summary"
|
|
echo "=========================================="
|
|
echo "Binary: $BUILD_DIR/$OUTPUT_NAME"
|
|
echo "Size: $(du -h "$BUILD_DIR/$OUTPUT_NAME" | cut -f1)"
|
|
echo "Platform: $PLATFORM"
|
|
if [ "$TRULY_STATIC" = true ]; then
|
|
echo "Type: Fully static binary (Alpine MUSL-based)"
|
|
echo "Portability: Works on ANY Linux distribution"
|
|
else
|
|
echo "Type: Static binary (may have minimal dependencies)"
|
|
fi
|
|
echo ""
|
|
echo "✓ Build complete!"
|
|
echo ""
|