Skip to content

Commit 6fa9e3d

Browse files
committed
Auto merge of rust-lang#119286 - jyn514:linker-output, r=<try>
show linker output even if the linker succeeds - show stderr by default - show stdout if `--verbose` is passed - remove both from RUSTC_LOG - hide the linker cli args unless `--verbose` is passed fixes rust-lang#83436. fixes rust-lang#38206. fixes rust-lang#109979. helps with rust-lang#46998. cc https://rust-lang.zulipchat.com/#narrow/stream/233931-t-compiler.2Fmajor-changes/topic/uplift.20some.20-Zverbose.20calls.20and.20rename.20to.E2.80.A6.20compiler-team.23706/near/408986134 this is based on rust-lang#119129 for convenience so i didn't have to duplicate the changes around saving `--verbose` in rust-lang@cb6d033#diff-7a49efa20548d6806dbe1c66dd4dc445fda18fcbbf1709520cadecc4841aae12 try-job: aarch64-apple r? `@bjorn3`
2 parents 0c4f3a4 + fc8b598 commit 6fa9e3d

File tree

27 files changed

+328
-79
lines changed

27 files changed

+328
-79
lines changed

compiler/rustc_codegen_llvm/src/lib.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use rustc_codegen_ssa::back::write::{
3434
CodegenContext, FatLtoInput, ModuleConfig, TargetMachineFactoryConfig, TargetMachineFactoryFn,
3535
};
3636
use rustc_codegen_ssa::traits::*;
37-
use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen};
37+
use rustc_codegen_ssa::{CodegenLintLevels, CodegenResults, CompiledModule, ModuleCodegen};
3838
use rustc_data_structures::fx::FxIndexMap;
3939
use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed, FatalError};
4040
use rustc_metadata::EncodedMetadata;
@@ -374,6 +374,7 @@ impl CodegenBackend for LlvmCodegenBackend {
374374
&self,
375375
sess: &Session,
376376
codegen_results: CodegenResults,
377+
lint_levels: CodegenLintLevels,
377378
outputs: &OutputFilenames,
378379
) -> Result<(), ErrorGuaranteed> {
379380
use rustc_codegen_ssa::back::link::link_binary;
@@ -382,7 +383,7 @@ impl CodegenBackend for LlvmCodegenBackend {
382383

383384
// Run the linker on any artifacts that resulted from the LLVM run.
384385
// This should produce either a finished executable or library.
385-
link_binary(sess, &LlvmArchiveBuilderBuilder, codegen_results, outputs)
386+
link_binary(sess, &LlvmArchiveBuilderBuilder, codegen_results, lint_levels, outputs)
386387
}
387388
}
388389

compiler/rustc_codegen_ssa/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,8 @@ codegen_ssa_linker_file_stem = couldn't extract file stem from specified linker
183183
codegen_ssa_linker_not_found = linker `{$linker_path}` not found
184184
.note = {$error}
185185
186+
codegen_ssa_linker_output = {$inner}
187+
186188
codegen_ssa_linker_unsupported_modifier = `as-needed` modifier not supported for current linker
187189
188190
codegen_ssa_linking_failed = linking with `{$linker_path}` failed: {$exit_status}

compiler/rustc_codegen_ssa/src/back/link.rs

