Skip to content

Commit be32e34

Browse files
authored
Rollup merge of rust-lang#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 rust-lang#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 rust-lang#110785: `@fee1-dead` `@jyn514` `@bjorn3`
2 parents 8f7b890 + 4d5134f commit be32e34

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

@@ -262,10 +262,10 @@ impl CodegenBackend for LlvmCodegenBackend {
262262
|tcx, ()| llvm_util::global_llvm_features(tcx.sess, true)
263263
}
264264

265-
fn print(&self, req: PrintRequest, sess: &Session) {
266-
match req {
267-
PrintRequest::RelocationModels => {
268-
println!("Available relocation models:");
265+
fn print(&self, req: &PrintRequest, out: &mut dyn PrintBackendInfo, sess: &Session) {
266+
match req.kind {
267+
PrintKind::RelocationModels => {
268+
writeln!(out, "Available relocation models:");
269269
for name in &[
270270
"static",
271271
"pic",
@@ -276,26 +276,27 @@ impl CodegenBackend for LlvmCodegenBackend {
276276
"ropi-rwpi",
277277
"default",
278278
] {
279-
println!(" {}", name);
279+
writeln!(out, " {}", name);
280280
}
281-
println!();
281+
writeln!(out);
282282
}
283-
PrintRequest::CodeModels => {
284-
println!("Available code models:");
283+
PrintKind::CodeModels => {
284+
writeln!(out, "Available code models:");
285285
for name in &["tiny", "small", "kernel", "medium", "large"] {
286-
println!(" {}", name);
286+
writeln!(out, " {}", name);
287287
}
288-
println!();
288+
writeln!(out);
289289
}
290-
PrintRequest::TlsModels => {
291-
println!("Available TLS models:");
290+
PrintKind::TlsModels => {
291+
writeln!(out, "Available TLS models:");
292292
for name in &["global-dynamic", "local-dynamic", "initial-exec", "local-exec"] {
293-
println!(" {}", name);
293+
writeln!(out, " {}", name);
294294
}
295-
println!();
295+
writeln!(out);
296296
}
297-
PrintRequest::StackProtectorStrategies => {
298-
println!(
297+
PrintKind::StackProtectorStrategies => {
298+
writeln!(
299+
out,
299300
r#"Available stack protector strategies:
300301
all
301302
Generate stack canaries in all functions.
@@ -319,7 +320,7 @@ impl CodegenBackend for LlvmCodegenBackend {
319320
"#
320321
);
321322
}
322-
req => llvm_util::print(req, sess),
323+
_other => llvm_util::print(req, out, sess),
323324
}
324325
}
325326

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

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

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

2283-
pub fn LLVMRustPrintTargetCPUs(T: &TargetMachine, cpu: *const c_char);
2283+
pub fn LLVMRustPrintTargetCPUs(
2284+
T: &TargetMachine,
2285+
cpu: *const c_char,
2286+
print: unsafe extern "C" fn(out: *mut c_void, string: *const c_char, len: usize),
2287+
out: *mut c_void,
2288+
);
22842289
pub fn LLVMRustGetTargetFeaturesCount(T: &TargetMachine) -> size_t;
22852290
pub fn LLVMRustGetTargetFeature(
22862291
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;
@@ -350,7 +351,7 @@ fn llvm_target_features(tm: &llvm::TargetMachine) -> Vec<(&str, &str)> {
350351
ret
351352
}
352353

353-
fn print_target_features(sess: &Session, tm: &llvm::TargetMachine) {
354+
fn print_target_features(out: &mut dyn PrintBackendInfo, sess: &Session, tm: &llvm::TargetMachine) {
354355
let mut llvm_target_features = llvm_target_features(tm);
355356
let mut known_llvm_target_features = FxHashSet::<&'static str>::default();
356357
let mut rustc_target_features = supported_target_features(sess)
@@ -383,36 +384,48 @@ fn print_target_features(sess: &Session, tm: &llvm::TargetMachine) {
383384
.max()
384385
.unwrap_or(0);
385386

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

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

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)