Skip to content

Commit 0617430

Browse files
committed
Implementation of target_api_features
1 parent 0301700 commit 0617430

File tree

14 files changed

+125
-0
lines changed

14 files changed

+125
-0
lines changed

src/doc/rustc/src/codegen-options/index.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,33 @@ point instructions in software. It takes one of the following values:
480480
* `y`, `yes`, `on`, or no value: use soft floats.
481481
* `n`, `no`, or `off`: use hardware floats (the default).
482482

483+
## target-api-features
484+
485+
This option tells `rustc` which operating system APIs are expected to be supported for the target.
486+
Implied features are added as well.
487+
488+
#### Windows
489+
490+
Currently, this option is only used for Windows targets, where the feature
491+
names are the `<major>.<minor>.<build>` versions of all major releases (e.g. `10.0.10240`).
492+
Any version selected adds all previous versions as well, allowing for "greater than"
493+
comparisons:
494+
495+
```rs
496+
if cfg!(target_api_feature = "10.0.10240") {
497+
println!("new win10 api here");
498+
} else if cfg!(target_api_feature = "6.1.7600") {
499+
println!("regular win7 api here");
500+
} else if cfg!(target_api_feature = "5.1.2600") {
501+
println!("legacy winxp api here");
502+
} else {
503+
println!("not supported");
504+
}
505+
```
506+
507+
Currently, the default for regular Windows targets is Windows 7 (`6.1.7600`).
508+
For UWP targets, it is Windows 10, Version 1509 (`10.0.10240`).
509+
483510
## target-cpu
484511

485512
This instructs `rustc` to generate code specifically for a particular processor.

src/librustc_interface/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ rustc_privacy = { path = "../librustc_privacy" }
4444
rustc_resolve = { path = "../librustc_resolve" }
4545
rustc_trait_selection = { path = "../librustc_trait_selection" }
4646
rustc_ty = { path = "../librustc_ty" }
47+
rustc_target = { path = "../librustc_target" }
4748
tempfile = "3.0.5"
4849
once_cell = "1"
4950

src/librustc_interface/tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ fn test_codegen_options_tracking_hash() {
444444
tracked!(profile_use, Some(PathBuf::from("abc")));
445445
tracked!(relocation_model, Some(RelocModel::Pic));
446446
tracked!(soft_float, true);
447+
tracked!(target_api_features, Some(vec![String::from("1"), String::from("2")]));
447448
tracked!(target_cpu, Some(String::from("abc")));
448449
tracked!(target_feature, String::from("all the features, all of them"));
449450
}

src/librustc_interface/util.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,22 @@ pub fn add_configuration(
5353
if sess.crt_static(None) {
5454
cfg.insert((tf, Some(sym::crt_dash_static)));
5555
}
56+
57+
let target_options = &sess.target.target.options;
58+
if let Some(target_api_kind) = &target_options.target_api_kind {
59+
let target_api_defaults = &target_options.target_api_default_features;
60+
let selected_target_apis =
61+
sess.opts.cg.target_api_features.as_ref().unwrap_or(target_api_defaults);
62+
63+
let apis = rustc_target::api::get_enabled_target_api_features(
64+
target_api_kind,
65+
selected_target_apis,
66+
);
67+
68+
let ta = sym::target_api_feature;
69+
cfg.extend(apis.into_iter().map(|api| (ta, Some(Symbol::intern(api)))));
70+
cfg.extend(selected_target_apis.into_iter().map(|api| (ta, Some(Symbol::intern(api)))));
71+
}
5672
}
5773

