Skip to content

Failed build script is not tracked in fingerprint. #6770

Closed
@ehuss

Description

@ehuss

There is a scenario where cargo fails to rebuild when the execution of a build script is interrupted (such as hitting ctrl-c). There are a variety of ways this can happen, the test below illustrates one way.

The fundamental problem is that the fingerprint does not track enough information about the execution of a build script as a dependency. #6720 added tracking the invoked.timestamp file, but that is not sufficient.

I've been pondering various ways to fix this, but not loving the options. I would be interested if anyone has any more ideas. Bonus points if both this and #6733 can be fixed. Some options:

  • Build script fingerprint of registry dependencies is not tracked in fingerprint. #6733 mentions adding the info from build_script_local_fingerprints, but there are some complications with updating that after the build is done (it would need to do everything that prepare_build_cmd does, too).
  • Add another file that is written in the fingerprint dir that tracks the completion of running the build script, perhaps with a sequence number bumped each time it is run.
  • When the build script starts, write invoked.timestamp.start (and delete invoked.timestamp) and then when the build script succeeds, rename it to invoked.timestamp. I think this should work, but I'm not sure.
  • (Crazy) Switch to a database for fingerprint tracking to make it easier to track dependencies.

Example

(This currently fails on the last line where the build succeeds when it should fail.)

#[test]
fn script_fails_stay_dirty() {
    let p = project()
        .file(
            "build.rs",
            r#"
                mod helper;
                fn main() {
                    println!("cargo:rerun-if-changed=build.rs");
                    helper::doit();
                }
            "#,
        )
        .file("helper.rs", "pub fn doit() {}")
        .file("src/lib.rs", "")
        .build();

    p.cargo("build").run();
    p.change_file("helper.rs", r#"pub fn doit() {panic!("Crash!");}"#);
    p.cargo("build")
        .with_stderr_contains("[..]Crash![..]")
        .with_status(101)
        .run();
    // There was a bug where this second call would be "fresh".
    p.cargo("build")
        .with_stderr_contains("[..]Crash![..]")
        .with_status(101)
        .run();
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions