From 329c9d951b8ae31d46a6959bd7e45a22e1ffdf6c Mon Sep 17 00:00:00 2001 From: Kacper Kuba Date: Sun, 6 Nov 2022 23:22:37 +0100 Subject: [PATCH] Fix split-debuginfo support detection cargo assumed that if -Csplit-debuginfo=packed worked, all values would be correct. This however is not the case -- as of Rust 1.65.0, rustc supports packed, but not unpacked or off on Windows. Because of this, having split-debuginfo="unpacked" on Windows has caused builds to fail, as cargo assumed that the option is fine (split-debuginfo=packed worked), but rustc then failed when being passed -Csplit-debuginfo=unpacked. This patch splits split-debuginfo support detection for respective options (off, packed, unpacked). --- .../compiler/build_context/target_info.rs | 30 +++++++++++++++---- src/cargo/core/compiler/mod.rs | 29 +++++++++++++++--- 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/src/cargo/core/compiler/build_context/target_info.rs b/src/cargo/core/compiler/build_context/target_info.rs index a8561278e588..501885e548f0 100644 --- a/src/cargo/core/compiler/build_context/target_info.rs +++ b/src/cargo/core/compiler/build_context/target_info.rs @@ -55,8 +55,12 @@ pub struct TargetInfo { pub rustflags: Vec, /// Extra flags to pass to `rustdoc`, see [`extra_args`]. pub rustdocflags: Vec, - /// Whether or not rustc supports the `-Csplit-debuginfo` flag. - pub supports_split_debuginfo: bool, + /// Whether or not rustc supports the `-Csplit-debuginfo=off` flag. + pub supports_split_debuginfo_off: bool, + /// Whether or not rustc supports the `-Csplit-debuginfo=packed` flag. + pub supports_split_debuginfo_packed: bool, + /// Whether or not rustc supports the `-Csplit-debuginfo=unpacked` flag. + pub supports_split_debuginfo_unpacked: bool, } /// Kind of each file generated by a Unit, part of `FileType`. @@ -199,14 +203,28 @@ impl TargetInfo { process.arg("--crate-type").arg(crate_type.as_str()); } - // An extra `rustc` call to determine `-Csplit-debuginfo=packed` support. - let supports_split_debuginfo = rustc + // 3 extra `rustc` calls to determine `-Csplit-debuginfo={off,packed,unpacked}` support. + let supports_split_debuginfo_off = rustc + .cached_output( + process.clone().arg("-Csplit-debuginfo=off"), + extra_fingerprint, + ) + .is_ok(); + + let supports_split_debuginfo_packed = rustc .cached_output( process.clone().arg("-Csplit-debuginfo=packed"), extra_fingerprint, ) .is_ok(); + let supports_split_debuginfo_unpacked = rustc + .cached_output( + process.clone().arg("-Csplit-debuginfo=unpacked"), + extra_fingerprint, + ) + .is_ok(); + process.arg("--print=sysroot"); process.arg("--print=cfg"); @@ -303,7 +321,9 @@ impl TargetInfo { Flags::Rustdoc, )?, cfg, - supports_split_debuginfo, + supports_split_debuginfo_off, + supports_split_debuginfo_packed, + supports_split_debuginfo_unpacked, }); } } diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 9fe859feee69..e54520b952be 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -894,10 +894,31 @@ fn build_base_args( cmd.args(<o_args(cx, unit)); // This is generally just an optimization on build time so if we don't pass - // it then it's ok. As of the time of this writing it's a very new flag, so - // we need to dynamically check if it's available. - if cx.bcx.target_data.info(unit.kind).supports_split_debuginfo { - if let Some(split) = split_debuginfo { + // it then it's ok. The values for the flag (off, packed, unpacked) may be supported + // or not depending on the platform, so availability is checked per-value. + // For example, at the time of writing this code, on Windows the only stable valid + // value for split-debuginfo is "packed", while on Linux "unpacked" is also stable. + if let Some(split) = split_debuginfo { + let is_supported_off = cx + .bcx + .target_data + .info(unit.kind) + .supports_split_debuginfo_off + && split == "off"; + let is_supported_packed = cx + .bcx + .target_data + .info(unit.kind) + .supports_split_debuginfo_packed + && split == "packed"; + let is_supported_unpacked = cx + .bcx + .target_data + .info(unit.kind) + .supports_split_debuginfo_unpacked + && split == "unpacked"; + + if is_supported_off || is_supported_packed || is_supported_unpacked { cmd.arg("-C").arg(format!("split-debuginfo={}", split)); } }