5874
pub fn create_session(

src/librustc_session/options.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,8 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
768768
"save all temporary output files during compilation (default: no)"),
769769
soft_float: bool = (false, parse_bool, [TRACKED],
770770
"use soft float ABI (*eabihf targets only) (default: no)"),
771+
target_api_features: Option<Vec<String>> = (None, parse_opt_list, [TRACKED],
772+
"a list of target APIs that are expected to be be available on the target (default: use target default)"),
771773
target_cpu: Option<String> = (None, parse_opt_string, [TRACKED],
772774
"select target processor (`rustc --print target-cpus` for details)"),
773775
target_feature: String = (String::new(), parse_target_feature, [TRACKED],

src/librustc_span/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,6 +1061,7 @@ symbols! {
10611061
sym,
10621062
sync,
10631063
sync_trait,
1064+
target_api_feature,
10641065
target_arch,
10651066
target_endian,
10661067
target_env,

src/librustc_target/api/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
pub mod windows;
2+
3+
pub fn get_enabled_target_api_features(
4+
target_kind: &str,
5+
requested_apis: &[String],
6+
) -> Vec<&'static str> {
7+
match target_kind {
8+
"windows" => windows::get_enabled_target_api_features(requested_apis),
9+
_ => vec![],
10+
}
11+
}

src/librustc_target/api/windows.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
const WINDOWS_VERSIONS: [&str; 25] = [
2+
"3.10.511", // NT 3.1
3+
"3.50.807", // NT 3.5
4+
"3.51.1057", // NT 3.51
5+
"4.0.1381", // NT 4
6+
"5.0.2195", // 2000
7+
"5.1.2600", // XP
8+
"5.2.3790", // XP 64bit, Server 2003
9+
"6.0.6000", // Vista, Server 2008
10+
"6.0.6001", // Vista SP1, Server 2008 SP1
11+
"6.0.6002", // Vista SP2, Server 2008 SP2
12+
"6.1.7600", // 7, Server 2008 R2
13+
"6.1.7601", // 7 SP1, Server 2008 R2 SP1
14+
"6.1.8400", // Home Server 2011
15+
"6.2.9200", // 8, Server 2012
16+
"6.3.9600", // 8.1, Server 2012 R2
17+
"10.0.10240", // 10 1507
18+
"10.0.10586", // 10 1511
19+
"10.0.14393", // 10 1607, Server 2016 1607
20+
"10.0.15063", // 10 1703
21+
"10.0.16299", // 10 1709, Server 2016 1709
22+
"10.0.17134", // 10 1803
23+
"10.0.17763", // 10 1809, Server 2019 1809
24+
"10.0.18362", // 10 1903
25+
"10.0.18363", // 10 1909
26+
"10.0.19041", // 10 2004
27+
];
28+
29+
pub fn get_enabled_target_api_features(requested_apis: &[String]) -> Vec<&'static str> {
30+
let highest_index = requested_apis.iter().fold(None, |old_highest_index, api| {
31+
if let Some((index, _)) = WINDOWS_VERSIONS.iter().enumerate().find(|&(_, ver)| ver == api) {
32+
old_highest_index.map(|old_index| std::cmp::max(old_index, index)).or(Some(index))
33+
} else {
34+
old_highest_index
35+
}
36+
});
37+
38+
highest_index.map(|i| WINDOWS_VERSIONS[..=i].into()).unwrap_or(vec![])
39+
}

src/librustc_target/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ extern crate rustc_macros;
2323
extern crate tracing;
2424

2525
pub mod abi;
26+
pub mod api;
2627
pub mod asm;
2728
pub mod spec;
2829

src/librustc_target/spec/mod.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -993,6 +993,12 @@ pub struct TargetOptions {
993993
/// used to locate unwinding information is passed
994994
/// (only has effect if the linker is `ld`-like).
995995
pub eh_frame_header: bool,
996+
997+
/// Decides which logic will be used for determining the full set of target API features
998+
pub target_api_kind: Option<String>,
999+
1000+
/// The default API features for this target.
1001+
pub target_api_default_features: Vec<String>,
9961002
}
9971003

9981004
impl Default for TargetOptions {
@@ -1085,6 +1091,8 @@ impl Default for TargetOptions {
10851091
llvm_args: vec![],
10861092
use_ctors_section: false,
10871093
eh_frame_header: true,
1094+
target_api_kind: None,
1095+
target_api_default_features: vec![],
10881096
}
10891097
}
10901098
}
@@ -1478,6 +1486,8 @@ impl Target {
14781486
key!(llvm_args, list);
14791487
key!(use_ctors_section, bool);
14801488
key!(eh_frame_header, bool);
1489+
key!(target_api_kind, optional);
1490+
key!(target_api_default_features, list);
14811491

14821492
// NB: The old name is deprecated, but support for it is retained for
14831493
// compatibility.
@@ -1716,6 +1726,8 @@ impl ToJson for Target {
17161726
target_option_val!(llvm_args);
17171727
target_option_val!(use_ctors_section);
17181728
target_option_val!(eh_frame_header);
1729+
target_option_val!(target_api_kind);
1730+
target_option_val!(target_api_default_features);
17191731

17201732
if default.unsupported_abis != self.options.unsupported_abis {
17211733
d.insert(
@@ -1791,3 +1803,10 @@ impl fmt::Display for TargetTriple {
17911803
write!(f, "{}", self.debug_triple())
17921804
}
17931805
}
1806+
1807+
/// A target api function and an optional default, if any
1808+
#[derive(PartialEq, Clone, Debug)]
1809+
pub struct TargetApiDefinition {
1810+
pub api_kind: String,
1811+
pub target_api_default_features: Vec<String>,
1812+
}

0 commit comments

Comments
 (0)