Currently there is no direct way for those proc macro to inform compiler about the dependency. One workaround is to use
include_bytes! macro and assign its result to a const. This isn’t ideal as the generated program doesn’t necessarily need such content, while including all the data into generated source file may slow down build time and bloat memory usage, especially when the file is large.
The largest example I can find right now is GitHub’s GraphQL schema file, which is ~256KiB. It isn’t too bad to include. But proc macro may at some point want to read larger files like archive files, system images, and so on, at which point, using
include_bytes! may not be an option.
Cargo build scripts can output
rerun-if-changed= to inform Cargo about such dependency, but proc macro has no way to do so at the moment.
Introduce a new compiler built-in macro
depends_on (name to be bikesheded) which takes a file name as argument (either absolute path or relative path to current file?). It informs the compiler that when the specified file is modified, the current file should be re-compiled.
There are several possible alternatives:
Add opt-in parameter to proc macro
For example, we can pass an additional, for example,
&mut Context parameter to proc macro function, via which the function can add new dependencies. To avoid breaking change, this may be controlled by an additional parameter to
#[proc_macro_derive] for whether such argument should be passed in.
Allow proc macro to return more than just
Convert return type of proc macro to something like
impl Into<ProcMacroResult>, and have
ProcMacroResult contain the current
TokenStream as well as dependency information. Then we just have
impl From<TokenStream> for ProcMacroResult.
This way we don’t break any existing proc macro, but make it possible to extend what can be returned from proc macro.
Have the compiler not actually import file content in certain case
Either the compiler don’t read the content when
include_bytes! is assigned to an underscore const, or an attribute can be added to communicate that.
Have compiler track file open in proc macro
Have the standard file functions track file opens when called from a proc macro, and emit dependencies accordingly.
Just have proc macros generate
include_bytes! for that purpose.
What do you think?
(Edit: added several proposals below to alternatives.)