A rustc configuration option to forbid producing dylib crates

There is a concern in software distributions and integration projects using Rust (e.g. Flatpak) about the absence of ABI stability (see a recent discussion on this problem space) coupled with the ability to produce dynamic library crates. This creates a potential for such ABI-unstable dynamic libraries to end up in the distribution's components, either through oversight or lack of awareness. Seeing how dylib is not a generally popular type of shipped Rust artifacts, would it make sense to add a rustc build option to disable this type of output crates?

Distribution and packaging tooling already has lots of specific rules as well as tooling to enforce them. I see no reason to add this specific rule to rustc instead of whatever downstream tooling wants to enforce this.

@jschievink How do you suggest it be done automatically? The build/integration tools may lack knowledge that a particular component is built using the Rust compiler. Detect certain symbols/section name patterns/metadata in dynamic library crates, accounting for platform differences and being in perfect sync with changes in what even the Rust compiler developers consider to be an internal matter?

Can you not detect .dylib files and reject them?

Just to clarify because I think I misread this first time. You want a build time option while compiling the rustc compiler that will not compile in support for creating dylib output types? Essentially creating a slightly more limited version of rustc that will suffice for 99% of use-cases (with one major exception of being used as a bootstrap compiler for the next version since rustc is one of the few users of dylib outputs).

Yes, and possible size reduction of the compiler binaries is a plus.

As far as I am aware, distros manage bootstrap from rust sources without any intermediate steps. But this does bring up an issue: dylibs should be always enabled in the stage 1 compiler, but optionally disabled in the stage 2 compiler built by stage 1. I don't know if this may get in the way of how stage 3 is currently built.

On Linux, the compiler produces .so shared libraries in the ELF format that are not immediately distinguishable from any other libraries, except the magic hash in their name. These libraries don't even have NEEDED entries referring to Rust system libraries, like libstd-6640d3868fa846e8.so. The magic hash varies between individual compiler releases, so I guess at least consumers of these libraries are prevented from using them with an ABI that has broken without library changes to answer for it. But is there a reliable way to detect rustc-produced dynamic libraries in an integration system that is generally agnostic of build systems of the components? The compiler also produces .rlib and .rmeta files alongside, but as far as I understand they are only needed to build dependent Rust crates, so the component build might not expose these as end artifacts to the integration tools.

More philosophically, the burden of preventing production of fragile components should lay on the specific build systems of the components; it should not be an integration system's job to retrospectively check every library and catch every possible wayward tool usage.

1 Like

Ah, I see. That does make things a bit tricky, yeah.

1 Like

What if you delete lib/rustlib/x86_64-unknown-linux-gnu/lib/lib*.so from the rustc sysroot? Then rustc won't be able to find a libstd-*.so to dynamically link to and will have to statically link libstd.rlib when producing a dylib. (Don't delete lib/libstd-*.so. That is the host version of libstd.so to which rustc is dynamically linked.)

The dylibs themselves have unstable ABI, symbols, and the soname, too.