Skip to content

Commit 0762e3b

Browse files
committed
Auto merge of #11649 - weihanglo:rust-1.68.0, r=ehuss
[beta-1.68] Backport fixes of split-debuginfo detection Beta backports: * #11347 — Fix split-debuginfo support detection * #11633 — Reduce target info rustc query calls In order to make CI pass, the following PR are also cherry-picked: * #11619 * #11609 * #11610
2 parents 985d561 + 6fe6437 commit 0762e3b

File tree

6 files changed

+117
-32
lines changed

6 files changed

+117
-32
lines changed

Cargo.toml

+4-2
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ jobserver = "0.1.24"
4444
lazycell = "1.2.0"
4545
libc = "0.2"
4646
log = "0.4.6"
47-
libgit2-sys = "0.14.1"
47+
# Temporarily pin libgit2-sys due to some issues with SSH not working on
48+
# Windows.
49+
libgit2-sys = "=0.14.1"
4850
memchr = "2.1.3"
4951
opener = "0.5"
5052
os_info = "3.5.0"
@@ -68,7 +70,7 @@ toml_edit = { version = "0.15.0", features = ["serde", "easy", "perf"] }
6870
unicode-xid = "0.2.0"
6971
url = "2.2.2"
7072
walkdir = "2.2"
71-
clap = "4.1.1"
73+
clap = "4.1.3"
7274
unicode-width = "0.1.5"
7375
openssl = { version = '0.10.11', optional = true }
7476
im-rc = "15.0.0"

src/cargo/core/compiler/build_context/target_info.rs

+53-25
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use crate::core::compiler::{
1212
};
1313
use crate::core::{Dependency, Package, Target, TargetKind, Workspace};
1414
use crate::util::config::{Config, StringList, TargetConfig};
15+
use crate::util::interning::InternedString;
1516
use crate::util::{CargoResult, Rustc};
1617
use anyhow::Context as _;
1718
use cargo_platform::{Cfg, CfgExpr};
@@ -43,6 +44,8 @@ pub struct TargetInfo {
4344
crate_types: RefCell<HashMap<CrateType, Option<(String, String)>>>,
4445
/// `cfg` information extracted from `rustc --print=cfg`.
4546
cfg: Vec<Cfg>,
47+
/// Supported values for `-Csplit-debuginfo=` flag, queried from rustc
48+
support_split_debuginfo: Vec<String>,
4649
/// Path to the sysroot.
4750
pub sysroot: PathBuf,
4851
/// Path to the "lib" or "bin" directory that rustc uses for its dynamic
@@ -55,8 +58,6 @@ pub struct TargetInfo {
5558
pub rustflags: Vec<String>,
5659
/// Extra flags to pass to `rustdoc`, see [`extra_args`].
5760
pub rustdocflags: Vec<String>,
58-
/// Whether or not rustc supports the `-Csplit-debuginfo` flag.
59-
pub supports_split_debuginfo: bool,
6061
}
6162

6263
/// Kind of each file generated by a Unit, part of `FileType`.
@@ -170,7 +171,8 @@ impl TargetInfo {
170171
// Query rustc for several kinds of info from each line of output:
171172
// 0) file-names (to determine output file prefix/suffix for given crate type)
172173
// 1) sysroot
173-
// 2) cfg
174+
// 2) split-debuginfo
175+
// 3) cfg
174176
//
175177
// Search `--print` to see what we query so far.
176178
let mut process = rustc.workspace_process();
@@ -199,15 +201,9 @@ impl TargetInfo {
199201
process.arg("--crate-type").arg(crate_type.as_str());
200202
}
201203

202-
// An extra `rustc` call to determine `-Csplit-debuginfo=packed` support.
203-
let supports_split_debuginfo = rustc
204-
.cached_output(
205-
process.clone().arg("-Csplit-debuginfo=packed"),
206-
extra_fingerprint,
207-
)
208-
.is_ok();
209-
210204
process.arg("--print=sysroot");
205+
process.arg("--print=split-debuginfo");
206+
process.arg("--print=crate-name"); // `___` as a delimiter.
211207
process.arg("--print=cfg");
212208

213209
let (output, error) = rustc
@@ -223,13 +219,8 @@ impl TargetInfo {
223219
map.insert(crate_type.clone(), out);
224220
}
225221

226-
let line = match lines.next() {
227-
Some(line) => line,
228-
None => anyhow::bail!(
229-
"output of --print=sysroot missing when learning about \
230-
target-specific information from rustc\n{}",
231-
output_err_info(&process, &output, &error)
232-
),
222+
let Some(line) = lines.next() else {
223+
return error_missing_print_output("sysroot", &process, &output, &error);
233224
};
234225
let sysroot = PathBuf::from(line);
235226
let sysroot_host_libdir = if cfg!(windows) {
@@ -246,6 +237,26 @@ impl TargetInfo {
246237
});
247238
sysroot_target_libdir.push("lib");
248239

240+
let support_split_debuginfo = {
241+
// HACK: abuse `--print=crate-name` to use `___` as a delimiter.
242+
let mut res = Vec::new();
243+
loop {
244+
match lines.next() {
245+
Some(line) if line == "___" => break,
246+
Some(line) => res.push(line.into()),
247+
None => {
248+
return error_missing_print_output(
249+
"split-debuginfo",
250+
&process,
251+
&output,
252+
&error,
253+
)
254+
}
255+
}
256+
}
257+
res
258+
};
259+
249260
let cfg = lines
250261
.map(|line| Ok(Cfg::from_str(line)?))
251262
.filter(TargetInfo::not_user_specific_cfg)
@@ -303,7 +314,7 @@ impl TargetInfo {
303314
Flags::Rustdoc,
304315
)?,
305316
cfg,
306-
supports_split_debuginfo,
317+
support_split_debuginfo,
307318
});
308319
}
309320
}
@@ -543,6 +554,13 @@ impl TargetInfo {
543554
}
544555
Ok((result, unsupported))
545556
}
557+
558+
/// Checks if the debuginfo-split value is supported by this target
559+
pub fn supports_debuginfo_split(&self, split: InternedString) -> bool {
560+
self.support_split_debuginfo
561+
.iter()
562+
.any(|sup| sup.as_str() == split.as_str())
563+
}
546564
}
547565

