Rust是否提供等效于C预处理器__DATE__和__TIME__的编译时间宏?
好问题!Rust标准库本身并没有像C语言里__DATE__和__TIME__那样的原生内置宏,但咱们有几种实用的方式来实现编译时日期时间的嵌入,完全能满足你的调试需求。
方法1:利用Cargo内置的环境变量(最省心)
从Rust 1.59版本开始,Cargo会自动为你设置几个和构建时间相关的环境变量,直接用env!宏就能读取:
CARGO_BUILD_DATE:返回YYYY-MM-DD格式的日期字符串,比如"2024-05-20"CARGO_BUILD_TIMESTAMP:返回构建时刻的Unix时间戳(整数形式的字符串,比如"1716182400")
给你个简单的示例代码:
fn main() { println!("构建日期: {}", env!("CARGO_BUILD_DATE")); println!("构建时间戳: {}", env!("CARGO_BUILD_TIMESTAMP")); // 要是想把时间戳转成人类更易读的格式,可以借助chrono库(需要在Cargo.toml里添加依赖) // 示例代码如下: // use chrono::{DateTime, Utc}; // let timestamp = env!("CARGO_BUILD_TIMESTAMP").parse::<i64>().unwrap(); // let build_time = DateTime::<Utc>::from_timestamp(timestamp, 0).unwrap(); // println!("构建时间: {}", build_time); }
方法2:自定义构建脚本(更灵活)
如果你的Rust版本低于1.59,或者需要更贴合C风格的格式(比如May 20 2024这种和__DATE__一致的格式),那就可以用构建脚本(build.rs)来实现:
步骤1:创建build.rs文件
在项目根目录新建build.rs,内容如下:
use std::env; use std::fs::File; use std::io::Write; use std::path::Path; use chrono::Utc; // 需要在Cargo.toml的[build-dependencies]里添加chrono依赖 fn main() { // 获取编译时的当前时间 let now = Utc::now(); // 自定义格式,完全模仿C的__DATE__和__TIME__ let date_str = now.format("%b %d %Y").to_string(); // 示例:"May 20 2024" let time_str = now.format("%H:%M:%S").to_string(); // 示例:"14:30:00" // 生成一个包含常量的rs文件 let out_dir = env::var("OUT_DIR").unwrap(); let dest_path = Path::new(&out_dir).join("build_info.rs"); let mut f = File::create(&dest_path).unwrap(); writeln!(f, "pub const BUILD_DATE: &str = \"{}\";", date_str).unwrap(); writeln!(f, "pub const BUILD_TIME: &str = \"{}\";", time_str).unwrap(); }
步骤2:添加构建依赖
在Cargo.toml里加入构建依赖:
[build-dependencies] chrono = "0.4"
步骤3:在主程序中使用
// 引入构建脚本生成的常量 include!(concat!(env!("OUT_DIR"), "/build_info.rs")); fn main() { println!("构建日期: {}", BUILD_DATE); println!("构建时间: {}", BUILD_TIME); }
小提醒
- 增量构建时,如果代码没有改动,Cargo可能会复用之前的构建结果,这时日期时间不会更新。如果需要强制刷新,先执行
cargo clean再重新构建就行。 - 方法1的环境变量是Cargo提供的,要是你不用Cargo直接用
rustc编译,这些变量就不存在,这时只能用方法2或者手动传递环境变量。
内容的提问来源于stack exchange,提问作者Steffen Vogel




