]> git.proxmox.com Git - rustc.git/blame - vendor/const_fn/build.rs
New upstream version 1.51.0+dfsg1
[rustc.git] / vendor / const_fn / build.rs
CommitLineData
5869c6ff
XL
1#![forbid(unsafe_code)]
2#![warn(rust_2018_idioms, single_use_lifetimes)]
3
4use std::{
5 env, fs,
6 path::{Path, PathBuf},
7 process::Command,
8 str,
9};
10
11// The rustc-cfg strings below are *not* public API. Please let us know by
12// opening a GitHub issue if your build environment requires some way to enable
13// these cfgs other than by executing our build script.
14fn main() {
15 let rustc: PathBuf = env::var_os("RUSTC").unwrap_or_else(|| "rustc".into()).into();
16 let version = match Version::from_rustc(&rustc) {
17 Ok(version) => version.print(),
18 Err(e) => {
19 println!(
20 "cargo:warning={}: unable to determine rustc version: {}",
21 env!("CARGO_PKG_NAME"),
22 e
23 );
24 return;
25 }
26 };
27
28 let out_dir: PathBuf = env::var_os("OUT_DIR").expect("OUT_DIR not set").into();
29 let out_file = &out_dir.join("version");
30 fs::write(out_file, version)
31 .unwrap_or_else(|e| panic!("failed to write {}: {}", out_file.display(), e));
32
33 // Mark as build script has been run successfully.
34 println!("cargo:rustc-cfg=const_fn_has_build_script");
35}
36
37struct Version {
38 minor: u32,
39 nightly: bool,
40}
41
42impl Version {
43 // Based on https://github.com/cuviper/autocfg/blob/1.0.1/src/version.rs#L25-L59
44 //
45 // TODO: use autocfg if https://github.com/cuviper/autocfg/issues/28 merged
46 // or https://github.com/taiki-e/const_fn/issues/27 rejected.
47 fn from_rustc(rustc: &Path) -> Result<Self, String> {
48 let output =
49 Command::new(rustc).args(&["--version", "--verbose"]).output().map_err(|e| {
50 format!("could not execute `{} --version --verbose`: {}", rustc.display(), e)
51 })?;
52 if !output.status.success() {
53 return Err(format!(
54 "process didn't exit successfully: `{} --version --verbose`",
55 rustc.display()
56 ));
57 }
58 let output = str::from_utf8(&output.stdout).map_err(|e| {
59 format!("failed to parse output of `{} --version --verbose`: {}", rustc.display(), e)
60 })?;
61
62 // Find the release line in the verbose version output.
63 let release = output
64 .lines()
65 .find(|line| line.starts_with("release: "))
66 .map(|line| &line["release: ".len()..])
67 .ok_or_else(|| {
68 format!(
69 "could not find rustc release from output of `{} --version --verbose`: {}",
70 rustc.display(),
71 output
72 )
73 })?;
74
75 // Split the version and channel info.
76 let mut version_channel = release.split('-');
77 let version = version_channel.next().unwrap();
78 let channel = version_channel.next();
79
80 let minor = (|| {
81 // Split the version into semver components.
82 let mut digits = version.splitn(3, '.');
83 let major = digits.next()?;
84 if major != "1" {
85 return None;
86 }
87 let minor = digits.next()?.parse().ok()?;
88 let _patch = digits.next()?;
89 Some(minor)
90 })()
91 .ok_or_else(|| {
92 format!("unexpected output from `{} --version --verbose`: {}", rustc.display(), output)
93 })?;
94
95 let nightly = channel.map_or(false, |c| c == "dev" || c == "nightly");
96 Ok(Self { minor, nightly })
97 }
98
99 fn print(&self) -> String {
100 format!("Version {{ minor: {}, nightly: {} }}\n", self.minor, self.nightly)
101 }
102}