Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit efeee84

Browse files
authoredSep 19, 2020
Rollup merge of rust-lang#76832 - khyperia:backend_target_override, r=eddyb
Let backends define custom targets Add a target_override hook that takes priority over builtin targets.
2 parents 488543c + 48655c2 commit efeee84

File tree

5 files changed

+24
-11
lines changed

5 files changed

+24
-11
lines changed
 

‎compiler/rustc_codegen_ssa/src/traits/backend.rs

+7
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use rustc_session::{
1515
};
1616
use rustc_span::symbol::Symbol;
1717
use rustc_target::abi::LayoutOf;
18+
use rustc_target::spec::Target;
1819

1920
pub use rustc_data_structures::sync::MetadataRef;
2021

@@ -54,6 +55,12 @@ pub trait CodegenBackend {
5455
fn print_passes(&self) {}
5556
fn print_version(&self) {}
5657

58+
/// If this plugin provides additional builtin targets, provide the one enabled by the options here.
59+
/// Be careful: this is called *before* init() is called.
60+
fn target_override(&self, _opts: &config::Options) -> Option<Target> {
61+
None
62+
}
63+
5764
fn metadata_loader(&self) -> Box<MetadataLoaderDyn>;
5865
fn provide(&self, _providers: &mut Providers);
5966
fn provide_extern(&self, _providers: &mut Providers);

‎compiler/rustc_interface/src/tests.rs

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
4040
DiagnosticOutput::Default,
4141
Default::default(),
4242
None,
43+
None,
4344
);
4445
(sess, cfg)
4546
}

‎compiler/rustc_interface/src/util.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -65,16 +65,21 @@ pub fn create_session(
6565
lint_caps: FxHashMap<lint::LintId, lint::Level>,
6666
descriptions: Registry,
6767
) -> (Lrc<Session>, Lrc<Box<dyn CodegenBackend>>) {
68+
let codegen_backend = get_codegen_backend(&sopts);
69+
// target_override is documented to be called before init(), so this is okay
70+
let target_override = codegen_backend.target_override(&sopts);
71+
6872
let mut sess = session::build_session(
6973
sopts,
7074
input_path,
7175
descriptions,
7276
diagnostic_output,
7377
lint_caps,
7478
file_loader,
79+
target_override,
7580
);
7681

77-
let codegen_backend = get_codegen_backend(&sess);
82+
codegen_backend.init(&sess);
7883

7984
let mut cfg = config::build_configuration(&sess, config::to_crate_config(cfg));
8085
add_configuration(&mut cfg, &mut sess, &*codegen_backend);
@@ -219,13 +224,13 @@ fn load_backend_from_dylib(path: &Path) -> fn() -> Box<dyn CodegenBackend> {
219224
}
220225
}
221226

222-
pub fn get_codegen_backend(sess: &Session) -> Box<dyn CodegenBackend> {
227+
pub fn get_codegen_backend(sopts: &config::Options) -> Box<dyn CodegenBackend> {
223228
static INIT: Once = Once::new();
224229

225230
static mut LOAD: fn() -> Box<dyn CodegenBackend> = || unreachable!();
226231

227232
INIT.call_once(|| {
228-
let codegen_name = sess.opts.debugging_opts.codegen_backend.as_deref().unwrap_or("llvm");
233+
let codegen_name = sopts.debugging_opts.codegen_backend.as_deref().unwrap_or("llvm");
229234
let backend = match codegen_name {
230235
filename if filename.contains('.') => load_backend_from_dylib(filename.as_ref()),
231236
codegen_name => get_builtin_codegen_backend(codegen_name),
@@ -235,9 +240,7 @@ pub fn get_codegen_backend(sess: &Session) -> Box<dyn CodegenBackend> {
235240
LOAD = backend;
236241
}
237242
});
238-
let backend = unsafe { LOAD() };
239-
backend.init(sess);
240-
backend
243+
unsafe { LOAD() }
241244
}
242245

243246
// This is used for rustdoc, but it uses similar machinery to codegen backend

‎compiler/rustc_session/src/config.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -818,10 +818,11 @@ pub fn build_configuration(sess: &Session, mut user_cfg: CrateConfig) -> CrateCo
818818
user_cfg
819819
}
820820

821-
pub fn build_target_config(opts: &Options, error_format: ErrorOutputType) -> Config {
822-
let target = Target::search(&opts.target_triple).unwrap_or_else(|e| {
821+
pub fn build_target_config(opts: &Options, target_override: Option<Target>) -> Config {
822+
let target_result = target_override.map_or_else(|| Target::search(&opts.target_triple), Ok);
823+
let target = target_result.unwrap_or_else(|e| {
823824
early_error(
824-
error_format,
825+
opts.error_format,
825826
&format!(
826827
"Error loading target specification: {}. \
827828
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
835836
"32" => 32,
836837
"64" => 64,
837838
w => early_error(
838-
error_format,
839+
opts.error_format,
839840
&format!(
840841
"target specification was invalid: \
841842
unrecognized target-pointer-width {}",

‎compiler/rustc_session/src/session.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1234,6 +1234,7 @@ pub fn build_session(
12341234
diagnostics_output: DiagnosticOutput,
12351235
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
12361236
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
1237+
target_override: Option<Target>,
12371238
) -> Session {
12381239
// FIXME: This is not general enough to make the warning lint completely override
12391240
// normal diagnostic warnings, since the warning lint can also be denied and changed
@@ -1253,7 +1254,7 @@ pub fn build_session(
12531254
DiagnosticOutput::Raw(write) => Some(write),
12541255
};
12551256

1256-
let target_cfg = config::build_target_config(&sopts, sopts.error_format);
1257+
let target_cfg = config::build_target_config(&sopts, target_override);
12571258
let host_triple = TargetTriple::from_triple(config::host_triple());
12581259
let host = Target::search(&host_triple).unwrap_or_else(|e| {
12591260
early_error(sopts.error_format, &format!("Error loading host specification: {}", e))

0 commit comments

Comments
 (0)
Please sign in to comment.