How to import macros in Rust?
Asked Answered
V

3

22

I'm struggling with how to import macros from an external crate. In my main.rs I'm importing the Glium crate:

#![macro_use]
extern crate glium;

pub use glium::*;

// where my actual main function will be done from
mod part01drawtriangle;

fn main() {
    part01drawtriangle::main();
}

In my other file, where my main function is coming from, I call one of the macros from that crate:

pub fn main() {
    implement_vertex!(Vertex, position);
}

When building, I get the error message:

error: macro undefined: 'implement_vertex!'
Verbiage answered 27/7, 2016 at 12:2 Comment(1)
I'm having trouble with the same problem, also with glium, but trying to apply the solution below doesn't work. I keep getting the macro undefined error. My directory structure is [main.rs, lib.rs, tutorial: [ mod.rs, draw_triangle.rs ]] where the implement_vertex! is being used in draw_triangle.rsBireme
O
25

#[macro_use], not #![macro_use].

#[..] applies an attribute to the thing after it (in this case, the extern crate). #![..] applies an attribute to the containing thing (in this case, the root module).

Olenolin answered 27/7, 2016 at 12:37 Comment(3)
but then I got errors like this failed to resolve. Use of undeclared type or module glium::glutin::WindowBuilder` is that namespace related? I've also added use glium::*; but still doesn't workVerbiage
Sounds like a brittle macro. Try adding use glium; to the top of part01drawtriangle.rs.Olenolin
You might want to open an issue with the crate; the solution is to use $crate:: instead of glium:: in the macro definition.Olenolin
H
20

According to the Rust Edition Guide:

In Rust 2018, you can import specific macros from external crates via use statements, rather than the old #[macro_use] attribute.

// in a `bar` crate's lib.rs:
#[macro_export]
macro_rules! baz {
    () => ()
}

// in your crate:
use bar::baz;

// Rather than:
//
// #[macro_use]
// extern crate bar;

This only works for macros defined in external crates. For macros defined locally, #[macro_use] mod foo; is still required, as it was in Rust 2015.

Hireling answered 8/6, 2020 at 17:11 Comment(1)
As of March 2022, macro_export exports to the root, and the macro can be used with 'use crate::baz'.Boeke
P
1

If using a macro exported by a library and imported by a binary within the same project then use the following pattern.

From lib.rs that is part of the [lib] definition within Cargo.toml

// src/lib/lib.rs

#[macro_export]
macro_rules! my_macro {
    // ...
}
pub use my_macro;

From the client file bin.rs that is part of the [[bin]] definition within Cargo.toml

// src/bin/bin.rs

use crate::my_macro;

Each imported macro needs it's own single use statement. Multiple items cannot be imported along with the macro (those need a separate use statement).

Permenter answered 25/2, 2023 at 8:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.