about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-09-22 06:02:21 +0000
committerbors <bors@rust-lang.org>2020-09-22 06:02:21 +0000
commit44ae0b8b2def2a26b82e0a93f8c8c2c523cc3643 (patch)
tree29a2bd0e86208b0aa2e192c45c2bd74d76b53209
parentc2bc344eb23d8c1d18e803b3f1e631cf99926fbb (diff)
parent363aff0a9d0b85285b7501cb04dd8263d29d273a (diff)
downloadrust-44ae0b8b2def2a26b82e0a93f8c8c2c523cc3643.tar.gz
rust-44ae0b8b2def2a26b82e0a93f8c8c2c523cc3643.zip
Auto merge of #76799 - Mark-Simulacrum:fix-cross-compile-dist, r=alexcrichton
Fix cross compiling dist/build invocations

I am uncertain why the first commit is not affecting CI. I suspect it's because we pass --disable-docs on most of our cross-compilation builders. The second commit doesn't affect CI because CI runs x.py dist, not x.py build.

Both commits are standalone; together they should resolve #76733. The first commit doesn't really fix that issue but rather just fixes cross-compiled x.py dist, resolving a bug introduced in #76549.
-rw-r--r--src/bootstrap/builder/tests.rs48
-rw-r--r--src/bootstrap/doc.rs4
-rw-r--r--src/bootstrap/tool.rs6
-rw-r--r--src/tools/lint-docs/src/groups.rs8
-rw-r--r--src/tools/lint-docs/src/lib.rs25
-rw-r--r--src/tools/lint-docs/src/main.rs15
6 files changed, 90 insertions, 16 deletions
diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs
index cd90021507e..4a9082d3e85 100644
--- a/src/bootstrap/builder/tests.rs
+++ b/src/bootstrap/builder/tests.rs
@@ -94,6 +94,54 @@ mod defaults {
     }
 
     #[test]
+    fn build_cross_compile() {
+        let config = Config { stage: 1, ..configure("build", &["B"], &["B"]) };
+        let build = Build::new(config);
+        let mut builder = Builder::new(&build);
+        builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]);
+
+        let a = TargetSelection::from_user("A");
+        let b = TargetSelection::from_user("B");
+
+        // Ideally, this build wouldn't actually have `target: a`
+        // rustdoc/rustcc/std here (the user only requested a host=B build, so
+        // there's not really a need for us to build for target A in this case
+        // (since we're producing stage 1 libraries/binaries).  But currently
+        // rustbuild is just a bit buggy here; this should be fixed though.
+        assert_eq!(
+            first(builder.cache.all::<compile::Std>()),
+            &[
+                compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },
+                compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
+                compile::Std { compiler: Compiler { host: a, stage: 0 }, target: b },
+                compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
+            ]
+        );
+        assert_eq!(
+            first(builder.cache.all::<compile::Assemble>()),
+            &[
+                compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } },
+                compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } },
+                compile::Assemble { target_compiler: Compiler { host: b, stage: 1 } },
+            ]
+        );
+        assert_eq!(
+            first(builder.cache.all::<tool::Rustdoc>()),
+            &[
+                tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } },
+                tool::Rustdoc { compiler: Compiler { host: b, stage: 1 } },
+            ],
+        );
+        assert_eq!(
+            first(builder.cache.all::<compile::Rustc>()),
+            &[
+                compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a },
+                compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: b },
+            ]
+        );
+    }
+
+    #[test]
     fn doc_default() {
         let mut config = configure("doc", &[], &[]);
         config.compiler_docs = true;
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 97f32b61fb9..aa670bd9a2e 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -752,6 +752,7 @@ impl Step for RustcBook {
         let out_listing = out_base.join("src/lints");
         builder.cp_r(&builder.src.join("src/doc/rustc"), &out_base);
         builder.info(&format!("Generating lint docs ({})", self.target));
+
         let rustc = builder.rustc(self.compiler);
         // The tool runs `rustc` for extracting output examples, so it needs a
         // functional sysroot.
@@ -762,7 +763,8 @@ impl Step for RustcBook {
         cmd.arg("--out");
         cmd.arg(&out_listing);
         cmd.arg("--rustc");
-        cmd.arg(rustc);
+        cmd.arg(&rustc);
+        cmd.arg("--rustc-target").arg(&self.target.rustc_target_arg());
         if builder.config.verbose() {
             cmd.arg("--verbose");
         }
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index 460dffb5c8a..290e3744852 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -470,7 +470,11 @@ impl Step for Rustdoc {
 
     fn make_run(run: RunConfig<'_>) {
         run.builder.ensure(Rustdoc {
-            compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
+            // Note: this is somewhat unique in that we actually want a *target*
+            // compiler here, because rustdoc *is* a compiler. We won't be using
+            // this as the compiler to build with, but rather this is "what
+            // compiler are we producing"?
+            compiler: run.builder.compiler(run.builder.top_stage, run.target),
         });
     }
 
diff --git a/src/tools/lint-docs/src/groups.rs b/src/tools/lint-docs/src/groups.rs
index a212459bb4d..6b32ebdc284 100644
--- a/src/tools/lint-docs/src/groups.rs
+++ b/src/tools/lint-docs/src/groups.rs
@@ -18,10 +18,10 @@ static GROUP_DESCRIPTIONS: &[(&str, &str)] = &[
 /// Updates the documentation of lint groups.
 pub(crate) fn generate_group_docs(
     lints: &[Lint],
-    rustc_path: &Path,
+    rustc: crate::Rustc<'_>,
     out_path: &Path,
 ) -> Result<(), Box<dyn Error>> {
-    let groups = collect_groups(rustc_path)?;
+    let groups = collect_groups(rustc)?;
     let groups_path = out_path.join("groups.md");
     let contents = fs::read_to_string(&groups_path)
         .map_err(|e| format!("could not read {}: {}", groups_path.display(), e))?;
@@ -36,9 +36,9 @@ pub(crate) fn generate_group_docs(
 type LintGroups = BTreeMap<String, BTreeSet<String>>;
 
 /// Collects the group names from rustc.
-fn collect_groups(rustc: &Path) -> Result<LintGroups, Box<dyn Error>> {
+fn collect_groups(rustc: crate::Rustc<'_>) -> Result<LintGroups, Box<dyn Error>> {
     let mut result = BTreeMap::new();
-    let mut cmd = Command::new(rustc);
+    let mut cmd = Command::new(rustc.path);
     cmd.arg("-Whelp");
     let output = cmd.output().map_err(|e| format!("failed to run command {:?}\n{}", cmd, e))?;
     if !output.status.success() {
diff --git a/src/tools/lint-docs/src/lib.rs b/src/tools/lint-docs/src/lib.rs
index 92b3d186fa1..6ca71dcaf3c 100644
--- a/src/tools/lint-docs/src/lib.rs
+++ b/src/tools/lint-docs/src/lib.rs
@@ -45,16 +45,22 @@ impl Level {
     }
 }
 
+#[derive(Copy, Clone)]
+pub struct Rustc<'a> {
+    pub path: &'a Path,
+    pub target: &'a str,
+}
+
 /// Collects all lints, and writes the markdown documentation at the given directory.
 pub fn extract_lint_docs(
     src_path: &Path,
     out_path: &Path,
-    rustc_path: &Path,
+    rustc: Rustc<'_>,
     verbose: bool,
 ) -> Result<(), Box<dyn Error>> {
     let mut lints = gather_lints(src_path)?;
     for lint in &mut lints {
-        generate_output_example(lint, rustc_path, verbose).map_err(|e| {
+        generate_output_example(lint, rustc, verbose).map_err(|e| {
             format!(
                 "failed to test example in lint docs for `{}` in {}:{}: {}",
                 lint.name,
@@ -65,7 +71,7 @@ pub fn extract_lint_docs(
         })?;
     }
     save_lints_markdown(&lints, &out_path.join("listing"))?;
-    groups::generate_group_docs(&lints, rustc_path, out_path)?;
+    groups::generate_group_docs(&lints, rustc, out_path)?;
     Ok(())
 }
 
@@ -208,7 +214,7 @@ fn lint_name(line: &str) -> Result<String, &'static str> {
 /// actual output from the compiler.
 fn generate_output_example(
     lint: &mut Lint,
-    rustc_path: &Path,
+    rustc: Rustc<'_>,
     verbose: bool,
 ) -> Result<(), Box<dyn Error>> {
     // Explicit list of lints that are allowed to not have an example. Please
@@ -230,7 +236,7 @@ fn generate_output_example(
     // separate test suite, and use an include mechanism such as mdbook's
     // `{{#rustdoc_include}}`.
     if !lint.is_ignored() {
-        replace_produces(lint, rustc_path, verbose)?;
+        replace_produces(lint, rustc, verbose)?;
     }
     Ok(())
 }
@@ -261,7 +267,7 @@ fn check_style(lint: &Lint) -> Result<(), Box<dyn Error>> {
 /// output from the compiler.
 fn replace_produces(
     lint: &mut Lint,
-    rustc_path: &Path,
+    rustc: Rustc<'_>,
     verbose: bool,
 ) -> Result<(), Box<dyn Error>> {
     let mut lines = lint.doc.iter_mut();
@@ -302,7 +308,7 @@ fn replace_produces(
                 Some(line) if line.is_empty() => {}
                 Some(line) if line == "{{produces}}" => {
                     let output =
-                        generate_lint_output(&lint.name, &example, &options, rustc_path, verbose)?;
+                        generate_lint_output(&lint.name, &example, &options, rustc, verbose)?;
                     line.replace_range(
                         ..,
                         &format!(
@@ -329,7 +335,7 @@ fn generate_lint_output(
     name: &str,
     example: &[&mut String],
     options: &[&str],
-    rustc_path: &Path,
+    rustc: Rustc<'_>,
     verbose: bool,
 ) -> Result<String, Box<dyn Error>> {
     if verbose {
@@ -364,13 +370,14 @@ fn generate_lint_output(
     }
     fs::write(&tempfile, source)
         .map_err(|e| format!("failed to write {}: {}", tempfile.display(), e))?;
-    let mut cmd = Command::new(rustc_path);
+    let mut cmd = Command::new(rustc.path);
     if options.contains(&"edition2015") {
         cmd.arg("--edition=2015");
     } else {
         cmd.arg("--edition=2018");
     }
     cmd.arg("--error-format=json");
+    cmd.arg("--target").arg(rustc.target);
     if options.contains(&"test") {
         cmd.arg("--test");
     }
diff --git a/src/tools/lint-docs/src/main.rs b/src/tools/lint-docs/src/main.rs
index 45d97bd4317..5db49007d37 100644
--- a/src/tools/lint-docs/src/main.rs
+++ b/src/tools/lint-docs/src/main.rs
@@ -13,6 +13,7 @@ fn doit() -> Result<(), Box<dyn Error>> {
     let mut src_path = None;
     let mut out_path = None;
     let mut rustc_path = None;
+    let mut rustc_target = None;
     let mut verbose = false;
     while let Some(arg) = args.next() {
         match arg.as_str() {
@@ -34,6 +35,12 @@ fn doit() -> Result<(), Box<dyn Error>> {
                     None => return Err("--rustc requires a value".into()),
                 };
             }
+            "--rustc-target" => {
+                rustc_target = match args.next() {
+                    Some(s) => Some(s),
+                    None => return Err("--rustc-target requires a value".into()),
+                };
+            }
             "-v" | "--verbose" => verbose = true,
             s => return Err(format!("unexpected argument `{}`", s).into()),
         }
@@ -47,10 +54,16 @@ fn doit() -> Result<(), Box<dyn Error>> {
     if rustc_path.is_none() {
         return Err("--rustc must be specified to the path of rustc".into());
     }
+    if rustc_target.is_none() {
+        return Err("--rustc-target must be specified to the rustc target".into());
+    }
     lint_docs::extract_lint_docs(
         &src_path.unwrap(),
         &out_path.unwrap(),
-        &rustc_path.unwrap(),
+        lint_docs::Rustc {
+            path: rustc_path.as_deref().unwrap(),
+            target: rustc_target.as_deref().unwrap(),
+        },
         verbose,
     )
 }