diff --git a/src/cargo/core/compiler/custom_build.rs b/src/cargo/core/compiler/custom_build.rs index be04dbe304c..a96d2cdeed0 100644 --- a/src/cargo/core/compiler/custom_build.rs +++ b/src/cargo/core/compiler/custom_build.rs @@ -343,7 +343,6 @@ fn build_work(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> CargoResul } else { build_runner.files().build_script_out_dir(unit) }; - let script_run_dir = build_runner.files().build_script_run_dir(unit); if let Some(deps) = unit.pkg.manifest().metabuild() { prepare_metabuild(build_runner, build_script_unit, deps)?; @@ -490,16 +489,14 @@ fn build_work(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> CargoResul let pkg_descr = unit.pkg.to_string(); let build_script_outputs = Arc::clone(&build_runner.build_script_outputs); let id = unit.pkg.package_id(); - let output_file = script_run_dir.join("output"); - let err_file = script_run_dir.join("stderr"); - let root_output_file = script_run_dir.join("root-output"); + let run_files = BuildScriptRunFiles::for_unit(build_runner, unit); let host_target_root = build_runner.files().host_dest().map(|v| v.to_path_buf()); let all = ( id, library_name.clone(), pkg_descr.clone(), Arc::clone(&build_script_outputs), - output_file.clone(), + run_files.stdout.clone(), script_out_dir.clone(), ); let build_scripts = build_runner.build_scripts.get(unit).cloned(); @@ -510,7 +507,7 @@ fn build_work(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> CargoResul paths::create_dir_all(&script_dir)?; paths::create_dir_all(&script_out_dir)?; - paths::create_dir_all(&script_run_dir)?; + paths::create_dir_all(&run_files.root)?; let nightly_features_allowed = build_runner.bcx.gctx.nightly_features_allowed; let targets: Vec = unit.pkg.targets().to_vec(); @@ -584,7 +581,7 @@ fn build_work(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> CargoResul // And now finally, run the build command itself! state.running(&cmd); - let timestamp = paths::set_invocation_time(&script_run_dir)?; + let timestamp = paths::set_invocation_time(&run_files.root)?; let prefix = format!("[{} {}] ", id.name(), id.version()); let mut log_messages_in_case_of_panic = Vec::new(); let span = tracing::debug_span!("build_script", process = cmd.to_string()); @@ -669,12 +666,12 @@ fn build_work(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> CargoResul // This is also the location where we provide feedback into the build // state informing what variables were discovered via our script as // well. - paths::write(&output_file, &output.stdout)?; + paths::write(&run_files.stdout, &output.stdout)?; // This mtime shift allows Cargo to detect if a source file was // modified in the middle of the build. - paths::set_file_time_no_err(output_file, timestamp); - paths::write(&err_file, &output.stderr)?; - paths::write(&root_output_file, paths::path2bytes(&script_out_dir)?)?; + paths::set_file_time_no_err(run_files.stdout, timestamp); + paths::write(&run_files.stderr, &output.stderr)?; + paths::write(&run_files.root_output, paths::path2bytes(&script_out_dir)?)?; let parsed_output = BuildOutput::parse( &output.stdout, library_name, @@ -1355,10 +1352,9 @@ pub fn build_map(build_runner: &mut BuildRunner<'_, '_>) -> CargoResult<()> { /// Load any dependency declarations from a previous build script run. fn parse_previous_explicit_deps(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) { - let script_run_dir = build_runner.files().build_script_run_dir(unit); - let output_file = script_run_dir.join("output"); + let run_files = BuildScriptRunFiles::for_unit(build_runner, unit); let (prev_output, _) = prev_build_output(build_runner, unit); - let deps = BuildDeps::new(&output_file, prev_output.as_ref()); + let deps = BuildDeps::new(&run_files.stdout, prev_output.as_ref()); build_runner.build_explicit_deps.insert(unit.clone(), deps); } } @@ -1377,17 +1373,15 @@ fn prev_build_output( } else { build_runner.files().build_script_out_dir(unit) }; - let script_run_dir = build_runner.files().build_script_run_dir(unit); - let root_output_file = script_run_dir.join("root-output"); - let output_file = script_run_dir.join("output"); + let run_files = BuildScriptRunFiles::for_unit(build_runner, unit); - let prev_script_out_dir = paths::read_bytes(&root_output_file) + let prev_script_out_dir = paths::read_bytes(&run_files.root_output) .and_then(|bytes| paths::bytes2path(&bytes)) .unwrap_or_else(|_| script_out_dir.clone()); ( BuildOutput::parse_file( - &output_file, + &run_files.stdout, unit.pkg.library().map(|t| t.crate_name()), &unit.pkg.to_string(), &prev_script_out_dir, @@ -1434,3 +1428,35 @@ impl BuildScriptOutputs { self.outputs.iter() } } + +/// Files with information about a running build script. +struct BuildScriptRunFiles { + /// The directory containing files related to running a build script. + root: PathBuf, + /// The stdout produced by the build script + stdout: PathBuf, + /// The stderr produced by the build script + stderr: PathBuf, + /// A file that contains the path of `root`. + /// This is used for detect if the directory was moved since the previous run. + root_output: PathBuf, +} + +impl BuildScriptRunFiles { + pub fn for_unit(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> Self { + let root = build_runner.files().build_script_run_dir(unit); + let stdout = if build_runner.bcx.gctx.cli_unstable().build_dir_new_layout { + root.join("stdout") + } else { + root.join("output") + }; + let stderr = root.join("stderr"); + let root_output = root.join("root-output"); + Self { + root, + stdout, + stderr, + root_output, + } + } +} diff --git a/tests/testsuite/build_dir.rs b/tests/testsuite/build_dir.rs index 60bd27a5171..92f17e7b5dd 100644 --- a/tests/testsuite/build_dir.rs +++ b/tests/testsuite/build_dir.rs @@ -297,7 +297,7 @@ fn build_script_should_output_to_build_dir() { [ROOT]/foo/build-dir/debug/build/foo/[HASH]/fingerprint/build-script-build-script-build [ROOT]/foo/build-dir/debug/build/foo/[HASH]/fingerprint/build-script-build-script-build.json [ROOT]/foo/build-dir/debug/build/foo/[HASH]/run/invoked.timestamp -[ROOT]/foo/build-dir/debug/build/foo/[HASH]/run/output +[ROOT]/foo/build-dir/debug/build/foo/[HASH]/run/stdout [ROOT]/foo/build-dir/debug/build/foo/[HASH]/run/root-output [ROOT]/foo/build-dir/debug/build/foo/[HASH]/run/stderr [ROOT]/foo/build-dir/debug/build/foo/[HASH]/.lock