Skip to content

Commit b1d1e99

Browse files
authored
Rollup merge of #113780 - dtolnay:printkindpath, r=b-naber
Support `--print KIND=PATH` command line syntax As is already done for `--emit KIND=PATH` and `-L KIND=PATH`. In the discussion of #110785, it was pointed out that `--print KIND=PATH` is nicer than trying to apply the single global `-o` path to `--print`'s output, because in general there can be multiple print requests within a single rustc invocation, and anyway `-o` would already be used for a different meaning in the case of `link-args` and `native-static-libs`. I am interested in using `--print cfg=PATH` in Buck2. Currently Buck2 works around the lack of support for `--print KIND=PATH` by [indirecting through a Python wrapper script](https://github.com/facebook/buck2/blob/d43cf3a51a31f00be2c2248e78271b0fef0452b4/prelude/rust/tools/get_rustc_cfg.py) to redirect rustc's stdout into the location dictated by the build system. From skimming Cargo's usages of `--print`, it definitely seems like it would benefit from `--print KIND=PATH` too. Currently it is working around the lack of this by inserting `--crate-name=___ --print=crate-name` so that it can look for a line containing `___` as a delimiter between the 2 other `--print` informations it actually cares about. This is commented as a "HACK" and "abuse". https://github.com/rust-lang/cargo/blob/31eda6f7c360d9911f853b3014e057db61238f3e/src/cargo/core/compiler/build_context/target_info.rs#L242 (FYI `@weihanglo` as you dealt with this recently in rust-lang/cargo#11633.) Mentioning reviewers active in #110785: `@fee1-dead` `@jyn514` `@bjorn3`
2 parents 2734b5a + 11ae0af commit b1d1e99

File tree

21 files changed

+299
-141
lines changed

21 files changed

+299
-141
lines changed

compiler/rustc_codegen_llvm/src/lib.rs

+19-18
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ use rustc_metadata::EncodedMetadata;
4040
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
4141
use rustc_middle::query::Providers;
4242
use rustc_middle::ty::TyCtxt;
43-
use rustc_session::config::{OptLevel, OutputFilenames, PrintRequest};
43+
use rustc_session::config::{OptLevel, OutputFilenames, PrintKind, PrintRequest};
4444
use rustc_session::Session;
4545
use rustc_span::symbol::Symbol;
4646

@@ -284,10 +284,10 @@ impl CodegenBackend for LlvmCodegenBackend {
284284
|tcx, ()| llvm_util::global_llvm_features(tcx.sess, true)
285285
}
286286

