我正在处理一些代码,其中缓冲区由静态大小的数组支持。由于Rust和IT提供的构建工具提供了有条件编译的可能性,因此我可以做这样的事情:
struct Buffer {
// default case, if none is set
#[cfg(not(buffersize))]
buffer: [f32; 16],
#[cfg(buffersize = "32")]
buffer: [f32; 32],
#[cfg(buffersize = "64")]
buffer: [f32; 64],
}
impl Buffer {
fn new() -> Buffer {
Buffer {
#[cfg(not(buffersize))]
buffer: [0.0; 16],
#[cfg(buffersize = "32")]
buffer: [0.0; 32],
#[cfg(buffersize = "64")]
buffer: [0.0; 64],
}
}
}
还有另一个使用功能有条件编译代码的问题。我只使用功能,我将不得不结合buffersize
和实际值,例如buffersize16
。是否可以向货物提供cfg
标志,还是我需要将它们直接提供给rustc
?
您可以设置环境变量RUSTFLAGS
或在.cargo/config
中设置rustflags
变量。
来自环境变异
rustflags - 分隔空间的自定义标志列表,可以传递给所有人 货物执行的编译器调用。与货物相反 rustc,这对于将标志传递给所有编译器实例很有用。
在您的示例中,您可以使用:
RUSTFLAGS='--cfg buffersize="32"' cargo build
我想向我的问题发布更新,作为如何通过构建脚本传递(数字(配置值的附加选项。
假设您的项目内有以下构建脚本:
use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;
fn main() {
println!("cargo:rerun-if-env-changed=SIZE");
let out_dir = env::var("OUT_DIR").unwrap();
let dest = Path::new(&out_dir).join("consts.rs");
let mut out_file = File::create(&dest).expect("Cannot create file");
let size: usize = env!("SIZE").parse().unwrap();
write!(&out_file, "pub const S : usize = {};", size);
}
它在编译时间读取环境变量,将其解析为usize
,并写入仅包含常数的Rust File(consts.rs
(。现在,在您的应用程序代码中,您可以包含此文件并将常数用于EG。在堆栈上分配内存:
include!(concat!(env!("OUT_DIR"), "/consts.rs"));
fn main() {
let array = [0.0f32; S];
println!("array len= {:?}", array.len());
}
此技巧的缺点是,由于cargo:rerun-if-env-changed=SIZE
不会被捕获,因此您必须在环境变量变化时重新编译整个项目(或部分(。这也意味着始终了解此配置选项的知识,但这可以包裹在诸如makefile之类的其他构建脚本中。即使这不是最优雅的选择,也可能是某些情况下的选择。
不过,将此作为宏选项会很不错。