-
Notifications
You must be signed in to change notification settings - Fork 13.5k
Implement ToolTarget
and port RemoteTestServer
and WasmComponentLd
to it
#143581
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…ith the stage0 compiler
This avoid needless rebuilds when the tool can be simply compiled by the stage0 compiler.
I don't think cross-compiling should result in a different binary at stage2 that native compilation. Nor should a local rebuild (using the current rustc version as bootstrap compiler) result in a different binary at stage2 than using the previous rustc version as bootstrap compiler. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I think this design seems like a "most correct" approach to address the nuisance of these tools. I do have a question.
@@ -196,7 +196,7 @@ impl Step for ToolBuild { | |||
Kind::Build, | |||
self.mode, | |||
self.tool, | |||
self.build_compiler.stage, | |||
self.build_compiler.stage + 1, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remark: this is because it's a product of the stage 0 rustc that is not the stage 0 library
/// Returns a compiler that is able to compile a `ToolTarget` tool for the given `target`. | ||
pub(crate) fn get_tool_target_compiler(builder: &Builder<'_>, target: TargetSelection) -> Compiler { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: this isn't quite obvious, because in the cross-compile case, we'll also have to ensure target std as a side-effect, right? I don't have a better name for this just yet, so not a blocker.
I can see why we might want to have some kind of "proof of std artifacts getting built".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that would indeed be nice, but that's a massive refactoring. I'm continuously thinking about how to approach it. The attachment of a std to Compiler
in bootstrap is currently fully implicit, so this just does what the rest of bootstrap does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this was more of a question, and not a blocking change request.
extra_features: vec![], | ||
allow_features: "min-specialization", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: hm, might this be a problem if min_specialization
ever gets renamed, removed or stabilized? Or rather, the tool now has to be support being built by both stage 0 compiler and stage 1 compiler right? In that situation, the tool would have to cfg(bootstrap)
anyway I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the feature flag is even needed, the tool compiles with the stable compiler... Unless it does some weird detection in build scripts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would keep it for now, to leave the previous functionality intact. If it becomes an issue, we can always try to remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, that sounds reasonable.
Hm, as in with this scheme, we would be producing different |
Yes. And in case it was compiled for the host a local rebuild won't produce an identical executable to a regular bootstrap. The local rebuild case matches when it was compiled for the target. |
But that is the point, right? If we compile rustc for |
I would expect cross-compiling from bar -> foo to produce the exact same executable as compiling natively on foo. Choosing between compiling with the bootstrap compiler and compiling with the local rustc depending on if you are cross-compiling or not causes both cases to produce different executables. |
Hmm, I see what you mean now. It seems like a noble goal, but do we actually uphold it in practice? I would be very much surprised if bootstrap managed to cross-compile 1:1 bitwise exact binaries, and we don't have tests for this, definitely not for the linker tools. We were also already compiling wasm-component-ld using the stage0 compiler before, we just recompiled it again using the stage1 compiler when doing a stage2 (or cross-compiling) build. More generally, these should be "normal" Rust tools compilable by a stable compiler. Does it matter so much with what compiler we build them? |
We only distribute the stage2 build. It is expected that the stage1 build doesn't exactly match.
I don't think we currently do it perfectly (especially for cross-compilation), but that doesn't mean we should make it worse. Having cross-compilation produce identical executables is maybe not the most important, but I do think local-rebuild should produce identical executables. |
Hmm, that's unfortunate. We spend ~2 minutes building just Another alternative would be to distinguish in bootstrap if tools are needed for the intermediate stages, and if not, then skip building them (e.g. if we do a stage 2 build, don't build wasm-component-ld for stage 1 rustc). But that's either a large refactoring or piling more hacks on top of the
Could you expand on this a bit more? We don't ever use local rebuild for dist builders (right?), and if you compile a "stage 0 bootstrap tool", e.g. |
Distros do use local rebuild.
Yes, it doesn't really matter for local tools, only for distributed tools. I believe cargo already has this issue now that I think about it, so I guess this PR doesn't make the problem much worse. So I withdraw my concern about this PR. |
Yeah, since cargo is also compilable by stage0, I wanted to turn it into Well, your concerns are quite interesting, I haven't thought of that. And this PR does add more complexity to bootstrap, although it also makes the behavior of the "target" tools more precise and unified, before they were using I would try to land this and see if anyone complaints about the non-identical binaries. I personally expect that our cross-compiles are far from identical anyway though, and that even local rebuild had some issues around this previously. If someone finds this to be an issue, we can still keep the more accurate tool mode, and just revert the change to compile with stage0. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, the changes look good to me. One comment request re. the reproducibility consideration so a Future Reader ™️ has some more context.
src/bootstrap/src/lib.rs
Outdated
/// Build a cross-compilable helper tool. | ||
/// - If we compile it for the host, we use the stage0 compiler. | ||
/// - If we compile it for another target, we use local compiler (because stage0 does not have | ||
/// stdlib for the tool available for other targets). | ||
/// | ||
/// This mode exists to avoid needless (re)builds of tools that can be compiled with | ||
/// a stable/stage0 compiler. It essentially behaves as `ToolBootstrap` when not | ||
/// cross-compiling, and as `ToolStd` when cross-compiling. | ||
/// | ||
/// It is used e.g. for linkers and linker tools invoked by rustc on its host target. | ||
/// | ||
/// These tools participate in staging only when required for cross-compilation. | ||
ToolTarget, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: can you leave a comment here about the interesting reproducibility question (that we considered it, but decided that it still seems worth trying this approach) re. we would not be producing the same tool as we use different compilers when the tool is built for host vs for target?
@rustbot author |
Done. @rustbot ready |
Thanks. |
This comment has been minimized.
This comment has been minimized.
@bors r- sigh |
5c85adc
to
4fddfd1
Compare
I want to get a bit more opinions on this. |
In addition to the non-identical binaries for cross-compilation and local rebuilds, this would mean that we can't easily ship security fixes to these tools when we |
We have a set of tools (such as the various linker wrappers - LLD/WASM/LLVM linkers) that behave like bootstrap tools when not cross-compiling, and like std tools when cross-compiling. Before, various modes were used for them (currently -
ModeStd
forWasmComponentLd
andLldWrapper
andToolRustc
forLlvmBitcodeLinker
). This was wasteful, if you did a stage 2 non-cross-compiled build,WasmComponentLd
would be built twice, even though we can just build it once using the stage0 compiler.I would like to unify these. This PR is the first step towards that. I started what I considered to be the simplest linker step out of the three.
r? @jieyouxu