Skip to content
Merged
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
5 changes: 5 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,12 @@ jobs:
echo "CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
echo "CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++" >> $GITHUB_ENV

- name: Build static Linux binary
if: contains(matrix.target, 'linux')
run: ./scripts/build-static.sh --ci ${{ matrix.target }}

- name: Build binary
if: "!contains(matrix.target, 'linux')"
run: cargo build --release --target ${{ matrix.target }}

- name: Create tarball
Expand Down
14 changes: 14 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,18 @@ fn main() {
"cargo:rustc-env=VERSION_WITH_GIT_HASH={} ({})",
version, git_hash
);

// Configure static linking for Linux gnu targets
// Note: We use gnu (glibc) instead of musl because V8 doesn't provide prebuilt musl binaries
// and building V8 from source for musl fails. Static glibc linking provides good portability
// while still allowing us to use V8 prebuilt binaries.
let target = env::var("TARGET").unwrap_or_default();
if target.contains("linux") && target.contains("gnu") {
// Enable static linking of the C runtime and standard library
// This links glibc statically, adding ~2-5MB to binary size but improving portability
println!("cargo:rustc-link-arg=-static-libgcc");

// Note: Full static linking (-static) would break NSS/DNS, so we use crt-static instead
// which is applied via RUSTFLAGS in the build process
}
}
117 changes: 117 additions & 0 deletions scripts/build-static.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#!/bin/bash
# Build and verify static glibc binaries for Linux
# This uses the gnu target with crt-static for better portability while avoiding musl/V8 issues
#
# Usage: ./build-static.sh [--ci|--non-interactive] [TARGET]
# TARGET: Optional rust target (e.g., x86_64-unknown-linux-gnu)
# If not provided, detects from uname -m

set -e

# Parse arguments
NON_INTERACTIVE=false
TARGET=""

for arg in "$@"; do
if [[ "$arg" == "--non-interactive" ]] || [[ "$arg" == "--ci" ]]; then
NON_INTERACTIVE=true
elif [[ "$arg" == *"unknown-linux-gnu"* ]]; then
TARGET="$arg"
fi
done

echo "=== httpjail static build verification ==="
echo ""

# Determine target if not provided
if [ -z "$TARGET" ]; then
ARCH=$(uname -m)
case "$ARCH" in
x86_64)
TARGET="x86_64-unknown-linux-gnu"
;;
aarch64|arm64)
TARGET="aarch64-unknown-linux-gnu"
;;
*)
echo "Unsupported architecture: $ARCH"
exit 1
;;
esac
echo "Auto-detected target from architecture: $ARCH -> $TARGET"
else
echo "Using specified target: $TARGET"
fi

echo "Note: Using gnu target with crt-static for static glibc linking"
echo ""

# Check if rust target is installed
echo "1. Checking Rust target..."
if ! rustup target list --installed | grep -q "$TARGET"; then
echo "Target $TARGET not installed. Installing..."
rustup target add "$TARGET"
else
echo "✓ Target $TARGET already installed"
fi
echo ""

# Build with static linking
echo "2. Building for $TARGET with static glibc..."
RUSTFLAGS="-C target-feature=+crt-static" cargo build --release --target "$TARGET"
echo ""

# Verify binary (check both local and shared cargo target)
BINARY="target/$TARGET/release/httpjail"
if [ ! -f "$BINARY" ] && [ -n "${CARGO_HOME}" ]; then
# Check shared cargo target when CARGO_HOME is set
BINARY="${CARGO_HOME}/shared-target/$TARGET/release/httpjail"
fi

if [ ! -f "$BINARY" ]; then
echo "✗ Binary not found at $BINARY"
exit 1
fi

echo "3. Verifying linking..."
echo ""

# Check file type
echo "File type:"
file "$BINARY"
echo ""

# Check dynamic dependencies
echo "Dynamic dependencies:"
if ldd "$BINARY" 2>&1; then
echo ""
echo "Note: Binary uses dynamic linking for some system libraries (expected with glibc)"
echo "The C runtime is statically linked, improving portability to older systems"
else
echo "✓ Binary is fully statically linked"
fi
echo ""

# Check binary size
SIZE=$(du -h "$BINARY" | cut -f1)
echo "Binary size: $SIZE"
echo ""

# Test basic functionality
echo "4. Testing binary..."
if "$BINARY" --version; then
echo "✓ Binary runs successfully"
else
echo "✗ Binary failed to run"
exit 1
fi
echo ""

echo "=== Build verification complete ==="
echo ""
echo "Binary location: $BINARY"
echo "To test on an older system, copy this binary and run:"
echo " ./httpjail --version"
echo ""
echo "The binary uses static glibc linking for improved portability while"
echo "still working with V8 prebuilt binaries (musl not supported by V8)."