-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d27b14d
commit 2e14513
Showing
1 changed file
with
30 additions
and
83 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,94 +1,41 @@ | ||
use std::{env, ffi, fmt, io, process, string}; | ||
|
||
struct ReadVersionError(String); | ||
|
||
impl fmt::Debug for ReadVersionError { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
f.write_str("failed to detect rustc version by ")?; | ||
f.write_str(self.0.as_str()) | ||
} | ||
} | ||
|
||
impl From<io::Error> for ReadVersionError { | ||
fn from(value: io::Error) -> Self { | ||
Self(format!("command I/O: {}", value)) | ||
} | ||
} | ||
|
||
impl From<string::FromUtf8Error> for ReadVersionError { | ||
fn from(value: string::FromUtf8Error) -> Self { | ||
Self(format!("decoding command result: {}", value)) | ||
} | ||
} | ||
|
||
impl From<String> for ReadVersionError { | ||
fn from(value: String) -> Self { | ||
Self(value) | ||
} | ||
} | ||
|
||
impl fmt::Display for ReadVersionError { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
fmt::Debug::fmt(&self, f) | ||
} | ||
} | ||
|
||
impl std::error::Error for ReadVersionError {} | ||
|
||
fn read_version(rustc: ffi::OsString) -> Result<(u16, u16), ReadVersionError> { | ||
let process::Output { status, stdout, .. } = process::Command::new(rustc) | ||
.args(["--version", "--verbose"]) | ||
.output()?; | ||
fn main() { | ||
let rustc = std::env::var_os("RUSTC").unwrap_or("rustc".into()); | ||
let output = std::process::Command::new(rustc) | ||
.arg("-vV") | ||
.output() | ||
.expect("Failed to execute `rustc -vV`"); | ||
|
||
if !status.success() { | ||
return Err(format!("the status of command result: {}", status).into()); | ||
if !output.status.success() { | ||
return println!( | ||
"cargo:warning=latches: {}", | ||
String::from_utf8_lossy(&output.stderr) | ||
); | ||
} | ||
|
||
let output = String::from_utf8(stdout)?; | ||
let mut version = ""; | ||
|
||
// Find the release line in the verbose version output. | ||
let output = String::from_utf8_lossy(&output.stdout); | ||
for line in output.lines() { | ||
if let Some(v) = line.strip_prefix("release: ") { | ||
version = v; | ||
break; | ||
if let Some(version) = line.strip_prefix("release: ") { | ||
if let Some((ver, _)) = version.rsplit_once('.') { | ||
if let Some(v) = into_tuple(ver) { | ||
if v < (1, 63) { | ||
println!("cargo:rustc-cfg=latches_no_const_sync"); | ||
} | ||
return; | ||
} | ||
} | ||
} | ||
} | ||
|
||
if version.is_empty() { | ||
return Err(format!("finding release line: {}", output).into()); | ||
} | ||
|
||
// build.rs don't need patch version and edition postfix. | ||
let mut iter = version.splitn(3, '.'); | ||
|
||
if let (Some(major), Some(minor)) = (iter.next(), iter.next()) { | ||
let major = match major.parse() { | ||
Ok(t) => t, | ||
Err(e) => return Err(format!("major: {} {}", major, e).into()), | ||
}; | ||
let minor = match minor.parse() { | ||
Ok(t) => t, | ||
Err(e) => return Err(format!("minor: {} {}", minor, e).into()), | ||
}; | ||
|
||
Ok((major, minor)) | ||
} else { | ||
Err(format!("spliting: {}", version).into()) | ||
} | ||
println!( | ||
"cargo:warning=latches: Unexpected output from `rustc -vV`:\n{}", | ||
output | ||
) | ||
} | ||
|
||
fn main() { | ||
let rustc = env::var_os("RUSTC").unwrap_or_else(|| "rustc".into()); | ||
let version = match read_version(rustc) { | ||
Ok(v) => v, | ||
Err(e) => { | ||
println!("cargo:warning=latches: {}", e); | ||
return; | ||
fn into_tuple(version: &str) -> Option<(u16, u16)> { | ||
if let Some((major, minor)) = version.split_once('.') { | ||
if let (Ok(maj), Ok(min)) = (major.parse(), minor.parse()) { | ||
return Some((maj, min)); | ||
} | ||
}; | ||
|
||
if version < (1, 63) { | ||
println!("cargo:rustc-cfg=latches_no_const_sync"); | ||
} | ||
None | ||
} |