Skip to content

Commit 6c910a9

Browse files
authored
Unrolled build for rust-lang#116793
Rollup merge of rust-lang#116793 - WaffleLapkin:target_rules_the_backend, r=cjgillot Allow targets to override default codegen backend Implements rust-lang/compiler-team#670.
2 parents 65cd843 + 6d115f5 commit 6c910a9

File tree

8 files changed

+117
-59
lines changed

8 files changed

+117
-59
lines changed

compiler/rustc_driver_impl/src/lib.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use rustc_session::config::{nightly_options, CG_OPTIONS, Z_OPTIONS};
3737
use rustc_session::config::{ErrorOutputType, Input, OutFileName, OutputType};
3838
use rustc_session::getopts::{self, Matches};
3939
use rustc_session::lint::{Lint, LintId};
40-
use rustc_session::{config, EarlyDiagCtxt, Session};
40+
use rustc_session::{config, filesearch, EarlyDiagCtxt, Session};
4141
use rustc_span::def_id::LOCAL_CRATE;
4242
use rustc_span::source_map::FileLoader;
4343
use rustc_span::symbol::sym;
@@ -887,7 +887,11 @@ pub fn version_at_macro_invocation(
887887

888888
let debug_flags = matches.opt_strs("Z");
889889
let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend="));
890-
get_codegen_backend(early_dcx, &None, backend_name).print_version();
890+
let opts = config::Options::default();
891+
let sysroot = filesearch::materialize_sysroot(opts.maybe_sysroot.clone());
892+
let target = config::build_target_config(early_dcx, &opts, None, &sysroot);
893+
894+
get_codegen_backend(early_dcx, &sysroot, backend_name, &target).print_version();
891895
}
892896
}
893897

@@ -1092,7 +1096,12 @@ pub fn describe_flag_categories(early_dcx: &EarlyDiagCtxt, matches: &Matches) ->
10921096

10931097
if cg_flags.iter().any(|x| *x == "passes=list") {
10941098
let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend="));
1095-
get_codegen_backend(early_dcx, &None, backend_name).print_passes();
1099+
1100+
let opts = config::Options::default();
1101+
let sysroot = filesearch::materialize_sysroot(opts.maybe_sysroot.clone());
1102+
let target = config::build_target_config(early_dcx, &opts, None, &sysroot);
1103+
1104+
get_codegen_backend(early_dcx, &sysroot, backend_name, &target).print_passes();
10961105
return true;
10971106
}
10981107

compiler/rustc_interface/src/interface.rs

+48-13
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc_parse::maybe_new_parser_from_source_str;
1616
use rustc_query_impl::QueryCtxt;
1717
use rustc_query_system::query::print_query_stack;
1818
use rustc_session::config::{self, Cfg, CheckCfg, ExpectedValues, Input, OutFileName};
19-
use rustc_session::filesearch::sysroot_candidates;
19+
use rustc_session::filesearch::{self, sysroot_candidates};
2020
use rustc_session::parse::ParseSess;
2121
use rustc_session::{lint, CompilerIO, EarlyDiagCtxt, Session};
2222
use rustc_span::source_map::FileLoader;
@@ -339,16 +339,53 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
339339

340340
let early_dcx = EarlyDiagCtxt::new(config.opts.error_format);
341341

342-
let codegen_backend = if let Some(make_codegen_backend) = config.make_codegen_backend {
343-
make_codegen_backend(&config.opts)
344-
} else {
345-
util::get_codegen_backend(
346-
&early_dcx,
347-
&config.opts.maybe_sysroot,
348-
config.opts.unstable_opts.codegen_backend.as_deref(),
349-
)
342+
let sysroot = filesearch::materialize_sysroot(config.opts.maybe_sysroot.clone());
343+
344+
let (codegen_backend, target_override) = match config.make_codegen_backend {
345+
None => {
346+
// Build a target without override, so that it can override the backend if needed
347+
let target =
348+
config::build_target_config(&early_dcx, &config.opts, None, &sysroot);
349+
350+
let backend = util::get_codegen_backend(
351+
&early_dcx,
352+
&sysroot,
353+
config.opts.unstable_opts.codegen_backend.as_deref(),
354+
&target,
355+
);
356+
357+
// target_override is documented to be called before init(), so this is okay
358+
let target_override = backend.target_override(&config.opts);
359+
360+
// Assert that we don't use target's override of the backend and
361+
// backend's override of the target at the same time
362+
if config.opts.unstable_opts.codegen_backend.is_none()
363+
&& target.default_codegen_backend.is_some()
364+
&& target_override.is_some()
365+
{
366+
rustc_middle::bug!(
367+
"Codegen backend requested target override even though the target requested the backend"
368+
);
369+
}
370+
371+
(backend, target_override)
372+
}
373+
Some(make_codegen_backend) => {
374+
// N.B. `make_codegen_backend` takes precedence over `target.default_codegen_backend`,
375+
// which is ignored in this case.
376+
let backend = make_codegen_backend(&config.opts);
377+
378+
// target_override is documented to be called before init(), so this is okay
379+
let target_override = backend.target_override(&config.opts);
380+
381+
(backend, target_override)
382+
}
350383
};
351384

385+
// Re-build target with the (potential) override
386+
let target_cfg =
387+
config::build_target_config(&early_dcx, &config.opts, target_override, &sysroot);
388+
352389
let temps_dir = config.opts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);
353390

