Skip to content

use cargo rustc for macro expansion so -Zbuild-std can be supported#5214

Open
skrap wants to merge 3 commits into
rust-lang:mainfrom
skrap:bugfix/allow-zbuild-std-macro-expansion
Open

use cargo rustc for macro expansion so -Zbuild-std can be supported#5214
skrap wants to merge 3 commits into
rust-lang:mainfrom
skrap:bugfix/allow-zbuild-std-macro-expansion

Conversation

@skrap

@skrap skrap commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Description

Address #5204 by invoking macro expansion through cargo rustc instead of rustc directly. This allows the use of the -Zbuild-std flag, enabling targets without a prebuilt std (e.g. tier 3 targets) to build the libc tests.

Checklist

  • Relevant tests in libc-test/semver have been updated
  • No placeholder or unstable values like *LAST or *MAX are
    included (see #3131)
  • Tested locally (cd libc-test && cargo test --target mytarget);
    especially relevant for platforms that may not be checked in CI

@rustbot rustbot added ctest Issues relating to the ctest crate S-waiting-on-review labels Jun 24, 2026
@skrap skrap force-pushed the bugfix/allow-zbuild-std-macro-expansion branch 4 times, most recently from 0689c20 to b5da051 Compare June 24, 2026 18:34
Comment thread ctest/src/macro_expansion.rs Outdated
@tgross35

Copy link
Copy Markdown
Contributor

Cc @mbyx for ctest

@tgross35 tgross35 added the stable-unneeded This PR is applied to main but already exists on libc-0.2 label Jun 24, 2026
@skrap skrap force-pushed the bugfix/allow-zbuild-std-macro-expansion branch from b5da051 to 1100563 Compare June 24, 2026 19:18
Comment thread ctest/src/macro_expansion.rs
Comment thread ctest/src/macro_expansion.rs Outdated
Comment thread ctest/src/macro_expansion.rs Outdated
.arg("--edition")
.arg(EDITION) // By default, -Zunpretty=expanded uses 2015 edition.
.arg(canonicalize(crate_path)?);
.env("RUSTFLAGS", "") // ignore RUSTFLAGS so we don't get -Dwarnings

@tgross35 tgross35 Jun 24, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Add a TestGenerator::expansion_rustflags(&str) and set RUSTFLAGS only if that has been called, otherwise just let it inherit. Since there might be some global options needed to build.

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We were not building with inherited RUSTFLAGS before this change, as RUSTFLAGS are a cargo-ism, and we were not using cargo before, but rather using rustc directly.

I think I will be a bit more tactical and just add a -Awarnings at the end of RUSTFLAGS so we don't error out over warnings if -Dwarnings is present. No new API required, and should be compatible with existing clients.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Fair point about compatibility! We probably shouldn't suppress warnings though, there could be some papercuts.

I think it might be best to leave exact env up to the user, since sometimes build scripts pick up other env that you may want to control. So perhaps:

impl TestGenerator {
    fn expansion_env(&mut self, k: impl AsRef<OsStr>, v: impl AsRef<OsStr>) -> &mut Self;
    fn expansion_env_clear(&mut self) -> &mut Self;
}

Then call cmd.env_clear().env(expansion_env) on the Command.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

But to what end? This is adding API surface which no crate user has asked for, and it might or might not be the correct thing. The previous code would emit warnings into /dev/null and then move on, and I think we should retain that behavior until some motivated person comes along to ask for it to change.

I would prefer we stick to the goal of this PR which is to enable tier 3 folks like me to build libc, and this API is beyond that goal.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If just calling .env_clear() works then I'm fine with that and no new API. But I don't want to hardcode any RUSTFLAGS - if those need to be adjusted then we should go with the suggested API.

We should give users a chance to catch anything warnings that happen during expansion in case it's due to the config they're providing. Macro expansion can be env-dependent as well.

Comment thread ctest/src/macro_expansion.rs Outdated
Comment thread ctest/src/macro_expansion.rs Outdated
Comment thread ctest/src/macro_expansion.rs
@rustbot

rustbot commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

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

@skrap skrap force-pushed the bugfix/allow-zbuild-std-macro-expansion branch from bef315b to af836b6 Compare July 1, 2026 03:16
@rustbot

This comment has been minimized.

@skrap

skrap commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

@rustbot review

I think I have addressed the feedback, though in exploring the changes I sometimes made some different choices. I've left comments in the conversations where appropriate.

Comment thread ctest/src/generator.rs Outdated
Comment on lines +728 to +733
/// Configures any extra arguments which to be passed to cargo
/// during macro expansion. This can be used, for example, to pass
/// -Zbuild-std if required.
pub fn set_macro_expansion_cargo_args(&mut self, args: Vec<String>) {
self.macro_expansion_cargo_args = args;
}

@tgross35 tgross35 Jul 1, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

To keep things a bit more composable so you can set args one at a time, replace this with fn expansion_cargo_arg(&mut self, &str) and fn clear_expansion_cargo_args(&mut self).

Also these methods should return &mut Self

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Curious why we would need a clear(). Why would a crate user add arguments only to remove them? Again I find myself concerned about increasing the API surface without a clear use case.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Any kind of pattern that sets defaults then clears them, so you can just use store the args in the TestGenerator rather than tracking them separately. Not likely to be used a lot: it's just the sort of thing that's pretty easy to add now, but more likely to be worked around than added in the future.

Rather than clear, something like expansion_cargo_args_mut(&mut self) -> &mut Vec<String> would be fine too for more flexibility.

Comment thread ctest/src/generator.rs Outdated
Comment thread ctest/src/generator.rs
Comment thread ctest/src/generator.rs Outdated
Comment thread ctest/src/macro_expansion.rs Outdated
Comment thread ctest/src/macro_expansion.rs
Comment thread ctest/src/macro_expansion.rs Outdated
Comment thread ctest/Cargo.toml Outdated
Comment thread ctest/src/macro_expansion.rs Outdated
.arg("--edition")
.arg(EDITION) // By default, -Zunpretty=expanded uses 2015 edition.
.arg(canonicalize(crate_path)?);
.env("RUSTFLAGS", "") // ignore RUSTFLAGS so we don't get -Dwarnings

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Fair point about compatibility! We probably shouldn't suppress warnings though, there could be some papercuts.

I think it might be best to leave exact env up to the user, since sometimes build scripts pick up other env that you may want to control. So perhaps:

impl TestGenerator {
    fn expansion_env(&mut self, k: impl AsRef<OsStr>, v: impl AsRef<OsStr>) -> &mut Self;
    fn expansion_env_clear(&mut self) -> &mut Self;
}

Then call cmd.env_clear().env(expansion_env) on the Command.

@skrap skrap force-pushed the bugfix/allow-zbuild-std-macro-expansion branch from 3294988 to 9dd5dd1 Compare July 1, 2026 13:12
@rustbot

This comment has been minimized.

@skrap skrap force-pushed the bugfix/allow-zbuild-std-macro-expansion branch from 9dd5dd1 to ba0cdaa Compare July 1, 2026 15:42
@skrap skrap force-pushed the bugfix/allow-zbuild-std-macro-expansion branch from ba0cdaa to f752fb9 Compare July 1, 2026 15:46
@rustbot

rustbot commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@skrap

skrap commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

@rustbot review

Further review feedback. I'm a bit shy about adding more API than necessary for the stated purpose of the PR. If we have a clear use case for the API proposed, I think that should be proposed in a separate PR.

Comment thread ctest/src/generator.rs
Comment on lines +737 to +740
/// Configures the crate name which should be used during macro expansion.
/// If the tested crate uses `#![crate_name = "..."]`, this must be called with the
/// same name. Otherwise, there will be an error about `--crate-name` not
/// matching.

@tgross35 tgross35 Jul 2, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// Configures the crate name which should be used during macro expansion.
/// If the tested crate uses `#![crate_name = "..."]`, this must be called with the
/// same name. Otherwise, there will be an error about `--crate-name` not
/// matching.
/// Configures the crate name which should be used during macro expansion.
///
/// If the tested crate uses `#![crate_name = "..."]`, this must be called with the
/// same name. Otherwise, there will be an error about `--crate-name` not
/// matching.

so rustdoc doesn't mush into the summary

View changes since the review

Comment thread ctest/src/generator.rs Outdated
Comment on lines +728 to +733
/// Configures any extra arguments which to be passed to cargo
/// during macro expansion. This can be used, for example, to pass
/// -Zbuild-std if required.
pub fn set_macro_expansion_cargo_args(&mut self, args: Vec<String>) {
self.macro_expansion_cargo_args = args;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Any kind of pattern that sets defaults then clears them, so you can just use store the args in the TestGenerator rather than tracking them separately. Not likely to be used a lot: it's just the sort of thing that's pretty easy to add now, but more likely to be worked around than added in the future.

Rather than clear, something like expansion_cargo_args_mut(&mut self) -> &mut Vec<String> would be fine too for more flexibility.

Comment thread ctest/src/macro_expansion.rs Outdated
.arg("--edition")
.arg(EDITION) // By default, -Zunpretty=expanded uses 2015 edition.
.arg(canonicalize(crate_path)?);
.env("RUSTFLAGS", "") // ignore RUSTFLAGS so we don't get -Dwarnings

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If just calling .env_clear() works then I'm fine with that and no new API. But I don't want to hardcode any RUSTFLAGS - if those need to be adjusted then we should go with the suggested API.

We should give users a chance to catch anything warnings that happen during expansion in case it's due to the config they're providing. Macro expansion can be env-dependent as well.

@tgross35 tgross35 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just updating the status here.

Also, regarding the general concern about API surface area: don't worry about it :) as long as it's somewhat sane, for ctest I tend to err on the side of adding small things we might need while related code is already being modified, rather than leaving a gap that might need ctest-specific changes in the future. There might be somebody who appreciates it even if libc doesn't have an immediate use.

View changes since this review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ctest Issues relating to the ctest crate S-waiting-on-author stable-unneeded This PR is applied to main but already exists on libc-0.2

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants