Можно ли избежать перекомпиляции ящика, если я не внес в него никаких изменений?

У меня есть ящик Rust, который является оболочкой для большого C API и требует нескольких минут для компиляции. Запуск cargo build в каталоге без внесения каких-либо изменений всегда приводит к перекомпиляции. Кажется, что Cargo не следует перекомпилировать этот ящик, если я не внесу изменения, чего я не делал.

Я хотел бы скомпилировать ящик один раз и избежать повторной компиляции ящика, если я не внесу изменений. Могу ли я избежать постоянной перекомпиляции этого скрайта?

Похоже, что в сценарии сборки моего ящика что-то не так. Я попытаюсь создать минимально воспроизводимый пример, но пока что я предоставил сценарий сборки ниже:

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, и проблема исчезла. Я продолжу дальнейшее расследование, чтобы выяснить, что именно было причиной проблемы, и обновлю этот пост, как только сузлю его.


person Nathan Fortier    schedule 02.04.2019    source источник
comment
FWIW, вам здесь не нужен Path::new из-за дженериков. Вы можете просто сказать let c_src_path = "parasail_c"; и .current_dir(c_src_path).   -  person Shepmaster    schedule 02.04.2019
comment
FWIW, поскольку вы игнорируете данные из output, вероятно, легче использовать _ 2_   -  person Shepmaster    schedule 02.04.2019
comment
Пожалуйста, включите Cargo.toml для ящика с парашютом.   -  person Shepmaster    schedule 02.04.2019
comment
Похоже, ваш сценарий сборки / CMake / Makefile изменяет файлы C по мере их компиляции. Это каждый раз приводило к перестройке. Возможно, прикоснитесь ко всем файлам в ящике с известной меткой времени, запустите сборку, а затем используйте такой инструмент, как find, чтобы показать файлы, которые не совпадают с этой известной меткой времени.   -  person Shepmaster    schedule 02.04.2019


Ответы (1)


Добавьте в сценарий сборки println!("cargo:rerun-if-changed={}", &file); строк для каждого файла и для каждого каталога.

person chabapok    schedule 02.04.2019