Change:
[ ! -d $(TMPDIR)/foo.dSYM ] else ifdef IS_WINDOWS <del> # Windows only supports =packed </del> <ins> # Windows only supports packed debuginfo - nothing to test. </ins> off: packed: unpacked: else <ins> # Some non-Windows, non-Darwin platforms are not stable, and some are. </ins> ifeq ($(UNAME),Linux) UNSTABLEOPTS := else UNSTABLEOPTS := -Zunstable-options endif <ins> # - Debuginfo in `.o` files # - `.o` deleted # - `.dwo` never created # - `.dwp` never created </ins> off: $(RUSTC) foo.rs -g -C $(UNSTABLEOPTS) split-debuginfo=off [ ! -f $(TMPDIR)/*.dwp ] [ ! -f $(TMPDIR)/*.dwo ] $(RUSTC) foo.rs -g [ ! -f $(TMPDIR)/*.dwp ] [ ! -f $(TMPDIR)/*.dwo ] <del> packed: packed-split packed-single </del> <ins> packed: packed-split packed-single packed-lto packed-remapped packed-crosscrate # - Debuginfo in `.dwo` files # - `.o` deleted # - `.dwo` deleted # - `.dwp` present </ins> packed-split: $(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=packed -Zsplit-dwarf-kind=split <del> ls $(TMPDIR)/*.dwp rm -rf $(TMPDIR)/*.dwp $(TMPDIR)/*.dwo </del> <ins> ls $(TMPDIR)/*.o && exit 1 || exit 0 ls $(TMPDIR)/*.dwo && exit 1 || exit 0 rm $(TMPDIR)/foo.dwp rm $(TMPDIR)/$(call BIN,foo) # - Debuginfo in `.o` files # - `.o` deleted # - `.dwo` never created # - `.dwp` present </ins> packed-single: $(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=packed -Zsplit-dwarf-kind=single <del> ls $(TMPDIR)/*.dwp </del> <ins> ls $(TMPDIR)/*.o && exit 1 || exit 0 ls $(TMPDIR)/*.dwo && exit 1 || exit 0 rm $(TMPDIR)/foo.dwp rm $(TMPDIR)/$(call BIN,foo) packed-lto: packed-lto-split 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 packed-lto-split: $(RUSTC) baz.rs -g $(UNSTABLEOPTS) -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split  --crate-type=rlib -Clinker-plugin-lto ls $(TMPDIR)/*.o && exit 1 || exit 0 ls $(TMPDIR)/*.dwo && exit 1 || exit 0 ls $(TMPDIR)/*.dwp && exit 1 || exit 0 rm $(TMPDIR)/libbaz.rlib # - 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 packed-lto-single: $(RUSTC) baz.rs -g $(UNSTABLEOPTS) -Csplit-debuginfo=packed -Zsplit-dwarf-kind=single  --crate-type=rlib -Clinker-plugin-lto ls $(TMPDIR)/*.o && exit 1 || exit 0 </ins> ls $(TMPDIR)/*.dwo && exit 1 || exit 0 <del> rm -rf $(TMPDIR)/*.dwp </del> <ins> ls $(TMPDIR)/*.dwp && exit 1 || exit 0 rm $(TMPDIR)/libbaz.rlib </ins> packed-remapped: packed-remapped-split packed-remapped-single <ins> # - Debuginfo in `.dwo` files # - `.o` and binary refer to remapped `.dwo` paths which do not exist # - `.o` deleted # - `.dwo` deleted # - `.dwp` present </ins> packed-remapped-split: $(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=packed -C debuginfo=2  -Z split-dwarf-kind=split --remap-path-prefix $(TMPDIR)=/a foo.rs -g objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1 <ins> ls $(TMPDIR)/*.o && exit 1 || exit 0 ls $(TMPDIR)/*.dwo && exit 1 || exit 0 rm $(TMPDIR)/foo.dwp rm $(TMPDIR)/$(call BIN,foo) # - Debuginfo in `.o` files # - `.o` and binary refer to remapped `.o` paths which do not exist # - `.o` deleted # - `.dwo` never created # - `.dwp` present </ins> packed-remapped-single: $(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=packed -C debuginfo=2  -Z split-dwarf-kind=single --remap-path-prefix $(TMPDIR)=/a foo.rs -g objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1 <ins> ls $(TMPDIR)/*.o && exit 1 || exit 0 ls $(TMPDIR)/*.dwo && exit 1 || exit 0 rm $(TMPDIR)/foo.dwp rm $(TMPDIR)/$(call BIN,foo) </ins> packed-crosscrate: packed-crosscrate-split packed-crosscrate-single <ins> # - 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 </ins> packed-crosscrate-split: $(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=packed  -Zsplit-dwarf-kind=split -C debuginfo=2 -g bar.rs ls $(TMPDIR)/*.rlib <ins> ls $(TMPDIR)/*.o && exit 1 || exit 0 </ins> ls $(TMPDIR)/*.dwo && exit 1 || exit 0 ls $(TMPDIR)/*.dwp && exit 1 || exit 0 <del> $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib -Z unstable-options $(UNSTABLEOPTS)  </del> <ins> $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib $(UNSTABLEOPTS)  </ins> -C split-debuginfo=packed -Zsplit-dwarf-kind=split -C debuginfo=2 -g main.rs <del> rm $(TMPDIR)/*.dwo </del> <ins> ls $(TMPDIR)/*.o && exit 1 || exit 0 ls $(TMPDIR)/*.dwo && exit 1 || exit 0 </ins> rm $(TMPDIR)/main.dwp rm $(TMPDIR)/$(call BIN,main) <ins> # - 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 </ins> packed-crosscrate-single: $(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=packed  -Zsplit-dwarf-kind=single -C debuginfo=2 -g bar.rs ls $(TMPDIR)/*.rlib <ins> ls $(TMPDIR)/*.o && exit 1 || exit 0 </ins> ls $(TMPDIR)/*.dwo && exit 1 || exit 0 ls $(TMPDIR)/*.dwp && exit 1 || exit 0 <del> $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib -Z unstable-options $(UNSTABLEOPTS)  </del> <ins> $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib $(UNSTABLEOPTS)  </ins> -C split-debuginfo=packed -Zsplit-dwarf-kind=single -C debuginfo=2 -g main.rs <ins> ls $(TMPDIR)/*.o && exit 1 || exit 0 </ins> ls $(TMPDIR)/*.dwo && exit 1 || exit 0 rm $(TMPDIR)/main.dwp rm $(TMPDIR)/$(call BIN,main) <del> unpacked: unpacked-split unpacked-single unpacked-remapped-split unpacked-remapped-single </del> <ins> unpacked: unpacked-split unpacked-single unpacked-lto unpacked-remapped unpacked-crosscrate # - Debuginfo in `.dwo` files # - `.o` deleted # - `.dwo` present # - `.dwp` never created </ins> unpacked-split: $(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=unpacked -Zsplit-dwarf-kind=split <ins> ls $(TMPDIR)/*.o && exit 1 || exit 0 rm $(TMPDIR)/*.dwo </ins> ls $(TMPDIR)/*.dwp && exit 1 || exit 0 <del> ls $(TMPDIR)/*.dwo rm -rf $(TMPDIR)/*.dwp $(TMPDIR)/*.dwo </del> <ins> rm $(TMPDIR)/$(call BIN,foo) # - Debuginfo in `.o` files # - `.o` present # - `.dwo` never created # - `.dwp` never created </ins> unpacked-single: $(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=unpacked -Zsplit-dwarf-kind=single <ins> ls $(TMPDIR)/*.o ls $(TMPDIR)/*.dwo && exit 1 || exit 0 ls $(TMPDIR)/*.dwp && exit 1 || exit 0 rm $(TMPDIR)/$(call BIN,foo) unpacked-lto: packed-lto-split 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 unpacked-lto-split: $(RUSTC) baz.rs -g $(UNSTABLEOPTS) -Csplit-debuginfo=unpacked -Zsplit-dwarf-kind=split  --crate-type=rlib -Clinker-plugin-lto ls $(TMPDIR)/*.o && exit 1 || exit 0 ls $(TMPDIR)/*.dwo && exit 1 || exit 0 </ins> ls $(TMPDIR)/*.dwp && exit 1 || exit 0 <ins> rm $(TMPDIR)/libbaz.rlib # - 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 unpacked-lto-single: $(RUSTC) baz.rs -g $(UNSTABLEOPTS) -Csplit-debuginfo=unpacked -Zsplit-dwarf-kind=single  --crate-type=rlib -Clinker-plugin-lto ls $(TMPDIR)/*.o && exit 1 || exit 0 </ins> ls $(TMPDIR)/*.dwo && exit 1 || exit 0 <ins> ls $(TMPDIR)/*.dwp && exit 1 || exit 0 rm $(TMPDIR)/libbaz.rlib unpacked-remapped: unpacked-remapped-split unpacked-remapped-single # - Debuginfo in `.dwo` files # - `.o` and binary refer to remapped `.dwo` paths which do not exist # - `.o` deleted # - `.dwo` present # - `.dwp` never created </ins> unpacked-remapped-split: $(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=unpacked -C debuginfo=2  -Z split-dwarf-kind=split --remap-path-prefix $(TMPDIR)=/a foo.rs -g objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1 <ins> ls $(TMPDIR)/*.o && exit 1 || exit 0 rm $(TMPDIR)/*.dwo ls $(TMPDIR)/*.dwp && exit 1 || exit 0 rm $(TMPDIR)/$(call BIN,foo) # - Debuginfo in `.o` files # - `.o` and binary refer to remapped `.o` paths which do not exist # - `.o` present # - `.dwo` never created # - `.dwp` never created </ins> unpacked-remapped-single: $(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=unpacked -C debuginfo=2  -Z split-dwarf-kind=single --remap-path-prefix $(TMPDIR)=/a foo.rs -g objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1 <ins> ls $(TMPDIR)/*.o ls $(TMPDIR)/*.dwo && exit 1 || exit 0 ls $(TMPDIR)/*.dwp && exit 1 || exit 0 rm $(TMPDIR)/$(call BIN,foo) unpacked-crosscrate: packed-crosscrate-split packed-crosscrate-single # - 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 unpacked-crosscrate-split: $(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=unpacked  -Zsplit-dwarf-kind=split -C debuginfo=2 -g bar.rs ls $(TMPDIR)/*.rlib ls $(TMPDIR)/*.o && exit 1 || exit 0 ls $(TMPDIR)/*.dwo ls $(TMPDIR)/*.dwp && exit 1 || exit 0 $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib $(UNSTABLEOPTS)  -C split-debuginfo=unpacked -Zsplit-dwarf-kind=split -C debuginfo=2 -g main.rs ls $(TMPDIR)/*.o && exit 1 || exit 0 rm $(TMPDIR)/*.dwo ls $(TMPDIR)/*.dwp && exit 1 || exit 0 rm $(TMPDIR)/$(call BIN,main) # - 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 unpacked-crosscrate-single: $(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=unpacked  -Zsplit-dwarf-kind=single -C debuginfo=2 -g bar.rs ls $(TMPDIR)/*.rlib ls $(TMPDIR)/*.o ls $(TMPDIR)/*.dwo && exit 1 || exit 0 ls $(TMPDIR)/*.dwp && exit 1 || exit 0 $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib $(UNSTABLEOPTS)  -C split-debuginfo=unpacked -Zsplit-dwarf-kind=single -C debuginfo=2 -g main.rs ls $(TMPDIR)/*.o ls $(TMPDIR)/*.dwo && exit 1 || exit 0 ls $(TMPDIR)/*.dwp && exit 1 || exit 0 rm $(TMPDIR)/$(call BIN,main) </ins> endif endif

