如何在Rust的build.rs中导入库内foo.rs中的内容?
当然可以实现!
不过要注意:build.rs 是 Rust 的构建脚本,它和你 src/ 下的库代码属于完全独立的编译单元——构建脚本会在你的库开始编译之前运行,所以没法直接像库内部那样通过use my_crate::foo::*来导入。不过有个简单的技巧可以解决这个问题:把需要在构建时用到的类型定义抽成共享代码,让两边都能访问到。
具体步骤:
1. 抽离共享类型代码
创建一个单独的文件,比如 src/schema_shared.rs,把你要生成 JSON Schema 的类型(以及它依赖的所有需要序列化的定义)放到这里,确保它能被构建脚本单独编译:
// src/schema_shared.rs use serde::Serialize; // 假设这是你要生成 Schema 的类型 #[derive(Serialize, schemars::JsonSchema)] pub struct MyType { pub name: String, pub value: u32, // 其他字段... }
2. 在库代码中引用这个共享模块
在 src/lib.rs 里导入它,这样 foo.rs 也能使用这个类型:
// src/lib.rs pub mod schema_shared; pub mod foo; // 如果 foo.rs 需要用到 MyType,让它通过 lib.rs 导入即可 // foo.rs 里可以写:use crate::schema_shared::MyType;
3. 在 build.rs 中导入共享代码
通过 Rust 的 include! 宏,直接把共享代码导入到构建脚本中:
// build.rs // 导入共享的类型定义 include!("src/schema_shared.rs"); use schemars::schema_for; use serde_json::to_string_pretty; fn main() { // 生成 JSON Schema let schema = schema_for!(MyType); // 把 Schema 写入到项目中(比如 src 目录下,或者 target/out 目录) std::fs::write( "src/my_type_schema.json", to_string_pretty(&schema).expect("Failed to serialize schema") ).expect("Failed to write schema file"); }
4. 配置 Cargo.toml 的构建依赖
别忘了在 Cargo.toml 里添加构建脚本需要的依赖(比如 serde、schemars 这些):
[build-dependencies] serde = { version = "1.0", features = ["derive"] } schemars = "0.8" serde_json = "1.0" # 同时你的库也需要这些依赖的话,加到 [dependencies] 里 [dependencies] serde = { version = "1.0", features = ["derive"] } schemars = "0.8"
为什么不能直接导入 foo.rs?
因为 build.rs 是一个独立的二进制 crate,它不能依赖还没编译的库代码——构建脚本的核心作用就是在库编译前完成一些前置工作,所以直接引用库的模块是行不通的。抽离共享代码是最稳妥的方案,既能保证两边使用的是同一个类型定义,又能避免编译顺序的问题。
内容的提问来源于stack exchange,提问作者Foobar
相关产品推荐
相关产品推荐

