Equivalent of cargo:rerun-if-changed for procedural macros?

Hello there :wave:

I'm currently writing a procedural macro that looks like my_macro!("../foo/bar").
It performs some computation on the files within the ../foo/bar directory, then "returns" the outcome.

It works fine, except that I would like the code that calls this macro to be recompiled if the content of foo/bar changes.
In other words, I would like an equivalent to printing cargo:rerun-if-changed from a build script but for procedural macros.

As a tentative solution, I've tried tweaking the Rust code that the procedural macro generate calls to generate calls to include_str!(path_file_we_depend_upon). This unfortunately doesn't work, as the compiler complains that the files I pass to include_str! don't exist (even though the paths are correct and the files do exist) and I don't understand why.

Is there any solution to this problem at the moment?
Thank you

I don't think there is one, since procedural macros execution order / repetition is unspecified :frowning:

So, the current solution seems to require "splitting" your "../foo/bar" logic in two:

  1. A build.rs script in charge of doing the computation (this way, you can use rerun-if-changed),

  2. An include_str! call in charge of loading the result of the build.rs computation.


To avoid the "../foo/bar/" repetition, there could be a more complex (and hacky) solution whereby the build.rs file scans all the source code of the project, and then when it encounters the syntactic call my_macro!(...), do the computation (and then maybe have my_macro be an alias for include_str!...)

1 Like

The is the standard (and only) way to get cargo to track external files used by proc macros at the current time.

My guess as to why it's erroring for you is the difference in relative path base. If a proc macro uses a relative path, it's relative to the project root by default (iirc, may also be working directory...). The include_str! relative path is relative to the file that it's located in.

1 Like

Oh thank you, I got it to work! It was a really stupid problem, as I had a trailing carriage return at the end of the file path passed to include_str!. The error message wasn't showing it.

2 Likes