What Happened

-linked executable. At runtime, 's existing glibc-linked GPU driver. No container, no AppImage, and no second process.

Static binaries are a wonderfully boring way to deploy software on Linux: one file, no dependencies, nothing to break. , a source-first build system for producing fully static Linux binaries. The boredom ends the moment the application : Vulkan and OpenGL drivers are supplied shared objects, usually built against glibc, and a fully static musl binary cannot normally dlopen() them.

SoLo crosses that boundary. It provides a dlfcn-style source API backed loader (x86-64 and aarch64) and a glibc ABI bridge implemented . The result ordinary static executable, graphics driver already installed on the machine.

The repository includes an end-to-end Vulkan proof: a fully static executable 's unmodified Vulkan driver, runs a compute shader, and writes the result to a PNG. Tested , radeonsi, Intel, and NVIDIA , M1 .

Why It Matters

a demo's word alone: on every commit, shared libraries of the 1,000 most-installed Debian packages — over 2,100 host objects — through SoLo, on both x86-64 and aarch64.

Grab the prebuilt binary — no clone, no toolchain, a Vulkan driver installed (mesa-vulkan-drivers is enough):

curl -LO https://github.com/pg83/solo/releases/latest/download/vulkan-x86_64 chmod +x vulkan-x86_64 ./vulkan-x86_64 hello.png vulkan-aarch64 arm64 machines. The command discovers the distro-installed Vulkan produces a 512×512 RGBA image. Shitty release binaries—a blazingly fast terminal emulator, BTW! To force a particular driver:

./vulkan-x86_64 --driver /usr/share/vulkan/icd.d/radeon_icd.x86_64.json radeon.png ./vulkan-x86_64 --driver /usr/share/vulkan/icd.d/lvp_icd.json lavapipe.png ICD manifest names vary slightly between distributions. Passing no --driver lets the embedded Khronos loader perform its normal discovery.

What Comes Next

You can verify that the executable itself is not dynamically linked:

readelf -lW ./vulkan-x86_64 | grep INTERP # no output readelf -dW ./vulkan-x86_64 # " dynamic section" source, with Python 3 and a C/C++ compiler in PATH:

://github.com/pg83/solo. ./build vulkan ./vulkan hello. a vkCreateInstance. The demo:

The complete example /vulkan, and the Vulkan program itself .cpp.

┌──────────────────── fully static executable ────────────────────┐ │ │ │ application → embedded Vulkan loader → SoLo dlopen/dlsym │ │ ├─ x86-64 ELF mapper │ │ └─ glibc ABI → musl │ │ │ │ └───────────────────────────────────────────┬─────────────────────┘ │ maps at runtime ▼ system Mesa/Vulkan ICD.so + DSOs elf_loader. segments, walks DT_NEEDED, resolves versioned symbols, applies x86-64 relocations, supports TLSDESC, materializes IFUNCs, applies RELRO, and runs initializers. Dependencies that are themselves loaded recursively.

glibc is deliberately not loaded. Imports such as malloc@GLIBC_2.2.5 are resolved by glibc_shim.-correct adapters over the process's existing musl runtime. Unsupported glibc functions have unique generated loudly symbol and version called, instead of silently corrupting the process.

Because synchronization objects architecture, the bridge does not shadow them: a pthread_mutex_t a driver creates . A lock is therefore loaded static executable , and glibc's static recursive and error-check initializers are adopted .

Explore more: Software & AI Guide