对于文件列表,如何仅针对已更改的文件运行构建脚本?

nik*_*ack 5 rust rust-cargo

我有一个文件列表,并且想为每个文件运行一些程序,但前提是它已更改。所以我将所有文件放入向量中并进行迭代,如下所示:

// build.rs

let files = vec![
    "fileA",
    "fileB",
];

for file in files{
    println!("cargo:rerun-if-changed={}", file);

    let output = Command::new("glslangValidator")
        .args(&["-V", file, "-o", file])
        .output()
        .expect("failed to run glslangValidator");
}
Run Code Online (Sandbox Code Playgroud)

这是可行的,但构建过程会针对每个文件运行,即使列表中只更改了一个文件。相反,我只想为构建之间更改的文件glslangValidator调用。

Sir*_*ius 3

如果您调用的命令生成输出文件,则常见的技术是将输出文件的修改日期与源文件的修改日期进行比较。

仅当输出文件早于源文件或输出文件不存在时,才需要调用该工具。

例子:

fn is_input_file_outdated<P1, P2>(input: P1, output: P2) -> io::Result<bool>
where
    P1: AsRef<Path>,
    P2: AsRef<Path>,
{
    let out_meta = fs::metadata(output);
    if let Ok(meta) = out_meta {
        let output_mtime = meta.modified()?;

        // if input file is more recent than our output, we are outdated
        let input_meta = fs::metadata(input)?;
        let input_mtime = input_meta.modified()?;

        Ok(input_mtime > output_mtime)
    } else {
        // output file not found, we are outdated
        Ok(true)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我会注意到,由于时间戳可能会出现问题 - 例如,如果输入文件在读取之后但在生成输出之前被修改怎么办?或者操作系统有问题?-- 稍微安全一点的版本是生成您读取的输入文件的良好哈希值(例如 SHA-1 或 SHA-2),并对照引用进行检查。 (2认同)