+38-5
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@ use rustc_ast::CRATE_NODE_ID;
1515
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
1616
use rustc_data_structures::memmap::Mmap;
1717
use rustc_data_structures::temp_dir::MaybeTempDir;
18-
use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed, FatalError};
18+
use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed, FatalError, LintDiagnostic};
1919
use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize};
2020
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
21+
use rustc_macros::LintDiagnostic;
2122
use rustc_metadata::fs::{METADATA_FILENAME, copy_to_stdout, emit_wrapper_file};
2223
use rustc_metadata::{find_native_static_library, walk_native_lib_search_dirs};
2324
use rustc_middle::bug;
25+
use rustc_middle::lint::lint_level;
2426
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
2527
use rustc_middle::middle::dependency_format::Linkage;
2628
use rustc_middle::middle::exported_symbols::SymbolExportKind;
@@ -29,6 +31,7 @@ use rustc_session::config::{
2931
OutputType, PrintKind, SplitDwarfKind, Strip,
3032
};
3133
use rustc_session::cstore::DllImport;
34+
use rustc_session::lint::builtin::LINKER_MESSAGES;
3235
use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename};
3336
use rustc_session::search_paths::PathKind;
3437
use rustc_session::utils::NativeLibKind;
@@ -52,7 +55,7 @@ use super::metadata::{MetadataPosition, create_wrapper_file};
5255
use super::rpath::{self, RPathConfig};
5356
use super::{apple, versioned_llvm_target};
5457
use crate::{
55-
CodegenResults, CompiledModule, CrateInfo, NativeLib, common, errors,
58+
CodegenLintLevels, CodegenResults, CompiledModule, CrateInfo, NativeLib, common, errors,
5659
looks_like_rust_object_file,
5760
};
5861

@@ -70,6 +73,7 @@ pub fn link_binary(
7073
sess: &Session,
7174
archive_builder_builder: &dyn ArchiveBuilderBuilder,
7275
codegen_results: CodegenResults,
76+
lint_levels: CodegenLintLevels,
7377
outputs: &OutputFilenames,
7478
) -> Result<(), ErrorGuaranteed> {
7579
let _timer = sess.timer("link_binary");
@@ -138,6 +142,7 @@ pub fn link_binary(
138142
crate_type,
139143
&out_filename,
140144
&codegen_results,
145+
lint_levels,
141146
path.as_ref(),
142147
)?;
143148
}
@@ -762,6 +767,14 @@ fn link_dwarf_object(sess: &Session, cg_results: &CodegenResults, executable_out
762767
}
763768
}
764769

