180 lines
5.0 KiB
Rust
180 lines
5.0 KiB
Rust
//! build.rs file to obtain the host information.
|
|
|
|
// Allow dead code in triple.rs and targets.rs for our purposes here.
|
|
#![allow(dead_code)]
|
|
|
|
use std::env;
|
|
use std::fs::File;
|
|
use std::io::{self, Write};
|
|
use std::path::PathBuf;
|
|
use std::process::Command;
|
|
use std::str::FromStr;
|
|
|
|
#[cfg(not(feature = "std"))]
|
|
extern crate alloc;
|
|
#[cfg(feature = "std")]
|
|
extern crate std as alloc;
|
|
|
|
// Include triple.rs and targets.rs so we can parse the TARGET environment variable.
|
|
// targets.rs depends on data_model
|
|
mod data_model {
|
|
include!("src/data_model.rs");
|
|
}
|
|
mod triple {
|
|
include!("src/triple.rs");
|
|
}
|
|
mod targets {
|
|
include!("src/targets.rs");
|
|
}
|
|
|
|
// Stub out `ParseError` to minimally support triple.rs and targets.rs.
|
|
mod parse_error {
|
|
#[derive(Debug)]
|
|
pub enum ParseError {
|
|
UnrecognizedArchitecture(String),
|
|
UnrecognizedVendor(String),
|
|
UnrecognizedOperatingSystem(String),
|
|
UnrecognizedEnvironment(String),
|
|
UnrecognizedBinaryFormat(String),
|
|
UnrecognizedField(String),
|
|
}
|
|
}
|
|
|
|
use self::targets::Vendor;
|
|
use self::triple::Triple;
|
|
|
|
fn main() {
|
|
let out_dir = PathBuf::from(
|
|
env::var_os("OUT_DIR").expect("The OUT_DIR environment variable must be set"),
|
|
);
|
|
let target = env::var("TARGET").expect("The TARGET environment variable must be set");
|
|
let triple =
|
|
Triple::from_str(&target).unwrap_or_else(|_| panic!("Invalid target name: '{}'", target));
|
|
let out = File::create(out_dir.join("host.rs")).expect("error creating host.rs");
|
|
write_host_rs(out, triple).expect("error writing host.rs");
|
|
if using_1_40() {
|
|
println!("cargo:rustc-cfg=feature=\"rust_1_40\"");
|
|
}
|
|
}
|
|
|
|
fn using_1_40() -> bool {
|
|
match (|| {
|
|
let rustc = env::var_os("RUSTC").unwrap();
|
|
let output = Command::new(rustc).arg("--version").output().ok()?;
|
|
let stdout = if output.status.success() {
|
|
output.stdout
|
|
} else {
|
|
return None;
|
|
};
|
|
std::str::from_utf8(&stdout)
|
|
.ok()?
|
|
.split(' ')
|
|
.nth(1)?
|
|
.split('.')
|
|
.nth(1)?
|
|
.parse::<i32>()
|
|
.ok()
|
|
})() {
|
|
Some(version) => version >= 40,
|
|
None => true, // assume we're using an up-to-date compiler
|
|
}
|
|
}
|
|
|
|
fn write_host_rs(mut out: File, triple: Triple) -> io::Result<()> {
|
|
// The generated Debug implementation for the inner architecture variants
|
|
// doesn't print the enum name qualifier, so import them here. There
|
|
// shouldn't be any conflicts because these enums all share a namespace
|
|
// in the triple string format.
|
|
writeln!(
|
|
out,
|
|
r#"
|
|
#[allow(unused_imports)]
|
|
use crate::Aarch64Architecture::*;
|
|
#[allow(unused_imports)]
|
|
use crate::ArmArchitecture::*;
|
|
#[allow(unused_imports)]
|
|
use crate::CustomVendor;
|
|
#[allow(unused_imports)]
|
|
use crate::Mips32Architecture::*;
|
|
#[allow(unused_imports)]
|
|
use crate::Mips64Architecture::*;
|
|
#[allow(unused_imports)]
|
|
use crate::Riscv32Architecture::*;
|
|
#[allow(unused_imports)]
|
|
use crate::Riscv64Architecture::*;
|
|
#[allow(unused_imports)]
|
|
use crate::X86_32Architecture::*;
|
|
|
|
/// The `Triple` of the current host.
|
|
pub const HOST: Triple = Triple {{
|
|
architecture: Architecture::{architecture:?},
|
|
vendor: Vendor::{vendor},
|
|
operating_system: OperatingSystem::{operating_system:?},
|
|
environment: Environment::{environment:?},
|
|
binary_format: BinaryFormat::{binary_format:?},
|
|
}};
|
|
|
|
impl Architecture {{
|
|
/// Return the architecture for the current host.
|
|
pub const fn host() -> Self {{
|
|
Architecture::{architecture:?}
|
|
}}
|
|
}}
|
|
|
|
impl Vendor {{
|
|
/// Return the vendor for the current host.
|
|
pub const fn host() -> Self {{
|
|
Vendor::{vendor}
|
|
}}
|
|
}}
|
|
|
|
impl OperatingSystem {{
|
|
/// Return the operating system for the current host.
|
|
pub const fn host() -> Self {{
|
|
OperatingSystem::{operating_system:?}
|
|
}}
|
|
}}
|
|
|
|
impl Environment {{
|
|
/// Return the environment for the current host.
|
|
pub const fn host() -> Self {{
|
|
Environment::{environment:?}
|
|
}}
|
|
}}
|
|
|
|
impl BinaryFormat {{
|
|
/// Return the binary format for the current host.
|
|
pub const fn host() -> Self {{
|
|
BinaryFormat::{binary_format:?}
|
|
}}
|
|
}}
|
|
|
|
impl Triple {{
|
|
/// Return the triple for the current host.
|
|
pub const fn host() -> Self {{
|
|
Self {{
|
|
architecture: Architecture::{architecture:?},
|
|
vendor: Vendor::{vendor},
|
|
operating_system: OperatingSystem::{operating_system:?},
|
|
environment: Environment::{environment:?},
|
|
binary_format: BinaryFormat::{binary_format:?},
|
|
}}
|
|
}}
|
|
}}"#,
|
|
architecture = triple.architecture,
|
|
vendor = vendor_display(&triple.vendor),
|
|
operating_system = triple.operating_system,
|
|
environment = triple.environment,
|
|
binary_format = triple.binary_format,
|
|
)?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn vendor_display(vendor: &Vendor) -> String {
|
|
match vendor {
|
|
Vendor::Custom(custom) => format!("Custom(CustomVendor::Static({:?}))", custom.as_str()),
|
|
known => format!("{:?}", known),
|
|
}
|
|
}
|