Let me write up my thoughts about the issue.
I am probably not the right person to talk about sysroot to though, I’ve never cross-compiled a rust crate!
Let’s define what a sysroot is, first.
This boils down to how compiler finds a foo
crate for an extern crate foo
declaration.
There are two mechanism for this:
- you can pass
rutsc --extern foo=/path/to/foo.rlib
on the command line
- compiler has a special directory where it tries to look up crates by name, (not unlike C’s include/library paths)
Everything beside std uses the first mechanism.
std and its dependencies use the second mechanism.
Here’s a simple program which demonstrates these lookup rules:
λ cat main.rs
extern crate rand;
fn main() {}
~/tmp
λ rustc main.rs
error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead? (see issue #27812)
--> main.rs:1:1
|
1 | extern crate rand;
| ^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.
What happens here is that rand is used in a sysroot, as a private implementation detail of libstd.
However, because it is in sysroot, this impl detail is observable, and so the user gets a confusing error message about an unstable feature, instead of the usual “can’t find crate”.
It seems to me that this difference between std an other libraries is not essential.
Std is definitely special because of prelude and lang item.
However, it doesn’t need to be special in a way how rustc discovers std crates: they also can be passed as arguments.
Of course, we should assume that, unless overridden, extern std=$(rustc --print sysroot)/lib/rustlib/...
is passed by default.
Otherwise, running rustc main.rs
by hand would be a nightmare.
Another accidental difference between std and usual crates is that std is always prebuild (distribution of Rust includes rlibs), while crates.io dependencies are build from source.
As xargo demonstrates, it is possible to build std locally.
However, it is an interesting question stability wise.
Currently we guarantee that for each tier-one platform we will supply prebuild standard library with each compiler.
If we stabilize ability to build your own sysroot, we, by default, guarantee that it is always possible to build standard library locally.
I think this is an unreasonable guarantee: for example, if stdlib depends on some native code, you’ll need to have a C compiler to build it.
Even if we remove all C from stdlib (like jemalloc), we can’t guarantee that we won’t need C in the future.
So, we need to be very careful with specifying what “you can build sysroot from sources” means.
Also, while writing it down, I’ve got the idea of an incremental step to make sysroot situation less special.
Will write it in the next comment.