Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid rebuilding a project when cwd changes #4788

Merged
merged 2 commits into from
Dec 12, 2017

Commits on Dec 8, 2017

  1. Avoid rebuilding a project when cwd changes

    This commit is targeted at solving a use case which typically comes up during CI
    builds -- the `target` directory is cached between builds but the cwd of the
    build changes over time. For example the following scenario can happen:
    
    1. A project is compiled at `/projects/a`.
    2. The `target` directory is cached.
    3. A new build is started in `/projects/b`.
    4. The previous `target` directory is restored to `/projects/b`.
    5. The build start, and Cargo rebuilds everything.
    
    The last piece of behavior is indeed unfortunate! Cargo's internal hashing
    currently isn't that resilient to changing cwd and this PR aims to help improve
    the situation!
    
    The first point of too-much-hashing came up with `Target::src_path`. Each
    `Target` was hashed and stored for all compilations, and the `src_path` field
    was an absolute path on the filesystem to the file that needed to be compiled.
    This path then changed over time when cwd changed, but otherwise everything else
    remained the same!
    
    This commit updates the handling of the `src_path` field to simply ignore it
    when hashing. Instead the path we actually pass to rustc is later calculated and
    then passed to the fingerprint calculation.
    
    The next problem this fixes is that the dep info files were augmented after
    creation to have the cwd of the compiler at the time to find the files at a
    later date. This, unfortunately, would cause issues if the cwd itself changed.
    Instead the cwd is now left out of dep-info files (they're no longer augmented)
    and instead the cwd is recalculated when parsing the dep info later.
    
    The final problem that this commit fixes is actually an existing issue in Cargo
    today. Right now you can actually execute `cargo build` from anywhere in a
    project and Cargo will execute the build. Unfortunately though the argument to
    rustc was actually different depending on what directory you were in (the
    compiler was invoked with a path relative to cwd). This path ends up being used
    for metadata like debuginfo which means that different directories would cause
    different artifacts to be created, but Cargo wouldn't rerun the compiler!
    
    To fix this issue the matter of cwd is now entirely excluded from compilation
    command lines. Instead rustc is unconditionally invoked with a relative path
    *if* the path is underneath the workspace root, and otherwise it's invoked as an
    absolute path (in which case the cwd doesn't matter).
    
    Once all these fixes were added up it means that now we can have projects where
    if you move the entire directory Cargo won't rebuild the original source!
    
    Note that this may be a bit of a breaking change, however. This means that the
    paths in error messages for cargo will no longer be unconditionally relative to
    the current working directory, but rather relative to the root of the workspace
    itself. Unfortunately this is moreso of a feature right now rather than a bug,
    so it may be one that we just have to stomach.
    alexcrichton committed Dec 8, 2017
    Configuration menu
    Copy the full SHA
    8647a87 View commit details
    Browse the repository at this point in the history

Commits on Dec 12, 2017

  1. Change Cargo's own dep-file format

    This commit alters the format of the dependency info that Cargo keeps track of
    for each crate. In order to be more resilient against directory renames and such
    Cargo will now postprocess the compiler's dep-info output and serialize into its
    own format. This format is intended to primarily list relative paths *to the
    root of the relevant package* rather than absolute or relative to some other
    location. If paths aren't actually relative to the package root they're still
    stored as absolute, but there's not much we can do about that!
    alexcrichton committed Dec 12, 2017
    Configuration menu
    Copy the full SHA
    f688e9c View commit details
    Browse the repository at this point in the history