How to add a dependency through a proc macro

Hi rust community,

I'm trying to create a proc-macro that takes a struct and wraps its fields in volatile_register::RW.
For example, a struct

struct A {
    x: u32,
    y: u32,
}

becomes

struct A {
    x: volatile_register::RW<u32>,
    y: volatile_register::RW<u32>,
}

I got the macro to work, however, for the code to work in the user crate, I need to add as a dependency both the proc macro crate and volatile_register, which feels incorrect. How can I make the macro bring all its necessary dependencies to the user crate.

This is not an unusual occurrence in the Rust ecosystem, as procedural macros need to be in their own package, separated from other, non-proc-macro items. However, you can re-export your macros from the corresponding non-proc-macro library (in your case the volatile_register library I believe). This is how e.g. serde does it. Basically the other way around, not letting the proc-macro crate bring the other items to the user, but re-export the proc-macros together with the items from the other crate.

3 Likes

Got it, thank you very much.

Regarding the volatile-register crate, be sure to read issue #10: Usage of references is in conflict with use for MMIO and the other issues linked from there. The bottom line is that the pattern used by volatile-register is very ergonomic, but is unsound in current Rust because it creates references to the data. References allow for spurious reads and writes, and that's unsound for volatile memory and memory-mapped devices where reads and writes have side effects.

You can have a look at How to make an access volatile without std library? - #4 by alice to see how to correctly implement volatile registers on your own. Or have a look at ready-made solutions, for example check out the crate volatile, or my own reg-map.