From 30fe923ca2cea2937210c7a8c7966444f271d2e2 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Thu, 26 Jan 2023 23:58:54 +0000 Subject: [PATCH] perf: reduce target info rustc query call to one This is kinda a hack since we abuse `--print=crate-name` where the crate name is `___` and used as a delimiter. --- .../compiler/build_context/target_info.rs | 51 ++++++++++++++----- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/src/cargo/core/compiler/build_context/target_info.rs b/src/cargo/core/compiler/build_context/target_info.rs index 61d1f3316..7ac48f735 100644 --- a/src/cargo/core/compiler/build_context/target_info.rs +++ b/src/cargo/core/compiler/build_context/target_info.rs @@ -168,22 +168,11 @@ impl TargetInfo { loop { let extra_fingerprint = kind.fingerprint_hash(); - // Query rustc for supported -Csplit-debuginfo values - let support_split_debuginfo = rustc - .cached_output( - rustc.workspace_process().arg("--print=split-debuginfo"), - extra_fingerprint, - ) - .unwrap_or_default() - .0 - .lines() - .map(String::from) - .collect(); - // Query rustc for several kinds of info from each line of output: // 0) file-names (to determine output file prefix/suffix for given crate type) // 1) sysroot - // 2) cfg + // 2) split-debuginfo + // 3) cfg // // Search `--print` to see what we query so far. let mut process = rustc.workspace_process(); @@ -213,6 +202,8 @@ impl TargetInfo { } process.arg("--print=sysroot"); + process.arg("--print=split-debuginfo"); + process.arg("--print=crate-name"); // `___` as a delimiter. process.arg("--print=cfg"); let (output, error) = rustc @@ -251,6 +242,26 @@ impl TargetInfo { }); sysroot_target_libdir.push("lib"); + let support_split_debuginfo = { + // HACK: abuse `--print=crate-name` to use `___` as a delimiter. + let mut res = Vec::new(); + loop { + match lines.next() { + Some(line) if line == "___" => break, + Some(line) => res.push(line.into()), + None => { + return error_missing_print_output( + "split-debuginfo", + &process, + &output, + &error, + ) + } + } + } + res + }; + let cfg = lines .map(|line| Ok(Cfg::from_str(line)?)) .filter(TargetInfo::not_user_specific_cfg) @@ -601,6 +612,20 @@ fn parse_crate_type( Ok(Some((prefix.to_string(), suffix.to_string()))) } +/// Helper for creating an error message for missing output from a certain `--print` request. +fn error_missing_print_output( + request: &str, + cmd: &ProcessBuilder, + stdout: &str, + stderr: &str, +) -> CargoResult { + let err_info = output_err_info(cmd, stdout, stderr); + anyhow::bail!( + "output of --print={request} missing when learning about \ + target-specific information from rustc\n{err_info}", + ) +} + /// Helper for creating an error message when parsing rustc output fails. fn output_err_info(cmd: &ProcessBuilder, stdout: &str, stderr: &str) -> String { let mut result = format!("command was: {}\n", cmd);