I have a requirement to pass to a procedural macro either a text file or the contents of a text file, such that the procedural macro acts based on the contents of that text file at compile time. That is, the text file configures the output of the macro. The use case for this is the file defining a register map which the macro builds into a library.
The second requirement is that the text file is properly handled by Cargo
, such that changes to the text file trigger a recompile in the same way as changes to the source file trigger a recompile.
My initial thought was to create a static
string using the include_str!
macro. This solves the second requirement but I can't see how to pass that to the macro - at that point I only have the identifier of the string to pass in:
use my_macro_lib::my_macro;
static MYSTRING: &'static str = include_str!("myfile");
my_macro!(MYSTRING); // Not the string itself!
I can pass a string to the macro with the name of the file in a string literal, and open the file inside the macro:
my_macro!("myfile");
At which point I have two problems:
- It's not obvious how to get the path of the calling function in order to get the path of the file. I initially thought this would be exposed through the token
Span
, but it seems in general not (perhaps I'm missing something?). - It's not obvious how to make the file make
Cargo
trigger a recompile on changes. One idea I had to force this was to add aninclude_str!("myfile")
to the output of the macro, which would hopefully result in the compile being made aware of "myfile", but this is a bit mucky.
Is there some way to do what I'm trying to do? Perhaps either by somehow getting the contents of the string inside the macro that was created outside, or reliably getting the path of the calling rust file (then making Cargo
treat changes properly).
As an aside, I've read various places that tell me I can't get access to the contents of variables inside the macro, but it seems to me that this is exactly what the quote
macro is doing with #variables
. How is this working?