rust - 当我没有对它进行任何更改时,是否可以避免重新编译它?

标签 rust rust-cargo

我有一个 Rust crate,它是一个大型 C API 的包装器,需要几分钟才能编译。在目录中运行 cargo build 而不做任何更改总是会导致重新编译。似乎 Cargo 不应该重新编译这个箱子,除非我做出改变,但我没有做过。

我想编译 crate 一次并避免重新编译 crate,除非我进行更改。我有什么办法可以避免不断地重新编译这个 scrate?

我的箱子的构建脚本中似乎有什么不正确的地方。我将尝试创建一个最小的可重现示例,但与此同时我提供了以下构建脚本:

use std::env;
use std::fs::copy;
use std::path::Path;
use std::process::Command;

fn main() {
    let out_dir = env::var("OUT_DIR").unwrap();
    let c_src_path = Path::new("parasail_c");

    // configure the build
    Command::new("cmake")
        .arg(".")
        .current_dir(&c_src_path)
        .output()
        .expect("Failed to configure parasail.");

    // build the library
    Command::new("make")
        .current_dir(&c_src_path)
        .output()
        .expect("Failed to build parasail.");

    // put the static library in the right directory so we can clean up
    let target_file = format!("{}/libparasail.so", out_dir);
    copy("parasail_c/libparasail.so", target_file)
        .expect("Problem copying library to target directoy.");

    let target_file = format!("{}/parasail.h", out_dir);
    copy("parasail_c/parasail.h", target_file)
        .expect("Problem copying header to target directoy.");

    // clean up the temporary build files
    Command::new("make")
        .current_dir(&c_src_path)
        .arg("clean")
        .output()
        .expect("Failed to clean up build files.");

    // clean up the configuration files
    Command::new("make")
        .arg("distclean")
        .current_dir(&c_src_path)
        .output()
        .expect("Failed to clean up configuration files.");

    // let cargo know that it can find the file in the out directory
    println!("cargo:rustc-link-search=native={}", out_dir);
    println!("cargo:rustc-link-lib=dylib=parasail");
}

这是 cargo build --verbose

的输出
cargo build --verbose
   Compiling parasail-sys v0.1.0 (/home/fortier/testcode/rust/pairhmm/parasail-sys)
       Fresh libc v0.2.51
     Running `/home/fortier/testcode/rust/pairhmm/parasail-sys/target/debug/build/parasail-sys-f2d2d1f27a70b4d4/build-script-build`
     Running `rustc --edition=2018 --crate-name parasail_sys src/lib.rs --color always --crate-type lib --emit=dep-info,link -C debuginfo=2 -C metadata=8879665b3d9bf7e1 -C extra-filename=-8879665b3d9bf7e1 --out-dir /home/fortier/testcode/rust/pairhmm/parasail-sys/target/debug/deps -C incremental=/home/fortier/testcode/rust/pairhmm/parasail-sys/target/debug/incremental -L dependency=/home/fortier/testcode/rust/pairhmm/parasail-sys/target/debug/deps --extern libc=/home/fortier/testcode/rust/pairhmm/parasail-sys/target/debug/deps/liblibc-bc949bf21f4fe772.rlib -L native=/home/fortier/testcode/rust/pairhmm/parasail-sys/target/debug/build/parasail-sys-2ac393455c1f3545/out -l dylib=parasail`
    Finished dev [unoptimized + debuginfo] target(s) in 1m 58s

经过进一步检查,我发现问题出在子包包装的 C 代码中的某处。我用旧版本替换了当前的 C 代码,同时没有更改任何 Rust 代码,问题就消失了。我将继续做一些进一步的调查,以找出导致问题的确切原因,并在缩小范围后更新这篇文章。

最佳答案

为每个文件和每个目录添加到构建脚本 println!("cargo:rerun-if-changed={}", &file); 行。

关于rust - 当我没有对它进行任何更改时,是否可以避免重新编译它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55476985/

相关文章:

rust - 如何解决错误 "thread ' main' paniced at 'no current reactor'”?

rust - 将 Rust 应用程序与不在运行时链接器搜索路径中的动态库链接

rust - 重构工作区结构会导致 extern crate 导入不起作用

rust - 如何返回 Arc<Vec<u8>> 作为 super 响应?

sqlite - 如何在 Cargo.toml 中静态链接 sqlite3

facebook - 错误 无法执行事务 : Transaction failed with vm status: Validation(UnknownScript)

rust - 当每晚使用 `cargo run` 和 Rust 1.9 运行时,从 stdin 读取不会读取任何数据

rustdoc no_main "crate-level attribute should be in the root module"

syntax - 为什么从字符串长度开始的切片不会 panic ?

rust - 如何在 Cargo.toml 中创建目标特定配置文件?