From 30fe923ca2cea2937210c7a8c7966444f271d2e2 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Thu, 26 Jan 2023 23:58:54 +0000 Subject: [PATCH 1/3] 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 61d1f331615..7ac48f73563 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); From 036ed3a2dd970241ff904e19a9a651116141745c Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 27 Jan 2023 02:04:07 +0000 Subject: [PATCH 2/3] test(cfg): parse `rustc --print=split-debuginfo` --- tests/testsuite/cfg.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tests/testsuite/cfg.rs b/tests/testsuite/cfg.rs index 3f79db77275..aac5c02b65a 100644 --- a/tests/testsuite/cfg.rs +++ b/tests/testsuite/cfg.rs @@ -356,6 +356,22 @@ fn bad_cfg_discovery() { return; } println!("{}", sysroot); + + if mode == "no-split-debuginfo" { + return; + } + loop { + let line = lines.next().unwrap(); + if line == "___" { + println!("\n{line}"); + break; + } else { + // As the number split-debuginfo options varies, + // concat them into one line. + print!("{line},"); + } + }; + if mode != "bad-cfg" { panic!("unexpected"); } @@ -412,6 +428,28 @@ command was: `[..]compiler[..]--crate-type [..]` [..]___[..] [..]___[..] +", + ) + .run(); + + p.cargo("build") + .env("RUSTC", &funky_rustc) + .env("FUNKY_MODE", "no-split-debuginfo") + .with_status(101) + .with_stderr( + "\ +[ERROR] output of --print=split-debuginfo missing when learning about target-specific information from rustc +command was: `[..]compiler[..]--crate-type [..]` + +--- stdout +[..]___[..] +[..]___[..] +[..]___[..] +[..]___[..] +[..]___[..] +[..]___[..] +[..] + ", ) .run(); @@ -430,6 +468,8 @@ command was: `[..]compiler[..]--crate-type [..]` [..]___[..] [..]___[..] [..] +[..],[..] +___ 123 From 1cef6d7675de9e559a3323667bd641338caa5735 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 27 Jan 2023 02:20:40 +0000 Subject: [PATCH 3/3] refactor: reuse `error_missing_print_output` on similar errors --- .../core/compiler/build_context/target_info.rs | 17 ++++------------- 1 file changed, 4 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 7ac48f73563..1ec0d9b5b4e 100644 --- a/src/cargo/core/compiler/build_context/target_info.rs +++ b/src/cargo/core/compiler/build_context/target_info.rs @@ -219,13 +219,8 @@ impl TargetInfo { map.insert(crate_type.clone(), out); } - let line = match lines.next() { - Some(line) => line, - None => anyhow::bail!( - "output of --print=sysroot missing when learning about \ - target-specific information from rustc\n{}", - output_err_info(&process, &output, &error) - ), + let Some(line) = lines.next() else { + return error_missing_print_output("sysroot", &process, &output, &error); }; let sysroot = PathBuf::from(line); let sysroot_host_libdir = if cfg!(windows) { @@ -601,12 +596,8 @@ fn parse_crate_type( }; let mut parts = line.trim().split("___"); let prefix = parts.next().unwrap(); - let suffix = match parts.next() { - Some(part) => part, - None => anyhow::bail!( - "output of --print=file-names has changed in the compiler, cannot parse\n{}", - output_err_info(cmd, output, error) - ), + let Some(suffix) = parts.next() else { + return error_missing_print_output("file-names", cmd, output, error); }; Ok(Some((prefix.to_string(), suffix.to_string())))