Guidelines for Distributions

Obviously we cannot control how distributors use musl; it’s free software, and anyone is free to make local changes/forks that don’t follow the intended usage. However, the following are guidelines written from a standpoint of helping systems integrators using musl to avoid some (possibly non-obvious) pitfalls that would preclude interoperability of binaries from/with other musl-based systems.

Standard Pathnames

The musl developers have attempted to avoid gratuitous dependence on fixed pathnames and have used existing, well-established ones when possible rather than inventing new ones. For compatibility of dynamic-linked musl-based binaries across different systems, the most important is the location of the dynamic linker. It should always be at /lib/ld-musl-$, where $ARCH is the full arch/sub-arch name produced by musl’s configure script for the target architecture/ABI combination. It does not matter whether it’s an actual file or a symbolic link to a file in another location, as long as it’s available at boot time (or as soon as you need dynamic-linked binaries to work). This pathname exactly (and not other variants based on your distribution’s symbolic link layout, etc.) should appear in the PT_INTERP header of dynamic-linked programs.

For other standard pathnames, like /etc/resolv.conf, /etc/passwd, etc. it’s non-invasive (but not officially supported) to change them in; dynamic linked programs will automatically use whatever uses. For static linking, however, it’s problematic to do so since the binaries will be tied down to your particular FS layout and not compatible with other systems. If possible, it’s best to just stick with all the standard pathnames.

Adding Functions

If musl is missing functions which are present in another libc and which are needed by programs you want to package for your distribution, there are several options for how to proceed:

Adding or Changing Features

When a feature does not affect the public API of an interface (examples: alternate passwd database backends, cpu-model-specific memcpy optimizations, etc.) there is no harm to compatibility in adding it locally. Some cases are more borderline (examples: adding iconv charsets, adding non-standard regex extensions, etc.) in that applications could depend on them and fail to work with a “stock” musl libc that does not provide them, and it’s probably best to attempt to coordinate such additions with upstream (at least to make sure that your local changes don’t conflict with future plans upstream).

When a feature does affect public API (example: additional GLOB_* flags) it’s effectively much closer to adding a function (see above).