diff --git a/src/command_helpers.rs b/src/command_helpers.rs index 919d276c..10dafeb1 100644 --- a/src/command_helpers.rs +++ b/src/command_helpers.rs @@ -215,7 +215,7 @@ fn write_warning(line: &[u8]) { fn wait_on_child( cmd: &Command, - program: &str, + program: &Path, child: &mut Child, cargo_output: &CargoOutput, ) -> Result<(), Error> { @@ -227,8 +227,10 @@ fn wait_on_child( return Err(Error::new( ErrorKind::ToolExecError, format!( - "Failed to wait on spawned child process, command {:?} with args {:?}: {}.", - cmd, program, e + "Failed to wait on spawned child process, command {:?} with args {}: {}.", + cmd, + program.display(), + e ), )); } @@ -242,8 +244,10 @@ fn wait_on_child( Err(Error::new( ErrorKind::ToolExecError, format!( - "Command {:?} with args {:?} did not execute successfully (status code {}).", - cmd, program, status + "Command {:?} with args {} did not execute successfully (status code {}).", + cmd, + program.display(), + status ), )) } @@ -299,18 +303,22 @@ pub(crate) fn objects_from_files(files: &[Arc], dst: &Path) -> Result, cargo_output: &CargoOutput, ) -> Result<(), Error> { + let program = program.as_ref(); + let mut child = spawn(cmd, program, cargo_output)?; wait_on_child(cmd, program, &mut child, cargo_output) } pub(crate) fn run_output( cmd: &mut Command, - program: &str, + program: impl AsRef, cargo_output: &CargoOutput, ) -> Result, Error> { + let program = program.as_ref(); + cmd.stdout(Stdio::piped()); let mut child = spawn(cmd, program, cargo_output)?; @@ -330,7 +338,7 @@ pub(crate) fn run_output( pub(crate) fn spawn( cmd: &mut Command, - program: &str, + program: &Path, cargo_output: &CargoOutput, ) -> Result { struct ResetStderr<'cmd>(&'cmd mut Command); @@ -358,14 +366,20 @@ for help)" }; Err(Error::new( ErrorKind::ToolNotFound, - format!("Failed to find tool. Is `{}` installed?{}", program, extra), + format!( + "Failed to find tool. Is `{}` installed?{}", + program.display(), + extra + ), )) } Err(e) => Err(Error::new( ErrorKind::ToolExecError, format!( - "Command {:?} with args {:?} failed to start: {:?}", - cmd.0, program, e + "Command {:?} with args {} failed to start: {:?}", + cmd.0, + program.display(), + e ), )), } @@ -393,7 +407,7 @@ pub(crate) fn command_add_output_file( #[cfg(feature = "parallel")] pub(crate) fn try_wait_on_child( cmd: &Command, - program: &str, + program: &Path, child: &mut Child, stdout: &mut dyn io::Write, stderr_forwarder: &mut StderrForwarder, @@ -412,8 +426,10 @@ pub(crate) fn try_wait_on_child( Err(Error::new( ErrorKind::ToolExecError, format!( - "Command {:?} with args {:?} did not execute successfully (status code {}).", - cmd, program, status + "Command {:?} with args {} did not execute successfully (status code {}).", + cmd, + program.display(), + status ), )) } @@ -424,8 +440,10 @@ pub(crate) fn try_wait_on_child( Err(Error::new( ErrorKind::ToolExecError, format!( - "Failed to wait on spawned child process, command {:?} with args {:?}: {}.", - cmd, program, e + "Failed to wait on spawned child process, command {:?} with args {}: {}.", + cmd, + program.display(), + e ), )) } diff --git a/src/lib.rs b/src/lib.rs index 92b8eff6..8ef48305 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1439,7 +1439,7 @@ impl Build { let pendings = Cell::new(Vec::<( Command, - String, + Cow<'static, Path>, KillOnDrop, parallel::job_token::JobToken, )>::new()); @@ -1563,7 +1563,10 @@ impl Build { Ok(()) } - fn create_compile_object_cmd(&self, obj: &Object) -> Result<(Command, String), Error> { + fn create_compile_object_cmd( + &self, + obj: &Object, + ) -> Result<(Command, Cow<'static, Path>), Error> { let asm_ext = AsmFileExt::from_path(&obj.src); let is_asm = asm_ext.is_some(); let target = self.get_target()?; @@ -1574,7 +1577,8 @@ impl Build { let is_assembler_msvc = msvc && asm_ext == Some(AsmFileExt::DotAsm); let (mut cmd, name) = if is_assembler_msvc { - self.msvc_macro_assembler()? + let (cmd, name) = self.msvc_macro_assembler()?; + (cmd, Cow::Borrowed(Path::new(name))) } else { let mut cmd = compiler.to_command(); for (a, b) in self.env.iter() { @@ -1585,9 +1589,9 @@ impl Build { compiler .path .file_name() - .ok_or_else(|| Error::new(ErrorKind::IOError, "Failed to get compiler path."))? - .to_string_lossy() - .into_owned(), + .ok_or_else(|| Error::new(ErrorKind::IOError, "Failed to get compiler path.")) + .map(PathBuf::from) + .map(Cow::Owned)?, ) }; let is_arm = target.contains("aarch64") || target.contains("arm"); @@ -1653,9 +1657,7 @@ impl Build { let name = compiler .path .file_name() - .ok_or_else(|| Error::new(ErrorKind::IOError, "Failed to get compiler path."))? - .to_string_lossy() - .into_owned(); + .ok_or_else(|| Error::new(ErrorKind::IOError, "Failed to get compiler path."))?; Ok(run_output(&mut cmd, &name, &self.cargo_output)?) } @@ -2321,7 +2323,7 @@ impl Build { } } - fn msvc_macro_assembler(&self) -> Result<(Command, String), Error> { + fn msvc_macro_assembler(&self) -> Result<(Command, &'static str), Error> { let target = self.get_target()?; let tool = if target.contains("x86_64") { "ml64.exe" @@ -2374,7 +2376,7 @@ impl Build { cmd.arg("-safeseh"); } - Ok((cmd, tool.to_string())) + Ok((cmd, tool)) } fn assemble(&self, lib_name: &str, dst: &Path, objs: &[Object]) -> Result<(), Error> { @@ -3026,7 +3028,7 @@ impl Build { } } - fn get_ar(&self) -> Result<(Command, String, bool), Error> { + fn get_ar(&self) -> Result<(Command, PathBuf, bool), Error> { self.try_get_archiver_and_flags() } @@ -3059,7 +3061,7 @@ impl Build { Ok(self.try_get_archiver_and_flags()?.0) } - fn try_get_archiver_and_flags(&self) -> Result<(Command, String, bool), Error> { + fn try_get_archiver_and_flags(&self) -> Result<(Command, PathBuf, bool), Error> { let (mut cmd, name) = self.get_base_archiver()?; let mut any_flags = false; if let Ok(flags) = self.envflags("ARFLAGS") { @@ -3073,12 +3075,14 @@ impl Build { Ok((cmd, name, any_flags)) } - fn get_base_archiver(&self) -> Result<(Command, String), Error> { + fn get_base_archiver(&self) -> Result<(Command, PathBuf), Error> { if let Some(ref a) = self.archiver { - return Ok((self.cmd(&**a), a.to_string_lossy().into_owned())); + let archiver = &**a; + return Ok((self.cmd(archiver), archiver.into())); } self.get_base_archiver_variant("AR", "ar") + .map(|(cmd, archiver)| (cmd, archiver.into())) } /// Get the ranlib that's in use for this configuration. diff --git a/src/tool.rs b/src/tool.rs index a193a90f..bb7de512 100644 --- a/src/tool.rs +++ b/src/tool.rs @@ -81,7 +81,7 @@ impl Tool { let stdout = match run_output( &mut cmd, - &path.to_string_lossy(), + path, // tool detection issues should always be shown as warnings cargo_output, )