Rollup merge of #76832 - khyperia:backend_target_override, r=eddyb
Let backends define custom targets Add a target_override hook that takes priority over builtin targets.
This commit is contained in:
commit
c847eaa91d
5 changed files with 24 additions and 11 deletions
|
@ -15,6 +15,7 @@ use rustc_session::{
|
||||||
};
|
};
|
||||||
use rustc_span::symbol::Symbol;
|
use rustc_span::symbol::Symbol;
|
||||||
use rustc_target::abi::LayoutOf;
|
use rustc_target::abi::LayoutOf;
|
||||||
|
use rustc_target::spec::Target;
|
||||||
|
|
||||||
pub use rustc_data_structures::sync::MetadataRef;
|
pub use rustc_data_structures::sync::MetadataRef;
|
||||||
|
|
||||||
|
@ -54,6 +55,12 @@ pub trait CodegenBackend {
|
||||||
fn print_passes(&self) {}
|
fn print_passes(&self) {}
|
||||||
fn print_version(&self) {}
|
fn print_version(&self) {}
|
||||||
|
|
||||||
|
/// If this plugin provides additional builtin targets, provide the one enabled by the options here.
|
||||||
|
/// Be careful: this is called *before* init() is called.
|
||||||
|
fn target_override(&self, _opts: &config::Options) -> Option<Target> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn metadata_loader(&self) -> Box<MetadataLoaderDyn>;
|
fn metadata_loader(&self) -> Box<MetadataLoaderDyn>;
|
||||||
fn provide(&self, _providers: &mut Providers);
|
fn provide(&self, _providers: &mut Providers);
|
||||||
fn provide_extern(&self, _providers: &mut Providers);
|
fn provide_extern(&self, _providers: &mut Providers);
|
||||||
|
|
|
@ -40,6 +40,7 @@ fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
|
||||||
DiagnosticOutput::Default,
|
DiagnosticOutput::Default,
|
||||||
Default::default(),
|
Default::default(),
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
(sess, cfg)
|
(sess, cfg)
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,10 @@ pub fn create_session(
|
||||||
lint_caps: FxHashMap<lint::LintId, lint::Level>,
|
lint_caps: FxHashMap<lint::LintId, lint::Level>,
|
||||||
descriptions: Registry,
|
descriptions: Registry,
|
||||||
) -> (Lrc<Session>, Lrc<Box<dyn CodegenBackend>>) {
|
) -> (Lrc<Session>, Lrc<Box<dyn CodegenBackend>>) {
|
||||||
|
let codegen_backend = get_codegen_backend(&sopts);
|
||||||
|
// target_override is documented to be called before init(), so this is okay
|
||||||
|
let target_override = codegen_backend.target_override(&sopts);
|
||||||
|
|
||||||
let mut sess = session::build_session(
|
let mut sess = session::build_session(
|
||||||
sopts,
|
sopts,
|
||||||
input_path,
|
input_path,
|
||||||
|
@ -72,9 +76,10 @@ pub fn create_session(
|
||||||
diagnostic_output,
|
diagnostic_output,
|
||||||
lint_caps,
|
lint_caps,
|
||||||
file_loader,
|
file_loader,
|
||||||
|
target_override,
|
||||||
);
|
);
|
||||||
|
|
||||||
let codegen_backend = get_codegen_backend(&sess);
|
codegen_backend.init(&sess);
|
||||||
|
|
||||||
let mut cfg = config::build_configuration(&sess, config::to_crate_config(cfg));
|
let mut cfg = config::build_configuration(&sess, config::to_crate_config(cfg));
|
||||||
add_configuration(&mut cfg, &mut sess, &*codegen_backend);
|
add_configuration(&mut cfg, &mut sess, &*codegen_backend);
|
||||||
|
@ -219,13 +224,13 @@ fn load_backend_from_dylib(path: &Path) -> fn() -> Box<dyn CodegenBackend> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_codegen_backend(sess: &Session) -> Box<dyn CodegenBackend> {
|
pub fn get_codegen_backend(sopts: &config::Options) -> Box<dyn CodegenBackend> {
|
||||||
static INIT: Once = Once::new();
|
static INIT: Once = Once::new();
|
||||||
|
|
||||||
static mut LOAD: fn() -> Box<dyn CodegenBackend> = || unreachable!();
|
static mut LOAD: fn() -> Box<dyn CodegenBackend> = || unreachable!();
|
||||||
|
|
||||||
INIT.call_once(|| {
|
INIT.call_once(|| {
|
||||||
let codegen_name = sess.opts.debugging_opts.codegen_backend.as_deref().unwrap_or("llvm");
|
let codegen_name = sopts.debugging_opts.codegen_backend.as_deref().unwrap_or("llvm");
|
||||||
let backend = match codegen_name {
|
let backend = match codegen_name {
|
||||||
filename if filename.contains('.') => load_backend_from_dylib(filename.as_ref()),
|
filename if filename.contains('.') => load_backend_from_dylib(filename.as_ref()),
|
||||||
codegen_name => get_builtin_codegen_backend(codegen_name),
|
codegen_name => get_builtin_codegen_backend(codegen_name),
|
||||||
|
@ -235,9 +240,7 @@ pub fn get_codegen_backend(sess: &Session) -> Box<dyn CodegenBackend> {
|
||||||
LOAD = backend;
|
LOAD = backend;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let backend = unsafe { LOAD() };
|
unsafe { LOAD() }
|
||||||
backend.init(sess);
|
|
||||||
backend
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is used for rustdoc, but it uses similar machinery to codegen backend
|
// This is used for rustdoc, but it uses similar machinery to codegen backend
|
||||||
|
|
|
@ -818,10 +818,11 @@ pub fn build_configuration(sess: &Session, mut user_cfg: CrateConfig) -> CrateCo
|
||||||
user_cfg
|
user_cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_target_config(opts: &Options, error_format: ErrorOutputType) -> Config {
|
pub fn build_target_config(opts: &Options, target_override: Option<Target>) -> Config {
|
||||||
let target = Target::search(&opts.target_triple).unwrap_or_else(|e| {
|
let target_result = target_override.map_or_else(|| Target::search(&opts.target_triple), Ok);
|
||||||
|
let target = target_result.unwrap_or_else(|e| {
|
||||||
early_error(
|
early_error(
|
||||||
error_format,
|
opts.error_format,
|
||||||
&format!(
|
&format!(
|
||||||
"Error loading target specification: {}. \
|
"Error loading target specification: {}. \
|
||||||
Use `--print target-list` for a list of built-in targets",
|
Use `--print target-list` for a list of built-in targets",
|
||||||
|
@ -835,7 +836,7 @@ pub fn build_target_config(opts: &Options, error_format: ErrorOutputType) -> Con
|
||||||
"32" => 32,
|
"32" => 32,
|
||||||
"64" => 64,
|
"64" => 64,
|
||||||
w => early_error(
|
w => early_error(
|
||||||
error_format,
|
opts.error_format,
|
||||||
&format!(
|
&format!(
|
||||||
"target specification was invalid: \
|
"target specification was invalid: \
|
||||||
unrecognized target-pointer-width {}",
|
unrecognized target-pointer-width {}",
|
||||||
|
|
|
@ -1234,6 +1234,7 @@ pub fn build_session(
|
||||||
diagnostics_output: DiagnosticOutput,
|
diagnostics_output: DiagnosticOutput,
|
||||||
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
|
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
|
||||||
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
|
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
|
||||||
|
target_override: Option<Target>,
|
||||||
) -> Session {
|
) -> Session {
|
||||||
// FIXME: This is not general enough to make the warning lint completely override
|
// FIXME: This is not general enough to make the warning lint completely override
|
||||||
// normal diagnostic warnings, since the warning lint can also be denied and changed
|
// normal diagnostic warnings, since the warning lint can also be denied and changed
|
||||||
|
@ -1253,7 +1254,7 @@ pub fn build_session(
|
||||||
DiagnosticOutput::Raw(write) => Some(write),
|
DiagnosticOutput::Raw(write) => Some(write),
|
||||||
};
|
};
|
||||||
|
|
||||||
let target_cfg = config::build_target_config(&sopts, sopts.error_format);
|
let target_cfg = config::build_target_config(&sopts, target_override);
|
||||||
let host_triple = TargetTriple::from_triple(config::host_triple());
|
let host_triple = TargetTriple::from_triple(config::host_triple());
|
||||||
let host = Target::search(&host_triple).unwrap_or_else(|e| {
|
let host = Target::search(&host_triple).unwrap_or_else(|e| {
|
||||||
early_error(sopts.error_format, &format!("Error loading host specification: {}", e))
|
early_error(sopts.error_format, &format!("Error loading host specification: {}", e))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue