Skip to content
Open
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
6 changes: 4 additions & 2 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
[target.aarch64-unknown-linux-musl]
rustflags = ["-C", "target-feature=+crt-static", "-C", "link-arg=-Wl,-z,stack-size=2097152"]
linker = "aarch64-linux-musl-gcc"
rustflags = ["-C", "target-feature=+crt-static", "-C", "link-arg=-static", "-C", "link-arg=-Wl,-z,stack-size=2097152"]

[target.x86_64-unknown-linux-musl]
rustflags = ["-C", "target-feature=+crt-static", "-C", "link-arg=-Wl,-z,stack-size=2097152"]
linker = "x86_64-linux-musl-gcc"
rustflags = ["-C", "target-feature=+crt-static", "-C", "link-arg=-static", "-C", "link-arg=-Wl,-z,stack-size=2097152"]
20 changes: 11 additions & 9 deletions scripts/build/build-guest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -120,26 +120,28 @@ build_guest_binary() {

cargo build $build_flag --target "$GUEST_TARGET" -p boxlite-guest

# Verify guest binary is statically linked
# Verify guest binary is truly statically linked (ET_EXEC, not static-PIE).
# Static-PIE (ET_DYN) binaries fail inside the VM because libkrunfw's kernel
# has CONFIG_RANDOMIZE_BASE disabled — the ELF loader can't handle ET_DYN
# without ASLR, causing the guest to exit immediately with no output.
local guest_binary="$PROJECT_ROOT/target/$GUEST_TARGET/$PROFILE/boxlite-guest"
local file_output
file_output=$(file "$guest_binary")
if echo "$file_output" | grep -q "dynamically linked"; then
if ! echo "$file_output" | grep -q "statically linked"; then
local musl_arch
musl_arch=$(echo "$GUEST_TARGET" | cut -d'-' -f1)
local musl_gcc="${musl_arch}-linux-musl-gcc"

print_error "boxlite-guest is dynamically linked, but must be statically linked"
print_error "boxlite-guest is not statically linked"
echo ""
echo "❌ Error: The boxlite-guest binary must be statically linked."
echo "❌ Error: The boxlite-guest binary must be truly statically linked (ET_EXEC)."
echo " Static-PIE (ET_DYN) binaries will NOT work inside the VM."
echo ""
echo "The guest binary at $guest_binary is dynamically linked, which means"
echo "it depends on shared libraries that won't be available inside the VM."
echo " file output: $file_output"
echo ""
echo "🔧 To fix this issue:"
echo " Check your $musl_gcc version:"
echo " $ $musl_gcc --version"
echo " Verify whether your C compiler is a gnu-gcc wrapper instead of true musl-gcc"
echo " Ensure .cargo/config.toml has '-C link-arg=-static' in rustflags"
echo " for the $GUEST_TARGET target, and that $musl_gcc is a true musl linker."
echo ""
exit 1
fi
Expand Down
30 changes: 30 additions & 0 deletions scripts/build/build-runtime.sh
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,36 @@ assemble_runtime() {
echo "✓"
fi

# Final gate: verify binaries are truly statically linked before packaging.
# This catches issues regardless of how binaries were built or cached.
if [ "$OS" = "linux" ]; then
echo ""
print_section "Verifying static linking..."
local failed=false
for bin in boxlite-guest boxlite-shim; do
local bin_path="$DEST_DIR/$bin"
if [ -f "$bin_path" ]; then
local file_output
file_output=$(file "$bin_path")
if echo "$file_output" | grep -q "statically linked"; then
print_step "$bin: "
print_success "statically linked ✓"
else
print_error "$bin is NOT statically linked"
echo " file: $file_output"
failed=true
fi
fi
done
if [ "$failed" = true ]; then
echo ""
print_error "Runtime contains non-static binaries. Aborting."
echo " Static-PIE (ET_DYN) binaries will fail inside the VM."
echo " Ensure .cargo/config.toml has '-C link-arg=-static' in rustflags."
exit 1
fi
fi

print_success "Runtime directory assembled"
}

Expand Down
14 changes: 14 additions & 0 deletions scripts/build/build-shim.sh
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,20 @@ build_shim_binary() {
else
cargo build $build_flag --bin boxlite-shim $features
fi

# Verify shim binary is statically linked on Linux
if [ "$OS" = "linux" ]; then
local file_output
file_output=$(file "$SHIM_BINARY_PATH")
if ! echo "$file_output" | grep -q "statically linked"; then
print_error "boxlite-shim is not statically linked"
echo ""
echo "❌ Error: The boxlite-shim binary must be statically linked."
echo " file output: $file_output"
echo ""
exit 1
fi
fi
}

# Sign the binary (macOS only, automatic)
Expand Down
45 changes: 37 additions & 8 deletions scripts/setup/setup-manylinux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ check_platform() {
fi
}

# Check if we need $SUDO (not root and sudo exists)
if [ "$EUID" -ne 0 ] && command -v sudo &> /dev/null; then
SUDO="sudo"
else
SUDO=""
fi

# Check if a yum package is installed
yum_installed() {
yum list installed "$1" &>/dev/null
Expand All @@ -34,7 +41,7 @@ yum_installed() {
# Update package lists
update_yum() {
print_section "🔄 Updating package lists..."
yum update -y -q
$SUDO yum update -y -q
echo ""
}

Expand All @@ -52,6 +59,7 @@ install_system_deps() {
unzip
file # file type detection
pkgconfig
patchelf # ELF binary patching (SONAME fixup, wheel repair)
openssl-devel

# libkrun build dependencies
Expand All @@ -60,8 +68,7 @@ install_system_deps() {
llvm
llvm-devel
libatomic
libepoxy-devel # Required by rutabaga_gfx for OpenGL
virglrenderer-devel # Required by rutabaga_gfx for GPU virtualization
libepoxy-devel # Required by rutabaga_gfx for OpenGL (optional on headless)

# libkrunfw kernel build dependencies
bc
Expand Down Expand Up @@ -90,9 +97,31 @@ install_system_deps() {
if yum_installed "$pkg"; then
print_success "Already installed"
else
echo -e "${YELLOW}Installing...${NC}"
yum install -y -q "$pkg"
# Some packages have -minimal variants (e.g., curl-minimal on Amazon Linux)
# that provide the same command. Skip if the command already exists.
local cmd_name="${pkg%%-*}" # e.g., "curl" from "curl", "gcc" from "gcc-c++"
if [ "$pkg" = "$cmd_name" ] && command -v "$cmd_name" &>/dev/null; then
print_success "Provided by alternative package"
else
echo -e "${YELLOW}Installing...${NC}"
$SUDO yum install -y -q "$pkg"
print_success "$pkg installed"
fi
fi
done

# Optional GPU packages (not available on all distros, e.g., Amazon Linux 2023)
local optional_packages=(
virglrenderer-devel # Required by rutabaga_gfx for GPU virtualization
)
for pkg in "${optional_packages[@]}"; do
print_step "Checking for $pkg (optional)... "
if yum_installed "$pkg"; then
print_success "Already installed"
elif $SUDO yum install -y -q "$pkg" 2>/dev/null; then
print_success "$pkg installed"
else
echo -e "${YELLOW}Not available (GPU features disabled)${NC}"
fi
done

Expand All @@ -103,7 +132,7 @@ install_system_deps() {
print_success "Already installed"
else
echo -e "${YELLOW}Installing...${NC}"
yum install -y -q glibc-static
$SUDO yum install -y -q glibc-static
print_success "glibc-static installed"
fi

Expand Down Expand Up @@ -176,7 +205,7 @@ install_protoc() {
local PROTOC_ZIP="/tmp/protoc.zip"

curl -sSL "$PROTOC_URL" -o "$PROTOC_ZIP"
unzip -q -o "$PROTOC_ZIP" -d /usr/local
$SUDO unzip -q -o "$PROTOC_ZIP" -d /usr/local
rm -f "$PROTOC_ZIP"

print_success "Installed protoc $PROTOC_VERSION"
Expand Down Expand Up @@ -216,7 +245,7 @@ install_nodejs() {

echo -e "${YELLOW}Downloading Node.js $NODE_VERSION...${NC}"
curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${NODE_ARCH}.tar.xz" \
| tar -xJ -C /usr/local --strip-components=1
| $SUDO tar -xJ -C /usr/local --strip-components=1
print_success "Node.js $NODE_VERSION installed"
echo ""
}
Expand Down
1 change: 1 addition & 0 deletions scripts/setup/setup-musllinux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ install_system_deps() {
unzip
file # file type detection
pkgconfig
patchelf # ELF binary patching (SONAME fixup, wheel repair)
openssl-dev

# musl development
Expand Down