Fix handling of std crates for no_std targets
This commit is contained in:
parent
5880a3196b
commit
d6bc881afb
3 changed files with 106 additions and 41 deletions
|
|
@ -449,21 +449,24 @@ fn copy_self_contained_objects(
|
|||
target_deps
|
||||
}
|
||||
|
||||
/// Resolves standard library crates for `Std::run_make` for any build kind (like check, build, clippy, etc.).
|
||||
/// Resolves standard library crates for `Std::run_make` for any build kind (like check, doc,
|
||||
/// build, clippy, etc.).
|
||||
pub fn std_crates_for_run_make(run: &RunConfig<'_>) -> Vec<String> {
|
||||
let has_alias = run.paths.iter().any(|set| set.assert_single_path().path.ends_with("library"));
|
||||
let target_is_no_std = run.builder.no_std(run.target).unwrap_or(false);
|
||||
let mut crates = run.make_run_crates(builder::Alias::Library);
|
||||
|
||||
// For no_std targets, do not add any additional crates to the compilation other than what `compile::std_cargo` already adds for no_std targets.
|
||||
// For no_std targets, we only want to check core and alloc
|
||||
// Regardless of core/alloc being selected explicitly or via the "library" default alias,
|
||||
// we only want to keep these two crates.
|
||||
// The set of no_std crates should be kept in sync with what `Builder::std_cargo` does.
|
||||
// Note: an alternative design would be to return an enum from this function (Default vs Subset)
|
||||
// of crates. However, several steps currently pass `-p <package>` even if all crates are
|
||||
// selected, because Cargo behaves differently in that case. To keep that behavior without
|
||||
// making further changes, we pre-filter the no-std crates here.
|
||||
let target_is_no_std = run.builder.no_std(run.target).unwrap_or(false);
|
||||
if target_is_no_std {
|
||||
vec![]
|
||||
}
|
||||
// If the paths include "library", build the entire standard library.
|
||||
else if has_alias {
|
||||
run.make_run_crates(builder::Alias::Library)
|
||||
} else {
|
||||
run.cargo_crates_in_set()
|
||||
crates.retain(|c| c == "core" || c == "alloc");
|
||||
}
|
||||
crates
|
||||
}
|
||||
|
||||
/// Tries to find LLVM's `compiler-rt` source directory, for building `library/profiler_builtins`.
|
||||
|
|
|
|||
|
|
@ -637,8 +637,8 @@ mod snapshot {
|
|||
|
||||
use crate::core::build_steps::{compile, dist, doc, test, tool};
|
||||
use crate::core::builder::tests::{
|
||||
TEST_TRIPLE_1, TEST_TRIPLE_2, TEST_TRIPLE_3, configure, configure_with_args, first,
|
||||
host_target, render_steps, run_build,
|
||||
RenderConfig, TEST_TRIPLE_1, TEST_TRIPLE_2, TEST_TRIPLE_3, configure, configure_with_args,
|
||||
first, host_target, render_steps, run_build,
|
||||
};
|
||||
use crate::core::builder::{Builder, Kind, StepDescription, StepMetadata};
|
||||
use crate::core::config::TargetSelection;
|
||||
|
|
@ -1521,6 +1521,49 @@ mod snapshot {
|
|||
steps.assert_contains(StepMetadata::test("CrateLibrustc", host));
|
||||
steps.assert_contains_fuzzy(StepMetadata::build("rustc", host));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn doc_library() {
|
||||
let ctx = TestCtx::new();
|
||||
insta::assert_snapshot!(
|
||||
ctx.config("doc")
|
||||
.path("library")
|
||||
.render_steps(), @r"
|
||||
[build] llvm <host>
|
||||
[build] rustc 0 <host> -> rustc 1 <host>
|
||||
[build] rustdoc 0 <host>
|
||||
[doc] std 1 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind]
|
||||
");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn doc_core() {
|
||||
let ctx = TestCtx::new();
|
||||
insta::assert_snapshot!(
|
||||
ctx.config("doc")
|
||||
.path("core")
|
||||
.render_steps(), @r"
|
||||
[build] llvm <host>
|
||||
[build] rustc 0 <host> -> rustc 1 <host>
|
||||
[build] rustdoc 0 <host>
|
||||
[doc] std 1 <host> crates=[core]
|
||||
");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn doc_library_no_std_target() {
|
||||
let ctx = TestCtx::new();
|
||||
insta::assert_snapshot!(
|
||||
ctx.config("doc")
|
||||
.path("core")
|
||||
.override_target_no_std(&host_target())
|
||||
.render_steps(), @r"
|
||||
[build] llvm <host>
|
||||
[build] rustc 0 <host> -> rustc 1 <host>
|
||||
[build] rustdoc 0 <host>
|
||||
[doc] std 1 <host> crates=[core]
|
||||
");
|
||||
}
|
||||
}
|
||||
|
||||
struct ExecutedSteps {
|
||||
|
|
@ -1529,7 +1572,10 @@ struct ExecutedSteps {
|
|||
|
||||
impl ExecutedSteps {
|
||||
fn render(&self) -> String {
|
||||
render_steps(&self.steps)
|
||||
self.render_with(RenderConfig::default())
|
||||
}
|
||||
fn render_with(&self, config: RenderConfig) -> String {
|
||||
render_steps(&self.steps, config)
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
|
|
@ -1538,7 +1584,7 @@ impl ExecutedSteps {
|
|||
if !self.contains(&metadata) {
|
||||
panic!(
|
||||
"Metadata `{}` ({metadata:?}) not found in executed steps:\n{}",
|
||||
render_metadata(&metadata),
|
||||
render_metadata(&metadata, &RenderConfig::default()),
|
||||
self.render()
|
||||
);
|
||||
}
|
||||
|
|
@ -1553,7 +1599,7 @@ impl ExecutedSteps {
|
|||
if !self.contains_fuzzy(&metadata) {
|
||||
panic!(
|
||||
"Metadata `{}` ({metadata:?}) not found in executed steps:\n{}",
|
||||
render_metadata(&metadata),
|
||||
render_metadata(&metadata, &RenderConfig::default()),
|
||||
self.render()
|
||||
);
|
||||
}
|
||||
|
|
@ -1565,7 +1611,7 @@ impl ExecutedSteps {
|
|||
if self.contains(&metadata) {
|
||||
panic!(
|
||||
"Metadata `{}` ({metadata:?}) found in executed steps (it should not be there):\n{}",
|
||||
render_metadata(&metadata),
|
||||
render_metadata(&metadata, &RenderConfig::default()),
|
||||
self.render()
|
||||
);
|
||||
}
|
||||
|
|
@ -1618,6 +1664,16 @@ impl ConfigBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
struct RenderConfig {
|
||||
normalize_host: bool,
|
||||
}
|
||||
|
||||
impl Default for RenderConfig {
|
||||
fn default() -> Self {
|
||||
Self { normalize_host: true }
|
||||
}
|
||||
}
|
||||
|
||||
/// Renders the executed bootstrap steps for usage in snapshot tests with insta.
|
||||
/// Only renders certain important steps.
|
||||
/// Each value in `steps` should be a tuple of (Step, step output).
|
||||
|
|
@ -1625,7 +1681,7 @@ impl ConfigBuilder {
|
|||
/// The arrow in the rendered output (`X -> Y`) means `X builds Y`.
|
||||
/// This is similar to the output printed by bootstrap to stdout, but here it is
|
||||
/// generated purely for the purpose of tests.
|
||||
fn render_steps(steps: &[ExecutedStep]) -> String {
|
||||
fn render_steps(steps: &[ExecutedStep], config: RenderConfig) -> String {
|
||||
steps
|
||||
.iter()
|
||||
.filter_map(|step| {
|
||||
|
|
@ -1635,35 +1691,35 @@ fn render_steps(steps: &[ExecutedStep]) -> String {
|
|||
return None;
|
||||
};
|
||||
|
||||
Some(render_metadata(&metadata))
|
||||
Some(render_metadata(&metadata, &config))
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n")
|
||||
}
|
||||
|
||||
fn render_metadata(metadata: &StepMetadata) -> String {
|
||||
fn render_metadata(metadata: &StepMetadata, config: &RenderConfig) -> String {
|
||||
let mut record = format!("[{}] ", metadata.kind.as_str());
|
||||
if let Some(compiler) = metadata.built_by {
|
||||
write!(record, "{} -> ", render_compiler(compiler));
|
||||
write!(record, "{} -> ", render_compiler(compiler, config));
|
||||
}
|
||||
let stage = metadata.get_stage().map(|stage| format!("{stage} ")).unwrap_or_default();
|
||||
write!(record, "{} {stage}<{}>", metadata.name, normalize_target(metadata.target));
|
||||
write!(record, "{} {stage}<{}>", metadata.name, normalize_target(metadata.target, config));
|
||||
if let Some(metadata) = &metadata.metadata {
|
||||
write!(record, " {metadata}");
|
||||
}
|
||||
record
|
||||
}
|
||||
|
||||
fn normalize_target(target: TargetSelection) -> String {
|
||||
target
|
||||
.to_string()
|
||||
.replace(&host_target(), "host")
|
||||
.replace(TEST_TRIPLE_1, "target1")
|
||||
.replace(TEST_TRIPLE_2, "target2")
|
||||
fn normalize_target(target: TargetSelection, config: &RenderConfig) -> String {
|
||||
let mut target = target.to_string();
|
||||
if config.normalize_host {
|
||||
target = target.replace(&host_target(), "host");
|
||||
}
|
||||
target.replace(TEST_TRIPLE_1, "target1").replace(TEST_TRIPLE_2, "target2")
|
||||
}
|
||||
|
||||
fn render_compiler(compiler: Compiler) -> String {
|
||||
format!("rustc {} <{}>", compiler.stage, normalize_target(compiler.host))
|
||||
fn render_compiler(compiler: Compiler, config: &RenderConfig) -> String {
|
||||
format!("rustc {} <{}>", compiler.stage, normalize_target(compiler.host, config))
|
||||
}
|
||||
|
||||
fn host_target() -> String {
|
||||
|
|
|
|||
|
|
@ -48,17 +48,30 @@ impl ConfigBuilder {
|
|||
}
|
||||
|
||||
pub fn path(mut self, path: &str) -> Self {
|
||||
self.args.push(path.to_string());
|
||||
self
|
||||
self.arg(path)
|
||||
}
|
||||
|
||||
pub fn paths(mut self, paths: &[&str]) -> Self {
|
||||
for path in paths {
|
||||
self = self.path(path);
|
||||
self.args(paths)
|
||||
}
|
||||
|
||||
pub fn arg(mut self, arg: &str) -> Self {
|
||||
self.args.push(arg.to_string());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn args(mut self, args: &[&str]) -> Self {
|
||||
for arg in args {
|
||||
self = self.arg(arg);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the specified target to be treated as a no_std target.
|
||||
pub fn override_target_no_std(mut self, target: &str) -> Self {
|
||||
self.args(&["--set", &format!("target.{target}.no-std=true")])
|
||||
}
|
||||
|
||||
pub fn hosts(mut self, targets: &[&str]) -> Self {
|
||||
self.args.push("--host".to_string());
|
||||
self.args.push(targets.join(","));
|
||||
|
|
@ -77,13 +90,6 @@ impl ConfigBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn args(mut self, args: &[&str]) -> Self {
|
||||
for arg in args {
|
||||
self.args.push(arg.to_string());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn create_config(mut self) -> Config {
|
||||
// Run in dry-check, otherwise the test would be too slow
|
||||
self.args.push("--dry-run".to_string());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue