-
Notifications
You must be signed in to change notification settings - Fork 451
/
main.rs
122 lines (105 loc) · 4.49 KB
/
main.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use std::io::Write as _;
use std::{fs::File, io::BufRead};
use gen_target_info::{
get_target_spec_from_msrv, get_target_specs_from_json, get_targets_msrv, RustcTargetSpecs,
};
const PRELUDE: &str = r#"//! This file is generated code. Please edit the generator
//! in dev-tools/gen-target-info if you need to make changes.
"#;
fn generate_target_mapping(f: &mut File, target_specs: &RustcTargetSpecs) -> std::io::Result<()> {
writeln!(f, "use super::TargetInfo;")?;
writeln!(f)?;
writeln!(
f,
"pub(crate) const LIST: &[(&str, TargetInfo<'static>)] = &["
)?;
for (triple, spec) in &target_specs.0 {
let full_arch = triple.split_once('-').unwrap().0;
let arch = &spec.arch;
let vendor = spec.vendor.as_deref().unwrap_or("unknown");
let os = spec.os.as_deref().unwrap_or("none");
let env = spec.env.as_deref().unwrap_or("");
let abi = spec.abi.as_deref().unwrap_or("");
let unversioned_llvm_target = if spec.llvm_target.contains("apple") {
// Remove deployment target information from LLVM target triples (we
// will add this in another part of CC).
//
// FIXME(madsmtm): Should become unnecessary after
// https://github.com/rust-lang/rust/pull/131037
let mut components = spec.llvm_target.split("-").collect::<Vec<_>>();
components[2] = components[2].trim_end_matches(|c: char| c.is_numeric() || c == '.');
components.join("-")
} else if os == "uefi" {
// Override the UEFI LLVM targets.
//
// The rustc mappings (as of 1.82) for the UEFI targets are:
// * i686-unknown-uefi -> i686-unknown-windows-gnu
// * x86_64-unknown-uefi -> x86_64-unknown-windows
// * aarch64-unknown-uefi -> aarch64-unknown-windows
//
// However, in cc-rs all the UEFI targets use
// -windows-gnu. This has been the case since 2021 [1].
// * i686-unknown-uefi -> i686-unknown-windows-gnu
// * x86_64-unknown-uefi -> x86_64-unknown-windows-gnu
// * aarch64-unknown-uefi -> aarch64-unknown-windows-gnu
//
// For now, override the UEFI mapping to keep the behavior
// of cc-rs unchanged.
//
// TODO: as discussed in [2], it may be possible to switch
// to new UEFI targets added to clang, and regardless it
// would be good to have consistency between rustc and
// cc-rs.
//
// [1]: https://github.com/rust-lang/cc-rs/pull/623
// [2]: https://github.com/rust-lang/cc-rs/pull/1264
let arch = if spec.arch == "x86" {
"i686"
} else {
&spec.arch
};
format!("{}-unknown-windows-gnu", arch)
} else {
spec.llvm_target.clone()
};
writeln!(f, " (")?;
writeln!(f, " {triple:?},")?;
writeln!(f, " TargetInfo {{")?;
writeln!(f, " full_arch: {full_arch:?},")?;
writeln!(f, " arch: {arch:?},")?;
writeln!(f, " vendor: {vendor:?},")?;
writeln!(f, " os: {os:?},")?;
writeln!(f, " env: {env:?},")?;
writeln!(f, " abi: {abi:?},")?;
writeln!(
f,
" unversioned_llvm_target: {unversioned_llvm_target:?},"
)?;
writeln!(f, " }},")?;
writeln!(f, " ),")?;
}
writeln!(f, "];")?;
Ok(())
}
fn main() {
// Primarily use information from nightly.
let mut target_specs = get_target_specs_from_json();
// Next, read from MSRV to support old, removed targets.
for target_triple in get_targets_msrv().lines() {
let target_triple = target_triple.unwrap();
let target_triple = target_triple.trim();
target_specs
.0
.entry(target_triple.to_string())
.or_insert_with(|| get_target_spec_from_msrv(target_triple));
}
// Open file to write to
let manifest_dir = env!("CARGO_MANIFEST_DIR");
let path = format!("{manifest_dir}/../../src/target/generated.rs");
let mut f = File::create(path).expect("failed to create src/target/generated.rs");
f.write_all(PRELUDE.as_bytes()).unwrap();
// Start generating
generate_target_mapping(&mut f, &target_specs).unwrap();
// Flush the data onto disk
f.flush().unwrap();
}