You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动