Skip to content

Build portable Linux binaries with musl static linking#17

Open
rgarcia wants to merge 1 commit intotobi:masterfrom
rgarcia:fix/static-linux-binaries
Open

Build portable Linux binaries with musl static linking#17
rgarcia wants to merge 1 commit intotobi:masterfrom
rgarcia:fix/static-linux-binaries

Conversation

@rgarcia
Copy link
Copy Markdown

@rgarcia rgarcia commented Dec 31, 2025

Summary

  • Switch Linux release builds from glibc (dynamic) to musl (static)
  • Binaries are now fully self-contained with no runtime dependencies

Problem

The release binaries were dynamically linked against Nix's glibc 2.40, making them non-portable to systems with older glibc versions:

/lib/x86_64-linux-gnu/libc.so.6: version 'GLIBC_2.38' not found

This contradicts the README's claim of "zero dependencies" and "single statically-linked binary".

Solution

  • Use pkgs.pkgsStatic for x86_64-linux (musl-based static toolchain)
  • Use pkgs.pkgsCross.aarch64-multiplatform-musl for aarch64-linux
  • Pass LDFLAGS="-static" to ensure fully static binaries

Binary size comparison

Build Size
Dynamic (current) 94 KB
Static (this PR) 182 KB

The ~2x size increase is a reasonable tradeoff for true portability.

Test plan

Verified locally with Nix:

$ nix build .#packages.x86_64-linux.x86_64-linux
$ file ./result/bin/try
./result/bin/try: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

$ nix build .#packages.x86_64-linux.aarch64-linux
$ file ./result/bin/try
./result/bin/try: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, not stripped

The release binaries were dynamically linked against Nix's glibc,
making them non-portable to systems with older or different glibc
versions. Users would see errors like:

  /lib/x86_64-linux-gnu/libc.so.6: version 'GLIBC_2.38' not found

This changes the Linux cross-compilation packages to use musl-based
static linking:
- x86_64-linux: Use pkgsStatic for musl static linking
- aarch64-linux: Use aarch64-multiplatform-musl for cross-compiled
  musl static linking
- Both builds now pass LDFLAGS="-static" to ensure fully static binaries

The resulting binaries are fully self-contained with no runtime
dependencies, matching the README's claim of "zero dependencies"
and "single statically-linked binary".

Tested with:
  nix build .#packages.x86_64-linux.x86_64-linux
  file ./result/bin/try  # Shows "statically linked"

  nix build .#packages.x86_64-linux.aarch64-linux
  file ./result/bin/try  # Shows "statically linked"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant