From e1d819d629e1fb71d3852126f1d9dfbc37fedb1d Mon Sep 17 00:00:00 2001 From: Rayhaan Jaufeerally Date: Sun, 4 Oct 2026 01:03:16 +0200 Subject: [PATCH] Add a script that builds a static Linux executable scripts/build-static.sh builds the daemon for x86_64 Linux against musl, as one executable without dependencies to copy to a router. It finds a musl C compiler for jemalloc (musl-cross on macOS, musl-gcc on Linux), and uses its ar and ranlib too: with the host's, a build from macOS gets an empty libjemalloc.a and fails to link. It prints the revision and the SHA-256 of the result. Co-Authored-By: Claude Opus 5.5 --- .../docs/getting-started/installation.md | 29 +++++++++++ scripts/build-static.sh | 49 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100755 scripts/build-static.sh diff --git a/docs/content/docs/getting-started/installation.md b/docs/content/docs/getting-started/installation.md index 7ab850c..b0c3c23 100644 --- a/docs/content/docs/getting-started/installation.md +++ b/docs/content/docs/getting-started/installation.md @@ -57,6 +57,35 @@ To build and install the daemon: The command displays the installed version, for example `bgp 0.1.0`. +## Building a Static Executable + +The script `scripts/build-static.sh` builds the daemon as a single static +executable for x86_64 Linux, linked against musl. The executable runs on any +x86_64 Linux distribution without other dependencies. + +The script requires the Rust target and a musl C compiler for jemalloc: + +```bash +rustup target add x86_64-unknown-linux-musl +``` + +On macOS, install the cross compiler with +`brew install FiloSottile/musl-cross/musl-cross`. On x86_64 Linux, install +`musl-tools` (Debian, Ubuntu) or `musl` (Arch Linux). + +```bash +scripts/build-static.sh +``` + +The script displays the path of the executable, the source revision, and +the SHA-256 checksum of the executable: + +``` +target/x86_64-unknown-linux-musl/release/bgp: ELF 64-bit LSB pie executable, x86-64, static-pie linked +revision 9ce81a8 +2faa32d3... target/x86_64-unknown-linux-musl/release/bgp +``` + ## Building a Container Image The `Dockerfile` in the repository builds the daemon in a Rust build stage diff --git a/scripts/build-static.sh b/scripts/build-static.sh new file mode 100755 index 0000000..88549bd --- /dev/null +++ b/scripts/build-static.sh @@ -0,0 +1,49 @@ +#!/bin/sh +# Builds the daemon as one static executable for x86_64 Linux, which runs +# on any x86_64 Linux distribution with nothing else installed. +# +# scripts/build-static.sh +# +# The executable is linked against musl, with jemalloc as the memory +# allocator (see bin/bgp/src/main.rs). jemalloc is C, so a C compiler for +# the target is needed as well as the Rust target: +# +# rustup target add x86_64-unknown-linux-musl +# macOS: brew install FiloSottile/musl-cross/musl-cross +# Debian, Ubuntu (on x86_64): apt-get install musl-tools +# Arch (on x86_64): pacman -S musl +set -eu +target=x86_64-unknown-linux-musl +repository="$(cd "$(dirname "$0")/.." && pwd)" + +# The cross compiler from musl-cross, or musl's own wrapper on Linux. +if command -v x86_64-linux-musl-gcc >/dev/null; then + cc=x86_64-linux-musl-gcc + ar=x86_64-linux-musl-ar + ranlib=x86_64-linux-musl-ranlib +elif command -v musl-gcc >/dev/null; then + cc=musl-gcc + ar=ar + ranlib=ranlib +else + echo "No C compiler for $target: see the comment at the top of $0" >&2 + exit 1 +fi + +cd "$repository" +# jemalloc is built by its own configure script, which looks for an +# archiver named after the target (x86_64-unknown-linux-musl-ar) and, not +# finding one, would take the host's: on macOS that one cannot index Linux +# objects, and the library comes out empty. So AR and RANLIB are named. +CC_x86_64_unknown_linux_musl=$cc \ +AR_x86_64_unknown_linux_musl=$ar \ +AR=$ar \ +RANLIB=$ranlib \ +CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER=$cc \ + cargo build --release --locked -p bgp --target "$target" + +binary="target/$target/release/bgp" +echo +file "$binary" +echo "revision $(git rev-parse --short HEAD)$(git diff --quiet HEAD || echo ', with uncommitted changes')" +if command -v sha256sum >/dev/null; then sha256sum "$binary"; else shasum -a 256 "$binary"; fi