@alexcrichton and I have been working on the build-std feature of Cargo that allows it to build the standard library from source for any project. One of the tricky issues we've been wrestling with is determining which crates of the standard library to build for each project, particularly for no_std targets. Currently you can pass them on the command (like -Zbuild-std=core,alloc
).
After discussing some different approaches we've concluded on a somewhat radical proposal: Change the standard library so that all of its crates build on all targets, no questions asked. We wanted to solicit feedback from a wider audience on this proposal.
Why build std
on all targets?
The current strategy of specifying on the command line what crates to build is not something we ever intend to stabilize long-term. The set of crates to build is something that the end-user shouldn't be configuring, but rather it's inherent to each crate itself (more or less), so the current flag is a bit backwards.
If std
simply builds on all targets, we think this could significantly simplify the user experience. Enabling build-std
mode would be a simple toggle (like setting CARGO_BUILD_STD=true
) which should work for any project.
Getting std
building for all targets
At a high-level what I mean when I say "get std
building for all targets" is simply "no compile errors". There's a number of questions about what APIs are available, but the bare minimum intention here is simply that the crate compiles with zero compile time errors.
In practice this means that we'll change the source of the standard library to some combination of adding runtime errors (like wasm, wasi, sgx, hermit, and cloudabi already do) and cfg
attributes to prune things that are not possible to express (for example a target which doesn't define the types for the std::os::raw
module).
Does this affect stable?
The intent is that initially this shouldn't have any user-visible changes on stable. For all targets that rustc supports std
either builds today or doesn't:
- If
std
builds it's already stable and nothing changes - If
std
doesn't build, then this proposal would markstd
as#[unstable]
for that target for the time being.
The longer-term future of this proposal is somewhat unclear. From the Cargo build-std
perspective there's no need to get a stable build of std
on all platforms, just the guarantee that it simply builds on all platforms.
It's hoped that this organization is something we'd experiment with over time. For example, maybe it's best to return runtime errors everywhere. Or maybe it's best to simply omit APIs and have a libstd that looks different on each target. We're not sure!
I recognize that it won't be easy, and I've been thinking about some of the trickier bits (handling libc, proc_macro, the panic runtimes, the global allocator, the sys
module, etc.). I would be happy to get some feedback on the general concept! I'm hoping that we don't get too hung up on "what would a stable libstd look like for all platforms" question just yet, but moreso hopefully gearing feedback towards the idea of getting libstd building everywhere and leaving us runway to answer that question later.