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.
This commit is contained in:
Weihang Lo 2023-01-26 23:58:54 +00:00
parent c03cc59809
commit 30fe923ca2
No known key found for this signature in database
GPG Key ID: D7DBF189825E82E7

View File

@ -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<T>(
request: &str,
cmd: &ProcessBuilder,
stdout: &str,
stderr: &str,
) -> CargoResult<T> {
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);