Rustc itself could generate the stubs from #[link(kind = "raw-dylib")] extern "C" {} blocks when compiling for an ELF target the same way it generates import libraries when compiling for Windows. You need the extern "C" {} blocks anyway to even be able to call functions from shared libraries. It would be relatively little extra effort to add whatever annotations are necessary to generate the right stub shared libraries. The worst case is glibc where you need to add symbol versions to all functions, but we need to add some way to select the right symbol versions to link against independent of the system glibc version anyway to prevent ABI issues in the future.
You only need changes whenever you want to change the exposed set of functions in which case you have to edit the extern "C" {} blocks anyway.
Just like when you change the extern "C" {} blocks right now. Nothing changing there.
Only when there is an ABI breaking change that would force changes to the extern "C" {} blocks.
All arguments you have against this are the exact same as using extern "C" {} blocks as opposed to always using the C header files already installed on the system. Bindgen can probably add all attributes that raw-dylibs would need for ELF and Mach-O just based on the header files and (in case symbol versioning is used and not reflected in the header files) the original dynamic libraries.
Another way to phrase my previous message is: We have already accepted the downsides of not using the system C headers and instead manually writing extern "C" {} blocks in the libc crate as well as most -sys crates. And the downsides of using -nostdlib and instead explicitly linking against the libraries gcc/clang would link against by default. We may as well take advantage of the things these decisions enables and allow seamless cross-compilation by among other things generating import libraries / .tbd files / stub shared libraries to pass to the linker in place of the dynamic libraries installed on the system.
You only need something like newlib for baremetal targets, right? We already fully support cross-compilation of Rust programs that don't use any C libraries to baremetal targets.
Right now we are using a lot of rust + c, but can't utilize "-C linker-plugin-lto" because c is compiled with gcc, while we really need to reduce the size.
extracting the part responsible for cross compilation and write it in rust.
If rust team willing to do it, that will avoid some maintenance questions (if zig disappears), and maybe, some license questions as we can be sure what license is used in there.
Take another look at what zig cc does to handle glibc versioning. They store a minimal, compressed amount of metadata about what symbols exist in what versions of glibc, and then use that information to link to glibc without depending on what version of libc.so.6 is on the system.