171 lines
6.2 KiB
Bash
Executable File
171 lines
6.2 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Build fully static MUSL binaries for C-Relay
|
|
# Produces portable binaries with zero runtime dependencies
|
|
|
|
set -e
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
BUILD_DIR="$SCRIPT_DIR/build"
|
|
|
|
echo "Building fully static MUSL binaries for C-Relay..."
|
|
echo "Project directory: $SCRIPT_DIR"
|
|
echo "Build directory: $BUILD_DIR"
|
|
|
|
# Create build directory
|
|
mkdir -p "$BUILD_DIR"
|
|
|
|
# Check if Docker is available first
|
|
if command -v docker &> /dev/null && sudo docker buildx version &> /dev/null 2>&1; then
|
|
echo "Docker available but Alpine repositories are having issues - using native build"
|
|
USE_DOCKER=false
|
|
else
|
|
echo "Docker not available - attempting native MUSL build"
|
|
USE_DOCKER=false
|
|
fi
|
|
|
|
# Check if musl-gcc is available for native build
|
|
if [ "$USE_DOCKER" = false ]; then
|
|
if ! command -v musl-gcc &> /dev/null; then
|
|
echo "Installing musl development tools..."
|
|
sudo apt update && sudo apt install -y musl-dev musl-tools
|
|
|
|
if ! command -v musl-gcc &> /dev/null; then
|
|
echo "ERROR: Failed to install musl-gcc"
|
|
echo "Please install musl-dev package manually: sudo apt install musl-dev musl-tools"
|
|
exit 1
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
if [ "$USE_DOCKER" = true ]; then
|
|
# Docker-based build
|
|
echo "Building x86_64 static binary with Docker..."
|
|
sudo docker buildx build \
|
|
--platform linux/amd64 \
|
|
-f "$SCRIPT_DIR/examples/deployment/static-builder.Dockerfile" \
|
|
-t c-relay-static-builder-x86_64 \
|
|
--load \
|
|
"$SCRIPT_DIR"
|
|
|
|
# Extract x86_64 binary
|
|
sudo docker run --rm -v "$BUILD_DIR:/output" c-relay-static-builder-x86_64 \
|
|
sh -c "cp /c_relay_static_musl_x86_64 /output/c_relay_static_x86_64"
|
|
|
|
echo "x86_64 static binary created: $BUILD_DIR/c_relay_static_x86_64"
|
|
|
|
# Build ARM64 static binary
|
|
echo "Building ARM64 static binary with Docker..."
|
|
sudo docker buildx build \
|
|
--platform linux/arm64 \
|
|
-f "$SCRIPT_DIR/examples/deployment/static-builder.Dockerfile" \
|
|
-t c-relay-static-builder-arm64 \
|
|
--load \
|
|
"$SCRIPT_DIR"
|
|
|
|
# Extract ARM64 binary
|
|
sudo docker run --rm -v "$BUILD_DIR:/output" c-relay-static-builder-arm64 \
|
|
sh -c "cp /c_relay_static_musl_arm64 /output/c_relay_static_arm64"
|
|
|
|
echo "ARM64 static binary created: $BUILD_DIR/c_relay_static_arm64"
|
|
else
|
|
# Native static build with regular gcc
|
|
echo "Building static binary with gcc..."
|
|
|
|
# Check for required static libraries
|
|
echo "Checking for static libraries..."
|
|
MISSING_LIBS=""
|
|
|
|
for lib in libsqlite3.a libssl.a libcrypto.a libz.a; do
|
|
if ! find /usr/lib* /usr/local/lib* -name "$lib" 2>/dev/null | head -1 | grep -q .; then
|
|
MISSING_LIBS="$MISSING_LIBS $lib"
|
|
fi
|
|
done
|
|
|
|
# libsecp256k1 might not be available as static lib, so we'll try without it first
|
|
|
|
# Initialize submodules if needed
|
|
if [ ! -f "nostr_core_lib/libnostr_core_x64.a" ]; then
|
|
echo "Building nostr_core_lib..."
|
|
git submodule update --init --recursive
|
|
cd nostr_core_lib && ./build.sh && cd ..
|
|
fi
|
|
|
|
# Install additional static libraries needed for libwebsockets
|
|
echo "Installing additional static libraries..."
|
|
sudo apt install -y libcap-dev libuv1-dev libev-dev
|
|
|
|
# Build SQLite with JSON1 extension if not available
|
|
echo "Building SQLite with JSON1 extension..."
|
|
SQLITE_BUILD_DIR="/tmp/sqlite-build-$$"
|
|
mkdir -p "$SQLITE_BUILD_DIR"
|
|
cd "$SQLITE_BUILD_DIR"
|
|
|
|
wget https://www.sqlite.org/2024/sqlite-autoconf-3460000.tar.gz
|
|
tar xzf sqlite-autoconf-3460000.tar.gz
|
|
cd sqlite-autoconf-3460000
|
|
|
|
./configure \
|
|
--enable-static \
|
|
--disable-shared \
|
|
--enable-json1 \
|
|
--enable-fts5 \
|
|
--prefix="$SQLITE_BUILD_DIR/install" \
|
|
CFLAGS="-DSQLITE_ENABLE_JSON1=1 -DSQLITE_ENABLE_FTS5=1"
|
|
|
|
make && make install
|
|
|
|
# Return to project directory
|
|
cd "$SCRIPT_DIR"
|
|
|
|
# Try building with regular gcc and static linking
|
|
echo "Compiling with gcc -static..."
|
|
|
|
# Use the same approach as the regular Makefile but with static linking
|
|
gcc -static -O2 -Wall -Wextra -std=c99 -g \
|
|
-I. -Inostr_core_lib -Inostr_core_lib/nostr_core -Inostr_core_lib/cjson -Inostr_core_lib/nostr_websocket \
|
|
-I"$SQLITE_BUILD_DIR/install/include" \
|
|
src/main.c src/config.c src/dm_admin.c src/request_validator.c src/nip009.c src/nip011.c src/nip013.c src/nip040.c src/nip042.c src/websockets.c src/subscriptions.c src/api.c src/embedded_web_content.c \
|
|
-o "$BUILD_DIR/c_relay_static_x86_64" \
|
|
nostr_core_lib/libnostr_core_x64.a \
|
|
"$SQLITE_BUILD_DIR/install/lib/libsqlite3.a" -lwebsockets -lz -ldl -lpthread -lm -L/usr/local/lib -lsecp256k1 -lssl -lcrypto -L/usr/local/lib -lcurl -lcap -luv_a -lev
|
|
|
|
# Clean up SQLite build directory
|
|
rm -rf "$SQLITE_BUILD_DIR"
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo "x86_64 static binary created: $BUILD_DIR/c_relay_static_x86_64"
|
|
else
|
|
echo "ERROR: Static build failed"
|
|
echo "This may be due to missing static libraries or incompatible library versions"
|
|
echo "Consider using Docker-based build instead"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# Verify binaries
|
|
echo "Verifying static binaries..."
|
|
for binary in "$BUILD_DIR"/c_relay_static_*; do
|
|
if [ -f "$binary" ]; then
|
|
echo "Binary: $(basename "$binary")"
|
|
file "$binary"
|
|
ls -lh "$binary"
|
|
|
|
# Test if binary is truly static (no dynamic dependencies)
|
|
if ldd "$binary" 2>/dev/null | grep -q "not a dynamic executable"; then
|
|
echo "✓ Binary is fully static"
|
|
elif ldd "$binary" 2>/dev/null | grep -q "statically linked"; then
|
|
echo "✓ Binary is statically linked"
|
|
else
|
|
echo "⚠ Binary may have dynamic dependencies:"
|
|
ldd "$binary" 2>/dev/null || echo " (ldd check failed)"
|
|
fi
|
|
echo ""
|
|
fi
|
|
done
|
|
|
|
echo "Static build complete!"
|
|
echo "Binaries available in: $BUILD_DIR/"
|
|
ls -la "$BUILD_DIR"/c_relay_static_* 2>/dev/null || echo "No static binaries found"
|
|
echo ""
|
|
echo "These binaries should have minimal runtime dependencies and work across Linux distributions." |