Michael Böckling
Michael Böckling

Reputation: 7862

How to use macros from re-exported crates

Crates can re-export crates on which they depend. In this example, the stm32f103xx-hal crate does that: pub extern crate stm32f103xx;.

In my code, I depend on stm32f103xx-hal. Now I want to use the interrupt!() macro that is exported by the stm32f103xx crate. Do I have to add a stm32f103xx crate dependency to my Cargo.toml, or is there a way to re-use the exported definition of stm32f103xx-hal?

Note that this is a different problem from simply "how to use a macro from a different crate". Declaring #[macro_use(interrupt)] on stm32f103xx-hal yields a cannot find macro 'interrupt!' in this scope error.

Upvotes: 6

Views: 5414

Answers (3)

Michael Böckling
Michael Böckling

Reputation: 7862

This was changed just recently to use the generic import system.

Assuming you want to use the interrupt! macro from the foocrate, the new way to do it looks like this:

#![feature(use_extern_macros)];

pub use foo::interrupt;

Note that this is not yet stable, so it is feature-gated behind use_extern_macros.

Upvotes: 0

Shepmaster
Shepmaster

Reputation: 430368

The intermediate crate should re-export the macros so that they are available:

mac/src/lib.rs

#[macro_export]
macro_rules! a_macro {
    () => (42);
}

inter/src/lib.rs

pub extern crate mac;
pub use mac::*; // Re-export the macros

ex/src/main.rs

#[macro_use]
extern crate inter;

fn main() {
    println!("Hello, {}", a_macro!());
}

In your case, it's either a bug with the library or they've deliberately decided to not re-export them, so you need to take it up with them. You can choose to directly rely on the underlying crate, but then you open yourself up to having mismatched versions of the crate, leading to annoying errors.

Upvotes: 1

Kim Desrosiers
Kim Desrosiers

Reputation: 764

I think you need to add stm32f103xx to your Cargo.toml. Here is why:

For example, in the Diesel lib.rs

#[macro_use]
extern crate diesel_derives;
#[doc(hidden)]
pub use diesel_derives::*;

They put #[macro_use] on the extern crate line then they use everything from the diesel_derives project.

In your case the lib.rs looks like that:

pub extern crate stm32f103xx;

So the re-export does not specify the use of macros.

This is why you need to add stm32f103xx to your Cargo.toml in order to specify the use of macros in your own lib.rs.

Upvotes: 4

Related Questions