Skip to content

Commit 8faed20

Browse files
committed
show linker warnings even if it returns 0
1 parent afb6118 commit 8faed20

File tree

5 files changed

+61
-2
lines changed

5 files changed

+61
-2
lines changed

compiler/rustc_codegen_ssa/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ codegen_ssa_linker_file_stem = couldn't extract file stem from specified linker
160160
codegen_ssa_linker_not_found = linker `{$linker_path}` not found
161161
.note = {$error}
162162
163+
codegen_ssa_linker_output = {$inner}
164+
163165
codegen_ssa_linker_unsupported_modifier = `as-needed` modifier not supported for current linker
164166
165167
codegen_ssa_linking_failed = linking with `{$linker_path}` failed: {$exit_status}

compiler/rustc_codegen_ssa/src/back/link.rs

+24-2
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,14 @@ fn link_dwarf_object<'a>(
721721
}
722722
}
723723

724+
#[derive(Diagnostic)]
725+
#[diag(codegen_ssa_linker_output)]
726+
/// Translating this is kind of useless. We don't pass translation flags to the linker, so we'd just
727+
/// end up with inconsistent languages within the same diagnostic.
728+
struct LinkerOutput {
729+
inner: String,
730+
}
731+
724732
/// Create a dynamic library or executable.
725733
///
726734
/// This will invoke the system linker/cc to create the resulting file. This links to all upstream
@@ -972,8 +980,22 @@ fn link_natively<'a>(
972980

973981
sess.abort_if_errors();
974982
}
975-
info!("linker stderr:\n{}", escape_string(&prog.stderr));
976-
info!("linker stdout:\n{}", escape_string(&prog.stdout));
983+
984+
if !prog.stderr.is_empty() {
985+
// We already print `warning:` at the start of the diagnostic. Remove it from the linker output if present.
986+
let stderr = escape_string(&prog.stderr);
987+
debug!("original stderr: {stderr}");
988+
let stderr = stderr
989+
.strip_prefix("warning: ")
990+
.unwrap_or(&stderr)
991+
.replace(": warning: ", ": ");
992+
sess.emit_warning(LinkerOutput { inner: format!("linker stderr: {stderr}") });
993+
}
994+
if !prog.stdout.is_empty() && sess.opts.verbose {
995+
sess.emit_warning(LinkerOutput {
996+
inner: format!("linker stdout: {}", escape_string(&prog.stdout)),
997+
});
998+
}
977999
}
9781000
Err(e) => {
9791001
let linker_not_found = e.kind() == io::ErrorKind::NotFound;
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
include ../tools.mk
2+
3+
RUN_RUSTC := $(RUSTC_ORIGINAL) main.rs -o $(TMPDIR)/main -C linker=./fake-linker.sh
4+
5+
all:
6+
# Run rustc with our fake linker, and make sure it shows warnings
7+
$(RUN_RUSTC) -C link-arg=run_make_warn 2>&1 | $(CGREP) "warning: linker stderr: bar"
8+
9+
# Make sure it shows stdout, but only when --verbose is passed
10+
$(RUN_RUSTC) -C link-arg=run_make_info --verbose 2>&1 | $(CGREP) "warning: linker stdout: foo"
11+
$(RUN_RUSTC) -C link-arg=run_make_info 2>&1 | $(CGREP) -v "warning: linker stdout: foo"
12+
13+
# Make sure we short-circuit this new path if the linker exits with an error (so the diagnostic is less verbose)
14+
rm -f $(TMPDIR)/main
15+
$(RUN_RUSTC) -C link-arg=run_make_error 2>&1 | $(CGREP) "note: error: baz"
16+
! [ -e $(TMPDIR)/main ]
17+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/bin/sh
2+
3+
code=0
4+
while ! [ $# = 0 ]; do
5+
case "$1" in
6+
run_make_info) echo "foo"
7+
;;
8+
run_make_warn) echo "warning: bar" >&2
9+
;;
10+
run_make_error) echo "error: baz" >&2; code=1
11+
;;
12+
*) ;; # rustc passes lots of args we don't care about
13+
esac
14+
shift
15+
done
16+
17+
exit $code

tests/run-make/linker-warning/main.rs

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fn main() {}

0 commit comments

Comments
 (0)