354391
let bundle = match rustc_errors::fluent_bundle(
@@ -367,9 +404,6 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
367404
let mut locale_resources = Vec::from(config.locale_resources);
368405
locale_resources.push(codegen_backend.locale_resource());
369406

370-
// target_override is documented to be called before init(), so this is okay
371-
let target_override = codegen_backend.target_override(&config.opts);
372-
373407
let mut sess = rustc_session::build_session(
374408
early_dcx,
375409
config.opts,
@@ -384,7 +418,8 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
384418
locale_resources,
385419
config.lint_caps,
386420
config.file_loader,
387-
target_override,
421+
target_cfg,
422+
sysroot,
388423
util::rustc_version_str().unwrap_or("unknown"),
389424
config.ice_file,
390425
config.using_internal_features,

compiler/rustc_interface/src/tests.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_session::config::{
1313
use rustc_session::lint::Level;
1414
use rustc_session::search_paths::SearchPath;
1515
use rustc_session::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
16-
use rustc_session::{build_session, getopts, CompilerIO, EarlyDiagCtxt, Session};
16+
use rustc_session::{build_session, filesearch, getopts, CompilerIO, EarlyDiagCtxt, Session};
1717
use rustc_span::edition::{Edition, DEFAULT_EDITION};
1818
use rustc_span::symbol::sym;
1919
use rustc_span::{FileName, SourceFileHashAlgorithm};
@@ -37,6 +37,12 @@ fn mk_session(matches: getopts::Matches) -> (Session, Cfg) {
3737
output_file: None,
3838
temps_dir,
3939
};
40+
41+
let sysroot = filesearch::materialize_sysroot(sessopts.maybe_sysroot.clone());
42+
43+
let target_cfg =
44+
rustc_session::config::build_target_config(&early_dcx, &sessopts, None, &sysroot);
45+
4046
let sess = build_session(
4147
early_dcx,
4248
sessopts,
@@ -46,7 +52,8 @@ fn mk_session(matches: getopts::Matches) -> (Session, Cfg) {
4652
vec![],
4753
Default::default(),
4854
None,
49-
None,
55+
target_cfg,
56+
sysroot,
5057
"",
5158
None,
5259
Arc::default(),

compiler/rustc_interface/src/util.rs

+26-21
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@ use rustc_session::{filesearch, output, Session};
1414
use rustc_span::edit_distance::find_best_match_for_name;
1515
use rustc_span::edition::Edition;
1616
use rustc_span::symbol::{sym, Symbol};
17+
use rustc_target::spec::Target;
1718
use session::EarlyDiagCtxt;
18-
use std::env;
1919
use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
2020
use std::path::{Path, PathBuf};
2121
use std::sync::atomic::{AtomicBool, Ordering};
2222
use std::sync::OnceLock;
2323
use std::thread;
24+
use std::{env, iter};
2425

2526
/// Function pointer type that constructs a new CodegenBackend.
2627
pub type MakeBackendFn = fn() -> Box<dyn CodegenBackend>;
@@ -195,21 +196,25 @@ fn load_backend_from_dylib(early_dcx: &EarlyDiagCtxt, path: &Path) -> MakeBacken
195196
/// A name of `None` indicates that the default backend should be used.
196197
pub fn get_codegen_backend(
197198
early_dcx: &EarlyDiagCtxt,
198-
maybe_sysroot: &Option<PathBuf>,
199+
sysroot: &Path,
199200
backend_name: Option<&str>,
201+
target: &Target,
200202
) -> Box<dyn CodegenBackend> {
201203
static LOAD: OnceLock<unsafe fn() -> Box<dyn CodegenBackend>> = OnceLock::new();
202204

203205
let load = LOAD.get_or_init(|| {
204-
let default_codegen_backend = option_env!("CFG_DEFAULT_CODEGEN_BACKEND").unwrap_or("llvm");
206+
let backend = backend_name
207+
.or(target.default_codegen_backend.as_deref())
208+
.or(option_env!("CFG_DEFAULT_CODEGEN_BACKEND"))
209+
.unwrap_or("llvm");
205210

206-
match backend_name.unwrap_or(default_codegen_backend) {
211+
match backend {
207212
filename if filename.contains('.') => {
208213
load_backend_from_dylib(early_dcx, filename.as_ref())
209214
}
210215
#[cfg(feature = "llvm")]
211216
"llvm" => rustc_codegen_llvm::LlvmCodegenBackend::new,
212-
backend_name => get_codegen_sysroot(early_dcx, maybe_sysroot, backend_name),
217+
backend_name => get_codegen_sysroot(early_dcx, sysroot, backend_name),
213218
}
214219
});
215220

@@ -244,7 +249,7 @@ fn get_rustc_path_inner(bin_path: &str) -> Option<PathBuf> {
244249
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
245250
fn get_codegen_sysroot(
246251
early_dcx: &EarlyDiagCtxt,
247-
maybe_sysroot: &Option<PathBuf>,
252+
sysroot: &Path,
248253
backend_name: &str,
249254
) -> MakeBackendFn {
250255
// For now we only allow this function to be called once as it'll dlopen a
@@ -261,28 +266,28 @@ fn get_codegen_sysroot(
261266
let target = session::config::host_triple();
262267
let sysroot_candidates = sysroot_candidates();
263268

264-
let sysroot = maybe_sysroot
265-
.iter()
266-
.chain(sysroot_candidates.iter())
269+
let sysroot = iter::once(sysroot)
270+
.chain(sysroot_candidates.iter().map(<_>::as_ref))
267271
.map(|sysroot| {
268272
filesearch::make_target_lib_path(sysroot, target).with_file_name("codegen-backends")
269273
})
270274
.find(|f| {
271275
info!("codegen backend candidate: {}", f.display());
272276
f.exists()
273-
});
274-
let sysroot = sysroot.unwrap_or_else(|| {
275-
let candidates = sysroot_candidates
276-
.iter()
277-
.map(|p| p.display().to_string())
278-
.collect::<Vec<_>>()
279-
.join("\n* ");
280-
let err = format!(
281-
"failed to find a `codegen-backends` folder \
277+
})
278+
.unwrap_or_else(|| {
279+
let candidates = sysroot_candidates
280+
.iter()
281+
.map(|p| p.display().to_string())
282+
.collect::<Vec<_>>()
283+
.join("\n* ");
284+
let err = format!(
285+
"failed to find a `codegen-backends` folder \
282286
in the sysroot candidates:\n* {candidates}"
283-
);
284-
early_dcx.early_fatal(err);
285-
});
287+
);
288+
early_dcx.early_fatal(err);
289+
});
290+
286291
info!("probing {} for a codegen backend", sysroot.display());
287292

288293
let d = sysroot.read_dir().unwrap_or_else(|e| {

compiler/rustc_session/src/config.rs

+5-13
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ pub use crate::options::*;
88
use crate::errors::FileWriteFail;
99
use crate::search_paths::SearchPath;
1010
use crate::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
11-
use crate::{lint, HashStableContext};
11+
use crate::{filesearch, lint, HashStableContext};
1212
use crate::{EarlyDiagCtxt, Session};
1313
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
1414
use rustc_data_structures::stable_hasher::{StableOrd, ToStableHashKey};
@@ -1564,7 +1564,7 @@ pub fn build_configuration(sess: &Session, mut user_cfg: Cfg) -> Cfg {
15641564
user_cfg
15651565
}
15661566

1567-
pub(super) fn build_target_config(
1567+
pub fn build_target_config(
15681568
early_dcx: &EarlyDiagCtxt,
15691569
opts: &Options,
15701570
target_override: Option<Target>,
@@ -2863,16 +2863,8 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
28632863

28642864
let logical_env = parse_logical_env(early_dcx, matches);
28652865

2866-
// Try to find a directory containing the Rust `src`, for more details see
2867-
// the doc comment on the `real_rust_source_base_dir` field.
2868-
let tmp_buf;
2869-
let sysroot = match &sysroot_opt {
2870-
Some(s) => s,
2871-
None => {
2872-
tmp_buf = crate::filesearch::get_or_default_sysroot().expect("Failed finding sysroot");
2873-
&tmp_buf
2874-
}
2875-
};
2866+
let sysroot = filesearch::materialize_sysroot(sysroot_opt);
2867+
28762868
let real_rust_source_base_dir = {
28772869
// This is the location used by the `rust-src` `rustup` component.
28782870
let mut candidate = sysroot.join("lib/rustlib/src/rust");
@@ -2916,7 +2908,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
29162908
describe_lints,
29172909
output_types,
29182910
search_paths,
2919-
maybe_sysroot: sysroot_opt,
2911+
maybe_sysroot: Some(sysroot),
29202912
target_triple,
29212913
test,
29222914
incremental,

compiler/rustc_session/src/filesearch.rs

+6
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,12 @@ pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> {
193193
return sysroot_candidates;
194194
}
195195

196+
/// Returns the provided sysroot or calls [`get_or_default_sysroot`] if it's none.
197+
/// Panics if [`get_or_default_sysroot`] returns an error.
198+
pub fn materialize_sysroot(maybe_sysroot: Option<PathBuf>) -> PathBuf {
199+
maybe_sysroot.unwrap_or_else(|| get_or_default_sysroot().expect("Failed finding sysroot"))
200+
}
201+
196202
/// This function checks if sysroot is found using env::args().next(), and if it
197203
/// is not found, finds sysroot from current rustc_driver dll.
198204
pub fn get_or_default_sysroot() -> Result<PathBuf, String> {

compiler/rustc_session/src/session.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -1016,7 +1016,8 @@ pub fn build_session(
10161016
fluent_resources: Vec<&'static str>,
10171017
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
10181018
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
1019-
target_override: Option<Target>,
1019+
target_cfg: Target,
1020+
sysroot: PathBuf,
10201021
cfg_version: &'static str,
10211022
ice_file: Option<PathBuf>,
10221023
using_internal_features: Arc<AtomicBool>,
@@ -1033,12 +1034,6 @@ pub fn build_session(
10331034
let cap_lints_allow = sopts.lint_cap.is_some_and(|cap| cap == lint::Allow);
10341035
let can_emit_warnings = !(warnings_allow || cap_lints_allow);
10351036

1036-
let sysroot = match &sopts.maybe_sysroot {
1037-
Some(sysroot) => sysroot.clone(),
1038-
None => filesearch::get_or_default_sysroot().expect("Failed finding sysroot"),
1039-
};
1040-
1041-
let target_cfg = config::build_target_config(&early_dcx, &sopts, target_override, &sysroot);
10421037
let host_triple = TargetTriple::from_triple(config::host_triple());
10431038
let (host, target_warnings) = Target::search(&host_triple, &sysroot).unwrap_or_else(|e| {
10441039
early_dcx.early_fatal(format!("Error loading host specification: {e}"))

compiler/rustc_target/src/spec/mod.rs

+9
Original file line numberDiff line numberDiff line change
@@ -2070,6 +2070,14 @@ pub struct TargetOptions {
20702070
/// Default number of codegen units to use in debug mode
20712071
pub default_codegen_units: Option<u64>,
20722072

2073+
/// Default codegen backend used for this target. Defaults to `None`.
2074+
///
2075+
/// If `None`, then `CFG_DEFAULT_CODEGEN_BACKEND` environmental variable captured when
2076+
/// compiling `rustc` will be used instead (or llvm if it is not set).
2077+
///
2078+
/// N.B. when *using* the compiler, backend can always be overriden with `-Zcodegen-backend`.
2079+
pub default_codegen_backend: Option<StaticCow<str>>,
2080+
20732081
/// Whether to generate trap instructions in places where optimization would
20742082
/// otherwise produce control flow that falls through into unrelated memory.
20752083
pub trap_unreachable: bool,
@@ -2376,6 +2384,7 @@ impl Default for TargetOptions {
23762384
stack_probes: StackProbeType::None,
23772385
min_global_align: None,
23782386
default_codegen_units: None,
2387+
default_codegen_backend: None,
23792388
trap_unreachable: true,
23802389
requires_lto: false,
23812390
singlethread: false,

0 commit comments

Comments
 (0)