548566
/// Takes rustc output (using specialized command line args), and calculates the file prefix and
@@ -578,17 +596,27 @@ fn parse_crate_type(
578596
};
579597
let mut parts = line.trim().split("___");
580598
let prefix = parts.next().unwrap();
581-
let suffix = match parts.next() {
582-
Some(part) => part,
583-
None => anyhow::bail!(
584-
"output of --print=file-names has changed in the compiler, cannot parse\n{}",
585-
output_err_info(cmd, output, error)
586-
),
599+
let Some(suffix) = parts.next() else {
600+
return error_missing_print_output("file-names", cmd, output, error);
587601
};
588602

589603
Ok(Some((prefix.to_string(), suffix.to_string())))
590604
}
591605

606+
/// Helper for creating an error message for missing output from a certain `--print` request.
607+
fn error_missing_print_output<T>(
608+
request: &str,
609+
cmd: &ProcessBuilder,
610+
stdout: &str,
611+
stderr: &str,
612+
) -> CargoResult<T> {
613+
let err_info = output_err_info(cmd, stdout, stderr);
614+
anyhow::bail!(
615+
"output of --print={request} missing when learning about \
616+
target-specific information from rustc\n{err_info}",
617+
)
618+
}
619+
592620
/// Helper for creating an error message when parsing rustc output fails.
593621
fn output_err_info(cmd: &ProcessBuilder, stdout: &str, stderr: &str) -> String {
594622
let mut result = format!("command was: {}\n", cmd);

src/cargo/core/compiler/mod.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -980,10 +980,17 @@ fn build_base_args(
980980
cmd.args(&lto_args(cx, unit));
981981

982982
// This is generally just an optimization on build time so if we don't pass
983-
// it then it's ok. As of the time of this writing it's a very new flag, so
984-
// we need to dynamically check if it's available.
985-
if cx.bcx.target_data.info(unit.kind).supports_split_debuginfo {
986-
if let Some(split) = split_debuginfo {
983+
// it then it's ok. The values for the flag (off, packed, unpacked) may be supported
984+
// or not depending on the platform, so availability is checked per-value.
985+
// For example, at the time of writing this code, on Windows the only stable valid
986+
// value for split-debuginfo is "packed", while on Linux "unpacked" is also stable.
987+
if let Some(split) = split_debuginfo {
988+
if cx
989+
.bcx
990+
.target_data
991+
.info(unit.kind)
992+
.supports_debuginfo_split(split)
993+
{
987994
cmd.arg("-C").arg(format!("split-debuginfo={}", split));
988995
}
989996
}

tests/testsuite/cargo_add/invalid_arg/stderr.log

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
error: unexpected argument '--flag' found
22

3-
note: to pass '--flag' as a value, use '-- --flag'
3+
note: argument '--tag' exists
44

55
Usage: cargo add [OPTIONS] <DEP>[@<VERSION>] ...
66
cargo add [OPTIONS] --path <PATH> ...

tests/testsuite/cfg.rs

+40
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,22 @@ fn bad_cfg_discovery() {
356356
return;
357357
}
358358
println!("{}", sysroot);
359+
360+
if mode == "no-split-debuginfo" {
361+
return;
362+
}
363+
loop {
364+
let line = lines.next().unwrap();
365+
if line == "___" {
366+
println!("\n{line}");
367+
break;
368+
} else {
369+
// As the number split-debuginfo options varies,
370+
// concat them into one line.
371+
print!("{line},");
372+
}
373+
};
374+
359375
if mode != "bad-cfg" {
360376
panic!("unexpected");
361377
}
@@ -412,6 +428,28 @@ command was: `[..]compiler[..]--crate-type [..]`
412428
[..]___[..]
413429
[..]___[..]
414430
431+
",
432+
)
433+
.run();
434+
435+
p.cargo("build")
436+
.env("RUSTC", &funky_rustc)
437+
.env("FUNKY_MODE", "no-split-debuginfo")
438+
.with_status(101)
439+
.with_stderr(
440+
"\
441+
[ERROR] output of --print=split-debuginfo missing when learning about target-specific information from rustc
442+
command was: `[..]compiler[..]--crate-type [..]`
443+
444+
--- stdout
445+
[..]___[..]
446+
[..]___[..]
447+
[..]___[..]
448+
[..]___[..]
449+
[..]___[..]
450+
[..]___[..]
451+
[..]
452+
415453
",
416454
)
417455
.run();
@@ -430,6 +468,8 @@ command was: `[..]compiler[..]--crate-type [..]`
430468
[..]___[..]
431469
[..]___[..]
432470
[..]
471+
[..],[..]
472+
___
433473
123
434474
435475

tests/testsuite/ssh.rs

+8
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,10 @@ Caused by:
386386
}
387387

388388
#[cargo_test(public_network_test)]
389+
// For unknown reasons, this test occasionally fails on Windows with a
390+
// LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE error:
391+
// failed to start SSH session: Unable to exchange encryption keys; class=Ssh (23)
392+
#[cfg_attr(windows, ignore = "test is flaky on windows")]
389393
fn invalid_github_key() {
390394
// A key for github.com in known_hosts should override the built-in key.
391395
// This uses a bogus key which should result in an error.
@@ -417,6 +421,10 @@ fn invalid_github_key() {
417421
}
418422

419423
#[cargo_test(public_network_test)]
424+
// For unknown reasons, this test occasionally fails on Windows with a
425+
// LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE error:
426+
// failed to start SSH session: Unable to exchange encryption keys; class=Ssh (23)
427+
#[cfg_attr(windows, ignore = "test is flaky on windows")]
420428
fn bundled_github_works() {
421429
// The bundled key for github.com works.
422430
//

0 commit comments

Comments
 (0)