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
|
@ -40,7 +40,7 @@ use rustc_metadata::EncodedMetadata;
|
|||
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::config::{OptLevel, OutputFilenames, PrintRequest};
|
||||
use rustc_session::config::{OptLevel, OutputFilenames, PrintKind, PrintRequest};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::symbol::Symbol;
|
||||
|
||||
|
@ -284,10 +284,10 @@ impl CodegenBackend for LlvmCodegenBackend {
|
|||
|tcx, ()| llvm_util::global_llvm_features(tcx.sess, true)
|
||||
}
|
||||
|
||||
fn print(&self, req: PrintRequest, sess: &Session) {
|
||||
match req {
|
||||
PrintRequest::RelocationModels => {
|
||||
println!("Available relocation models:");
|
||||
fn print(&self, req: &PrintRequest, out: &mut dyn PrintBackendInfo, sess: &Session) {
|
||||
match req.kind {
|
||||
PrintKind::RelocationModels => {
|
||||
writeln!(out, "Available relocation models:");
|
||||
for name in &[
|
||||
"static",
|
||||
"pic",
|
||||
|
@ -298,26 +298,27 @@ impl CodegenBackend for LlvmCodegenBackend {
|
|||
"ropi-rwpi",
|
||||
"default",
|
||||
] {
|
||||
println!(" {}", name);
|
||||
writeln!(out, " {}", name);
|
||||
}
|
||||
println!();
|
||||
writeln!(out);
|
||||
}
|
||||
PrintRequest::CodeModels => {
|
||||
println!("Available code models:");
|
||||
PrintKind::CodeModels => {
|
||||
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:");
|
||||
PrintKind::TlsModels => {
|
||||
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!(
|
||||
PrintKind::StackProtectorStrategies => {
|
||||
writeln!(
|
||||
out,
|
||||
r#"Available stack protector strategies:
|
||||
all
|
||||
Generate stack canaries in all functions.
|
||||
|
@ -341,7 +342,7 @@ impl CodegenBackend for LlvmCodegenBackend {
|
|||
"#
|
||||
);
|
||||
}
|
||||
req => llvm_util::print(req, sess),
|
||||
_other => llvm_util::print(req, out, sess),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2283,7 +2283,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,
|
||||
|
|
|
@ -8,16 +8,17 @@ 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;
|
||||
use rustc_middle::bug;
|
||||
use rustc_session::config::PrintRequest;
|
||||
use rustc_session::config::{PrintKind, 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;
|
||||
|
@ -354,7 +355,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)
|
||||
|
@ -387,36 +388,48 @@ 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 {
|
||||
PrintRequest::TargetCPUs => {
|
||||
match req.kind {
|
||||
PrintKind::TargetCPUs => {
|
||||
// SAFETY generate a C compatible string from a byte slice to pass
|
||||
// the target CPU name into LLVM, the lifetime of the reference is
|
||||
// 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),
|
||||
PrintKind::TargetFeatures => print_target_features(out, sess, tm),
|
||||
_ => bug!("rustc_codegen_llvm can't handle print request: {:?}", req),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue