Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
860 views
in Technique[技术] by (71.8m points)

rust - How can I override a constant via a compiler option?

Is it possible to define a constant in source code that can be overridden by a compiler flag? That is, something like setting a #define value in the C preprocessor with the -D key=val option to the compiler.

I have read about conditional compilation via the #[cfg(...)] attribute, but that only seems to support booleans. I want to allow the user to set the value of a constant during compilation.

Something like this:

#[from_cfg("max_dimensions")]
const MAX_DIMENSIONS: usize = 100_000;
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Building on Lukas Kalbertodt's answer, you can get the environment variable as a constant number with some extra indirection, namely by using a build script.

build.rs

use std::{env, fs::File, io::Write, path::Path};

fn main() {
    let out_dir = env::var("OUT_DIR").expect("No out dir");
    let dest_path = Path::new(&out_dir).join("constants.rs");
    let mut f = File::create(&dest_path).expect("Could not create file");

    let max_dimensions = option_env!("MAX_DIMENSIONS");
    let max_dimensions = max_dimensions
        .map_or(Ok(10_000), str::parse)
        .expect("Could not parse MAX_DIMENSIONS");

    write!(&mut f, "const MAX_DIMENSIONS: usize = {};", max_dimensions)
        .expect("Could not write file");
    println!("cargo:rerun-if-env-changed=MAX_DIMENSIONS");
}

main.rs

include!(concat!(env!("OUT_DIR"), "/constants.rs"));

fn main() {
    println!("The value is {} ({})", MAX_DIMENSIONS, MAX_DIMENSIONS + 1);
}
$ cargo run
The value is 10000 (10001)

$ MAX_DIMENSIONS=17 cargo run
The value is 17 (18)

$ MAX_DIMENSIONS=1 cargo run
The value is 1 (2)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...