show linker warnings even if it returns 0
This commit is contained in:
parent
9f4d9dc102
commit
c0822ed9b8
10 changed files with 82 additions and 27 deletions
|
@ -183,6 +183,8 @@ codegen_ssa_linker_file_stem = couldn't extract file stem from specified linker
|
|||
codegen_ssa_linker_not_found = linker `{$linker_path}` not found
|
||||
.note = {$error}
|
||||
|
||||
codegen_ssa_linker_output = {$inner}
|
||||
|
||||
codegen_ssa_linker_unsupported_modifier = `as-needed` modifier not supported for current linker
|
||||
|
||||
codegen_ssa_linking_failed = linking with `{$linker_path}` failed: {$exit_status}
|
||||
|
|
|
@ -18,6 +18,7 @@ use rustc_data_structures::temp_dir::MaybeTempDir;
|
|||
use rustc_errors::DiagCtxtHandle;
|
||||
use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize};
|
||||
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
|
||||
use rustc_macros::Diagnostic;
|
||||
use rustc_metadata::fs::{METADATA_FILENAME, copy_to_stdout, emit_wrapper_file};
|
||||
use rustc_metadata::{find_native_static_library, walk_native_lib_search_dirs};
|
||||
use rustc_middle::bug;
|
||||
|
@ -749,6 +750,14 @@ fn link_dwarf_object(sess: &Session, cg_results: &CodegenResults, executable_out
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_ssa_linker_output)]
|
||||
/// Translating this is kind of useless. We don't pass translation flags to the linker, so we'd just
|
||||
/// end up with inconsistent languages within the same diagnostic.
|
||||
struct LinkerOutput {
|
||||
inner: String,
|
||||
}
|
||||
|
||||
/// Create a dynamic library or executable.
|
||||
///
|
||||
/// This will invoke the system linker/cc to create the resulting file. This links to all upstream
|
||||
|
@ -1028,8 +1037,22 @@ fn link_natively(
|
|||
|
||||
sess.dcx().abort_if_errors();
|
||||
}
|
||||
info!("linker stderr:\n{}", escape_string(&prog.stderr));
|
||||
info!("linker stdout:\n{}", escape_string(&prog.stdout));
|
||||
|
||||
if !prog.stderr.is_empty() {
|
||||
// We already print `warning:` at the start of the diagnostic. Remove it from the linker output if present.
|
||||
let stderr = escape_string(&prog.stderr);
|
||||
debug!("original stderr: {stderr}");
|
||||
let stderr = stderr
|
||||
.strip_prefix("warning: ")
|
||||
.unwrap_or(&stderr)
|
||||
.replace(": warning: ", ": ");
|
||||
sess.dcx().emit_warn(LinkerOutput { inner: format!("linker stderr: {stderr}") });
|
||||
}
|
||||
if !prog.stdout.is_empty() && sess.opts.verbose {
|
||||
sess.dcx().emit_warn(LinkerOutput {
|
||||
inner: format!("linker stdout: {}", escape_string(&prog.stdout)),
|
||||
});
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
let linker_not_found = e.kind() == io::ErrorKind::NotFound;
|
||||
|
|
|
@ -44,7 +44,8 @@ use crate::mir::operand::OperandValue;
|
|||
use crate::mir::place::PlaceRef;
|
||||
use crate::traits::*;
|
||||
use crate::{
|
||||
CachedModuleCodegen, CompiledModule, CrateInfo, ModuleCodegen, ModuleKind, errors, meth, mir,
|
||||
CachedModuleCodegen, CodegenLintLevels, CompiledModule, CrateInfo, ModuleCodegen, ModuleKind,
|
||||
errors, meth, mir,
|
||||
};
|
||||
|
||||
pub(crate) fn bin_op_to_icmp_predicate(op: BinOp, signed: bool) -> IntPredicate {
|
||||
|
@ -927,6 +928,7 @@ impl CrateInfo {
|
|||
dependency_formats: Lrc::clone(tcx.dependency_formats(())),
|
||||
windows_subsystem,
|
||||
natvis_debugger_visualizers: Default::default(),
|
||||
lint_levels: CodegenLintLevels::from_tcx(tcx),
|
||||
};
|
||||
|
||||
info.native_libraries.reserve(n_crates);
|
||||
|
|
|
@ -200,6 +200,7 @@ pub struct CrateInfo {
|
|||
pub dependency_formats: Lrc<Dependencies>,
|
||||
pub windows_subsystem: Option<String>,
|
||||
pub natvis_debugger_visualizers: BTreeSet<DebuggerVisualizerFile>,
|
||||
pub lint_levels: CodegenLintLevels,
|
||||
}
|
||||
|
||||
#[derive(Encodable, Decodable)]
|
||||
|
|
17
tests/run-make/linker-warning/fake-linker.sh
Executable file
17
tests/run-make/linker-warning/fake-linker.sh
Executable file
|
@ -0,0 +1,17 @@
|
|||
#!/bin/sh
|
||||
|
||||
code=0
|
||||
while ! [ $# = 0 ]; do
|
||||
case "$1" in
|
||||
run_make_info) echo "foo"
|
||||
;;
|
||||
run_make_warn) echo "warning: bar" >&2
|
||||
;;
|
||||
run_make_error) echo "error: baz" >&2; code=1
|
||||
;;
|
||||
*) ;; # rustc passes lots of args we don't care about
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
exit $code
|
|
@ -10,6 +10,25 @@ fn main() {
|
|||
// first, compile our linker
|
||||
rustc().arg("fake-linker.rs").output("fake-linker").run();
|
||||
|
||||
// Run rustc with our fake linker, and make sure it shows warnings
|
||||
let warnings = run_rustc().link_arg("run_make_warn").run();
|
||||
warnings.assert_stderr_contains("warning: linker stderr: bar");
|
||||
|
||||
// Make sure it shows stdout, but only when --verbose is passed
|
||||
run_rustc()
|
||||
.link_arg("run_make_info")
|
||||
.verbose()
|
||||
.run()
|
||||
.assert_stderr_contains("warning: linker stdout: foo");
|
||||
run_rustc()
|
||||
.link_arg("run_make_info")
|
||||
.run()
|
||||
.assert_stderr_not_contains("warning: linker stdout: foo");
|
||||
|
||||
// Make sure we short-circuit this new path if the linker exits with an error
|
||||
// (so the diagnostic is less verbose)
|
||||
run_rustc().link_arg("run_make_error").run_fail().assert_stderr_contains("note: error: baz");
|
||||
|
||||
// Make sure we don't show the linker args unless `--verbose` is passed
|
||||
run_rustc()
|
||||
.link_arg("run_make_error")
|
||||
|
|
|
@ -12,11 +12,7 @@ use run_make_support::rustc;
|
|||
fn main() {
|
||||
// A regular compilation should not use rust-lld by default. We'll check that by asking the
|
||||
// linker to display its version number with a link-arg.
|
||||
let output = rustc()
|
||||
.env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info")
|
||||
.link_arg("-Wl,-v")
|
||||
.input("main.rs")
|
||||
.run();
|
||||
let output = rustc().verbose().link_arg("-Wl,-v").input("main.rs").run();
|
||||
assert!(
|
||||
!find_lld_version_in_logs(output.stderr_utf8()),
|
||||
"the LLD version string should not be present in the output logs:\n{}",
|
||||
|
|
|
@ -12,11 +12,7 @@ use run_make_support::rustc;
|
|||
fn main() {
|
||||
// A regular compilation should use rust-lld by default. We'll check that by asking the linker
|
||||
// to display its version number with a link-arg.
|
||||
let output = rustc()
|
||||
.env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info")
|
||||
.link_arg("-Wl,-v")
|
||||
.input("main.rs")
|
||||
.run();
|
||||
let output = rustc().verbose().link_arg("-Wl,-v").input("main.rs").run();
|
||||
assert!(
|
||||
find_lld_version_in_logs(output.stderr_utf8()),
|
||||
"the LLD version string should be present in the output logs:\n{}",
|
||||
|
@ -24,12 +20,8 @@ fn main() {
|
|||
);
|
||||
|
||||
// But it can still be disabled by turning the linker feature off.
|
||||
let output = rustc()
|
||||
.env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info")
|
||||
.link_arg("-Wl,-v")
|
||||
.arg("-Zlinker-features=-lld")
|
||||
.input("main.rs")
|
||||
.run();
|
||||
let output =
|
||||
rustc().verbose().link_arg("-Wl,-v").arg("-Zlinker-features=-lld").input("main.rs").run();
|
||||
assert!(
|
||||
!find_lld_version_in_logs(output.stderr_utf8()),
|
||||
"the LLD version string should not be present in the output logs:\n{}",
|
||||
|
@ -38,6 +30,7 @@ fn main() {
|
|||
}
|
||||
|
||||
fn find_lld_version_in_logs(stderr: String) -> bool {
|
||||
let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap();
|
||||
let lld_version_re =
|
||||
Regex::new(r"^warning: linker stdout: LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap();
|
||||
stderr.lines().any(|line| lld_version_re.is_match(line.trim()))
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ fn main() {
|
|||
// Compile to a custom target spec with rust-lld enabled by default. We'll check that by asking
|
||||
// the linker to display its version number with a link-arg.
|
||||
let output = rustc()
|
||||
.env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info")
|
||||
.verbose()
|
||||
.crate_type("cdylib")
|
||||
.target("custom-target.json")
|
||||
.link_arg("-Wl,-v")
|
||||
|
@ -29,7 +29,7 @@ fn main() {
|
|||
|
||||
// But it can also be disabled via linker features.
|
||||
let output = rustc()
|
||||
.env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info")
|
||||
.verbose()
|
||||
.crate_type("cdylib")
|
||||
.target("custom-target.json")
|
||||
.arg("-Zlinker-features=-lld")
|
||||
|
@ -44,6 +44,7 @@ fn main() {
|
|||
}
|
||||
|
||||
fn find_lld_version_in_logs(stderr: String) -> bool {
|
||||
let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap();
|
||||
let lld_version_re =
|
||||
Regex::new(r"^warning: linker stdout: LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap();
|
||||
stderr.lines().any(|line| lld_version_re.is_match(line.trim()))
|
||||
}
|
||||
|
|
|
@ -14,10 +14,10 @@ fn main() {
|
|||
// Opt-in to lld and the self-contained linker, to link with rust-lld. We'll check that by
|
||||
// asking the linker to display its version number with a link-arg.
|
||||
let output = rustc()
|
||||
.env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info")
|
||||
.arg("-Zlinker-features=+lld")
|
||||
.arg("-Clink-self-contained=+linker")
|
||||
.arg("-Zunstable-options")
|
||||
.verbose()
|
||||
.link_arg(linker_version_flag)
|
||||
.input("main.rs")
|
||||
.run();
|
||||
|
@ -29,8 +29,8 @@ fn main() {
|
|||
|
||||
// It should not be used when we explicitly opt-out of lld.
|
||||
let output = rustc()
|
||||
.env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info")
|
||||
.link_arg(linker_version_flag)
|
||||
.verbose()
|
||||
.arg("-Zlinker-features=-lld")
|
||||
.input("main.rs")
|
||||
.run();
|
||||
|
@ -43,8 +43,8 @@ fn main() {
|
|||
// While we're here, also check that the last linker feature flag "wins" when passed multiple
|
||||
// times to rustc.
|
||||
let output = rustc()
|
||||
.env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info")
|
||||
.link_arg(linker_version_flag)
|
||||
.verbose()
|
||||
.arg("-Clink-self-contained=+linker")
|
||||
.arg("-Zunstable-options")
|
||||
.arg("-Zlinker-features=-lld")
|
||||
|
@ -60,6 +60,7 @@ fn main() {
|
|||
}
|
||||
|
||||
fn find_lld_version_in_logs(stderr: String) -> bool {
|
||||
let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap();
|
||||
let lld_version_re =
|
||||
Regex::new(r"^warning: linker stdout: LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap();
|
||||
stderr.lines().any(|line| lld_version_re.is_match(line.trim()))
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue