重导出过程宏时出现「unresolved extern crate」错误的解决方法
如何从自定义crate中正确重导出Maud的
html过程宏? 问题背景
尝试从Maud库重导出html过程宏,在Cargo工作区中从crate a重导出后,在crate b中使用时始终报「unresolved extern crate」错误,提示找不到maud crate。
环境与代码
工作区配置
# Cargo.toml [workspace] members = ["a", "b"] resolver = "2" [workspace.dependencies] a = { path = "a" } maud = "0.26.0"
Crate a配置与代码
# a/Cargo.toml [package] name = "a" [dependencies] maud.workspace = true
// a/src/lib.rs pub use maud::html;
Crate b配置与代码
# b/Cargo.toml [package] name = "b" [dependencies] a.workspace = true
// b/src/lib.rs use a::html; fn test() { let markup = html!{ "hello" }; // ^^^^^^^^^^^^^^^^ // unresolved extern crate // can't find crate for `maud` }
解决方案
问题根源是过程宏的依赖未传递:html宏展开时需要直接访问maud crate,但下游crate b无法通过普通重导出获取该依赖。按以下步骤修改即可解决:
步骤1:让crate a传递maud依赖
修改a/Cargo.toml,给maud依赖添加public = true,开启依赖传递:
# a/Cargo.toml [package] name = "a" [dependencies] maud = { workspace = true, public = true }
步骤2:确保crate b能找到maud
有两种可选方式:
方式一:直接添加
maud依赖
在b/Cargo.toml中添加maud的工作区依赖:# b/Cargo.toml [dependencies] a.workspace = true maud.workspace = true此方式无需修改
b的代码,编译器会自动找到maud。方式二:显式声明
maudcrate
若不想添加直接依赖,可在b/src/lib.rs中添加extern crate声明:// b/src/lib.rs use a::html; extern crate maud; // 让编译器感知到maud的存在 fn test() { let markup = html!{ "hello" }; }
原理说明
过程宏属于编译期扩展,宏展开后的代码会直接引用maud的内部实现,因此使用宏的crate必须能在编译时找到maud crate。普通的pub use仅重导出宏的符号,不会自动传递其依赖,因此需要通过public = true开启依赖传递,或让下游crate显式声明依赖。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

