如何在不清理整个项目的情况下强制`build.rs`再次运行?

tve*_*eeg 5 rust rust-cargo

如何build.rs在不清理整个项目的情况下强行再次运行?我查了cargo build --help但是找不到任何相关内容build.rs.

Tim*_*ann 9

如果你打印

"cargo:rerun-if-changed=<FILE>"
Run Code Online (Sandbox Code Playgroud)

每次文件更改时都会触发构建.

rerun-if-changed=PATH是一个文件或目录的路径,指示如果构建脚本发生更改(应该通过文件上更新的最后修改时间戳检测到),则应重新运行构建脚本.通常,如果crate根目录中的任何文件发生更改,则会重新运行构建脚本,但这可以用于将更改范围仅限于一小组文件.- 来源

我不知道没有手动更改文件的解决方案(我只是在我的任何地方放置一个空格build.rs,但它将被移除rustfmt).

我的项目中有几个构建脚本,大多数这两行给了我一个很好的解决方案:

println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=path/to/Cargo.lock");
Run Code Online (Sandbox Code Playgroud)

但我想你正在寻找一个命令rustc/ cargo命令.无论如何,你可以放入一个小脚本,它将编辑某个文件,这将触发构建过程.

  • 我不明白“请注意,如果构建脚本本身(或其依赖项之一)发生变化,那么它会无条件地重建并重新运行,因此 Cargo:rerun-if-changed=build.rs 几乎总是多余的(除非您想忽略除 build.rs 之外的所有其他文件中的更改。” 这不是必需的 (2认同)

Dan*_*H-M 9

注册build.rs为 crate 的bin目标:

  1. 将此添加到您的Cargo.toml文件中:

    [package]
    edition = "2018"
    build = "build.rs"
    
    [[bin]]
    name = "force-build"
    path = "build.rs"
    required-features = ["build_deps"]  # only needed for build-dependencies
    
    Run Code Online (Sandbox Code Playgroud)
  2. 如果您有任何[build-dependencies]some_crate = "1.2.3"),你需要添加那些(主)[dependencies](可惜没有[bin-dependencies]作为尚未),但你可以让他们可选:

    [dependencies]
    some_crate = { version = "1.2.3", optional = true }
    
    [features]
    build_deps = ["some_crate"]
    
    Run Code Online (Sandbox Code Playgroud)

然后您可以使用以下命令运行构建脚本:

$ cargo run --bin force-build --features build_deps
Run Code Online (Sandbox Code Playgroud)

(或$ cargo run --bin force-build当没有时[build-dependencies]

  • 你甚至可以禁用自动通过更换构建脚本呼叫build = "build.rs"排队Cargo.tomlbuild = false

  • 注意:由于目标OUT_DIR不存在 env var bin,如果您的build.rs脚本使用env!("OUT_DIR"),您可以通过使用concat!(env!("CARGO_MANIFEST_DIR"), "/target/")来“修复此问题” 。

  • 谢谢,这是一个非常有帮助的偏离典型解决方案的方法 (2认同)

Sei*_*van 6

如果您获得了目标gitignore(您应该这样做),那么当您开发和测试构建脚本时,这可能对任何文件更改很有用。

if Path::new(".git/HEAD").exists() {
    println!("cargo:rerun-if-changed=.git/HEAD");
}
Run Code Online (Sandbox Code Playgroud)


Sta*_*eur 5

如果build.rs发生更改,Cargo已经重建了项目:

请注意,如果构建脚本本身(或其依赖项之一)发生了变化,那么它将无条件地重建和重新运行,因此cargo:rerun-if-changed=build.rs几乎总是多余的(除非您想忽略除之外的所有其他文件中的更改build.rs)。doc

在Linux上,我会这样做touch build.rs && cargo build。对于Windows,请参见Windows等价于Linux命令“ touch”?