Generating constants ar compile time from file content

Viewed 1054

Let's say I have a file with some constants in it. This file probably comes from a different service and might be different for different scenarios. Now I want to squeeze every last bit of performance out of my program, want the compiler to do as much optimization as possible and I would compile the project for every scenario separately if needed.

Is there a way to take a file at compile time, turn it into rust code through some conversion logic, e.g. generate some constants, and compile the result (all inside the rust tooling, no other code-generation)?

2 Answers

If you write a build.rs file in the root of your crate it will be compiled and run with each crate compilation.

It is usually used to build C bindings and such, but nothing prevents you from using it for your own purposes.

Usually this build.rs creates a Rust source file somewhere int the output directory, reading the OUT_DIR environment variable:

fn main() {
    println!("cargo:rerun-if-changed=build.rs");
    println!("cargo:rerun-if-changed=data.txt");

    let out_dir = std::env::var_os("OUT_DIR").unwrap();
    let path = std::path::Path::new(&out_dir).join("test.rs");
    std::fs::write(&path, "pub fn test() { todo!() }").unwrap();
}

Then the source is included in your project, usually in its own module with:

mod test {
    include!(concat!(env!("OUT_DIR"), "/test.rs"));
}

You could just generate rust source files that contain your constants.

These parts can be in any language:

  1. Generate data you want to use as constants
  2. Save them into rust source files as constants using some string manipulation

In rust:

  1. pub mod const_file in path/to/mod.rs
  2. use path::to::const_file::MY_CONST;
  3. cargo build your rust program

Example for a constant array that you get from python:

array = [0, 10, 34]
const_file_str = f"pub const MY_CONST: [u16; 3] = {array};\n"

with open("path/to/const_file.rs", "w") as rust_file:
    rust_file.write(const_file_str)

Related