我想这样做,以便当我的程序启动时,它打印到stderr:
This is Program X v. 0.1.0 compiled on 20180110. Now listening on stdin,
quit with SIGINT (^C). EOF is ignored. For licensing information, read
LICENSE. To suppress this message, supply --quiet or --suppress-greeting
Run Code Online (Sandbox Code Playgroud)
在C/C++中,我将使用Makefile实现此目的,例如:
VERSION = 0.1.0
FLAGS = -Wall -pipe -O3 -funroll-loops -Wall -DVERSION="\"$(VERSION)\"" -DCOMPILED_AT="\"`date +%Y%m%d`\""
Run Code Online (Sandbox Code Playgroud)
然后,在源代码中,我会使用这些常量,因为我很高兴,也许是在调用fprintf.#ifdef当然,在检查它们是否确实存在之后.
如何在Rust中实现这一目标?我需要使用程序宏吗?我可以用cargo某种方式吗?
我知道env!("CARGO_PKG_VERSION")可以作为替代品VERSION,但是怎么样COMPILED_AT?
有两种方法可以做到这一点.
build.rs脚本使用build.rs脚本的好处是编译程序的其他用户不必以cargo特殊方式调用或设置其环境.这是如何做到这一点的最小例子.
build.rsuse std::process::{Command, exit};
use std::str;
static CARGOENV: &str = "cargo:rustc-env=";
fn main() {
let time_c = Command::new("date").args(&["+%Y%m%d"]).output();
match time_c {
Ok(t) => {
let time;
unsafe {
time = str::from_utf8_unchecked( &t.stdout );
}
println!("{}COMPILED_AT={}", CARGOENV, time);
}
Err(_) => exit(1)
}
}
Run Code Online (Sandbox Code Playgroud)
src/main.rsfn main() {
println!("This is Example Program {} compiled at {}", env!("CARGO_PKG_VERSION"), env!("COMPILED_AT"));
}
Run Code Online (Sandbox Code Playgroud)
Cargo.toml[package]
name = "compiled_at"
version = "0.1.0"
authors = ["Fredrick Brennan <copypaste@kittens.ph>"]
build = "build.rs"
[dependencies]
Run Code Online (Sandbox Code Playgroud)
显然,这可以调整,以使其在其他没有/bin/date或编译其他东西的平台上工作,如Git版本号.此脚本基于Jmb提供的示例,该示例演示了如何在编译时将Mercurial信息添加到程序中.
这可以保证COMPILED_AT将设置或构建失败.这样其他Rust程序员就可以通过这样做来构建cargo build.
[osboxes@osboxes compiled_at]$ cargo run
Compiling compiled_at v0.1.0 (file:///home/osboxes/Workspace/rust/compiled_at)
Finished dev [unoptimized + debuginfo] target(s) in 1.27 secs
Running `target/debug/compiled_at`
This is Example Program 0.1.0 compiled at 20180202
Run Code Online (Sandbox Code Playgroud)
env!(),然后要求用户在构建之前设置其环境在我问这个问题后尝试以下内容时,它发生了,它确实有效(vim正在使用,因此转义%s),cargo确实将我的环境传递给rustc:
COMPILED_AT=`date +\%Y\%m\%d` cargo run
Run Code Online (Sandbox Code Playgroud)
然后,在Rust:
fn main() {
eprintln!("{}", env!("COMPILED_AT"));
}
Run Code Online (Sandbox Code Playgroud)
如果我不提供环境变量,Rust编译器拒绝编译代码,这是一个很好的接触.
error: environment variable `COMPILED_AT` not defined
--> src/main.rs:147:21
|
147 | eprintln!("{}", env!("COMPILED_AT"));
| ^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
Run Code Online (Sandbox Code Playgroud)
这种方式非常hacky,并且保证会惹恼其他想要构建的Rust程序员cargo build,但它确实有效.如果可以的话,建议build.rs改用.
| 归档时间: |
|
| 查看次数: |
451 次 |
| 最近记录: |