770+
#[derive(LintDiagnostic)]
771+
#[diag(codegen_ssa_linker_output)]
772+
/// Translating this is kind of useless. We don't pass translation flags to the linker, so we'd just
773+
/// end up with inconsistent languages within the same diagnostic.
774+
struct LinkerOutput {
775+
inner: String,
776+
}
777+
765778
/// Create a dynamic library or executable.
766779
///
767780
/// This will invoke the system linker/cc to create the resulting file. This links to all upstream
@@ -772,6 +785,7 @@ fn link_natively(
772785
crate_type: CrateType,
773786
out_filename: &Path,
774787
codegen_results: &CodegenResults,
788+
lint_levels: CodegenLintLevels,
775789
tmpdir: &Path,
776790
) -> Result<(), ErrorGuaranteed> {
777791
info!("preparing {:?} to {:?}", crate_type, out_filename);
@@ -998,12 +1012,12 @@ fn link_natively(
9981012
let mut output = prog.stderr.clone();
9991013
output.extend_from_slice(&prog.stdout);
10001014
let escaped_output = escape_linker_output(&output, flavor);
1001-
// FIXME: Add UI tests for this error.
10021015
let err = errors::LinkingFailed {
10031016
linker_path: &linker_path,
10041017
exit_status: prog.status,
10051018
command: &cmd,
10061019
escaped_output,
1020+
verbose: sess.opts.verbose,
10071021
};
10081022
sess.dcx().emit_err(err);
10091023
// If MSVC's `link.exe` was expected but the return code
@@ -1045,8 +1059,27 @@ fn link_natively(
10451059

10461060
sess.dcx().abort_if_errors();
10471061
}
1048-
info!("linker stderr:\n{}", escape_string(&prog.stderr));
1049-
info!("linker stdout:\n{}", escape_string(&prog.stdout));
1062+
1063+
let (level, src) = lint_levels.linker_messages;
1064+
let lint = |msg| {
1065+
lint_level(sess, LINKER_MESSAGES, level, src, None, |diag| {
1066+
LinkerOutput { inner: msg }.decorate_lint(diag)
1067+
})
1068+
};
1069+
1070+
if !prog.stderr.is_empty() {
1071+
// We already print `warning:` at the start of the diagnostic. Remove it from the linker output if present.
1072+
let stderr = escape_string(&prog.stderr);
1073+
debug!("original stderr: {stderr}");
1074+
let stderr = stderr
1075+
.strip_prefix("warning: ")
1076+
.unwrap_or(&stderr)
1077+
.replace(": warning: ", ": ");
1078+
lint(format!("linker stderr: {stderr}"));
1079+
}
1080+
if !prog.stdout.is_empty() && sess.opts.verbose {
1081+
lint(format!("linker stdout: {}", escape_string(&prog.stdout)))
1082+
}
10501083
}
10511084
Err(e) => {
10521085
let linker_not_found = e.kind() == io::ErrorKind::NotFound;

compiler/rustc_codegen_ssa/src/errors.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ pub(crate) struct LinkingFailed<'a> {
349349
pub exit_status: ExitStatus,
350350
pub command: &'a Command,
351351
pub escaped_output: String,
352+
pub verbose: bool,
352353
}
353354

354355
impl<G: EmissionGuarantee> Diagnostic<'_, G> for LinkingFailed<'_> {
@@ -359,7 +360,13 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for LinkingFailed<'_> {
359360

360361
let contains_undefined_ref = self.escaped_output.contains("undefined reference to");
361362

362-
diag.note(format!("{:?}", self.command)).note(self.escaped_output);
363+
if self.verbose {
364+
diag.note(format!("{:?}", self.command));
365+
} else {
366+
diag.note("use `--verbose` to show all linker arguments");
367+
}
368+
369+
diag.note(self.escaped_output);
363370

364371
// Trying to match an error from OS linkers
365372
// which by now we have no way to translate.

compiler/rustc_codegen_ssa/src/lib.rs

+26-2
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,23 @@ use rustc_ast as ast;
2929
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
3030
use rustc_data_structures::sync::Lrc;
3131
use rustc_data_structures::unord::UnordMap;
32+
use rustc_hir::CRATE_HIR_ID;
3233
use rustc_hir::def_id::CrateNum;
3334
use rustc_macros::{Decodable, Encodable, HashStable};
3435
use rustc_middle::dep_graph::WorkProduct;
36+
use rustc_middle::lint::LintLevelSource;
3537
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
3638
use rustc_middle::middle::dependency_format::Dependencies;
3739
use rustc_middle::middle::exported_symbols::SymbolExportKind;
40+
use rustc_middle::ty::TyCtxt;
3841
use rustc_middle::util::Providers;
3942
use rustc_serialize::opaque::{FileEncoder, MemDecoder};
4043
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
4144
use rustc_session::Session;
4245
use rustc_session::config::{CrateType, OutputFilenames, OutputType, RUST_CGU_EXT};
4346
use rustc_session::cstore::{self, CrateSource};
47+
use rustc_session::lint::Level;
48+
use rustc_session::lint::builtin::LINKER_MESSAGES;
4449
use rustc_session::utils::NativeLibKind;
4550
use rustc_span::symbol::Symbol;
4651

@@ -251,6 +256,7 @@ impl CodegenResults {
251256
sess: &Session,
252257
rlink_file: &Path,
253258
codegen_results: &CodegenResults,
259+
lint_levels: CodegenLintLevels,
254260
outputs: &OutputFilenames,
255261
) -> Result<usize, io::Error> {
256262
let mut encoder = FileEncoder::new(rlink_file)?;
@@ -260,14 +266,15 @@ impl CodegenResults {
260266
encoder.emit_raw_bytes(&RLINK_VERSION.to_be_bytes());
261267
encoder.emit_str(sess.cfg_version);
262268
Encodable::encode(codegen_results, &mut encoder);
269+
Encodable::encode(&lint_levels, &mut encoder);
263270
Encodable::encode(outputs, &mut encoder);
264271
encoder.finish().map_err(|(_path, err)| err)
265272
}
266273

267274
pub fn deserialize_rlink(
268275
sess: &Session,
269276
data: Vec<u8>,
270-
) -> Result<(Self, OutputFilenames), CodegenErrors> {
277+
) -> Result<(Self, CodegenLintLevels, OutputFilenames), CodegenErrors> {
271278
// The Decodable machinery is not used here because it panics if the input data is invalid
272279
// and because its internal representation may change.
273280
if !data.starts_with(RLINK_MAGIC) {
@@ -298,7 +305,24 @@ impl CodegenResults {
298305
}
299306

300307
let codegen_results = CodegenResults::decode(&mut decoder);
308+
let lint_levels = CodegenLintLevels::decode(&mut decoder);
301309
let outputs = OutputFilenames::decode(&mut decoder);
302-
Ok((codegen_results, outputs))
310+
Ok((codegen_results, lint_levels, outputs))
311+
}
312+
}
313+
314+
/// A list of lint levels used in codegen.
315+
///
316+
/// When using `-Z link-only`, we don't have access to the tcx and must work
317+
/// solely from the `.rlink` file. `Lint`s are defined too early to be encodeable.
318+
/// Instead, encode exactly the information we need.
319+
#[derive(Copy, Clone, Encodable, Decodable)]
320+
pub struct CodegenLintLevels {
321+
linker_messages: (Level, LintLevelSource),
322+
}
323+
324+
impl CodegenLintLevels {
325+
pub fn from_tcx(tcx: TyCtxt<'_>) -> Self {
326+
Self { linker_messages: tcx.lint_level_at_node(LINKER_MESSAGES, CRATE_HIR_ID) }
303327
}
304328
}

compiler/rustc_codegen_ssa/src/traits/backend.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use super::write::WriteBackendMethods;
1919
use crate::back::archive::ArArchiveBuilderBuilder;
2020
use crate::back::link::link_binary;
2121
use crate::back::write::TargetMachineFactoryFn;
22-
use crate::{CodegenResults, ModuleCodegen};
22+
use crate::{CodegenLintLevels, CodegenResults, ModuleCodegen};
2323

2424
pub trait BackendTypes {
2525
type Value: CodegenObject;
@@ -88,9 +88,10 @@ pub trait CodegenBackend {
8888
&self,
8989
sess: &Session,
9090
codegen_results: CodegenResults,
91+
lint_levels: CodegenLintLevels,
9192
outputs: &OutputFilenames,
9293
) -> Result<(), ErrorGuaranteed> {
93-
link_binary(sess, &ArArchiveBuilderBuilder, codegen_results, outputs)
94+
link_binary(sess, &ArArchiveBuilderBuilder, codegen_results, lint_levels, outputs)
9495
}
9596

9697
/// Returns `true` if this backend can be safely called from multiple threads.

compiler/rustc_driver_impl/src/lib.rs

+28-21
Original file line numberDiff line numberDiff line change
@@ -645,27 +645,34 @@ fn process_rlink(sess: &Session, compiler: &interface::Compiler) {
645645
let rlink_data = fs::read(file).unwrap_or_else(|err| {
646646
dcx.emit_fatal(RlinkUnableToRead { err });
647647
});
648-
let (codegen_results, outputs) = match CodegenResults::deserialize_rlink(sess, rlink_data) {
649-
Ok((codegen, outputs)) => (codegen, outputs),
650-
Err(err) => {
651-
match err {
652-
CodegenErrors::WrongFileType => dcx.emit_fatal(RLinkWrongFileType),
653-
CodegenErrors::EmptyVersionNumber => dcx.emit_fatal(RLinkEmptyVersionNumber),
654-
CodegenErrors::EncodingVersionMismatch { version_array, rlink_version } => dcx
655-
.emit_fatal(RLinkEncodingVersionMismatch { version_array, rlink_version }),
656-
CodegenErrors::RustcVersionMismatch { rustc_version } => {
657-
dcx.emit_fatal(RLinkRustcVersionMismatch {
658-
rustc_version,
659-
current_version: sess.cfg_version,
660-
})
661-
}
662-
CodegenErrors::CorruptFile => {
663-
dcx.emit_fatal(RlinkCorruptFile { file });
664-
}
665-
};
666-
}
667-
};
668-
if compiler.codegen_backend.link(sess, codegen_results, &outputs).is_err() {
648+
let (codegen_results, lint_levels, outputs) =
649+
match CodegenResults::deserialize_rlink(sess, rlink_data) {
650+
Ok((codegen, lints, outputs)) => (codegen, lints, outputs),
651+
Err(err) => {
652+
match err {
653+
CodegenErrors::WrongFileType => dcx.emit_fatal(RLinkWrongFileType),
654+
CodegenErrors::EmptyVersionNumber => {
655+
dcx.emit_fatal(RLinkEmptyVersionNumber)
656+
}
657+
CodegenErrors::EncodingVersionMismatch { version_array, rlink_version } => {
658+
dcx.emit_fatal(RLinkEncodingVersionMismatch {
659+
version_array,
660+
rlink_version,
661+
})
662+
}
663+
CodegenErrors::RustcVersionMismatch { rustc_version } => {
664+
dcx.emit_fatal(RLinkRustcVersionMismatch {
665+
rustc_version,
666+
current_version: sess.cfg_version,
667+
})
668+
}
669+
CodegenErrors::CorruptFile => {
670+
dcx.emit_fatal(RlinkCorruptFile { file });
671+
}
672+
};
673+
}
674+
};
675+
if compiler.codegen_backend.link(sess, codegen_results, lint_levels, &outputs).is_err() {
669676
FatalError.raise();
670677
}
671678
} else {

compiler/rustc_interface/src/queries.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use std::cell::{RefCell, RefMut};
33
use std::sync::Arc;
44

55
use rustc_ast as ast;
6-
use rustc_codegen_ssa::CodegenResults;
76
use rustc_codegen_ssa::traits::CodegenBackend;
7+
use rustc_codegen_ssa::{CodegenLintLevels, CodegenResults};
88
use rustc_data_structures::steal::Steal;
99
use rustc_data_structures::svh::Svh;
1010
use rustc_data_structures::sync::{OnceLock, WorkerLocal};
@@ -117,6 +117,7 @@ impl<'tcx> Queries<'tcx> {
117117
pub struct Linker {
118118
dep_graph: DepGraph,
119119
output_filenames: Arc<OutputFilenames>,
120+
lint_levels: CodegenLintLevels,
120121
// Only present when incr. comp. is enabled.
121122
crate_hash: Option<Svh>,
122123
ongoing_codegen: Box<dyn Any>,
@@ -144,6 +145,7 @@ impl Linker {
144145
Ok(Linker {
145146
dep_graph: tcx.dep_graph.clone(),
146147
output_filenames: Arc::clone(tcx.output_filenames(())),
148+
lint_levels: CodegenLintLevels::from_tcx(tcx),
147149
crate_hash: if tcx.needs_crate_hash() {
148150
Some(tcx.crate_hash(LOCAL_CRATE))
149151
} else {
@@ -187,6 +189,7 @@ impl Linker {
187189
sess,
188190
&rlink_file,
189191
&codegen_results,
192+
self.lint_levels,
190193
&*self.output_filenames,
191194
)
192195
.map_err(|error| {
@@ -196,7 +199,7 @@ impl Linker {
196199
}
197200

198201
let _timer = sess.prof.verbose_generic_activity("link_crate");
199-
codegen_backend.link(sess, codegen_results, &self.output_filenames)
202+
codegen_backend.link(sess, codegen_results, self.lint_levels, &self.output_filenames)
200203
}
201204
}
202205

0 commit comments

Comments
 (0)