build.rs和Cargo.toml的关系
Cargo.toml 是包的配置清单;build.rs 是可选的、编译阶段执行的自定义脚本。二者配合,但是相互独立,build.rs 默认不需要在 Cargo.toml 里注册。
1. 各自职责
Cargo.toml
Cargo 的包描述文件:声明包名、版本、依赖、features、元信息。 它告诉 Cargo:这个 package 叫什么、依赖哪些 crate、编译的基础配置。
build.rs
构建脚本(可选),在编译本 crate 的 Rust 源码之前运行。 作用:在编译期执行自定义逻辑,通过 println!("cargo:xxx=yyy"); 向 Cargo动态传递构建指令。
2. 关联规则
- 默认规则 只要包目录存在
build.rs,Cargo 会自动识别并运行,不需要在 Cargo.toml 写任何声明。 - 在 Cargo.toml 可以显式控制 build 脚本(可选配置)
[package]
# 显式指定构建脚本文件,默认就是 build.rs
build = "build.rs"
# build = false
# 作用:哪怕目录下存在 build.rs,也不执行它,禁用构建脚本
3. 数据流向
- Cargo.toml:静态配置,写死在文件里,Cargo 一开始就读取。
- build.rs:运行时输出指令给 Cargo(动态) build.rs 通过
cargo:xxx输出,动态修改构建行为,比如:println!("cargo:rustc-link-lib=m"); println!("cargo:rerun-if-changed=wrapper.h");
Cargo.toml 只能写静态配置;链接库、搜索路径、重跑条件这类动态构建信息,只能由 build.rs 在构建期间输出。
- 作用范围:build.rs 属于当前 package workspace 的根 Cargo.toml 的
[workspace]没有 build 字段;build.rs 只能放在子 package 里,每个包可以拥有自己独立的构建脚本。
4. 对比总结
表格
| 项目 | Cargo.toml | build.rs |
|---|---|---|
| 类型 | 静态配置文件(toml 文本) | Rust 可执行脚本,编译前运行 |
| 读取时机 | Cargo 一开始就加载 | 在 rustc 编译源码之前执行 |
| 能力 | 声明包、依赖、feature、版本 | 动态告诉 Cargo:链接库、头文件依赖、什么时候重新跑 build 脚本 |
| 是否必选 | 必须(package 一定要有 Cargo.toml) | 可选 |
5. 精简版
Cargo.toml 是包的静态配置文件,每个 package 必须有;build.rs 是可选的构建脚本。默认目录存在 build.rs 就自动执行,也可以在 Cargo.toml 中用build=手动指定路径或者禁用。 Cargo.toml 提供静态构建配置;build.rs 运行后通过cargo:指令动态向 Cargo 传递链接参数、文件依赖等构建信息,用于处理 Cargo.toml 无法表达的复杂构建逻辑。
参考资料:
rust实践录-III
浙公网安备 33010602011771号