Currently we distribute a shared library for each internal rustc library we have. However, ultimately, what really needs to be exposed are two symbols main for rustc and main for rustdoc; everything else may be as private or internal as they need to be.
High level proposal is to instead ship a large librustc_everything.so/rustc_everything.dll/etc shared library and two ultra-thin binaries which essentially are
#[link="rustc_everything"]
extern "Rust" { fn rustc_main(); }
fn main() {
rustc_main();
}
rustc_everything would link all the libraries we currently ship statically and only export the two entry points for rustc and rustdoc (potentially others for whatever other tools we would produce).
This proposal, would help us with enforcing our stability story. Currently you can link to the librustc_* libraries with plain -l circumventing any stability checks and thus increasingly de facto stabilising crates we do not want to stabilise (most notably I myself experimented heavily in that direction with the llvm_build_utils crate and librustc_llvm library). It allows us to hide stuff like rustc-internal serialize or getopts as well.
That being said, what I’m proposing here is obviously a breaking change. It breaks anybody linking to rustc crates via -l. And it breaks anybody using extern crate getopts without cargo and with the unstable(rustc_private).
I’m still not entirely sure how this would work with syntax extensions, though. Do they need (some) internal crates exposed to have what to link to? At runtime they obviously could just use what’s already loaded into the process space, but what about compile time? We could have rustc_stuff_for_syntax_extensions and rustc_everything_else, or rustc_everything could selectively re-export crates necessary for syntax extensions.
cc @alexcrichton @brson