Repository navigation
Using --extern is apparently not equivalent to --sysroot #40
Description
Activity
- addedimplementationImplementation exploration and tracking issuesImplementation exploration and tracking issues
on Sep 6, 2019 Hmm what happens if you pass an empty sysroot? (See #31 where it mentions that). Perhaps there is an issue of search priority?
Ouch. Looks like this stems from rust-lang/rust#54658 (comment).
@Ericson2314 redirecting
--sysrootdoesn't matter here.I don't really understand why they are not allowed to shadow. Might be good to better understand that (and why sysroot is allowed to be shadowed but not
--extern).@petrochenkov can you explain why a macro-expanded
extern crateis allowed to shadow a sysroot crate, but not one from--extern? Is this restriction intended to be permanent?For context, this project is to add standard library support to Cargo. My original strategy was to use
--externflags to tell rustc where to load the newly built std crates. However, it runs afoul of the check added in rust-lang/rust#54658 for things like this idiom in crossbeam-utils.@ehuss
Sysroot crates do not exist from name resolution point of view, so they cannot be shadowed.
extern crate my_sysroot;is the only entity that pulls a crate from sysroot (or a crate from-Ldirectories) into name resolution.
(Note, thatstdandcorespecifically behave as if--extern std/coreis passed implicitly, so they exist from name resolution point of view, and can be affected by shadowing restrictions.)The shadowing restriction can be relaxed (by using
may_appear_afterinstead ofexpansion != ExpnId::root(), rust-lang/rust#54658 was a bit lazy in this regard), but not removed entirely.Hm so now this is sort of an interesting question. I think that we want
-Z build-stdto have the same semantics both if you use and if you don't. It looks like bothcoreandstdare implicit names in name resolution today, but bothproc_macroandalloc, the other two stable crates, need to be implicitly exported. By using--extern alloc=...and--extern proc_macro=...we're actually changing the semantics of-Z build-stdcode because they don't need to sayextern crate alloc. That seems bad!Now the "solution" to this is probably to use
--sysroot, but I'm realizing now I don't actually think that this is an easily viable option. The reason for this is that crates have implicit access to all crates in the sysroot, including the dependencies ofstditself. For example you can doextern crate backtrace;today on nightly but it just gives you a warning about the usage of therustc_privateunstable feature. If we don't build crates with-Zforce-unstable-if-unmarkedthen crates will have implicit stable access tobacktrace, for example, using-Zbuild-std.So I think that our main goal should be parity between "normal mode" and
-Z build-stdmode. We can't today achieve that with--externboth because of this bug and also because today stable Rust requiresextern crate alloc, even thoughallocis stable. We also can't achieve it today with--sysrootbecause we have no way of building the dependencies of libstd as unstable without a-Zflag.I think the best way forward, in general, is to "basically do the same thing" as rust-lang/rust. I think that we should use
--sysroot(or-L) to load libstd crates, and we should also figure out how to mark them as inaccessible (maybe that's with the-Zflag of today, maybe not).Using
--sysrootis doable but much more complicated, and will require a lot of changes. I'd like to make sure we're certain it is the way to go. I don't mind rewriting it, I just don't want to make this change haphazardly. (Using--sysrootwas my initial approach, but I was lured by the simplicity of using--extern.)I was originally thinking
allocandproc_macrowould need to be explicitly mentioned as dependencies inCargo.toml, otherwise the--externflag wouldn't be used. However, I see that would be a backwards-incompatible change for dependencies that aren't std-aware.Hm, it's a bit unfortunate, but I can't think of better options.
My current thinking is we should do one of two things:
-
Use
--sysrootin Cargo, compile everything into the sysroot. We'd compile everything with-Zforce-unstable-if-unmarked. -
Add a new flag to rustc, like
--extern-sysroot NAME=PATH. That would behave "as if the crate was in the sysroot" so it's available forextern cratebut it doesn't inject names into resolution as--externdoes.
I'm a fan personally of avoiding rustc changes if we can, but you're probably not wrong in that this is a much easier rustc change than a Cargo change. I was sort of hoping we could "just change the
--out-dir" for libstd crates to the sysroot and don't pass--externat all for sysroot crates in Cargo, but I suspect that's a bit too naive.-
@alexcrichton I've been blocked for a while trying to think of a way to get the mock test suite to work. The fundamental problem is that there are duplicate
coreorstdcrate errors because there is both the mock one and the real one in the link path. Do you have any ideas on how the mock suite can be changed to work?Oh dear yeah I can see where that would cause problems. Want to gist what you've got and I can try to poke around?
It may be that "mock std" either fundamentally no longer works or we can add
name = "something-other-than-std"annotations and hack our way to success. It may be sort of fundamentally a broken idea now though, which would be a bummer!Here is a work-in-progress (no test changes): ehuss/cargo@1ed8760
I've been trying a variety of things but keep hitting different problems. I was thinking of manually adding
--externflags into the original sysroot, but I keep hitting various issues.Not my proudest moment, but I think this does the trick - alexcrichton/cargo@dead4d0
Reacted by Josh Bowman-Matthews- added a commit that references this issue
on Sep 25, 2019 Fixed in rust-lang/cargo#7421
--extern-sysrootis a much better fix, I believe, not just easier.- added a commit that references this issue
on Dec 12, 2019
Testing out building a crate graph with
-Z build-std=std,alloc(note that the need to passallocis a separate bug) ends up yielding:Sure enough this code:
fails to compile:
I'm not entirely sure the origin of this error, but it seems that we either need to:
--sysroot