I have a procedural macro that needs to store semi-persistent state. The state needs to survive compilation runs and should be cleaned up when cargo clean
is run.
In the past, I used the ./target
directory this purpose. However, this was a mistake because some of the files my procedural macro would generated could conflict with those generated by rustc and cargo. The location of the target directory can also be changed from the default.
Note that this question is not a duplicate of Is it possible to store state within Rust's procedural macros?. That question covers procedural macro state in general while this question is about determining a suitable location within a crate's file structure.
It appears that the best place for storing temporary files that both (1) persist across compilation runs and (2) also get cleaned up by Cargo is to use OUT_DIR
:
OUT_DIR
— If the package has a build script, this is set to the folder where the build script should place its output. See below for more information. (Only set during compilation.)
This environment variable is only available to build scripts if I recall correctly, so you must use a build script to expose the path to the rest of crate. Do note that OUT_DIR
is shared with any crate that uses your macros for a given compilation run, so you need to factor this in a way you use that directory to avoid conflicts.
This solution in steps:
Re-export the OUT_DIR
to the rest of the crate by adding the following line to the build script of your procedural macro crate:
println!("cargo:rustc-env=PROC_ARTIFACT_DIR={}",
std::env::var("OUT_DIR").unwrap() )
Use env!("PROC_ARTIFACT_DIR")
in your procedural macros to get the path to the state directory.
This should only serve as a temporary workaround until Cargo supports temp directories (?) properly. Full credit for this method goes to @sven-marnach.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With