@@ -18,6 +18,7 @@ use rustc_data_structures::temp_dir::MaybeTempDir;
18
18
use rustc_errors:: { DiagCtxtHandle , ErrorGuaranteed , FatalError } ;
19
19
use rustc_fs_util:: { fix_windows_verbatim_for_gcc, try_canonicalize} ;
20
20
use rustc_hir:: def_id:: { CrateNum , LOCAL_CRATE } ;
21
+ use rustc_macros:: Diagnostic ;
21
22
use rustc_metadata:: fs:: { copy_to_stdout, emit_wrapper_file, METADATA_FILENAME } ;
22
23
use rustc_metadata:: { find_native_static_library, walk_native_lib_search_dirs} ;
23
24
use rustc_middle:: bug;
@@ -438,7 +439,7 @@ fn link_rlib<'a>(
438
439
ab. add_file ( & lib)
439
440
}
440
441
441
- return Ok ( ab) ;
442
+ Ok ( ab)
442
443
}
443
444
444
445
/// Extract all symbols defined in raw-dylib libraries, collated by library name.
@@ -750,6 +751,14 @@ fn link_dwarf_object(sess: &Session, cg_results: &CodegenResults, executable_out
750
751
}
751
752
}
752
753
754
+ #[ derive( Diagnostic ) ]
755
+ #[ diag( codegen_ssa_linker_output) ]
756
+ /// Translating this is kind of useless. We don't pass translation flags to the linker, so we'd just
757
+ /// end up with inconsistent languages within the same diagnostic.
758
+ struct LinkerOutput {
759
+ inner : String ,
760
+ }
761
+
753
762
/// Create a dynamic library or executable.
754
763
///
755
764
/// This will invoke the system linker/cc to create the resulting file. This links to all upstream
@@ -976,12 +985,12 @@ fn link_natively(
976
985
let mut output = prog. stderr . clone ( ) ;
977
986
output. extend_from_slice ( & prog. stdout ) ;
978
987
let escaped_output = escape_linker_output ( & output, flavor) ;
979
- // FIXME: Add UI tests for this error.
980
988
let err = errors:: LinkingFailed {
981
989
linker_path : & linker_path,
982
990
exit_status : prog. status ,
983
991
command : & cmd,
984
992
escaped_output,
993
+ verbose : sess. opts . verbose ,
985
994
} ;
986
995
sess. dcx ( ) . emit_err ( err) ;
987
996
// If MSVC's `link.exe` was expected but the return code
@@ -1022,8 +1031,22 @@ fn link_natively(
1022
1031
1023
1032
sess. dcx ( ) . abort_if_errors ( ) ;
1024
1033
}
1025
- info ! ( "linker stderr:\n {}" , escape_string( & prog. stderr) ) ;
1026
- info ! ( "linker stdout:\n {}" , escape_string( & prog. stdout) ) ;
1034
+
1035
+ if !prog. stderr . is_empty ( ) {
1036
+ // We already print `warning:` at the start of the diagnostic. Remove it from the linker output if present.
1037
+ let stderr = escape_string ( & prog. stderr ) ;
1038
+ debug ! ( "original stderr: {stderr}" ) ;
1039
+ let stderr = stderr
1040
+ . strip_prefix ( "warning: " )
1041
+ . unwrap_or ( & stderr)
1042
+ . replace ( ": warning: " , ": " ) ;
1043
+ sess. dcx ( ) . emit_warn ( LinkerOutput { inner : format ! ( "linker stderr: {stderr}" ) } ) ;
1044
+ }
1045
+ if !prog. stdout . is_empty ( ) && sess. opts . verbose {
1046
+ sess. dcx ( ) . emit_warn ( LinkerOutput {
1047
+ inner : format ! ( "linker stdout: {}" , escape_string( & prog. stdout) ) ,
1048
+ } ) ;
1049
+ }
1027
1050
}
1028
1051
Err ( e) => {
1029
1052
let linker_not_found = e. kind ( ) == io:: ErrorKind :: NotFound ;
@@ -1319,15 +1342,15 @@ fn link_sanitizer_runtime(
1319
1342
fn find_sanitizer_runtime ( sess : & Session , filename : & str ) -> PathBuf {
1320
1343
let path = sess. target_tlib_path . dir . join ( filename) ;
1321
1344
if path. exists ( ) {
1322
- return sess. target_tlib_path . dir . clone ( ) ;
1345
+ sess. target_tlib_path . dir . clone ( )
1323
1346
} else {
1324
1347
let default_sysroot =
1325
1348
filesearch:: get_or_default_sysroot ( ) . expect ( "Failed finding sysroot" ) ;
1326
1349
let default_tlib = filesearch:: make_target_lib_path (
1327
1350
& default_sysroot,
1328
1351
sess. opts . target_triple . triple ( ) ,
1329
1352
) ;
1330
- return default_tlib;
1353
+ default_tlib
1331
1354
}
1332
1355
}
1333
1356
0 commit comments