Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Respect -o output file in --print #110785

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions compiler/rustc_codegen_llvm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,10 +262,10 @@ impl CodegenBackend for LlvmCodegenBackend {
|tcx, ()| llvm_util::global_llvm_features(tcx.sess, true)
}

fn print(&self, req: PrintRequest, sess: &Session) {
fn print(&self, req: PrintRequest, out: &mut dyn PrintBackendInfo, sess: &Session) {
match req {
PrintRequest::RelocationModels => {
println!("Available relocation models:");
writeln!(out, "Available relocation models:");
for name in &[
"static",
"pic",
Expand All @@ -276,26 +276,27 @@ impl CodegenBackend for LlvmCodegenBackend {
"ropi-rwpi",
"default",
] {
println!(" {}", name);
writeln!(out, " {}", name);
}
println!();
writeln!(out);
}
PrintRequest::CodeModels => {
println!("Available code models:");
writeln!(out, "Available code models:");
for name in &["tiny", "small", "kernel", "medium", "large"] {
println!(" {}", name);
writeln!(out, " {}", name);
}
println!();
writeln!(out);
}
PrintRequest::TlsModels => {
println!("Available TLS models:");
writeln!(out, "Available TLS models:");
for name in &["global-dynamic", "local-dynamic", "initial-exec", "local-exec"] {
println!(" {}", name);
writeln!(out, " {}", name);
}
println!();
writeln!(out);
}
PrintRequest::StackProtectorStrategies => {
println!(
writeln!(
out,
r#"Available stack protector strategies:
all
Generate stack canaries in all functions.
Expand All @@ -319,7 +320,7 @@ impl CodegenBackend for LlvmCodegenBackend {
"#
);
}
req => llvm_util::print(req, sess),
req => llvm_util::print(req, out, sess),
}
}

Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2281,7 +2281,12 @@ extern "C" {

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

pub fn LLVMRustPrintTargetCPUs(T: &TargetMachine, cpu: *const c_char);
pub fn LLVMRustPrintTargetCPUs(
T: &TargetMachine,
cpu: *const c_char,
print: unsafe extern "C" fn(out: *mut c_void, string: *const c_char, len: usize),
out: *mut c_void,
);
pub fn LLVMRustGetTargetFeaturesCount(T: &TargetMachine) -> size_t;
pub fn LLVMRustGetTargetFeature(
T: &TargetMachine,
Expand Down
41 changes: 27 additions & 14 deletions compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use libc::c_int;
use rustc_codegen_ssa::target_features::{
supported_target_features, tied_target_features, RUSTC_SPECIFIC_FEATURES,
};
use rustc_codegen_ssa::traits::PrintBackendInfo;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_fs_util::path_to_c_string;
Expand All @@ -16,8 +17,8 @@ use rustc_session::config::PrintRequest;
use rustc_session::Session;
use rustc_span::symbol::Symbol;
use rustc_target::spec::{MergeFunctions, PanicStrategy};
use std::ffi::{CStr, CString};

use std::ffi::{c_char, c_void, CStr, CString};
use std::path::Path;
use std::ptr;
use std::slice;
Expand Down Expand Up @@ -350,7 +351,7 @@ fn llvm_target_features(tm: &llvm::TargetMachine) -> Vec<(&str, &str)> {
ret
}

fn print_target_features(sess: &Session, tm: &llvm::TargetMachine) {
fn print_target_features(out: &mut dyn PrintBackendInfo, sess: &Session, tm: &llvm::TargetMachine) {
let mut llvm_target_features = llvm_target_features(tm);
let mut known_llvm_target_features = FxHashSet::<&'static str>::default();
let mut rustc_target_features = supported_target_features(sess)
Expand Down Expand Up @@ -383,24 +384,24 @@ fn print_target_features(sess: &Session, tm: &llvm::TargetMachine) {
.max()
.unwrap_or(0);

println!("Features supported by rustc for this target:");
writeln!(out, "Features supported by rustc for this target:");
for (feature, desc) in &rustc_target_features {
println!(" {1:0$} - {2}.", max_feature_len, feature, desc);
writeln!(out, " {1:0$} - {2}.", max_feature_len, feature, desc);
}
println!("\nCode-generation features supported by LLVM for this target:");
writeln!(out, "\nCode-generation features supported by LLVM for this target:");
for (feature, desc) in &llvm_target_features {
println!(" {1:0$} - {2}.", max_feature_len, feature, desc);
writeln!(out, " {1:0$} - {2}.", max_feature_len, feature, desc);
}
if llvm_target_features.is_empty() {
println!(" Target features listing is not supported by this LLVM version.");
writeln!(out, " Target features listing is not supported by this LLVM version.");
}
println!("\nUse +feature to enable a feature, or -feature to disable it.");
println!("For example, rustc -C target-cpu=mycpu -C target-feature=+feature1,-feature2\n");
println!("Code-generation features cannot be used in cfg or #[target_feature],");
println!("and may be renamed or removed in a future version of LLVM or rustc.\n");
writeln!(out, "\nUse +feature to enable a feature, or -feature to disable it.");
writeln!(out, "For example, rustc -C target-cpu=mycpu -C target-feature=+feature1,-feature2\n");
writeln!(out, "Code-generation features cannot be used in cfg or #[target_feature],");
writeln!(out, "and may be renamed or removed in a future version of LLVM or rustc.\n");
}

pub(crate) fn print(req: PrintRequest, sess: &Session) {
pub(crate) fn print(req: PrintRequest, mut out: &mut dyn PrintBackendInfo, sess: &Session) {
require_inited();
let tm = create_informational_target_machine(sess);
match req {
Expand All @@ -410,9 +411,21 @@ pub(crate) fn print(req: PrintRequest, sess: &Session) {
// at least as long as the C function
let cpu_cstring = CString::new(handle_native(sess.target.cpu.as_ref()))
.unwrap_or_else(|e| bug!("failed to convert to cstring: {}", e));
unsafe { llvm::LLVMRustPrintTargetCPUs(tm, cpu_cstring.as_ptr()) };
unsafe extern "C" fn callback(out: *mut c_void, string: *const c_char, len: usize) {
let out = &mut *(out as *mut &mut dyn PrintBackendInfo);
let bytes = slice::from_raw_parts(string as *const u8, len);
write!(out, "{}", String::from_utf8_lossy(bytes));
}
unsafe {
llvm::LLVMRustPrintTargetCPUs(
tm,
cpu_cstring.as_ptr(),
callback,
&mut out as *mut &mut dyn PrintBackendInfo as *mut c_void,
);
}
}
PrintRequest::TargetFeatures => print_target_features(sess, tm),
PrintRequest::TargetFeatures => print_target_features(out, sess, tm),
_ => bug!("rustc_codegen_llvm can't handle print request: {:?}", req),
}
}
Expand Down
20 changes: 19 additions & 1 deletion compiler/rustc_codegen_ssa/src/traits/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ use rustc_span::symbol::Symbol;
use rustc_target::abi::call::FnAbi;
use rustc_target::spec::Target;

use std::fmt;

pub trait BackendTypes {
type Value: CodegenObject;
type Function: CodegenObject;
Expand Down Expand Up @@ -61,7 +63,7 @@ pub trait CodegenBackend {
fn locale_resource(&self) -> &'static str;

fn init(&self, _sess: &Session) {}
fn print(&self, _req: PrintRequest, _sess: &Session) {}
fn print(&self, _req: PrintRequest, _out: &mut dyn PrintBackendInfo, _sess: &Session) {}
fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec<Symbol> {
vec![]
}
Expand Down Expand Up @@ -162,3 +164,19 @@ pub trait ExtraBackendMethods:
std::thread::Builder::new().name(name).spawn(f)
}
}

pub trait PrintBackendInfo {
fn infallible_write_fmt(&mut self, args: fmt::Arguments<'_>);
}

impl PrintBackendInfo for String {
fn infallible_write_fmt(&mut self, args: fmt::Arguments<'_>) {
fmt::Write::write_fmt(self, args).unwrap();
}
}

impl dyn PrintBackendInfo + '_ {
pub fn write_fmt(&mut self, args: fmt::Arguments<'_>) {
self.infallible_write_fmt(args);
}
}
4 changes: 3 additions & 1 deletion compiler/rustc_codegen_ssa/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ mod write;

pub use self::abi::AbiBuilderMethods;
pub use self::asm::{AsmBuilderMethods, AsmMethods, GlobalAsmOperandRef, InlineAsmOperandRef};
pub use self::backend::{Backend, BackendTypes, CodegenBackend, ExtraBackendMethods};
pub use self::backend::{
Backend, BackendTypes, CodegenBackend, ExtraBackendMethods, PrintBackendInfo,
};
pub use self::builder::{BuilderMethods, OverflowOp};
pub use self::consts::ConstMethods;
pub use self::coverageinfo::CoverageInfoBuilderMethods;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_driver_impl/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ driver_impl_rlink_unable_to_read = failed to read rlink file: `{$err}`

driver_impl_rlink_wrong_file_type = The input does not look like a .rlink file

driver_impl_unpretty_dump_fail = pretty-print failed to write `{$path}` due to error `{$err}`
driver_impl_unpretty_dump_fail = failed to write `{$path}` due to error `{$err}`
51 changes: 37 additions & 14 deletions compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,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};
Expand All @@ -67,6 +68,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.
Expand Down Expand Up @@ -718,6 +724,13 @@ fn print_crate_info(
parse_attrs: bool,
) -> Compilation {
use rustc_session::config::PrintRequest::*;

// 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) {
Expand All @@ -736,17 +749,24 @@ fn print_crate_info(
} else {
None
};

let mut crate_info = String::new();
macro println_info($($arg:tt)*) {
crate_info.write_fmt(format_args!("{}\n", format_args!($($arg)*))).unwrap()
}

let mut how_to_proceed = Compilation::Stop;
for req in &sess.opts.prints {
match *req {
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();
Expand All @@ -755,24 +775,25 @@ 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 => {
let Some(attrs) = attrs.as_ref() else {
// no crate attributes, print out an error and exit
return Compilation::Continue;
how_to_proceed = Compilation::Continue;
break;
};
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}");
println_info!("{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());
}
}
Cfg => {
Expand Down Expand Up @@ -806,21 +827,21 @@ 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
dtolnay marked this conversation as resolved.
Show resolved Hide resolved
| TlsModels
| 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 => {}
Expand All @@ -830,15 +851,15 @@ 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}");
}
}
}
DeploymentTarget => {
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")
Expand All @@ -850,7 +871,9 @@ fn print_crate_info(
}
}
}
Compilation::Stop

pretty::write_or_print(&crate_info, sess);
how_to_proceed
}

/// Prints version information
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_driver_impl/src/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ fn get_source(sess: &Session) -> (String, FileName) {
(src, src_name)
}

fn write_or_print(out: &str, sess: &Session) {
pub fn write_or_print(out: &str, sess: &Session) {
match &sess.io.output_file {
None | Some(OutFileName::Stdout) => print!("{out}"),
Some(OutFileName::Real(p)) => {
Expand Down
Loading