From 245b589a3a8899233c849e41691381379f509d64 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 28 Mar 2024 10:07:59 +0000 Subject: [PATCH] Move `build_aux` to an inherent method on `BuildManager` --- src/dependencies.rs | 113 ++++++++++++++++++++++++++++++++++++++++++-- src/lib.rs | 101 --------------------------------------- 2 files changed, 109 insertions(+), 105 deletions(-) diff --git a/src/dependencies.rs b/src/dependencies.rs index 7f8e6dcc..fd8c46fa 100644 --- a/src/dependencies.rs +++ b/src/dependencies.rs @@ -1,18 +1,23 @@ +use bstr::ByteSlice; use cargo_metadata::{camino::Utf8PathBuf, DependencyKind}; use cargo_platform::Cfg; use color_eyre::eyre::{bail, eyre, Result}; use std::{ collections::{hash_map::Entry, HashMap, HashSet}, ffi::OsString, - path::PathBuf, + path::{Path, PathBuf}, process::Command, str::FromStr, sync::{Arc, OnceLock, RwLock}, }; use crate::{ - build_aux, status_emitter::StatusEmitter, test_result::Errored, Config, Mode, - OutputConflictHandling, + crate_type, default_per_file_config, + per_test_config::{Comments, TestConfig}, + rustc_stderr, + status_emitter::StatusEmitter, + test_result::Errored, + Config, CrateType, Error, Mode, OutputConflictHandling, }; #[derive(Default, Debug)] @@ -291,7 +296,7 @@ impl<'a> BuildManager<'a> { Err(()) } }, - Build::Aux { aux_file } => match build_aux(aux_file, config, self) { + Build::Aux { aux_file } => match self.build_aux(aux_file, config) { Ok(args) => Ok(args.iter().map(Into::into).collect()), Err(e) => { err = Some(e); @@ -321,4 +326,104 @@ impl<'a> BuildManager<'a> { }) }) } + + fn build_aux( + &self, + aux_file: &Path, + config: &Config, + ) -> std::result::Result, Errored> { + let file_contents = std::fs::read(aux_file).map_err(|err| Errored { + command: Command::new(format!("reading aux file `{}`", aux_file.display())), + errors: vec![], + stderr: err.to_string().into_bytes(), + stdout: vec![], + })?; + let comments = Comments::parse(&file_contents, config.comment_defaults.clone(), aux_file) + .map_err(|errors| Errored::new(errors, "parse aux comments"))?; + assert_eq!( + comments.revisions, None, + "aux builds cannot specify revisions" + ); + + let mut config = config.clone(); + + // Strip any `crate-type` flags from the args, as we need to set our own, + // and they may conflict (e.g. `lib` vs `proc-macro`); + let mut prev_was_crate_type = false; + config.program.args.retain(|arg| { + if prev_was_crate_type { + prev_was_crate_type = false; + return false; + } + if arg == "--test" { + false + } else if arg == "--crate-type" { + prev_was_crate_type = true; + false + } else if let Some(arg) = arg.to_str() { + !arg.starts_with("--crate-type=") + } else { + true + } + }); + + default_per_file_config(&mut config, aux_file, &file_contents); + + match crate_type(&file_contents) { + // Proc macros must be run on the host + CrateType::ProcMacro => config.target = config.host.clone(), + CrateType::Test | CrateType::Bin | CrateType::Lib => {} + } + + let mut config = TestConfig { + config, + revision: "", + comments: &comments, + path: aux_file, + }; + + config.patch_out_dir(); + + let mut aux_cmd = config.build_command()?; + + let mut extra_args = config.build_aux_files(aux_file.parent().unwrap(), self)?; + // Make sure we see our dependencies + aux_cmd.args(extra_args.iter()); + + aux_cmd.arg("--emit=link"); + let filename = aux_file.file_stem().unwrap().to_str().unwrap(); + let output = aux_cmd.output().unwrap(); + if !output.status.success() { + let error = Error::Command { + kind: "compilation of aux build failed".to_string(), + status: output.status, + }; + return Err(Errored { + command: aux_cmd, + errors: vec![error], + stderr: rustc_stderr::process(aux_file, &output.stderr).rendered, + stdout: output.stdout, + }); + } + + // Now run the command again to fetch the output filenames + aux_cmd.arg("--print").arg("file-names"); + let output = aux_cmd.output().unwrap(); + assert!(output.status.success()); + + for file in output.stdout.lines() { + let file = std::str::from_utf8(file).unwrap(); + let crate_name = filename.replace('-', "_"); + let path = config.config.out_dir.join(file); + extra_args.push("--extern".into()); + let mut cname = OsString::from(&crate_name); + cname.push("="); + cname.push(path); + extra_args.push(cname); + // Help cargo find the crates added with `--extern`. + extra_args.push("-L".into()); + extra_args.push(config.config.out_dir.as_os_str().to_os_string()); + } + Ok(extra_args) + } } diff --git a/src/lib.rs b/src/lib.rs index 32b17ae1..b284ab13 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,7 +17,6 @@ use per_test_config::TestConfig; use rustc_stderr::Message; use status_emitter::{StatusEmitter, TestStatus}; use std::collections::VecDeque; -use std::ffi::OsString; use std::num::NonZeroUsize; use std::path::{Component, Path, Prefix}; use std::process::{Command, Output}; @@ -429,106 +428,6 @@ fn parse_and_test_file( .collect()) } -fn build_aux( - aux_file: &Path, - config: &Config, - build_manager: &BuildManager<'_>, -) -> std::result::Result, Errored> { - let file_contents = std::fs::read(aux_file).map_err(|err| Errored { - command: Command::new(format!("reading aux file `{}`", aux_file.display())), - errors: vec![], - stderr: err.to_string().into_bytes(), - stdout: vec![], - })?; - let comments = Comments::parse(&file_contents, config.comment_defaults.clone(), aux_file) - .map_err(|errors| Errored::new(errors, "parse aux comments"))?; - assert_eq!( - comments.revisions, None, - "aux builds cannot specify revisions" - ); - - let mut config = config.clone(); - - // Strip any `crate-type` flags from the args, as we need to set our own, - // and they may conflict (e.g. `lib` vs `proc-macro`); - let mut prev_was_crate_type = false; - config.program.args.retain(|arg| { - if prev_was_crate_type { - prev_was_crate_type = false; - return false; - } - if arg == "--test" { - false - } else if arg == "--crate-type" { - prev_was_crate_type = true; - false - } else if let Some(arg) = arg.to_str() { - !arg.starts_with("--crate-type=") - } else { - true - } - }); - - default_per_file_config(&mut config, aux_file, &file_contents); - - match crate_type(&file_contents) { - // Proc macros must be run on the host - CrateType::ProcMacro => config.target = config.host.clone(), - CrateType::Test | CrateType::Bin | CrateType::Lib => {} - } - - let mut config = TestConfig { - config, - revision: "", - comments: &comments, - path: aux_file, - }; - - config.patch_out_dir(); - - let mut aux_cmd = config.build_command()?; - - let mut extra_args = config.build_aux_files(aux_file.parent().unwrap(), build_manager)?; - // Make sure we see our dependencies - aux_cmd.args(extra_args.iter()); - - aux_cmd.arg("--emit=link"); - let filename = aux_file.file_stem().unwrap().to_str().unwrap(); - let output = aux_cmd.output().unwrap(); - if !output.status.success() { - let error = Error::Command { - kind: "compilation of aux build failed".to_string(), - status: output.status, - }; - return Err(Errored { - command: aux_cmd, - errors: vec![error], - stderr: rustc_stderr::process(aux_file, &output.stderr).rendered, - stdout: output.stdout, - }); - } - - // Now run the command again to fetch the output filenames - aux_cmd.arg("--print").arg("file-names"); - let output = aux_cmd.output().unwrap(); - assert!(output.status.success()); - - for file in output.stdout.lines() { - let file = std::str::from_utf8(file).unwrap(); - let crate_name = filename.replace('-', "_"); - let path = config.config.out_dir.join(file); - extra_args.push("--extern".into()); - let mut cname = OsString::from(&crate_name); - cname.push("="); - cname.push(path); - extra_args.push(cname); - // Help cargo find the crates added with `--extern`. - extra_args.push("-L".into()); - extra_args.push(config.config.out_dir.as_os_str().to_os_string()); - } - Ok(extra_args) -} - fn run_command(mut cmd: Command) -> Result<(Command, Output), Errored> { match cmd.output() { Err(err) => Err(Errored {