无法在使用该库的可执行文件中的库中导入宏

时间:2015-09-27 03:16:13

标签: macros rust

我在从另一个箱子中获取宏以在Rust中工作时遇到了很多麻烦。我的lib.rs文件如下所示:

#[macro_use]
extern crate session_types;

mod main;

这是我的main.rs的简化部分,展示了offer!宏的正确使用:

use session_types::*;

type Server = Offer<Choose<Var<Z>, Var<Z>>, Choose<Var<Z>, Var<Z>>>;

struct Foo;

impl Foo {
    fn server(&self, c: Chan<(), Rec<Server>>) {
        let mut c = c.enter();
        loop {
            c = offer!{ c,
                LEFT_BRANCH => c.sel1().zero(),
                RIGHT_BRANCH => c.sel2().zero()
            };
        }
    }
}

我知道编译器能够扩展offer!,因为我在该宏内部的块中调试了代码,并且我收到有关该宏中未使用的变量的警告,如下所示:

<session_types macros>:1:1: 5:16 note: in expansion of offer!
src/main.rs:107:21: 133:14 note: expansion site
<session_types macros>:3:53: 3:57: warning: unused variable: 'right', #[warn(unused_variables)] on by default
<session_types macros>:3 Branch:: Left ( $id ) => $code, Branch:: Right ( $id ) => offer! {

显然包含宏的一部分。但是,我收到编译错误,说明在使用它们的行时,宏offer!未定义。

src/main.rs:107:21: 133:14 note: in this expansion of offer! (defined in <session_types macros>)
src/main.rs:57:17: 57:22 error: macro undefined: 'offer!'
src/main.rs:57             c = offer!{ c,
                               ^~~~~
src/main.rs:107:21: 107:26 error: macro undefined: 'offer!'
src/main.rs:107             night = offer!{ night,

注意:这发生在编译器的夜间分支上。

1 个答案:

答案 0 :(得分:3)

此示例重现您的问题:

<强> Cargo.toml

[package]
name = "mac"
version = "0.1.0"
authors = ["An Devloper <an.devloper@example.com>"]

[dependencies]
lazy_static = "0.1.14"

<强>的src / lib.rs

#[macro_use]
extern crate lazy_static;

lazy_static! {
    pub static ref LIBRARY_VERSION: u8 = 1;
}

pub fn adder(a: u8, b: u8) -> u8 { a + b }

<强>的src / main.rs

extern crate mac;

lazy_static! {
    static ref EXECUTABLE_VERSION: u8 = 1;
}

fn main() {
    println!("Adder version {} (lib version {})", *EXECUTABLE_VERSION, *mac::LIBRARY_VERSION);
    println!("Result: {}", mac::adder(1, 2));
}

问题是宏观包含物不能跨越板条箱传递。将它们包含在库文件中不会使它们在使用您的库的任何下游包中都可用。这样可以完全排除水中的任何选择性使用;想想在一个有20个依赖项的项目中你会有多少项目(每个项目本身都有依赖项)!

您还需要在可执行文件中明确包含宏,因为它是一个不同的包:

#[macro_use]
extern crate lazy_static;
// ... rest of above src/main.rs