// ignore-tidy-linelength //! Basic smoke tests for behavior of `-C split-debuginfo` and the combined behavior when used in //! conjunction with other flags such as: //! //! - `--remap-path-prefix`: see //! . //! - `-Z remap-path-scope`: see //! - //! - //! - RFC #3127 trim-paths: //! - `-Z split-dwarf-kind`: see . //! - `-Clinker-plugin-lto`: see . //! //! # Test implementation remark //! //! - The pattern match on enum variants are intentional, because I find that they are very //! revealing with respect to the kind of test coverage that we have and don't have. //! //! # Known limitations //! //! - The linux test coverage of cross-interactions between `-C split-debuginfo` and other flags are //! significantly higher than the lack of such coverage for Windows and Darwin. //! - windows-gnu is not tested at all, see the `FIXME(#135531)`s below. //! - This test for the most part merely checks for existence/absence of certain artifacts, it does //! not sanity check if the debuginfo artifacts are actually usable or contains the expected //! amount/quality of debuginfo, especially on windows-msvc and darwin. //! - FIXME(#111540): this test has insufficient coverage in relation to trim-paths RFC, see also //! the comment . The //! basic `llvm-dwarfdump` textual output inspection here is very fragile. The original `Makefile` //! version used `objdump` (not to be confused with `llvm-objdump`) but inspected the wrong line //! because it was looking at `DW_AT_GNU_dwo_name` when it should've been looking at //! `DW_AT_comp_dir`. //! - This test does not have good coverage for what values of `-Csplit-debuginfo` are stable vs //! non-stable for the various targets, i.e. which values *should* be gated behind //! `-Zunstable-options` for a given target. The `Makefile` version yolo'd a `-Zunstable-options` //! for non-windows + non-linux + non-darwin, but had a misplaced interpolation which suggested to //! me that that conditional `-Zunstable-options` never actually materialized. //! //! # Additional references //! //! - Apple `.dSYM` debug symbol bundles: . //! - LLVM `dsymutil`: . // NOTE: this is a host test //@ ignore-cross-compile // NOTE: this seems to be a host test, and testing on host `riscv64-gc-unknown-linux-gnu` reveals // that this test is failing because of [MC: "error: A dwo section may not contain relocations" when // building with fission + RISCV64 #56642](https://github.com/llvm/llvm-project/issues/56642). This // test is ignored for now to unblock efforts to bring riscv64 targets to be exercised in CI, cf. // [Enable riscv64gc-gnu testing #126641](https://github.com/rust-lang/rust/pull/126641). //@ ignore-riscv64 (https://github.com/llvm/llvm-project/issues/56642) // FIXME(#135531): the `Makefile` version practically didn't test `-C split-debuginfo` on Windows // at all, and lumped windows-msvc and windows-gnu together at that. //@ ignore-windows-gnu #![deny(warnings)] use std::collections::BTreeSet; use run_make_support::rustc::Rustc; use run_make_support::{ cwd, has_extension, is_darwin, is_msvc, is_windows, llvm_dwarfdump, run_in_tmpdir, rustc, shallow_find_directories, shallow_find_files, uname, }; /// `-C debuginfo`. See . #[derive(Debug, PartialEq, Copy, Clone)] enum DebuginfoLevel { /// `-C debuginfo=0` or `-C debuginfo=none` aka no debuginfo at all, default. None, /// `-C debuginfo=2` aka full debuginfo, aliased via `-g`. Full, /// The cli flag is not explicitly provided; default. Unspecified, } impl DebuginfoLevel { fn cli_value(&self) -> &'static str { // `-Cdebuginfo=...` match self { DebuginfoLevel::None => "none", DebuginfoLevel::Full => "2", DebuginfoLevel::Unspecified => unreachable!(), } } } /// `-C split-debuginfo`. See /// . /// /// Note that all three options are supported on Linux and Apple platforms, packed is supported on /// Windows-MSVC, and all other platforms support off. Attempting to use an unsupported option /// requires using the nightly channel with the `-Z unstable-options` flag. #[derive(Debug, PartialEq, Copy, Clone)] enum SplitDebuginfo { /// `-C split-debuginfo=off`. Default for platforms with ELF binaries and windows-gnu (not /// Windows MSVC and not macOS). Typically DWARF debug information can be found in the final /// artifact in sections of the executable. /// /// - Not supported on Windows MSVC. /// - On macOS this options prevents the final execution of `dsymutil` to generate debuginfo. Off, /// `-C split-debuginfo=unpacked`. Debug information will be found in separate files for each /// compilation unit (object file). /// /// - Not supported on Windows MSVC. /// - On macOS this means the original object files will contain debug information. /// - On other Unix platforms this means that `*.dwo` files will contain debug information. Unpacked, /// `-C split-debuginfo=packed`. Default for Windows MSVC and macOS. "Packed" here means that /// all the debug information is packed into a separate file from the main executable. /// /// - On Windows MSVC this is a `*.pdb` file. /// - On macOS this is a `*.dSYM` folder. /// - On other platforms this is a `*.dwp` file. Packed, /// The cli flag is not explicitly provided; uses platform default. Unspecified, } impl SplitDebuginfo { fn cli_value(&self) -> &'static str { // `-Csplit-debuginfo=...` match self { SplitDebuginfo::Off => "off", SplitDebuginfo::Unpacked => "unpacked", SplitDebuginfo::Packed => "packed", SplitDebuginfo::Unspecified => unreachable!(), } } } /// `-Z split-dwarf-kind` #[derive(Debug, PartialEq, Copy, Clone)] enum SplitDwarfKind { /// `-Zsplit-dwarf-kind=split` Split, /// `-Zsplit-dwarf-kind=single` Single, Unspecified, } impl SplitDwarfKind { fn cli_value(&self) -> &'static str { // `-Zsplit-dwarf-kind=...` match self { SplitDwarfKind::Split => "split", SplitDwarfKind::Single => "single", SplitDwarfKind::Unspecified => unreachable!(), } } } /// `-C linker-plugin-lto` #[derive(Debug, PartialEq, Copy, Clone)] enum LinkerPluginLto { /// Pass `-C linker-plugin-lto`. Yes, /// Don't pass `-C linker-plugin-lto`. Unspecified, } /// `--remap-path-prefix` or not. #[derive(Debug, Clone)] enum RemapPathPrefix { /// `--remap-path-prefix=$prefix=$remapped_prefix`. Yes { remapped_prefix: &'static str }, /// Don't pass `--remap-path-prefix`. Unspecified, } /// `-Zremap-path-scope`. See /// . #[derive(Debug, Clone)] enum RemapPathScope { /// Comma-separated list of remap scopes: `macro`, `diagnostics`, `debuginfo`, `object`, `all`. Yes(&'static str), Unspecified, } /// Whether to pass `-Zunstable-options`. #[derive(Debug, PartialEq, Copy, Clone)] enum UnstableOptions { Yes, Unspecified, } #[track_caller] fn cwd_filenames() -> BTreeSet { let files = shallow_find_files(cwd(), |path| { // Fiilter out source files !has_extension(path, "rs") }); files.iter().map(|p| p.file_name().unwrap().to_os_string().into_string().unwrap()).collect() } #[track_caller] fn cwd_dwo_filenames() -> BTreeSet { let files = shallow_find_files(cwd(), |path| has_extension(path, "dwo")); files.iter().map(|p| p.file_name().unwrap().to_os_string().into_string().unwrap()).collect() } #[track_caller] fn cwd_object_filenames() -> BTreeSet { let files = shallow_find_files(cwd(), |path| has_extension(path, "o")); files.iter().map(|p| p.file_name().unwrap().to_os_string().into_string().unwrap()).collect() } #[must_use] struct FileAssertions<'expected> { expected_files: BTreeSet<&'expected str>, } impl<'expected> FileAssertions<'expected> { #[track_caller] fn assert_on(self, found_files: &BTreeSet) { let found_files: BTreeSet<_> = found_files.iter().map(|f| f.as_str()).collect(); assert!( found_files.is_superset(&self.expected_files), "expected {:?} to exist, but only found {:?}", self.expected_files, found_files ); let unexpected_files: BTreeSet<_> = found_files.difference(&self.expected_files).copied().collect(); assert!(unexpected_files.is_empty(), "found unexpected files: {:?}", unexpected_files); } } /// Windows MSVC only supports packed debuginfo. mod windows_msvc_tests { use super::*; pub(crate) fn split_debuginfo(split_kind: SplitDebuginfo, level: DebuginfoLevel) { // NOTE: `-C debuginfo` and other flags are not exercised here on Windows MSVC. run_in_tmpdir(|| { println!("checking: split_kind={:?} + level={:?}", split_kind, level); match (split_kind, level) { (SplitDebuginfo::Off, _) => { rustc() .input("foo.rs") .split_debuginfo(split_kind.cli_value()) .run_fail() .assert_stderr_contains( "error: `-Csplit-debuginfo=off` is unstable on this platform", ); } (SplitDebuginfo::Unpacked, _) => { rustc() .input("foo.rs") .split_debuginfo(split_kind.cli_value()) .run_fail() .assert_stderr_contains( "error: `-Csplit-debuginfo=unpacked` is unstable on this platform", ); } (SplitDebuginfo::Packed, _) => { rustc().input("foo.rs").split_debuginfo(split_kind.cli_value()).run(); let found_files = cwd_filenames(); FileAssertions { expected_files: BTreeSet::from(["foo.exe", "foo.pdb"]) } .assert_on(&found_files); } (split_kind, level) => { panic!( "split_kind={:?} + level={:?} is not handled on Windows MSVC", split_kind, level ) } } }); } } mod darwin_tests { use super::*; pub(crate) fn split_debuginfo(split_kind: SplitDebuginfo, level: DebuginfoLevel) { run_in_tmpdir(|| { println!("checking: split_kind={:?} + level={:?}", split_kind, level); let dsym_directories = || shallow_find_directories(cwd(), |path| has_extension(path, "dSYM")); match (split_kind, level) { (_, DebuginfoLevel::Unspecified) => { rustc().input("foo.rs").run(); let directories = shallow_find_directories(cwd(), |path| has_extension(path, "dSYM")); assert!( directories.is_empty(), "expected no `*.dSYM` folder to be generated when `-Cdebuginfo` is not specified" ); } (_, DebuginfoLevel::None) => { rustc().input("foo.rs").debuginfo(level.cli_value()).run(); let directories = dsym_directories(); assert!( directories.is_empty(), "expected no `*.dSYM` folder to be generated when `-Cdebuginfo=none`" ); } (SplitDebuginfo::Off, _) => { rustc() .input("foo.rs") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .run(); let directories = dsym_directories(); assert!( directories.is_empty(), "expected no `*.dSYM` folder to be generated since we expect `-Csplit-debuginfo=off` to inhibit final debuginfo generation on macOS" ); } (SplitDebuginfo::Unpacked, _) => { rustc().input("foo.rs").split_debuginfo(split_kind.cli_value()).run(); let directories = dsym_directories(); assert!( directories.is_empty(), "expected no `*.dSYM` folder to be generated since we expect on macOS the object files to contain debuginfo instead" ); } (SplitDebuginfo::Packed, DebuginfoLevel::Full) => { rustc() .input("foo.rs") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .run(); let directories = shallow_find_directories(cwd(), |path| { path.file_name().unwrap() == "foo.dSYM" }); assert_eq!(directories.len(), 1, "failed to find `foo.dSYM`"); } (SplitDebuginfo::Unspecified, DebuginfoLevel::Full) => { rustc().input("foo.rs").debuginfo(level.cli_value()).run(); let directories = shallow_find_directories(cwd(), |path| { path.file_name().unwrap() == "foo.dSYM" }); assert_eq!(directories.len(), 1, "failed to find `foo.dSYM`"); } } }); } } mod shared_linux_other_tests { use std::path::PathBuf; use super::*; fn rustc(unstable_options: UnstableOptions) -> Rustc { if unstable_options == UnstableOptions::Yes { let mut rustc = run_make_support::rustc(); rustc.arg("-Zunstable-options"); rustc } else { run_make_support::rustc() } } #[derive(PartialEq)] pub(crate) enum CrossCrateTest { Yes, No, } pub(crate) fn split_debuginfo( cross_crate_test: CrossCrateTest, unstable_options: UnstableOptions, split_kind: SplitDebuginfo, level: DebuginfoLevel, split_dwarf_kind: SplitDwarfKind, lto: LinkerPluginLto, remap_path_prefix: RemapPathPrefix, remap_path_scope: RemapPathScope, ) { run_in_tmpdir(|| { println!( "checking: unstable_options={:?} + split_kind={:?} + level={:?} + split_dwarf_kind={:?} + lto={:?} + remap_path_prefix={:?} + remap_path_scope={:?}", unstable_options, split_kind, level, split_dwarf_kind, lto, remap_path_prefix, remap_path_scope ); match cross_crate_test { CrossCrateTest::Yes => cross_crate_split_debuginfo( unstable_options, split_kind, level, split_dwarf_kind, lto, remap_path_prefix, remap_path_scope, ), CrossCrateTest::No => simple_split_debuginfo( unstable_options, split_kind, level, split_dwarf_kind, lto, remap_path_prefix, remap_path_scope, ), } }); } fn cross_crate_split_debuginfo( unstable_options: UnstableOptions, split_kind: SplitDebuginfo, level: DebuginfoLevel, split_dwarf_kind: SplitDwarfKind, lto: LinkerPluginLto, remap_path_prefix: RemapPathPrefix, remap_path_scope: RemapPathScope, ) { match (split_kind, level, split_dwarf_kind, lto, remap_path_prefix, remap_path_scope) { // packed-crosscrate-split // - Debuginfo in `.dwo` files // - (bar) `.rlib` file created, contains `.dwo` // - (bar) `.o` deleted // - (bar) `.dwo` deleted // - (bar) `.dwp` never created // - (main) `.o` deleted // - (main) `.dwo` deleted // - (main) `.dwp` present ( SplitDebuginfo::Packed, DebuginfoLevel::Full, SplitDwarfKind::Split, LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ) => { rustc(unstable_options) .input("bar.rs") .crate_type("lib") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .run(); let found_files = cwd_filenames(); FileAssertions { expected_files: BTreeSet::from(["libbar.rlib"]) } .assert_on(&found_files); rustc(unstable_options) .extern_("bar", "libbar.rlib") .input("main.rs") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .run(); let found_files = cwd_filenames(); FileAssertions { expected_files: BTreeSet::from(["libbar.rlib", "main", "main.dwp"]), } .assert_on(&found_files); } // packed-crosscrate-single // - Debuginfo in `.o` files // - (bar) `.rlib` file created, contains `.o` // - (bar) `.o` deleted // - (bar) `.dwo` never created // - (bar) `.dwp` never created // - (main) `.o` deleted // - (main) `.dwo` never created // - (main) `.dwp` present ( SplitDebuginfo::Packed, DebuginfoLevel::Full, SplitDwarfKind::Single, LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ) => { rustc(unstable_options) .input("bar.rs") .crate_type("lib") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .run(); let found_files = cwd_filenames(); FileAssertions { expected_files: BTreeSet::from(["libbar.rlib"]) } .assert_on(&found_files); rustc(unstable_options) .extern_("bar", "libbar.rlib") .input("main.rs") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .run(); let found_files = cwd_filenames(); FileAssertions { expected_files: BTreeSet::from(["libbar.rlib", "main", "main.dwp"]), } .assert_on(&found_files); } // unpacked-crosscrate-split // - Debuginfo in `.dwo` files // - (bar) `.rlib` file created, contains `.dwo` // - (bar) `.o` deleted // - (bar) `.dwo` present // - (bar) `.dwp` never created // - (main) `.o` deleted // - (main) `.dwo` present // - (main) `.dwp` never created ( SplitDebuginfo::Unpacked, DebuginfoLevel::Full, SplitDwarfKind::Split, LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ) => { rustc(unstable_options) .input("bar.rs") .crate_type("lib") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .run(); let bar_found_files = cwd_filenames(); let bar_dwo_files = cwd_dwo_filenames(); assert_eq!(bar_dwo_files.len(), 1); let mut bar_expected_files = BTreeSet::new(); bar_expected_files.extend(bar_dwo_files); bar_expected_files.insert("libbar.rlib".to_string()); FileAssertions { expected_files: bar_expected_files.iter().map(String::as_ref).collect(), } .assert_on(&bar_found_files); rustc(unstable_options) .extern_("bar", "libbar.rlib") .input("main.rs") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .run(); let overall_found_files = cwd_filenames(); let overall_dwo_files = cwd_dwo_filenames(); assert_eq!(overall_dwo_files.len(), 2); let mut overall_expected_files = BTreeSet::new(); overall_expected_files.extend(overall_dwo_files); overall_expected_files.insert("main".to_string()); overall_expected_files.insert("libbar.rlib".to_string()); FileAssertions { expected_files: overall_expected_files.iter().map(String::as_ref).collect(), } .assert_on(&overall_found_files); } // unpacked-crosscrate-single // - Debuginfo in `.o` files // - (bar) `.rlib` file created, contains `.o` // - (bar) `.o` present // - (bar) `.dwo` never created // - (bar) `.dwp` never created // - (main) `.o` present // - (main) `.dwo` never created // - (main) `.dwp` never created ( SplitDebuginfo::Unpacked, DebuginfoLevel::Full, SplitDwarfKind::Single, LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ) => { rustc(unstable_options) .input("bar.rs") .crate_type("lib") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .run(); let bar_found_files = cwd_filenames(); let bar_object_files = cwd_object_filenames(); assert_eq!(bar_object_files.len(), 1); let mut bar_expected_files = BTreeSet::new(); bar_expected_files.extend(bar_object_files); bar_expected_files.insert("libbar.rlib".to_string()); FileAssertions { expected_files: bar_expected_files.iter().map(String::as_ref).collect(), } .assert_on(&bar_found_files); rustc(unstable_options) .extern_("bar", "libbar.rlib") .input("main.rs") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .run(); let overall_found_files = cwd_filenames(); let overall_object_files = cwd_object_filenames(); assert_eq!(overall_object_files.len(), 2); let mut overall_expected_files = BTreeSet::new(); overall_expected_files.extend(overall_object_files); overall_expected_files.insert("main".to_string()); overall_expected_files.insert("libbar.rlib".to_string()); FileAssertions { expected_files: overall_expected_files.iter().map(String::as_ref).collect(), } .assert_on(&overall_found_files); } _ => {} } } fn simple_split_debuginfo( unstable_options: UnstableOptions, split_kind: SplitDebuginfo, level: DebuginfoLevel, split_dwarf_kind: SplitDwarfKind, lto: LinkerPluginLto, remap_path_prefix: RemapPathPrefix, remap_path_scope: RemapPathScope, ) { match (split_kind, level, split_dwarf_kind, lto, remap_path_prefix, remap_path_scope) { // off (unspecified): // - Debuginfo in `.o` files // - `.o` deleted // - `.dwo` never created // - `.dwp` never created ( SplitDebuginfo::Unspecified, DebuginfoLevel::Full, SplitDwarfKind::Unspecified, LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ) => { rustc(unstable_options).input("foo.rs").debuginfo(level.cli_value()).run(); let found_files = cwd_filenames(); FileAssertions { expected_files: BTreeSet::from(["foo"]) }.assert_on(&found_files); } // off: // - Debuginfo in `.o` files // - `.o` deleted // - `.dwo` never created // - `.dwp` never created ( SplitDebuginfo::Off, DebuginfoLevel::Full, SplitDwarfKind::Unspecified, LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ) => { rustc(unstable_options) .input("foo.rs") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .run(); let found_files = cwd_filenames(); FileAssertions { expected_files: BTreeSet::from(["foo"]) }.assert_on(&found_files); } // packed-split: // - Debuginfo in `.dwo` files // - `.o` deleted // - `.dwo` deleted // - `.dwp` present ( SplitDebuginfo::Packed, DebuginfoLevel::Full, SplitDwarfKind::Split, LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ) => { rustc(unstable_options) .input("foo.rs") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .run(); let found_files = cwd_filenames(); FileAssertions { expected_files: BTreeSet::from(["foo", "foo.dwp"]) } .assert_on(&found_files); } // packed-single: // - Debuginfo in `.o` files // - `.o` deleted // - `.dwo` never created // - `.dwp` present ( SplitDebuginfo::Packed, DebuginfoLevel::Full, SplitDwarfKind::Single, LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ) => { rustc(unstable_options) .input("foo.rs") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .run(); let found_files = cwd_filenames(); FileAssertions { expected_files: BTreeSet::from(["foo", "foo.dwp"]) } .assert_on(&found_files); } // packed-lto-split:: // - `rmeta` file added to `rlib`, no object files are generated and thus no // debuginfo is generated. // - `.o` never created // - `.dwo` never created // - `.dwp` never created ( SplitDebuginfo::Packed, DebuginfoLevel::Full, SplitDwarfKind::Split, LinkerPluginLto::Yes, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ) => { rustc(unstable_options) .input("baz.rs") .crate_type("rlib") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .arg("-Clinker-plugin-lto") .run(); let found_files = cwd_filenames(); FileAssertions { expected_files: BTreeSet::from(["libbaz.rlib"]) } .assert_on(&found_files); } // packed-lto-single: // - `rmeta` file added to `rlib`, no object files are generated and thus no // debuginfo is generated // - `.o` never created // - `.dwo` never created // - `.dwp` never created ( SplitDebuginfo::Packed, DebuginfoLevel::Full, SplitDwarfKind::Single, LinkerPluginLto::Yes, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ) => { rustc(unstable_options) .input("baz.rs") .crate_type("rlib") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .arg("-Clinker-plugin-lto") .run(); let found_files = cwd_filenames(); FileAssertions { expected_files: BTreeSet::from(["libbaz.rlib"]) } .assert_on(&found_files); } // packed-remapped-split: // - Debuginfo in `.dwo` files // - `.o` and binary refer to remapped `.dwo` paths which do not exist // - `.o` deleted // - `.dwo` deleted // - `.dwp` present ( SplitDebuginfo::Packed, DebuginfoLevel::Full, SplitDwarfKind::Split, LinkerPluginLto::Unspecified, RemapPathPrefix::Yes { remapped_prefix }, RemapPathScope::Unspecified, ) => { rustc(unstable_options) .input("foo.rs") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .remap_path_prefix(cwd(), remapped_prefix) .run(); let found_files = cwd_filenames(); FileAssertions { expected_files: BTreeSet::from(["foo", "foo.dwp"]) } .assert_on(&found_files); check_path_remap(cwd(), RemapExpectation::Remapped); } // packed-remapped-single: // - `.o` and binary refer to remapped `.o` paths which do not exist // - `.o` deleted // - `.dwo` never created // - `.dwp` present ( SplitDebuginfo::Packed, DebuginfoLevel::Full, SplitDwarfKind::Single, LinkerPluginLto::Unspecified, RemapPathPrefix::Yes { remapped_prefix }, RemapPathScope::Unspecified, ) => { rustc(unstable_options) .input("foo.rs") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .remap_path_prefix(cwd(), remapped_prefix) .run(); let found_files = cwd_filenames(); FileAssertions { expected_files: BTreeSet::from(["foo", "foo.dwp"]) } .assert_on(&found_files); check_path_remap(cwd(), RemapExpectation::Remapped); } // packed-remapped-scope: // - Debuginfo in `.o` files // - `.o` and binary refer to remapped `.o` paths which do not exist // - `.o` deleted // - `.dwo` never created // - `.dwp` present ( SplitDebuginfo::Packed, DebuginfoLevel::Full, SplitDwarfKind::Single, LinkerPluginLto::Unspecified, RemapPathPrefix::Yes { remapped_prefix }, RemapPathScope::Yes(scope @ "debuginfo"), ) => { rustc(unstable_options) .input("foo.rs") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .remap_path_prefix(cwd(), remapped_prefix) .arg(format!("-Zremap-path-scope={scope}")) .run(); let found_files = cwd_filenames(); FileAssertions { expected_files: BTreeSet::from(["foo", "foo.dwp"]) } .assert_on(&found_files); check_path_remap(cwd(), RemapExpectation::Remapped); } // packed-remapped-wrong-scope: // - `.o` and binary refer to un-remapped `.o` paths because remap path scope is // macro. // - `.o` deleted // - `.dwo` never created // - `.dwp` present ( SplitDebuginfo::Packed, DebuginfoLevel::Full, SplitDwarfKind::Single, LinkerPluginLto::Unspecified, RemapPathPrefix::Yes { remapped_prefix }, RemapPathScope::Yes(scope @ "macro"), ) => { rustc(unstable_options) .input("foo.rs") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .remap_path_prefix(cwd(), remapped_prefix) .arg(format!("-Zremap-path-scope={scope}")) .run(); let found_files = cwd_filenames(); FileAssertions { expected_files: BTreeSet::from(["foo", "foo.dwp"]) } .assert_on(&found_files); check_path_remap(cwd(), RemapExpectation::NoRemap); } // unpacked-split // - Debuginfo in `.dwo` files // - `.o` deleted // - `.dwo` present // - `.dwp` never created ( SplitDebuginfo::Unpacked, DebuginfoLevel::Full, SplitDwarfKind::Split, LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ) => { rustc(unstable_options) .input("foo.rs") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .run(); let found_files = cwd_filenames(); let dwo_files = cwd_dwo_filenames(); assert_eq!(dwo_files.len(), 1); let mut expected_files = BTreeSet::new(); expected_files.extend(dwo_files); expected_files.insert("foo".to_string()); FileAssertions { expected_files: expected_files.iter().map(String::as_str).collect(), } .assert_on(&found_files); } // unpacked-single // - Debuginfo in `.o` files // - `.o` present // - `.dwo` never created // - `.dwp` never created ( SplitDebuginfo::Unpacked, DebuginfoLevel::Full, SplitDwarfKind::Single, LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ) => { rustc(unstable_options) .input("foo.rs") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .run(); let found_files = cwd_filenames(); let object_files = cwd_object_filenames(); assert_eq!(object_files.len(), 1); let mut expected_files = BTreeSet::new(); expected_files.extend(object_files); expected_files.insert("foo".to_string()); FileAssertions { expected_files: expected_files.iter().map(String::as_str).collect(), } .assert_on(&found_files); } // unpacked-lto-split // - `rmeta` file added to `rlib`, no object files are generated and thus no debuginfo // is generated // - `.o` not present // - `.dwo` never created // - `.dwp` never created ( SplitDebuginfo::Unpacked, DebuginfoLevel::Full, SplitDwarfKind::Split, LinkerPluginLto::Yes, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ) => { rustc(unstable_options) .input("baz.rs") .crate_type("rlib") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .arg("-Clinker-plugin-lto") .run(); let found_files = cwd_filenames(); FileAssertions { expected_files: BTreeSet::from(["libbaz.rlib"]) } .assert_on(&found_files); } // unpacked-lto-single // - rmeta file added to rlib, no object files are generated and thus no debuginfo is generated // - `.o` present (bitcode) // - `.dwo` never created // - `.dwp` never created ( SplitDebuginfo::Unpacked, DebuginfoLevel::Full, SplitDwarfKind::Single, LinkerPluginLto::Yes, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ) => { rustc(unstable_options) .input("baz.rs") .crate_type("rlib") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .arg("-Clinker-plugin-lto") .run(); let found_files = cwd_filenames(); let object_files = cwd_object_filenames(); assert_eq!(object_files.len(), 1); let mut expected_files = BTreeSet::new(); expected_files.extend(object_files); expected_files.insert("libbaz.rlib".to_string()); FileAssertions { expected_files: expected_files.iter().map(String::as_ref).collect(), } .assert_on(&found_files); } // unpacked-remapped-split // - Debuginfo in `.dwo` files // - `.o` and binary refer to remapped `.dwo` paths which do not exist // - `.o` deleted // - `.dwo` present // - `.dwp` never created ( SplitDebuginfo::Unpacked, DebuginfoLevel::Full, SplitDwarfKind::Split, LinkerPluginLto::Unspecified, RemapPathPrefix::Yes { remapped_prefix }, RemapPathScope::Unspecified, ) => { rustc(unstable_options) .input("foo.rs") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .remap_path_prefix(cwd(), remapped_prefix) .run(); let found_files = cwd_filenames(); let dwo_files = cwd_dwo_filenames(); assert_eq!(dwo_files.len(), 1); let mut expected_files = BTreeSet::new(); expected_files.extend(dwo_files); expected_files.insert("foo".to_string()); FileAssertions { expected_files: expected_files.iter().map(String::as_ref).collect(), } .assert_on(&found_files); check_path_remap(cwd(), RemapExpectation::Remapped); } // unpacked-remapped-single // - Debuginfo in `.o` files // - `.o` and binary refer to remapped `.o` paths which do not exist // - `.o` present // - `.dwo` never created // - `.dwp` never created ( SplitDebuginfo::Unpacked, DebuginfoLevel::Full, SplitDwarfKind::Single, LinkerPluginLto::Unspecified, RemapPathPrefix::Yes { remapped_prefix }, RemapPathScope::Unspecified, ) => { rustc(unstable_options) .input("foo.rs") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .remap_path_prefix(cwd(), remapped_prefix) .run(); let found_files = cwd_filenames(); let object_files = cwd_object_filenames(); assert_eq!(object_files.len(), 1); let mut expected_files = BTreeSet::new(); expected_files.extend(object_files); expected_files.insert("foo".to_string()); FileAssertions { expected_files: expected_files.iter().map(String::as_ref).collect(), } .assert_on(&found_files); check_path_remap(cwd(), RemapExpectation::Remapped); } // unpacked-remapped-scope // - Debuginfo in `.o` files // - `.o` and binary refer to remapped `.o` paths which do not exist // - `.o` present // - `.dwo` never created // - `.dwp` never created ( SplitDebuginfo::Unpacked, DebuginfoLevel::Full, SplitDwarfKind::Single, LinkerPluginLto::Unspecified, RemapPathPrefix::Yes { remapped_prefix }, RemapPathScope::Yes(scope @ "debuginfo"), ) => { rustc(unstable_options) .input("foo.rs") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .remap_path_prefix(cwd(), remapped_prefix) .arg(format!("-Zremap-path-scope={scope}")) .run(); let found_files = cwd_filenames(); let object_files = cwd_object_filenames(); assert_eq!(object_files.len(), 1); let mut expected_files = BTreeSet::new(); expected_files.extend(object_files); expected_files.insert("foo".to_string()); FileAssertions { expected_files: expected_files.iter().map(String::as_ref).collect(), } .assert_on(&found_files); check_path_remap(cwd(), RemapExpectation::Remapped); } // unpacked-remapped-wrong-scope // - Debuginfo in `.o` files // - `.o` and binary refer to un-remapped `.o` paths because remap path scope is macro // - `.o` present // - `.dwo` never created // - `.dwp` never created ( SplitDebuginfo::Unpacked, DebuginfoLevel::Full, SplitDwarfKind::Single, LinkerPluginLto::Unspecified, RemapPathPrefix::Yes { remapped_prefix }, RemapPathScope::Yes(scope @ "macro"), ) => { rustc(unstable_options) .input("foo.rs") .split_debuginfo(split_kind.cli_value()) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .remap_path_prefix(cwd(), remapped_prefix) .arg(format!("-Zremap-path-scope={scope}")) .run(); let found_files = cwd_filenames(); let object_files = cwd_object_filenames(); assert_eq!(object_files.len(), 1); let mut expected_files = BTreeSet::new(); expected_files.extend(object_files); expected_files.insert("foo".to_string()); FileAssertions { expected_files: expected_files.iter().map(String::as_ref).collect(), } .assert_on(&found_files); check_path_remap(cwd(), RemapExpectation::NoRemap); } (split_kind, level, split_dwarf_kind, lto, remap_path_prefix, remap_path_scope) => { panic!( "split_kind={:?} + level={:?} + split_dwarf_kind={:?} + lto={:?} + remap_path_prefix={:?} + remap_path_scope={:?} is not handled on linux/other", split_kind, level, split_dwarf_kind, lto, remap_path_prefix, remap_path_scope ) } } } #[derive(PartialEq)] enum RemapExpectation { Remapped, NoRemap, } #[track_caller] fn check_path_remap(cwd_path: PathBuf, remap_expectation: RemapExpectation) { let cwd_path = cwd_path.to_str().unwrap(); let output = llvm_dwarfdump().input("foo").arg("--debug-info").run().stdout_utf8(); let output_lines: Vec<_> = output.lines().collect(); // Look for `DW_AT_comp_dir` and `DW_AT_GNU_dwo_name` via `llvm-dwarfdump`. Note: space // between uses tabs. // // ```text // 0x0000000b: DW_TAG_compile_unit // DW_AT_stmt_list (0x00000000) // DW_AT_comp_dir ("/__MY_REMAPPED_PATH") # this could be e.g. /home/repos/rust/ if not remapped // DW_AT_GNU_dwo_name ("foo.foo.fc848df41df7a00d-cgu.0.rcgu.dwo") // ``` // // FIXME: this is very fragile because the output format can be load-bearing, but doing this // via `object` + `gimli` is rather difficult. let mut window = output_lines.windows(2); while let Some([first_ln, second_ln]) = window.next() { let first_ln = first_ln.trim(); let second_ln = second_ln.trim(); if !second_ln.starts_with("DW_AT_GNU_dwo_name") { continue; } let Some((comp_dir_attr_name, comp_dir_attr_val)) = first_ln.split_once("\t") else { continue; }; println!("comp_dir_attr_name: `{}`", comp_dir_attr_name); println!("cwd_path_string: `{}`", cwd_path); if comp_dir_attr_name != "DW_AT_comp_dir" { continue; } println!("comp_dir_attr_val: `{}`", comp_dir_attr_val); // Possibly `("/__MY_REMAPPED_PATH")` or `($cwd_path_string)`. // // FIXME: this check is insufficiently precise, it should probably also match on suffix // (`.o` vs `.dwo` reference). But also, string matching is just very fragile. let comp_dir_attr_val = comp_dir_attr_val.trim(); match remap_expectation { RemapExpectation::Remapped => { assert!( !comp_dir_attr_val.contains(&cwd_path), "unexpected non-remapped path found in `DW_AT_comp_dir`: {}", comp_dir_attr_val ); } RemapExpectation::NoRemap => { assert!( comp_dir_attr_val.contains(&cwd_path), "failed to find un-remapped path in `DW_AT_comp_dir`: {}", comp_dir_attr_val ); } } } } } fn main() { // ENHANCEMENT: we are only checking that split-debuginfo is splitting is some way, shape or // form, we do not sanity check the actual debuginfo artifacts on non-Linux! It may be possible // to also sanity check the debuginfo artifacts, but I did not want to do that during the port // to rmake.rs initially. // ENHANCEMENT: the Linux checks have significantly more coverage for interaction between `-C // split-debuginfo` and other flags compared to windows-msvc or windows-gnu or darwin or some // other non-linux targets. It would be cool if their test coverage could be improved. // NOTE: these combinations are not exhaustive, because while porting to rmake.rs initially I // tried to preserve the existing test behavior closely. Notably, no attempt was made to // exhaustively cover all cases in the 6-fold Cartesian product of `{,-Csplit=debuginfo=...}` x // `{,-Cdebuginfo=...}` x `{,--remap-path-prefix}` x `{,-Zremap-path-scope=...}` x // `{,-Zsplit-dwarf-kind=...}` x `{,-Clinker-plugin-lto}`. If you really want to, you can // identify which combination isn't exercised with a 6-layers nested for loop iterating through // each of the cli flag enum variants. if is_msvc() { // FIXME: the windows-msvc test coverage is sparse at best. windows_msvc_tests::split_debuginfo(SplitDebuginfo::Off, DebuginfoLevel::Unspecified); windows_msvc_tests::split_debuginfo(SplitDebuginfo::Unpacked, DebuginfoLevel::Unspecified); windows_msvc_tests::split_debuginfo(SplitDebuginfo::Packed, DebuginfoLevel::Unspecified); windows_msvc_tests::split_debuginfo(SplitDebuginfo::Off, DebuginfoLevel::None); windows_msvc_tests::split_debuginfo(SplitDebuginfo::Unpacked, DebuginfoLevel::None); windows_msvc_tests::split_debuginfo(SplitDebuginfo::Packed, DebuginfoLevel::None); windows_msvc_tests::split_debuginfo(SplitDebuginfo::Off, DebuginfoLevel::Full); windows_msvc_tests::split_debuginfo(SplitDebuginfo::Unpacked, DebuginfoLevel::Full); windows_msvc_tests::split_debuginfo(SplitDebuginfo::Packed, DebuginfoLevel::Full); } else if is_windows() { // FIXME(#135531): the `Makefile` version didn't test windows at all. I don't know about the // intended behavior on windows-gnu to expand test coverage while porting this to rmake.rs, // but the test coverage here really should be expanded since some windows-gnu targets are // Tier 1. } else if is_darwin() { // FIXME: the darwin test coverage is sparse at best. // Expect no `.dSYM` generation if debuginfo is not requested (special case). darwin_tests::split_debuginfo(SplitDebuginfo::Unspecified, DebuginfoLevel::Unspecified); darwin_tests::split_debuginfo(SplitDebuginfo::Off, DebuginfoLevel::Unspecified); darwin_tests::split_debuginfo(SplitDebuginfo::Unpacked, DebuginfoLevel::Unspecified); darwin_tests::split_debuginfo(SplitDebuginfo::Packed, DebuginfoLevel::Unspecified); darwin_tests::split_debuginfo(SplitDebuginfo::Off, DebuginfoLevel::None); darwin_tests::split_debuginfo(SplitDebuginfo::Unpacked, DebuginfoLevel::None); darwin_tests::split_debuginfo(SplitDebuginfo::Packed, DebuginfoLevel::None); darwin_tests::split_debuginfo(SplitDebuginfo::Off, DebuginfoLevel::Full); darwin_tests::split_debuginfo(SplitDebuginfo::Unpacked, DebuginfoLevel::Full); darwin_tests::split_debuginfo(SplitDebuginfo::Packed, DebuginfoLevel::Full); } else { // Unix as well as the non-linux + non-windows + non-darwin targets. // FIXME: this `uname` check is very funny, it really should be refined (e.g. llvm bug // for riscv64 targets). // NOTE: some options are not stable on non-linux + non-windows + non-darwin targets... let unstable_options = if uname() == "Linux" { UnstableOptions::Unspecified } else { UnstableOptions::Yes }; // FIXME: we should add a test with scope `split-debuginfo,split-debuginfo-path` that greps // the entire `.dwp` file for remapped paths (i.e. without going through objdump or // readelf). See . use shared_linux_other_tests::CrossCrateTest; // unspecified `-Csplit-debuginfo` shared_linux_other_tests::split_debuginfo( CrossCrateTest::No, unstable_options, SplitDebuginfo::Unspecified, DebuginfoLevel::Full, SplitDwarfKind::Unspecified, LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ); // off shared_linux_other_tests::split_debuginfo( CrossCrateTest::No, unstable_options, SplitDebuginfo::Off, DebuginfoLevel::Full, SplitDwarfKind::Unspecified, LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ); // packed-split shared_linux_other_tests::split_debuginfo( CrossCrateTest::No, unstable_options, SplitDebuginfo::Packed, DebuginfoLevel::Full, SplitDwarfKind::Split, LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ); // packed-single shared_linux_other_tests::split_debuginfo( CrossCrateTest::No, unstable_options, SplitDebuginfo::Packed, DebuginfoLevel::Full, SplitDwarfKind::Single, LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ); // packed-lto-split shared_linux_other_tests::split_debuginfo( CrossCrateTest::No, unstable_options, SplitDebuginfo::Packed, DebuginfoLevel::Full, SplitDwarfKind::Split, LinkerPluginLto::Yes, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ); // packed-lto-single shared_linux_other_tests::split_debuginfo( CrossCrateTest::No, unstable_options, SplitDebuginfo::Packed, DebuginfoLevel::Full, SplitDwarfKind::Single, LinkerPluginLto::Yes, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ); // FIXME: the remapping tests probably need to be reworked, see // . // packed-remapped-split shared_linux_other_tests::split_debuginfo( CrossCrateTest::No, unstable_options, SplitDebuginfo::Packed, DebuginfoLevel::Full, SplitDwarfKind::Split, LinkerPluginLto::Unspecified, RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" }, RemapPathScope::Unspecified, ); // packed-remapped-single shared_linux_other_tests::split_debuginfo( CrossCrateTest::No, unstable_options, SplitDebuginfo::Packed, DebuginfoLevel::Full, SplitDwarfKind::Single, LinkerPluginLto::Unspecified, RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" }, RemapPathScope::Unspecified, ); // packed-remapped-scope shared_linux_other_tests::split_debuginfo( CrossCrateTest::No, unstable_options, SplitDebuginfo::Packed, DebuginfoLevel::Full, SplitDwarfKind::Single, LinkerPluginLto::Unspecified, RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" }, RemapPathScope::Yes("debuginfo"), ); // packed-remapped-wrong-scope shared_linux_other_tests::split_debuginfo( CrossCrateTest::No, unstable_options, SplitDebuginfo::Packed, DebuginfoLevel::Full, SplitDwarfKind::Single, LinkerPluginLto::Unspecified, RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" }, RemapPathScope::Yes("macro"), ); // packed-crosscrate-split shared_linux_other_tests::split_debuginfo( CrossCrateTest::Yes, unstable_options, SplitDebuginfo::Packed, DebuginfoLevel::Full, SplitDwarfKind::Split, LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ); // packed-crosscrate-single shared_linux_other_tests::split_debuginfo( CrossCrateTest::Yes, unstable_options, SplitDebuginfo::Packed, DebuginfoLevel::Full, SplitDwarfKind::Single, LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ); // unpacked-split shared_linux_other_tests::split_debuginfo( CrossCrateTest::No, unstable_options, SplitDebuginfo::Unpacked, DebuginfoLevel::Full, SplitDwarfKind::Split, LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ); // unpacked-single shared_linux_other_tests::split_debuginfo( CrossCrateTest::No, unstable_options, SplitDebuginfo::Unpacked, DebuginfoLevel::Full, SplitDwarfKind::Single, LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ); // unpacked-lto-split shared_linux_other_tests::split_debuginfo( CrossCrateTest::No, unstable_options, SplitDebuginfo::Unpacked, DebuginfoLevel::Full, SplitDwarfKind::Split, LinkerPluginLto::Yes, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ); // unpacked-lto-single shared_linux_other_tests::split_debuginfo( CrossCrateTest::No, unstable_options, SplitDebuginfo::Unpacked, DebuginfoLevel::Full, SplitDwarfKind::Single, LinkerPluginLto::Yes, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ); // unpacked-remapped-split shared_linux_other_tests::split_debuginfo( CrossCrateTest::No, unstable_options, SplitDebuginfo::Unpacked, DebuginfoLevel::Full, SplitDwarfKind::Split, LinkerPluginLto::Unspecified, RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" }, RemapPathScope::Unspecified, ); // unpacked-remapped-single shared_linux_other_tests::split_debuginfo( CrossCrateTest::No, unstable_options, SplitDebuginfo::Unpacked, DebuginfoLevel::Full, SplitDwarfKind::Single, LinkerPluginLto::Unspecified, RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" }, RemapPathScope::Unspecified, ); // unpacked-remapped-scope shared_linux_other_tests::split_debuginfo( CrossCrateTest::No, unstable_options, SplitDebuginfo::Unpacked, DebuginfoLevel::Full, SplitDwarfKind::Single, LinkerPluginLto::Unspecified, RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" }, RemapPathScope::Yes("debuginfo"), ); // unpacked-remapped-wrong-scope shared_linux_other_tests::split_debuginfo( CrossCrateTest::No, unstable_options, SplitDebuginfo::Unpacked, DebuginfoLevel::Full, SplitDwarfKind::Single, LinkerPluginLto::Unspecified, RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" }, RemapPathScope::Yes("macro"), ); // unpacked-crosscrate-split shared_linux_other_tests::split_debuginfo( CrossCrateTest::Yes, unstable_options, SplitDebuginfo::Unpacked, DebuginfoLevel::Full, SplitDwarfKind::Split, LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ); // unpacked-crosscrate-single shared_linux_other_tests::split_debuginfo( CrossCrateTest::Yes, unstable_options, SplitDebuginfo::Unpacked, DebuginfoLevel::Full, SplitDwarfKind::Single, LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, ); } }