Set `proc-macro = true` in a library crate’s `[lib]` section to make it a procedural-macro crate. Create that crate with `cargo init --lib`; consumers then add it as a dependency and invoke the exported macros while compiling their own code. section 3.1 section 4.1
Listing 3.1 The lib section and dependencies of hello-world-macro
[package] name = "hello-world-macro" version = "0.1.0" edition = "2021" [dependencies] quote = "1.0.33" syn = "2.0.39" [lib] proc-macro = true
The essential manifest change is `[lib] proc-macro = true`; `syn` and `quote` are helpful dependencies, not the setting itself. section 3.1
Minimal derive-macro crate
A macro crate can expose a derive entry point such as `#[proc_macro_derive(Hello)] pub fn hello(item: TokenStream) -> TokenStream`. An application depends on the crate by package name and can then write `#[derive(Hello)]` on a struct. A relative path works for a nearby local crate; the dependency name must match the imported package. section 3.1
A procedural-macro crate may export any number of derive, attribute, or function-like procedural macros, but it cannot export ordinary functions for consumers. When generated code needs shared runtime helpers, place the macro crate behind another ordinary library that reexports the macro and exports those helpers. section 10.9 section 5.3
For a production macro crate:
- Use feature flags to make optional macro functionality available only when needed. section 10.9
- Provide test coverage, error handling, and documentation, ideally with doctests. section 10.9
- Keep macro implementation dependencies and macro-facing features organized separately when integrating with a larger library. section 10.6
Feature-gated macro integration
A larger crate can expose a `macros` feature that enables an optional procedural-macro dependency. Tokio uses this arrangement for `tokio-macros`; its macro crate is marked `proc-macro = true` and exposes attribute macros such as `#[tokio::main]` and `#[tokio::test]`. section 10.6
