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](d43cf3a51a/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".31eda6f7c3/src/cargo/core/compiler/build_context/target_info.rs (L242)
(FYI `@weihanglo` as you dealt with this recently in https://github.com/rust-lang/cargo/pull/11633.) Mentioning reviewers active in #110785: `@fee1-dead` `@jyn514` `@bjorn3`
This commit is contained in:
commit
b1d1e99c22
21 changed files with 299 additions and 141 deletions
|
@ -37,9 +37,7 @@ use rustc_interface::{interface, Queries};
|
|||
use rustc_lint::LintStore;
|
||||
use rustc_metadata::locator;
|
||||
use rustc_session::config::{nightly_options, CG_OPTIONS, Z_OPTIONS};
|
||||
use rustc_session::config::{
|
||||
ErrorOutputType, Input, OutFileName, OutputType, PrintRequest, TrimmedDefPaths,
|
||||
};
|
||||
use rustc_session::config::{ErrorOutputType, Input, OutFileName, OutputType, TrimmedDefPaths};
|
||||
use rustc_session::cstore::MetadataLoader;
|
||||
use rustc_session::getopts::{self, Matches};
|
||||
use rustc_session::lint::{Lint, LintId};
|
||||
|
@ -53,6 +51,7 @@ use std::cmp::max;
|
|||
use std::collections::BTreeMap;
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::fmt::Write as _;
|
||||
use std::fs;
|
||||
use std::io::{self, IsTerminal, Read, Write};
|
||||
use std::panic::{self, catch_unwind};
|
||||
|
@ -72,6 +71,11 @@ macro do_not_use_print($($t:tt)*) {
|
|||
)
|
||||
}
|
||||
|
||||
#[allow(unused_macros)]
|
||||
macro do_not_use_safe_print($($t:tt)*) {
|
||||
std::compile_error!("Don't use `safe_print` or `safe_println` here, use `println_info` instead")
|
||||
}
|
||||
|
||||
// This import blocks the use of panicking `print` and `println` in all the code
|
||||
// below. Please use `safe_print` and `safe_println` to avoid ICE when
|
||||
// encountering an I/O error during print.
|
||||
|
@ -720,10 +724,17 @@ fn print_crate_info(
|
|||
sess: &Session,
|
||||
parse_attrs: bool,
|
||||
) -> Compilation {
|
||||
use rustc_session::config::PrintRequest::*;
|
||||
use rustc_session::config::PrintKind::*;
|
||||
|
||||
// This import prevents the following code from using the printing macros
|
||||
// used by the rest of the module. Within this function, we only write to
|
||||
// the output specified by `sess.io.output_file`.
|
||||
#[allow(unused_imports)]
|
||||
use {do_not_use_safe_print as safe_print, do_not_use_safe_print as safe_println};
|
||||
|
||||
// NativeStaticLibs and LinkArgs are special - printed during linking
|
||||
// (empty iterator returns true)
|
||||
if sess.opts.prints.iter().all(|&p| p == NativeStaticLibs || p == LinkArgs) {
|
||||
if sess.opts.prints.iter().all(|p| p.kind == NativeStaticLibs || p.kind == LinkArgs) {
|
||||
return Compilation::Continue;
|
||||
}
|
||||
|
||||
|
@ -739,17 +750,23 @@ fn print_crate_info(
|
|||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
for req in &sess.opts.prints {
|
||||
match *req {
|
||||
let mut crate_info = String::new();
|
||||
macro println_info($($arg:tt)*) {
|
||||
crate_info.write_fmt(format_args!("{}\n", format_args!($($arg)*))).unwrap()
|
||||
}
|
||||
|
||||
match req.kind {
|
||||
TargetList => {
|
||||
let mut targets = rustc_target::spec::TARGETS.to_vec();
|
||||
targets.sort_unstable();
|
||||
safe_println!("{}", targets.join("\n"));
|
||||
println_info!("{}", targets.join("\n"));
|
||||
}
|
||||
Sysroot => safe_println!("{}", sess.sysroot.display()),
|
||||
TargetLibdir => safe_println!("{}", sess.target_tlib_path.dir.display()),
|
||||
Sysroot => println_info!("{}", sess.sysroot.display()),
|
||||
TargetLibdir => println_info!("{}", sess.target_tlib_path.dir.display()),
|
||||
TargetSpec => {
|
||||
safe_println!("{}", serde_json::to_string_pretty(&sess.target.to_json()).unwrap());
|
||||
println_info!("{}", serde_json::to_string_pretty(&sess.target.to_json()).unwrap());
|
||||
}
|
||||
AllTargetSpecs => {
|
||||
let mut targets = BTreeMap::new();
|
||||
|
@ -758,26 +775,30 @@ fn print_crate_info(
|
|||
let target = Target::expect_builtin(&triple);
|
||||
targets.insert(name, target.to_json());
|
||||
}
|
||||
safe_println!("{}", serde_json::to_string_pretty(&targets).unwrap());
|
||||
println_info!("{}", serde_json::to_string_pretty(&targets).unwrap());
|
||||
}
|
||||
FileNames | CrateName => {
|
||||
FileNames => {
|
||||
let Some(attrs) = attrs.as_ref() else {
|
||||
// no crate attributes, print out an error and exit
|
||||
return Compilation::Continue;
|
||||
};
|
||||
let t_outputs = rustc_interface::util::build_output_filenames(attrs, sess);
|
||||
let id = rustc_session::output::find_crate_name(sess, attrs);
|
||||
if *req == PrintRequest::CrateName {
|
||||
safe_println!("{id}");
|
||||
continue;
|
||||
}
|
||||
let crate_types = collect_crate_types(sess, attrs);
|
||||
for &style in &crate_types {
|
||||
let fname =
|
||||
rustc_session::output::filename_for_input(sess, style, id, &t_outputs);
|
||||
safe_println!("{}", fname.as_path().file_name().unwrap().to_string_lossy());
|
||||
println_info!("{}", fname.as_path().file_name().unwrap().to_string_lossy());
|
||||
}
|
||||
}
|
||||
CrateName => {
|
||||
let Some(attrs) = attrs.as_ref() else {
|
||||
// no crate attributes, print out an error and exit
|
||||
return Compilation::Continue;
|
||||
};
|
||||
let id = rustc_session::output::find_crate_name(sess, attrs);
|
||||
println_info!("{id}");
|
||||
}
|
||||
Cfg => {
|
||||
let mut cfgs = sess
|
||||
.parse_sess
|
||||
|
@ -809,13 +830,13 @@ fn print_crate_info(
|
|||
|
||||
cfgs.sort();
|
||||
for cfg in cfgs {
|
||||
safe_println!("{cfg}");
|
||||
println_info!("{cfg}");
|
||||
}
|
||||
}
|
||||
CallingConventions => {
|
||||
let mut calling_conventions = rustc_target::spec::abi::all_names();
|
||||
calling_conventions.sort_unstable();
|
||||
safe_println!("{}", calling_conventions.join("\n"));
|
||||
println_info!("{}", calling_conventions.join("\n"));
|
||||
}
|
||||
RelocationModels
|
||||
| CodeModels
|
||||
|
@ -823,7 +844,7 @@ fn print_crate_info(
|
|||
| TargetCPUs
|
||||
| StackProtectorStrategies
|
||||
| TargetFeatures => {
|
||||
codegen_backend.print(*req, sess);
|
||||
codegen_backend.print(req, &mut crate_info, sess);
|
||||
}
|
||||
// Any output here interferes with Cargo's parsing of other printed output
|
||||
NativeStaticLibs => {}
|
||||
|
@ -833,7 +854,7 @@ fn print_crate_info(
|
|||
|
||||
for split in &[Off, Packed, Unpacked] {
|
||||
if sess.target.options.supported_split_debuginfo.contains(split) {
|
||||
safe_println!("{split}");
|
||||
println_info!("{split}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -841,7 +862,7 @@ fn print_crate_info(
|
|||
use rustc_target::spec::current_apple_deployment_target;
|
||||
|
||||
if sess.target.is_like_osx {
|
||||
safe_println!(
|
||||
println_info!(
|
||||
"deployment_target={}",
|
||||
current_apple_deployment_target(&sess.target)
|
||||
.expect("unknown Apple target OS")
|
||||
|
@ -852,6 +873,8 @@ fn print_crate_info(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
req.out.overwrite(&crate_info, sess);
|
||||
}
|
||||
Compilation::Stop
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
//! The various pretty-printing routines.
|
||||
|
||||
use crate::session_diagnostics::UnprettyDumpFail;
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
|
@ -358,17 +357,7 @@ fn get_source(sess: &Session) -> (String, FileName) {
|
|||
}
|
||||
|
||||
fn write_or_print(out: &str, sess: &Session) {
|
||||
match &sess.io.output_file {
|
||||
None | Some(OutFileName::Stdout) => print!("{out}"),
|
||||
Some(OutFileName::Real(p)) => {
|
||||
if let Err(e) = std::fs::write(p, out) {
|
||||
sess.emit_fatal(UnprettyDumpFail {
|
||||
path: p.display().to_string(),
|
||||
err: e.to_string(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
sess.io.output_file.as_ref().unwrap_or(&OutFileName::Stdout).overwrite(out, sess);
|
||||
}
|
||||
|
||||
pub fn print_after_parsing(sess: &Session, krate: &ast::Crate, ppm: PpMode) {
|
||||
|
|
|
@ -32,13 +32,6 @@ pub(crate) struct RLinkRustcVersionMismatch<'a> {
|
|||
#[diag(driver_impl_rlink_no_a_file)]
|
||||
pub(crate) struct RlinkNotAFile;
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(driver_impl_unpretty_dump_fail)]
|
||||
pub(crate) struct UnprettyDumpFail {
|
||||
pub path: String,
|
||||
pub err: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(driver_impl_ice)]
|
||||
pub(crate) struct Ice;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue