1use std::str::FromStr;
6
7use crate::{Error, ErrorKind};
8
9mod apple;
10mod generated;
11mod llvm;
12mod parser;
13
14pub(crate) use parser::TargetInfoParser;
15
16#[derive(Debug, PartialEq, Clone)]
20pub(crate) struct TargetInfo<'a> {
21 pub full_arch: &'a str,
26 pub arch: &'a str,
30 pub vendor: &'a str,
34 pub os: &'a str,
38 pub env: &'a str,
42 pub abi: &'a str,
46 pub llvm_target: &'a str,
51}
52
53impl FromStr for TargetInfo<'_> {
54 type Err = Error;
55
56 fn from_str(target_triple: &str) -> Result<Self, Error> {
58 if let Ok(index) =
59 generated::LIST.binary_search_by_key(&target_triple, |(target_triple, _)| target_triple)
60 {
61 let (_, info) = &generated::LIST[index];
62 Ok(info.clone())
63 } else {
64 Err(Error::new(
65 ErrorKind::UnknownTarget,
66 format!(
67 "unknown target `{target_triple}`.
68
69NOTE: `cc-rs` only supports a fixed set of targets when not in a build script.
70- If adding a new target, you will need to fork of `cc-rs` until the target
71 has landed on nightly and the auto-generated list has been updated. See also
72 the `rustc` dev guide on adding a new target:
73 https://rustc-dev-guide.rust-lang.org/building/new-target.html
74- If using a custom target, prefer to upstream it to `rustc` if possible,
75 otherwise open an issue with `cc-rs`:
76 https://github.com/rust-lang/cc-rs/issues/new
77"
78 ),
79 ))
80 }
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use std::str::FromStr;
87
88 use super::TargetInfo;
89
90 #[test]
92 fn tier1() {
93 let targets = [
94 "aarch64-unknown-linux-gnu",
95 "aarch64-apple-darwin",
96 "i686-pc-windows-gnu",
97 "i686-pc-windows-msvc",
98 "i686-unknown-linux-gnu",
99 "x86_64-apple-darwin",
100 "x86_64-pc-windows-gnu",
101 "x86_64-pc-windows-msvc",
102 "x86_64-unknown-linux-gnu",
103 ];
104
105 for target in targets {
106 let _ = TargetInfo::from_str(target).unwrap();
108 }
109 }
110
111 #[test]
113 fn cannot_parse_extra() {
114 let targets = [
115 "aarch64-unknown-none-gnu",
116 "aarch64-uwp-windows-gnu",
117 "arm-frc-linux-gnueabi",
118 "arm-unknown-netbsd-eabi",
119 "armv7neon-unknown-linux-gnueabihf",
120 "armv7neon-unknown-linux-musleabihf",
121 "thumbv7-unknown-linux-gnueabihf",
122 "thumbv7-unknown-linux-musleabihf",
123 "x86_64-rumprun-netbsd",
124 "x86_64-unknown-linux",
125 ];
126
127 for target in targets {
128 let _ = TargetInfo::from_str(target).unwrap_err();
130 }
131 }
132}