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.
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
$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/passwd, etc. it’s
non-invasive (but not officially supported) to change them in libc.so; dynamic
linked programs will automatically use whatever libc.so 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.
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:
- The safest solution is always putting the new functions in a separate (preferably static) library file and linking them into the programs that need them. This will not affect backwards compatibility, forwards compatibility, compatibility with foreign musl-linked binaries (from other musl-based systems), or compatibility with foreign musl ld.so (using your distribution’s binaries on other musl-based systems).
- For functions where there is an upstream commitment to adding it in a future version, patching it into your libc might be an option. Programs built against it would then have a requirement which could be satisfied either by your custom libc or a future “stock” musl. Care should be taken not to introduce subtle incompatibilities or interface-contract bugs which your programs might come to depend on, however.
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).