Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 45 additions & 19 deletions src/cargo/core/compiler/custom_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)?;
Expand Down Expand Up @@ -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();
Expand All @@ -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<Target> = unit.pkg.targets().to_vec();
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
}
}
Expand All @@ -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,
Expand Down Expand Up @@ -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,
}
}
}
2 changes: 1 addition & 1 deletion tests/testsuite/build_dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down