287-
fn print(&self, req: PrintRequest, sess: &Session) {
288-
match req {
289-
PrintRequest::RelocationModels => {
290-
println!("Available relocation models:");
287+
fn print(&self, req: &PrintRequest, out: &mut dyn PrintBackendInfo, sess: &Session) {
288+
match req.kind {
289+
PrintKind::RelocationModels => {
290+
writeln!(out, "Available relocation models:");
291291
for name in &[
292292
"static",
293293
"pic",
@@ -298,26 +298,27 @@ impl CodegenBackend for LlvmCodegenBackend {
298298
"ropi-rwpi",
299299
"default",
300300
] {
301-
println!(" {}", name);
301+
writeln!(out, " {}", name);
302302
}
303-
println!();
303+
writeln!(out);
304304
}
305-
PrintRequest::CodeModels => {
306-
println!("Available code models:");
305+
PrintKind::CodeModels => {
306+
writeln!(out, "Available code models:");
307307
for name in &["tiny", "small", "kernel", "medium", "large"] {
308-
println!(" {}", name);
308+
writeln!(out, " {}", name);
309309
}
310-
println!();
310+
writeln!(out);
311311
}
312-
PrintRequest::TlsModels => {
313-
println!("Available TLS models:");
312+
PrintKind::TlsModels => {
313+
writeln!(out, "Available TLS models:");
314314
for name in &["global-dynamic", "local-dynamic", "initial-exec", "local-exec"] {
315-
println!(" {}", name);
315+
writeln!(out, " {}", name);
316316
}
317-
println!();
317+
writeln!(out);
318318
}
319-
PrintRequest::StackProtectorStrategies => {
320-
println!(
319+
PrintKind::StackProtectorStrategies => {
320+
writeln!(
321+
out,
321322
r#"Available stack protector strategies:
322323
all
323324
Generate stack canaries in all functions.
@@ -341,7 +342,7 @@ impl CodegenBackend for LlvmCodegenBackend {
341342
"#
342343
);
343344
}
344-
req => llvm_util::print(req, sess),
345+
_other => llvm_util::print(req, out, sess),
345346
}
346347
}
347348

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -2283,7 +2283,12 @@ extern "C" {
22832283

22842284
pub fn LLVMRustHasFeature(T: &TargetMachine, s: *const c_char) -> bool;
22852285

2286-
pub fn LLVMRustPrintTargetCPUs(T: &TargetMachine, cpu: *const c_char);
2286+
pub fn LLVMRustPrintTargetCPUs(
2287+
T: &TargetMachine,
2288+
cpu: *const c_char,
2289+
print: unsafe extern "C" fn(out: *mut c_void, string: *const c_char, len: usize),
2290+
out: *mut c_void,
2291+
);
22872292
pub fn LLVMRustGetTargetFeaturesCount(T: &TargetMachine) -> size_t;
22882293
pub fn LLVMRustGetTargetFeature(
22892294
T: &TargetMachine,

compiler/rustc_codegen_llvm/src/llvm_util.rs

+30-17
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,17 @@ use libc::c_int;
88
use rustc_codegen_ssa::target_features::{
99
supported_target_features, tied_target_features, RUSTC_SPECIFIC_FEATURES,
1010
};
11+
use rustc_codegen_ssa::traits::PrintBackendInfo;
1112
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1213
use rustc_data_structures::small_c_str::SmallCStr;
1314
use rustc_fs_util::path_to_c_string;
1415
use rustc_middle::bug;
15-
use rustc_session::config::PrintRequest;
16+
use rustc_session::config::{PrintKind, PrintRequest};
1617
use rustc_session::Session;
1718
use rustc_span::symbol::Symbol;
1819
use rustc_target::spec::{MergeFunctions, PanicStrategy};
19-
use std::ffi::{CStr, CString};
2020

21+
use std::ffi::{c_char, c_void, CStr, CString};
2122
use std::path::Path;
2223
use std::ptr;
2324
use std::slice;
@@ -354,7 +355,7 @@ fn llvm_target_features(tm: &llvm::TargetMachine) -> Vec<(&str, &str)> {
354355
ret
355356
}
356357

357-
fn print_target_features(sess: &Session, tm: &llvm::TargetMachine) {
358+
fn print_target_features(out: &mut dyn PrintBackendInfo, sess: &Session, tm: &llvm::TargetMachine) {
358359
let mut llvm_target_features = llvm_target_features(tm);
359360
let mut known_llvm_target_features = FxHashSet::<&'static str>::default();
360361
let mut rustc_target_features = supported_target_features(sess)
@@ -387,36 +388,48 @@ fn print_target_features(sess: &Session, tm: &llvm::TargetMachine) {
387388
.max()
388389
.unwrap_or(0);
389390

390-
println!("Features supported by rustc for this target:");
391+
writeln!(out, "Features supported by rustc for this target:");
391392
for (feature, desc) in &rustc_target_features {
392-
println!(" {1:0$} - {2}.", max_feature_len, feature, desc);
393+
writeln!(out, " {1:0$} - {2}.", max_feature_len, feature, desc);
393394
}
394-
println!("\nCode-generation features supported by LLVM for this target:");
395+
writeln!(out, "\nCode-generation features supported by LLVM for this target:");
395396
for (feature, desc) in &llvm_target_features {
396-
println!(" {1:0$} - {2}.", max_feature_len, feature, desc);
397+
writeln!(out, " {1:0$} - {2}.", max_feature_len, feature, desc);
397398
}
398399
if llvm_target_features.is_empty() {
399-
println!(" Target features listing is not supported by this LLVM version.");
400+
writeln!(out, " Target features listing is not supported by this LLVM version.");
400401
}
401-
println!("\nUse +feature to enable a feature, or -feature to disable it.");
402-
println!("For example, rustc -C target-cpu=mycpu -C target-feature=+feature1,-feature2\n");
403-
println!("Code-generation features cannot be used in cfg or #[target_feature],");
404-
println!("and may be renamed or removed in a future version of LLVM or rustc.\n");
402+
writeln!(out, "\nUse +feature to enable a feature, or -feature to disable it.");
403+
writeln!(out, "For example, rustc -C target-cpu=mycpu -C target-feature=+feature1,-feature2\n");
404+
writeln!(out, "Code-generation features cannot be used in cfg or #[target_feature],");
405+
writeln!(out, "and may be renamed or removed in a future version of LLVM or rustc.\n");
405406
}
406407

407-
pub(crate) fn print(req: PrintRequest, sess: &Session) {
408+
pub(crate) fn print(req: &PrintRequest, mut out: &mut dyn PrintBackendInfo, sess: &Session) {
408409
require_inited();
409410
let tm = create_informational_target_machine(sess);
410-
match req {
411-
PrintRequest::TargetCPUs => {
411+
match req.kind {
412+
PrintKind::TargetCPUs => {
412413
// SAFETY generate a C compatible string from a byte slice to pass
413414
// the target CPU name into LLVM, the lifetime of the reference is
414415
// at least as long as the C function
415416
let cpu_cstring = CString::new(handle_native(sess.target.cpu.as_ref()))
416417
.unwrap_or_else(|e| bug!("failed to convert to cstring: {}", e));
417-
unsafe { llvm::LLVMRustPrintTargetCPUs(tm, cpu_cstring.as_ptr()) };
418+
unsafe extern "C" fn callback(out: *mut c_void, string: *const c_char, len: usize) {
419+
let out = &mut *(out as *mut &mut dyn PrintBackendInfo);
420+
let bytes = slice::from_raw_parts(string as *const u8, len);
421+
write!(out, "{}", String::from_utf8_lossy(bytes));
422+
}
423+
unsafe {
424+
llvm::LLVMRustPrintTargetCPUs(
425+
tm,
426+
cpu_cstring.as_ptr(),
427+
callback,
428+
&mut out as *mut &mut dyn PrintBackendInfo as *mut c_void,
429+
);
430+
}
418431
}
419-
PrintRequest::TargetFeatures => print_target_features(sess, tm),
432+
PrintKind::TargetFeatures => print_target_features(out, sess, tm),
420433
_ => bug!("rustc_codegen_llvm can't handle print request: {:?}", req),
421434
}
422435
}

compiler/rustc_codegen_ssa/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ codegen_ssa_specify_libraries_to_link = use the `-l` flag to specify native libr
197197
198198
codegen_ssa_static_library_native_artifacts = Link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms.
199199
200+
codegen_ssa_static_library_native_artifacts_to_file = Native artifacts to link against have been written to {$path}. The order and any duplication can be significant on some platforms.
201+
200202
codegen_ssa_stripping_debug_info_failed = stripping debug info with `{$util}` failed: {$status}
201203
.note = {$output}
202204

compiler/rustc_codegen_ssa/src/back/link.rs

+28-11
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use rustc_metadata::fs::{copy_to_stdout, emit_wrapper_file, METADATA_FILENAME};
1212
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
1313
use rustc_middle::middle::dependency_format::Linkage;
1414
use rustc_middle::middle::exported_symbols::SymbolExportKind;
15-
use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, Strip};
16-
use rustc_session::config::{OutputFilenames, OutputType, PrintRequest, SplitDwarfKind};
15+
use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, OutFileName, Strip};
16+
use rustc_session::config::{OutputFilenames, OutputType, PrintKind, SplitDwarfKind};
1717
use rustc_session::cstore::DllImport;
1818
use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename};
1919
use rustc_session::search_paths::PathKind;
@@ -596,8 +596,10 @@ fn link_staticlib<'a>(
596596

597597
all_native_libs.extend_from_slice(&codegen_results.crate_info.used_libraries);
598598

599-
if sess.opts.prints.contains(&PrintRequest::NativeStaticLibs) {
600-
print_native_static_libs(sess, &all_native_libs, &all_rust_dylibs);
599+
for print in &sess.opts.prints {
600+
if print.kind == PrintKind::NativeStaticLibs {
601+
print_native_static_libs(sess, &print.out, &all_native_libs, &all_rust_dylibs);
602+
}
601603
}
602604

603605
Ok(())
@@ -744,8 +746,11 @@ fn link_natively<'a>(
744746
cmd.env_remove(k.as_ref());
745747
}
746748

747-
if sess.opts.prints.contains(&PrintRequest::LinkArgs) {
748-
println!("{:?}", &cmd);
749+
for print in &sess.opts.prints {
750+
if print.kind == PrintKind::LinkArgs {
751+
let content = format!("{:?}", cmd);
752+
print.out.overwrite(&content, sess);
753+
}
749754
}
750755

751756
// May have not found libraries in the right formats.
@@ -1386,6 +1391,7 @@ enum RlibFlavor {
13861391

13871392
fn print_native_static_libs(
13881393
sess: &Session,
1394+
out: &OutFileName,
13891395
all_native_libs: &[NativeLib],
13901396
all_rust_dylibs: &[&Path],
13911397
) {
@@ -1459,11 +1465,22 @@ fn print_native_static_libs(
14591465
lib_args.push(format!("-l{}", lib));
14601466
}
14611467
}
1462-
if !lib_args.is_empty() {
1463-
sess.emit_note(errors::StaticLibraryNativeArtifacts);
1464-
// Prefix for greppability
1465-
// Note: This must not be translated as tools are allowed to depend on this exact string.
1466-
sess.note_without_error(format!("native-static-libs: {}", &lib_args.join(" ")));
1468+
1469+
match out {
1470+
OutFileName::Real(path) => {
1471+
out.overwrite(&lib_args.join(" "), sess);
1472+
if !lib_args.is_empty() {
1473+
sess.emit_note(errors::StaticLibraryNativeArtifactsToFile { path });
1474+
}
1475+
}
1476+
OutFileName::Stdout => {
1477+
if !lib_args.is_empty() {
1478+
sess.emit_note(errors::StaticLibraryNativeArtifacts);
1479+
// Prefix for greppability
1480+
// Note: This must not be translated as tools are allowed to depend on this exact string.
1481+
sess.note_without_error(format!("native-static-libs: {}", &lib_args.join(" ")));
1482+
}
1483+
}
14671484
}
14681485
}
14691486

compiler/rustc_codegen_ssa/src/errors.rs

+6
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,12 @@ pub struct LinkerFileStem;
455455
#[diag(codegen_ssa_static_library_native_artifacts)]
456456
pub struct StaticLibraryNativeArtifacts;
457457

458+
#[derive(Diagnostic)]
459+
#[diag(codegen_ssa_static_library_native_artifacts_to_file)]
460+
pub struct StaticLibraryNativeArtifactsToFile<'a> {
461+
pub path: &'a Path,
462+
}
463+
458464
#[derive(Diagnostic)]
459465
#[diag(codegen_ssa_link_script_unavailable)]
460466
pub struct LinkScriptUnavailable;

compiler/rustc_codegen_ssa/src/traits/backend.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ use rustc_span::symbol::Symbol;
2323
use rustc_target::abi::call::FnAbi;
2424
use rustc_target::spec::Target;
2525

26+
use std::fmt;
27+
2628
pub trait BackendTypes {
2729
type Value: CodegenObject;
2830
type Function: CodegenObject;
@@ -61,7 +63,7 @@ pub trait CodegenBackend {
6163
fn locale_resource(&self) -> &'static str;
6264

6365
fn init(&self, _sess: &Session) {}
64-
fn print(&self, _req: PrintRequest, _sess: &Session) {}
66+
fn print(&self, _req: &PrintRequest, _out: &mut dyn PrintBackendInfo, _sess: &Session) {}
6567
fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec<Symbol> {
6668
vec![]
6769
}
@@ -162,3 +164,19 @@ pub trait ExtraBackendMethods:
162164
std::thread::Builder::new().name(name).spawn(f)
163165
}
164166
}
167+
168+
pub trait PrintBackendInfo {
169+
fn infallible_write_fmt(&mut self, args: fmt::Arguments<'_>);
170+
}
171+
172+
impl PrintBackendInfo for String {
173+
fn infallible_write_fmt(&mut self, args: fmt::Arguments<'_>) {
174+
fmt::Write::write_fmt(self, args).unwrap();
175+
}
176+
}
177+
178+
impl dyn PrintBackendInfo + '_ {
179+
pub fn write_fmt(&mut self, args: fmt::Arguments<'_>) {
180+
self.infallible_write_fmt(args);
181+
}
182+
}

compiler/rustc_codegen_ssa/src/traits/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ mod write;
3030

3131
pub use self::abi::AbiBuilderMethods;
3232
pub use self::asm::{AsmBuilderMethods, AsmMethods, GlobalAsmOperandRef, InlineAsmOperandRef};
33-
pub use self::backend::{Backend, BackendTypes, CodegenBackend, ExtraBackendMethods};
33+
pub use self::backend::{
34+
Backend, BackendTypes, CodegenBackend, ExtraBackendMethods, PrintBackendInfo,
35+
};
3436
pub use self::builder::{BuilderMethods, OverflowOp};
3537
pub use self::consts::ConstMethods;
3638
pub use self::coverageinfo::CoverageInfoBuilderMethods;

compiler/rustc_driver_impl/messages.ftl

-2
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,3 @@ driver_impl_rlink_rustc_version_mismatch = .rlink file was produced by rustc ver
1919
driver_impl_rlink_unable_to_read = failed to read rlink file: `{$err}`
2020
2121
driver_impl_rlink_wrong_file_type = The input does not look like a .rlink file
22-
23-
driver_impl_unpretty_dump_fail = pretty-print failed to write `{$path}` due to error `{$err}`

0 commit comments

Comments
 (0)