首页 > 解决方案 > 对于文件列表,如何仅为已更改的文件运行构建脚本?

问题描述

我有一个文件列表,并且想为每个文件运行一些程序,但前提是它已更改。所以我把所有的文件都放在了向量中,然后迭代,像这样:

// 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");
}

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

标签: rustrust-cargo

解决方案


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

仅当输出文件比源文件旧时,或者输出文件不存在时,您才需要调用该工具。

例子:

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)
    }
}

推荐阅读