@@ -166,7 +166,9 @@ pub(crate) fn link_binary(sess: &Session,
166166
167167 // Remove the temporary object file and metadata if we aren't saving temps
168168 if !sess. opts . cg . save_temps {
169- if sess. opts . output_types . should_trans ( ) {
169+ if sess. opts . output_types . should_trans ( ) &&
170+ !preserve_objects_for_their_debuginfo ( sess)
171+ {
170172 for obj in trans. modules . iter ( ) . filter_map ( |m| m. object . as_ref ( ) ) {
171173 remove ( sess, obj) ;
172174 }
@@ -190,6 +192,52 @@ pub(crate) fn link_binary(sess: &Session,
190192 out_filenames
191193}
192194
195+ /// Returns a boolean indicating whether we should preserve the object files on
196+ /// the filesystem for their debug information. This is often useful with
197+ /// split-dwarf like schemes.
198+ fn preserve_objects_for_their_debuginfo ( sess : & Session ) -> bool {
199+ // If the objects don't have debuginfo there's nothing to preserve.
200+ if sess. opts . debuginfo == NoDebugInfo {
201+ return false
202+ }
203+
204+ // If we're only producing artifacts that are archives, no need to preserve
205+ // the objects as they're losslessly contained inside the archives.
206+ let output_linked = sess. crate_types . borrow ( )
207+ . iter ( )
208+ . any ( |x| * x != config:: CrateTypeRlib && * x != config:: CrateTypeStaticlib ) ;
209+ if !output_linked {
210+ return false
211+ }
212+
213+ // If we're on OSX then the equivalent of split dwarf is turned on by
214+ // default. The final executable won't actually have any debug information
215+ // except it'll have pointers to elsewhere. Historically we've always run
216+ // `dsymutil` to "link all the dwarf together" but this is actually sort of
217+ // a bummer for incremental compilation! (the whole point of split dwarf is
218+ // that you don't do this sort of dwarf link).
219+ //
220+ // Basically as a result this just means that if we're on OSX and we're
221+ // *not* running dsymutil then the object files are the only source of truth
222+ // for debug information, so we must preserve them.
223+ if sess. target . target . options . is_like_osx {
224+ match sess. opts . debugging_opts . run_dsymutil {
225+ // dsymutil is not being run, preserve objects
226+ Some ( false ) => return true ,
227+
228+ // dsymutil is being run, no need to preserve the objects
229+ Some ( true ) => return false ,
230+
231+ // The default historical behavior was to always run dsymutil, so
232+ // we're preserving that temporarily, but we're likely to switch the
233+ // default soon.
234+ None => return false ,
235+ }
236+ }
237+
238+ false
239+ }
240+
193241fn filename_for_metadata ( sess : & Session , crate_name : & str , outputs : & OutputFilenames ) -> PathBuf {
194242 let out_filename = outputs. single_output_file . clone ( )
195243 . unwrap_or ( outputs
@@ -736,8 +784,12 @@ fn link_natively(sess: &Session,
736784
737785
738786 // On macOS, debuggers need this utility to get run to do some munging of
739- // the symbols
740- if sess. target . target . options . is_like_osx && sess. opts . debuginfo != NoDebugInfo {
787+ // the symbols. Note, though, that if the object files are being preserved
788+ // for their debug information there's no need for us to run dsymutil.
789+ if sess. target . target . options . is_like_osx &&
790+ sess. opts . debuginfo != NoDebugInfo &&
791+ !preserve_objects_for_their_debuginfo ( sess)
792+ {
741793 match Command :: new ( "dsymutil" ) . arg ( out_filename) . output ( ) {
742794 Ok ( ..) => { }
743795 Err ( e) => sess. fatal ( & format ! ( "failed to run dsymutil: {}" , e) ) ,
0 commit comments