Skip to content

Simplify LLVM bitcode linker in bootstrap and add tests for it #142357

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

Merged
merged 5 commits into from
Jul 9, 2025

Conversation

Kobzol
Copy link
Member

@Kobzol Kobzol commented Jun 11, 2025

This PR tries to simplify the LlvmBitcodeLinker step a little bit, and add tests for it. It also adds tests for LldWrapper.

r? @jieyouxu

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) labels Jun 11, 2025
Copy link
Member

@jieyouxu jieyouxu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, some questions/feedback, but looks good overall

Comment on lines 2037 to 2069
let bindir_self_contained = builder
.sysroot(compiler)
.join(format!("lib/rustlib/{}/bin/self-contained", compiler.host));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion (follow-up, not for this PR): maybe pull out a method to do the "path to sysroot target self-contained" logic.

Copy link
Member Author

@Kobzol Kobzol Jun 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually had a commit for that, but it's super tricky (lol). Because:

  • There are like 5 places in bootstrap that access the self-contained directory. Some of them need a relative path, some of them absolute, some of them work with a compiler, some don't, it's a mess.
  • The functions that we have in Builder for getting similar paths (invoked through the Libdir step) actually delete the directory before returning it to you 🤦 I tried to use it here and it broke everything 😂 I need to clean all of this up eventually, and move the directory clearing to a single step, so that you can get a path to something without bootstrap falling over, lol.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is uhhh tricky. I'll open a issue about this follow-up (and that it's tricky).

Copy link
Member

@jieyouxu jieyouxu Jun 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#142361, not in scope for this PR (keeping this unresolved to make it easier to find).

