Skip to content

Commit 9c663ca

Browse files
authored
Use rustc's knowledge of LLVM/Clang target triples (#1252)
* Rename Target -> TargetInfo * Add LLVM target triple to TargetInfo * Remove AppleOs wrapper struct * Simplify SDK name lookup code * Fix passing --target to Clang Use the same LLVM target triple as rustc does * Don't pass `--target` twice on Windows * Simplify LLVM target triple version removal * Appease clippy * Fix naming mistake * Simplify
1 parent 290a629 commit 9c663ca

File tree

9 files changed

+764
-479
lines changed

9 files changed

+764
-479
lines changed

.github/workflows/regenerate-target-info.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,4 @@ jobs:
5252
env:
5353
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
5454
run: |
55-
gh pr create --base main --title "Update src/target_info.rs" --body "Automatically regenerated in CI"
55+
gh pr create --base main --title "Update src/target/generated.rs" --body "Automatically regenerated in CI"

dev-tools/gen-target-info/src/main.rs

+22-3
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ const PRELUDE: &str = r#"//! This file is generated code. Please edit the genera
1111
"#;
1212

1313
fn generate_target_mapping(f: &mut File, target_specs: &RustcTargetSpecs) -> std::io::Result<()> {
14-
writeln!(f, "use super::Target;")?;
14+
writeln!(f, "use super::TargetInfo;")?;
1515
writeln!(f, "use std::borrow::Cow;")?;
1616
writeln!(f)?;
17-
writeln!(f, "pub(crate) const LIST: &[(&str, Target)] = &[")?;
17+
writeln!(f, "pub(crate) const LIST: &[(&str, TargetInfo)] = &[")?;
1818

1919
for (triple, spec) in &target_specs.0 {
2020
let full_arch = triple.split_once('-').unwrap().0;
@@ -24,15 +24,34 @@ fn generate_target_mapping(f: &mut File, target_specs: &RustcTargetSpecs) -> std
2424
let env = spec.env.as_deref().unwrap_or("");
2525
let abi = spec.abi.as_deref().unwrap_or("");
2626

27+
// Remove deployment target information from LLVM target triples (we
28+
// will add this in another part of CC).
29+
//
30+
// FIXME(madsmtm): Should become unnecessary after
31+
// https://github.com/rust-lang/rust/pull/131037
32+
let unversioned_llvm_target = if spec.llvm_target.contains("apple") {
33+
let mut components = spec.llvm_target.split("-").collect::<Vec<_>>();
34+
35+
components[2] = components[2].trim_end_matches(|c: char| c.is_numeric() || c == '.');
36+
37+
components.join("-")
38+
} else {
39+
spec.llvm_target.clone()
40+
};
41+
2742
writeln!(f, " (")?;
2843
writeln!(f, " {triple:?},")?;
29-
writeln!(f, " Target {{")?;
44+
writeln!(f, " TargetInfo {{")?;
3045
writeln!(f, " full_arch: Cow::Borrowed({full_arch:?}),")?;
3146
writeln!(f, " arch: Cow::Borrowed({arch:?}),")?;
3247
writeln!(f, " vendor: Cow::Borrowed({vendor:?}),")?;
3348
writeln!(f, " os: Cow::Borrowed({os:?}),")?;
3449
writeln!(f, " env: Cow::Borrowed({env:?}),")?;
3550
writeln!(f, " abi: Cow::Borrowed({abi:?}),")?;
51+
writeln!(
52+
f,
53+
" unversioned_llvm_target: Cow::Borrowed({unversioned_llvm_target:?}),"
54+
)?;
3655
writeln!(f, " }},")?;
3756
writeln!(f, " ),")?;
3857
}

src/lib.rs

+51-181
Large diffs are not rendered by default.

src/target.rs

+21-10
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ use std::{borrow::Cow, env, str::FromStr};
66

77
use crate::{Error, ErrorKind};
88

9+
mod apple;
910
mod generated;
11+
mod llvm;
1012

11-
/// The parts of `rustc`'s target triple.
13+
/// Information specific to a `rustc` target.
1214
///
1315
/// See <https://doc.rust-lang.org/cargo/appendix/glossary.html#target>.
1416
#[derive(Debug, PartialEq, Clone)]
15-
pub(crate) struct Target {
17+
pub(crate) struct TargetInfo {
1618
/// The full architecture, including the subarchitecture.
1719
///
1820
/// This differs from `cfg!(target_arch)`, which only specifies the
@@ -38,9 +40,11 @@ pub(crate) struct Target {
3840
///
3941
/// This is the same as the value of `cfg!(target_abi)`.
4042
pub abi: Cow<'static, str>,
43+
/// The unversioned LLVM/Clang target triple.
44+
unversioned_llvm_target: Cow<'static, str>,
4145
}
4246

43-
impl Target {
47+
impl TargetInfo {
4448
pub fn from_cargo_environment_variables() -> Result<Self, Error> {
4549
// `TARGET` must be present.
4650
//
@@ -90,7 +94,7 @@ impl Target {
9094
// back back to data from the known set of target triples instead.
9195
//
9296
// See discussion in #1225 for further details.
93-
let fallback_target = Target::from_str(&target_triple).ok();
97+
let fallback_target = TargetInfo::from_str(&target_triple).ok();
9498
let ft = fallback_target.as_ref();
9599
let arch = cargo_env("CARGO_CFG_TARGET_ARCH", ft.map(|t| t.arch.clone()))?;
96100
let vendor = cargo_env("CARGO_CFG_TARGET_VENDOR", ft.map(|t| t.vendor.clone()))?;
@@ -102,27 +106,34 @@ impl Target {
102106
let abi = cargo_env("CARGO_CFG_TARGET_ABI", ft.map(|t| t.abi.clone()))
103107
.unwrap_or(Cow::Borrowed(""));
104108

109+
// Prefer `rustc`'s LLVM target triple information.
110+
let unversioned_llvm_target = match fallback_target {
111+
Some(ft) => ft.unversioned_llvm_target,
112+
None => llvm::guess_llvm_target_triple(full_arch, &vendor, &os, &env, &abi).into(),
113+
};
114+
105115
Ok(Self {
106116
full_arch: full_arch.to_string().into(),
107117
arch,
108118
vendor,
109119
os,
110120
env,
111121
abi,
122+
unversioned_llvm_target,
112123
})
113124
}
114125
}
115126

116-
impl FromStr for Target {
127+
impl FromStr for TargetInfo {
117128
type Err = Error;
118129

119130
/// This will fail when using a custom target triple unknown to `rustc`.
120131
fn from_str(target_triple: &str) -> Result<Self, Error> {
121132
if let Ok(index) =
122133
generated::LIST.binary_search_by_key(&target_triple, |(target_triple, _)| target_triple)
123134
{
124-
let (_, target) = &generated::LIST[index];
125-
Ok(target.clone())
135+
let (_, info) = &generated::LIST[index];
136+
Ok(info.clone())
126137
} else {
127138
Err(Error::new(
128139
ErrorKind::InvalidTarget,
@@ -136,7 +147,7 @@ impl FromStr for Target {
136147
mod tests {
137148
use std::str::FromStr;
138149

139-
use super::Target;
150+
use super::TargetInfo;
140151

141152
// Test tier 1 targets
142153
#[test]
@@ -155,7 +166,7 @@ mod tests {
155166

156167
for target in targets {
157168
// Check that it parses
158-
let _ = Target::from_str(target).unwrap();
169+
let _ = TargetInfo::from_str(target).unwrap();
159170
}
160171
}
161172

@@ -177,7 +188,7 @@ mod tests {
177188

178189
for target in targets {
179190
// Check that it does not parse
180-
let _ = Target::from_str(target).unwrap_err();
191+
let _ = TargetInfo::from_str(target).unwrap_err();
181192
}
182193
}
183194
}

src/target/apple.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
use super::TargetInfo;
2+
3+
impl TargetInfo {
4+
pub(crate) fn apple_sdk_name(&self) -> &'static str {
5+
match (&*self.os, &*self.abi) {
6+
("macos", "") => "macosx",
7+
("ios", "") => "iphoneos",
8+
("ios", "sim") => "iphonesimulator",
9+
("ios", "macabi") => "macosx",
10+
("tvos", "") => "appletvos",
11+
("tvos", "sim") => "appletvsimulator",
12+
("watchos", "") => "watchos",
13+
("watchos", "sim") => "watchsimulator",
14+
("visionos", "") => "xros",
15+
("visionos", "sim") => "xrsimulator",
16+
(os, _) => panic!("invalid Apple target OS {}", os),
17+
}
18+
}
19+
}

0 commit comments

Comments
 (0)