musl - standard C library


musl provides consistent implementation behavior from tiny embedded systems to full-fledged servers.

Designed for static linking, musl avoids pulling in large amounts of code or data that the application will not use. Dynamic linking is also efficient; by integrating the entire standard library implementation, including threads, math, and even the dynamic linker itself into a single shared object, most of the startup time and memory overhead of dynamic linking have been eliminated.

musl features the first post-NPTL implementation of POSIX threads for Linux, and the first aimed at complete conformance and robustness. Thread cancellation has been re-designed to avoid serious race conditions in the original NPTL design.

Musl has been designed for realtime-quality robustness. Low-memory or resource exhaustion conditions are never fatal. musl has no unnecessary dynamic allocation and no unrecoverable late failures. All error conditions can be detected and handled by applications; interfaces for which an application could not reasonably handle failure do not fail.

Binaries statically linked with musl have no external dependencies, even for features like DNS lookups or character set conversions that are implemented with dynamic loading on glibc.

Please see the page for more information.

Installing and Testing

musl is included in Debian since Jessie (8).

For further package information see


To install musl run:

# apt-get update
# apt-get install musl

This will install the musl runtime but will not install any development packages. If you are a developer and/or want to compile simple C99 based programs, please have also a look at the packages musl-dev and musl-tools.


The musl runtime uses a similiar aproach for configuring shared library paths as glibc. If you want to add your library in a non standard path, please add a config file under /etc/ld-musl-$ARCH.d/ containing your custom path. After that you can run:

# ld-musl-config

Please note that it requires root privileges to do so. For additional information see the manpage to ld-musl-config.

There are other options available to influence the musl libc dynamic loader. Full documentation can be found under In particular the variable TZ, LD_PRELOAD and LD_LIBRARY_PATH might be of intrest.

To limit the influence of a variable to a single binary, use something like:

# LD_PRELOAD=$PWD/ ./yourbin

Use it

Select a compiler






The following script was verified with clang-13 and libgcc.a in gcc-11:

   1 #!/bin/sh
   3 ARCH=aarch64
   4 # or ARCH=x86_64 etc.
   7 # Scrt1.o for dynamic PIE
   8 # rcrt1.o for static PIE
   9 # crt1.o for no PIE
  10 LIBPREFIX=/usr/lib/${ARCH}-linux-musl
  11 GNULIBPREFIX=/usr/lib/gcc/${ARCH}-linux-gnu/$GCCVERSION
  13 if echo " $@" | fgrep -q -- ' -static'; then
  14   DYNLINKER=''
  15   if echo " $@" | fgrep -q -- ' -static-pie'; then
  16     CRT=${LIBPREFIX}/rcrt1.o
  17   else
  18     CRT=${LIBPREFIX}/crt1.o
  19   fi
  20 else
  21   DYNLINKER="-Wl,-dynamic-linker,/lib/ld-musl-${ARCH}.so.1"
  22   if echo " $@" | fgrep -q -- ' -pie'; then
  23     CRT=${LIBPREFIX}/Scrt1.o
  24   else
  25     CRT=${LIBPREFIX}/crt1.o
  26   fi
  27 fi
  28 exec clang $DYNLINKER -nostdinc -isystem /usr/include/${ARCH}-linux-musl -nostdlib -nostdlib++ -nodefaultlibs -nostartfiles -L${LIBPREFIX} $CRT ${LIBPREFIX}/crti.o "$@" -lc ${GNULIBPREFIX}/libgcc.a ${LIBPREFIX}/crtn.o

Use cases

Static compiled admin binaries


Fast static C CGI Scripts


Embedded Linux

t.b.d. ... and mor t.b.d.