Comment on lines 1318 to 1319
/// Return the lowest stage compiler that can compile code for the given `target`.
pub fn compiler_for_target(&self, target: TargetSelection) -> Compiler {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussion: maybe tool_compiler_for_target? I ask because this should also say something like "it must not be used to build stuff that depends on staged rustc/std", right?

Copy link
Member Author

@Kobzol Kobzol Jun 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there's any requirement like this. It's really just "give me a compiler that can build code for target T". If stage0 could cross-compile for any target, we could use it for this always.

We actually have a bunch of situations like this in bootstrap already, but it was always done sort of implicitly. Here I wanted to make it explicit.

In other words, I think that this could be useful also for other things than just tools. But right now it's only for a single tool, ofc, so happy to rename if you want.

Copy link
Member

@jieyouxu jieyouxu Jun 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm right. The reason I asked is that

this could be useful also for other things than just tools

is probably true, just that the "other things" must not use this method if they do "depend on staged compiler/std" (be it through rustc_private or directly or somehow).

For now, I think it's safer to name this as sth like tool_compiler_for_target to make it clear that you should not use it for sth beyond its purpose (because we also have Builder::{compiler,compiler_for}), and then consider its naming if we do use it for not-just-tools, but it's not really a blocking concern.

Comment on lines 1238 to 1241
/// Check that during a non-cross-compiling stage 2 build, we only compile rustc host tools
/// (such as llvm-bitcode-linker) only once.
#[test]
fn llvm_bitcode_linker_compile_once() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: should we have another test that does check the cross-compiling case, that we do build a stage 1 (rustc, std) pair that can produce artifacts for target, and that llvm-bitcode-linker is produced by that pair for the target?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, happy to add it. Although from my local experiments, I'm almost sure that bootstrap is actually broken for these situations somehow. Like, ./x build --host i686-unknown-linux-gnu, which is like the simplest cross-compilation scenario on x64 Linux, fails for me on master.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And you would be right 🎡

@jieyouxu
Copy link
Member

@rustbot author

@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 11, 2025
@rustbot
Copy link
Collaborator

rustbot commented Jun 11, 2025

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@rustbot rustbot added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Jun 11, 2025
@rust-log-analyzer

This comment has been minimized.

@bors
Copy link
Collaborator

bors commented Jun 12, 2025

☔ The latest upstream changes (presumably #142392) made this pull request unmergeable. Please resolve the merge conflicts.

tgross35 added a commit to tgross35/rust that referenced this pull request Jun 16, 2025
…=jieyouxu

Add initial version of snapshot tests to bootstrap

When making any changes to bootstrap (steps), it is very difficult to realize how does it affect various common bootstrap commands, and if everything still works as we expect it to. We are far away from having actual end-to-end tests, but what we could at least do is have a way of testing what steps does bootstrap execute in dry run mode. Now, we already have something like this in `src/bootstrap/src/core/builder/tests.rs`, however that is quite limited, because it only checks executed steps for a specific impl of `Step` and it does not consider step order.

Recently, when working on what I thought was one of the simplest possible step untanglings in bootstrap (rust-lang#142357), I ran into errors in tests that were quite hard to debug. Partly also because the current staging test diffs are multiline and use `Debug` output, so it's quite difficult for me to make sense of them.

In this PR, I introduce `insta`, which allows writing snapshot tests in a very simple way. With it, I want to allow writing tests that will clearly show us what is going on during bootstrap execution, and then write golden tests for `build/check/test` stage `0/1/2` for compiler/std/tools etc., to make sure that we don't regress something, and also to help with [#t-infra/bootstrap > Proposal to cleanup stages and steps after the redesign](https://rust-lang.zulipchat.com/#narrow/channel/326414-t-infra.2Fbootstrap/topic/Proposal.20to.20cleanup.20stages.20and.20steps.20after.20the.20redesign/with/523488806), to help avoid a situation where we would (again) have to make a flurry of staging changes because of unexpected consequences.

In the snapshot tests, we currently render the build of rustc, std and LLVM. Currently I render the executed steps using downcasting, which is not super pretty, but it allows us to make the test rendering localized in one place, and it's IMO enough for now.

I implemented only a single test using the new machinery. Maybe if you take a look at it, you will understand why 😆 Bootstrap currently does some peculiar things, such as running a stage 0 std step (even though stage 0 std no longer exists) and running the Rustc stage 0 -> 1 step twice, once with a single crates, once with all rustc crates. So I think that even with this single step, there will be a bunch of things to fix in the near future...

The way we currently prepare the Config test fixtures is far from ideal, this is something I think `@Shourya742` could work on as a part of their GSoC project (remove as much command execution from Config construction as possible, actually run bootstrap on a temporary directory instead of running it on the rustc checkout, create a Builder-like API for creating the Config test fixtures).

r? `@jieyouxu`
@Kobzol Kobzol marked this pull request as draft June 16, 2025 08:41
Kobzol added a commit to Kobzol/rust that referenced this pull request Jun 16, 2025
…=jieyouxu

Add initial version of snapshot tests to bootstrap

When making any changes to bootstrap (steps), it is very difficult to realize how does it affect various common bootstrap commands, and if everything still works as we expect it to. We are far away from having actual end-to-end tests, but what we could at least do is have a way of testing what steps does bootstrap execute in dry run mode. Now, we already have something like this in `src/bootstrap/src/core/builder/tests.rs`, however that is quite limited, because it only checks executed steps for a specific impl of `Step` and it does not consider step order.

Recently, when working on what I thought was one of the simplest possible step untanglings in bootstrap (rust-lang#142357), I ran into errors in tests that were quite hard to debug. Partly also because the current staging test diffs are multiline and use `Debug` output, so it's quite difficult for me to make sense of them.

In this PR, I introduce `insta`, which allows writing snapshot tests in a very simple way. With it, I want to allow writing tests that will clearly show us what is going on during bootstrap execution, and then write golden tests for `build/check/test` stage `0/1/2` for compiler/std/tools etc., to make sure that we don't regress something, and also to help with [#t-infra/bootstrap > Proposal to cleanup stages and steps after the redesign](https://rust-lang.zulipchat.com/#narrow/channel/326414-t-infra.2Fbootstrap/topic/Proposal.20to.20cleanup.20stages.20and.20steps.20after.20the.20redesign/with/523488806), to help avoid a situation where we would (again) have to make a flurry of staging changes because of unexpected consequences.

In the snapshot tests, we currently render the build of rustc, std and LLVM. Currently I render the executed steps using downcasting, which is not super pretty, but it allows us to make the test rendering localized in one place, and it's IMO enough for now.

I implemented only a single test using the new machinery. Maybe if you take a look at it, you will understand why 😆 Bootstrap currently does some peculiar things, such as running a stage 0 std step (even though stage 0 std no longer exists) and running the Rustc stage 0 -> 1 step twice, once with a single crates, once with all rustc crates. So I think that even with this single step, there will be a bunch of things to fix in the near future...

The way we currently prepare the Config test fixtures is far from ideal, this is something I think ``@Shourya742`` could work on as a part of their GSoC project (remove as much command execution from Config construction as possible, actually run bootstrap on a temporary directory instead of running it on the rustc checkout, create a Builder-like API for creating the Config test fixtures).

r? ``@jieyouxu``
rust-timer added a commit that referenced this pull request Jun 16, 2025
Rollup merge of #142431 - Kobzol:bootstrap-snapshot-tests, r=jieyouxu

Add initial version of snapshot tests to bootstrap

When making any changes to bootstrap (steps), it is very difficult to realize how does it affect various common bootstrap commands, and if everything still works as we expect it to. We are far away from having actual end-to-end tests, but what we could at least do is have a way of testing what steps does bootstrap execute in dry run mode. Now, we already have something like this in `src/bootstrap/src/core/builder/tests.rs`, however that is quite limited, because it only checks executed steps for a specific impl of `Step` and it does not consider step order.

Recently, when working on what I thought was one of the simplest possible step untanglings in bootstrap (#142357), I ran into errors in tests that were quite hard to debug. Partly also because the current staging test diffs are multiline and use `Debug` output, so it's quite difficult for me to make sense of them.

In this PR, I introduce `insta`, which allows writing snapshot tests in a very simple way. With it, I want to allow writing tests that will clearly show us what is going on during bootstrap execution, and then write golden tests for `build/check/test` stage `0/1/2` for compiler/std/tools etc., to make sure that we don't regress something, and also to help with [#t-infra/bootstrap > Proposal to cleanup stages and steps after the redesign](https://rust-lang.zulipchat.com/#narrow/channel/326414-t-infra.2Fbootstrap/topic/Proposal.20to.20cleanup.20stages.20and.20steps.20after.20the.20redesign/with/523488806), to help avoid a situation where we would (again) have to make a flurry of staging changes because of unexpected consequences.

In the snapshot tests, we currently render the build of rustc, std and LLVM. Currently I render the executed steps using downcasting, which is not super pretty, but it allows us to make the test rendering localized in one place, and it's IMO enough for now.

I implemented only a single test using the new machinery. Maybe if you take a look at it, you will understand why 😆 Bootstrap currently does some peculiar things, such as running a stage 0 std step (even though stage 0 std no longer exists) and running the Rustc stage 0 -> 1 step twice, once with a single crates, once with all rustc crates. So I think that even with this single step, there will be a bunch of things to fix in the near future...

The way we currently prepare the Config test fixtures is far from ideal, this is something I think ``@Shourya742`` could work on as a part of their GSoC project (remove as much command execution from Config construction as possible, actually run bootstrap on a temporary directory instead of running it on the rustc checkout, create a Builder-like API for creating the Config test fixtures).

r? ``@jieyouxu``
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Jun 17, 2025
Add initial version of snapshot tests to bootstrap

When making any changes to bootstrap (steps), it is very difficult to realize how does it affect various common bootstrap commands, and if everything still works as we expect it to. We are far away from having actual end-to-end tests, but what we could at least do is have a way of testing what steps does bootstrap execute in dry run mode. Now, we already have something like this in `src/bootstrap/src/core/builder/tests.rs`, however that is quite limited, because it only checks executed steps for a specific impl of `Step` and it does not consider step order.

Recently, when working on what I thought was one of the simplest possible step untanglings in bootstrap (rust-lang/rust#142357), I ran into errors in tests that were quite hard to debug. Partly also because the current staging test diffs are multiline and use `Debug` output, so it's quite difficult for me to make sense of them.

In this PR, I introduce `insta`, which allows writing snapshot tests in a very simple way. With it, I want to allow writing tests that will clearly show us what is going on during bootstrap execution, and then write golden tests for `build/check/test` stage `0/1/2` for compiler/std/tools etc., to make sure that we don't regress something, and also to help with [#t-infra/bootstrap > Proposal to cleanup stages and steps after the redesign](https://rust-lang.zulipchat.com/#narrow/channel/326414-t-infra.2Fbootstrap/topic/Proposal.20to.20cleanup.20stages.20and.20steps.20after.20the.20redesign/with/523488806), to help avoid a situation where we would (again) have to make a flurry of staging changes because of unexpected consequences.

In the snapshot tests, we currently render the build of rustc, std and LLVM. Currently I render the executed steps using downcasting, which is not super pretty, but it allows us to make the test rendering localized in one place, and it's IMO enough for now.

I implemented only a single test using the new machinery. Maybe if you take a look at it, you will understand why 😆 Bootstrap currently does some peculiar things, such as running a stage 0 std step (even though stage 0 std no longer exists) and running the Rustc stage 0 -> 1 step twice, once with a single crates, once with all rustc crates. So I think that even with this single step, there will be a bunch of things to fix in the near future...

The way we currently prepare the Config test fixtures is far from ideal, this is something I think ``@Shourya742`` could work on as a part of their GSoC project (remove as much command execution from Config construction as possible, actually run bootstrap on a temporary directory instead of running it on the rustc checkout, create a Builder-like API for creating the Config test fixtures).

r? ``@jieyouxu``
Kobzol added 4 commits July 8, 2025 11:39
That step should be responsible for building the tool, not performing side-effects. Also, only copy the tool to the `self-contained` directory, not to the `rustlib/<target>/bin` directory.
@Kobzol Kobzol force-pushed the simplify-llvm-bitcode-linker branch from 769f984 to b14323a Compare July 8, 2025 09:49
@Kobzol Kobzol changed the title Simplify LLVM bitcode linker in bootstrap Simplify LLVM bitcode linker in bootstrap and add tests for it Jul 8, 2025
@Kobzol Kobzol marked this pull request as ready for review July 8, 2025 09:49
@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jul 8, 2025
@Kobzol
Copy link
Member Author

Kobzol commented Jul 8, 2025

I nerfed this PR to only add tests and do some light cleanup, without the stage changes.

@jieyouxu
Copy link
Member

jieyouxu commented Jul 8, 2025

What? Why is my review "outdated" 😓

@Kobzol Kobzol removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Jul 8, 2025
@jieyouxu
Copy link
Member

jieyouxu commented Jul 8, 2025

Thanks, you can r=me after PR CI is green.

@Kobzol
Copy link
Member Author

Kobzol commented Jul 8, 2025

@bors r=jieyouxu

@bors
Copy link
Collaborator

bors commented Jul 8, 2025

📌 Commit 961bac0 has been approved by jieyouxu

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 8, 2025
bors added a commit that referenced this pull request Jul 9, 2025
Rollup of 9 pull requests

Successful merges:

 - #142357 (Simplify LLVM bitcode linker in bootstrap and add tests for it)
 - #143177 (Remove false label when `self` resolve failure does not relate to macro)
 - #143339 (Respect endianness correctly in CheckEnums test suite)
 - #143426 (clippy fix: indentation)
 - #143475 (tests: Use `cfg_target_has_reliable_f16_f128` in `conv-bits-runtime-const`)
 - #143499 (Don't call `predicates_of` on a dummy obligation cause's body id)
 - #143520 (Fix perf regression caused by tracing)
 - #143532 (More carefully consider span context when suggesting remove `&mut`)
 - #143606 (configure.py: Write last key in each section)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit d069a7c into rust-lang:master Jul 9, 2025
11 checks passed
@rustbot rustbot added this to the 1.90.0 milestone Jul 9, 2025
@Kobzol Kobzol deleted the simplify-llvm-bitcode-linker branch July 9, 2025 09:45
rust-timer added a commit that referenced this pull request Jul 9, 2025
Rollup merge of #142357 - Kobzol:simplify-llvm-bitcode-linker, r=jieyouxu

Simplify LLVM bitcode linker in bootstrap and add tests for it

This PR tries to simplify the `LlvmBitcodeLinker` step a little bit, and add tests for it. It also adds tests for `LldWrapper`.

r? `@jieyouxu`
github-actions bot pushed a commit to devnexen/miri that referenced this pull request Jul 10, 2025
Rollup of 9 pull requests

Successful merges:

 - rust-lang/rust#142357 (Simplify LLVM bitcode linker in bootstrap and add tests for it)
 - rust-lang/rust#143177 (Remove false label when `self` resolve failure does not relate to macro)
 - rust-lang/rust#143339 (Respect endianness correctly in CheckEnums test suite)
 - rust-lang/rust#143426 (clippy fix: indentation)
 - rust-lang/rust#143475 (tests: Use `cfg_target_has_reliable_f16_f128` in `conv-bits-runtime-const`)
 - rust-lang/rust#143499 (Don't call `predicates_of` on a dummy obligation cause's body id)
 - rust-lang/rust#143520 (Fix perf regression caused by tracing)
 - rust-lang/rust#143532 (More carefully consider span context when suggesting remove `&mut`)
 - rust-lang/rust#143606 (configure.py: Write last key in each section)

r? `@ghost`
`@rustbot` modify labels: rollup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants