bigywater.tech
Rust · 85

Build Script build.rs

build.rs 是 Cargo 在编译 crate 之前先运行的一段 Rust 程序。它什么时候运行、能生成什么、改了哪些文件会触发重跑、失败了会怎样?这篇用一个最小项目把每个问题都跑出结果。

3 类
build.rs 的 cargo: 指令效果:OUT_DIR 代码、rustc-env、rustc-cfg(以及 warning)
1 → 1 → 2 → 2
build.rs 运行次数:首次、没改动、改 data.txt、只改 main.rs
101
build.rs panic 时 cargo 的退出码

build.rs 做了什么

实测 · 本机执行输出
  cargo build 输出(只保留关键行):
    Compiling app v0.3.1 (<实验目录>/proj/u85)
    warning: app@0.3.1: build.rs 运行了:读到 1 行
    warning: unexpected `cfg` condition name: `has_data`
    = help: or consider adding `println!("cargo::rustc-check-cfg=cfg(has_data)");` to the top of the `build.rs`
    warning: unexpected `cfg` condition name: `has_data`
    = help: or consider adding `println!("cargo::rustc-check-cfg=cfg(has_data)");` to the top of the `build.rs`
    warning: `app` (bin "app") generated 2 warnings
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.58s
  运行 app:
    LINES = 1  FIRST = "alpha"
    BUILT_BY = build.rs-0.3.1
    cfg(has_data) 为真
  OUT_DIR 里生成的 gen.rs 内容:
    pub const LINES: usize = 1;
    pub const FIRST: &str = "alpha";

build.rs 属于 Cargo,更多配置见Cargo Build Script。上一篇中遇到的「读文件却没触发重编译」问题见函数式宏。

rerun-if-changed

实测 · 本机执行输出
  第一次 build 之后:1 次;没改动再 build:1 次;改了 data.txt 之后 build:2 次(运行 app:LINES = 3  FIRST = "alpha");只改 main.rs 之后 build:2 次

不写 rerun-if-changed

实测 · 本机执行输出
  去掉 rerun-if-changed 并 build 一次后累计 3 次;只改 main.rs 再 build:累计 4 次(新增 1)

失败的 build.rs

实测 · 本机执行输出
  退出码 101
    error: failed to run custom build command for `app v0.3.1 (<实验目录>/proj/u85)`
    Caused by:
      process didn't exit successfully: `<实验目录>/target/debug/build/app-571b150f2e5c57c7/build-script-build` (exit status: 101)
      --- stderr
      thread 'main' (7161489) panicked at build.rs:1:13:
      build.rs 故意失败
      note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

可用的环境变量

实测 · 本机执行输出
  warning: app@0.3.1: CARGO_PKG_NAME=app
  warning: app@0.3.1: CARGO_PKG_VERSION=0.3.1
  warning: app@0.3.1: TARGET=aarch64-apple-darwin
  warning: app@0.3.1: HOST=aarch64-apple-darwin
  warning: app@0.3.1: PROFILE=debug
  warning: app@0.3.1: OPT_LEVEL=0
  warning: app@0.3.1: CARGO_MANIFEST_DIR=<实验目录>/proj/u85
  warning: app@0.3.1: cwd 是 manifest 目录: true

分步演示

build.rs
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / rustc 1.98.1(brew)/ cargo 1.98.1;单个文件用 rustc 直接编译,需要依赖时用 cargo(经代理从 crates.io 下载);计时用 std::time::Instant,数字每次运行会有小幅抖动。cargo 1.98 的行为
    • 没有验证:链接 C 库的 cargo:rustc-link-lib / rustc-link-search、cc crate 编译 C 代码、links 字段、rerun-if-env-changed、build-dependencies 的用法、跨平台交叉编译时 build.rs 的 HOST 与 TARGET 区别
    京ICP备2026067502号-1京公网安备11010502063487号