Discussion:
When I add to my in (on Linux), my build fails with: In debug I initially had the same problem but a fixed it without requiring me to turn off . However, release continues to be failing even after . rustc --version rustc 1.65.0 ( 2022-11-02) cargo --version cargo 1.65.0 ( 2022-10-20)
It's silent in my macOS in release profile, but no dSYM generated. It's OK in dev profile.
Oh not sure if it matters, but I also have debug = true set for my release build.
Thanks for your reminder. I forgot that is off by default in release profile.
Can confirm this happens for me as well but with .
Can you provide some more information, such as the target you are building for (?), the output of , and anything else that might help narrow down the issue? Is your profile exactly this?
I got this same error when I tried compiling with both split debug info and linker plugin LTO.
also need LTO enabled, works fine without here
Thanks for clarifying. Yeah, I do have LTO on as well.
cc or in case this didn't hit your radar. The reproduction is: with the error: From what I can tell, the archiver is expecting a file to exist ( around ). AFAIK, that doesn't make sense with a bitcode-only output. The decision of whether or not a dwo is expected I think is made around . I'm guessing that decision (or perhaps something at a higher level) needs to be aware that the split-dwarf won't happen with bitcode-only output? (IOW, that case should only be true if was called with a value with ?)
Should this issue be marked as a stable-to-stable regression?
Submitted to fix this.
Thanks for the ping and the great pre-investigation,
I am encountering this on without LTO. (Or at least I'm not explicitly enabling LTO, and I don't have LTO enabled in ). Builds in local projects work fine, only is affected. Adding the following to triggers it: Should I open a new issue, or do you want to track this together with the LTO case?
Can you put together a reproduction?

Also, it might help to post the output of with your command (along with the exact command you are running).
Here are the outputs of : <details<summarySuccessful run</summary</details<details<summaryFailed run</summary</detailsI imagine simply running Ubuntu 20.04 and adding this to should do the trick: But I'll verify it and let you know.
Yes, I've verified that this is reproducible on a clean Ubuntu 20.04 installation or live CD. Other than the commands above you need to and install Rust through
Oh, I see that the failed run does contain the flag. So it is the same issue. I'm confused why implicitly enables it by default while other invocations don't, but that's a separate issue.
rustfilt sets LTO . I don't know what other commands you are running, but if it is , then that would use the dev profile without LTO.
Up on message: