use std::env;
use std::fs;
use std::path::Path;
fn main() {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=Cargo.toml");
set_build_info();
check_target_platform();
set_optimization_flags();
generate_version_info();
}
fn set_build_info() {
let build_time = chrono::Utc::now().format("%Y-%m-%d %H:%M:%S UTC").to_string();
println!("cargo:rustc-env=BUILD_TIME={}", build_time);
if let Ok(output) = std::process::Command::new("git")
.args(["rev-parse", "--short", "HEAD"])
.output()
{
if output.status.success() {
let git_hash = String::from_utf8_lossy(&output.stdout).trim().to_string();
println!("cargo:rustc-env=GIT_HASH={}", git_hash);
}
}
let profile = env::var("PROFILE").unwrap_or_else(|_| "unknown".to_string());
println!("cargo:rustc-env=BUILD_PROFILE={}", profile);
let target = env::var("TARGET").unwrap_or_else(|_| "unknown".to_string());
println!("cargo:rustc-env=BUILD_TARGET={}", target);
}
fn check_target_platform() {
let target = env::var("TARGET").unwrap_or_default();
if target.contains("linux") {
println!("cargo:rustc-cfg=target_os_linux");
println!("cargo:rustc-link-arg=-Wl,--as-needed");
} else if target.contains("darwin") {
println!("cargo:rustc-cfg=target_os_macos");
} else if target.contains("windows") {
println!("cargo:rustc-cfg=target_os_windows");
}
if target.contains("x86_64") || target.contains("aarch64") {
println!("cargo:rustc-cfg=target_arch_64bit");
}
}
fn set_optimization_flags() {
let profile = env::var("PROFILE").unwrap_or_default();
if profile == "release" {
println!("cargo:rustc-cfg=optimized_build");
println!("cargo:rustc-env=CARGO_CFG_TARGET_FEATURE=+lto");
if env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_default() == env::var("HOST").unwrap_or_default().split('-').next().unwrap_or("") {
println!("cargo:rustc-env=RUSTFLAGS=-C target-cpu=native");
}
} else {
println!("cargo:rustc-cfg=debug_build");
}
}
fn generate_version_info() {
let out_dir = env::var("OUT_DIR").unwrap();
let dest_path = Path::new(&out_dir).join("version_info.rs");
let version = env::var("CARGO_PKG_VERSION").unwrap_or_else(|_| "unknown".to_string());
let name = env::var("CARGO_PKG_NAME").unwrap_or_else(|_| "rat_engine".to_string());
let authors = env::var("CARGO_PKG_AUTHORS").unwrap_or_else(|_| "Unknown".to_string());
let description = env::var("CARGO_PKG_DESCRIPTION").unwrap_or_else(|_| "RAT Engine".to_string());
let build_time = env::var("BUILD_TIME").unwrap_or_else(|_| "unknown".to_string());
let git_hash = env::var("GIT_HASH").unwrap_or_else(|_| "unknown".to_string());
let profile = env::var("BUILD_PROFILE").unwrap_or_else(|_| "unknown".to_string());
let target = env::var("BUILD_TARGET").unwrap_or_else(|_| "unknown".to_string());
let version_info = format!(
"
/// 构建时生成的版本信息
pub const VERSION_INFO: VersionInfo = VersionInfo {{
name: \"{}\",
version: \"{}\",
authors: \"{}\",
description: \"{}\",
build_time: \"{}\",
git_hash: \"{}\",
profile: \"{}\",
target: \"{}\",
}};
/// 版本信息结构
#[derive(Debug, Clone)]
pub struct VersionInfo {{
pub name: &'static str,
pub version: &'static str,
pub authors: &'static str,
pub description: &'static str,
pub build_time: &'static str,
pub git_hash: &'static str,
pub profile: &'static str,
pub target: &'static str,
}}
impl VersionInfo {{
/// 获取完整版本字符串
pub fn full_version(&self) -> String {{
format!(\"{{}} {{}} ({{}})\", self.name, self.version, self.git_hash)
}}
/// 获取构建信息
pub fn build_info(&self) -> String {{
format!(\"Built on {{}} for {{}} ({{}})\", self.build_time, self.target, self.profile)
}}
/// 打印版本信息
pub fn print(&self) {{
println!(\"🚀 {{}} v{{}}\", self.name, self.version);
println!(\"📝 {{}}\", self.description);
println!(\"👥 Authors: {{}}\", self.authors);
println!(\"🔨 {{}}\", self.build_info());
println!(\"📦 Git: {{}}\", self.git_hash);
}}
}}
",
name, version, authors, description, build_time, git_hash, profile, target
);
fs::write(&dest_path, version_info).unwrap();
println!("cargo:rerun-if-changed={}", dest_path.display());
}