Skip to content

Relative cargo:rerun-if-changed paths are not resolved in dep-info files #9445

Closed
@futile

Description

@futile

Problem

If I have a dependency that has a build.rs build script that outputs a relative path (e.g., cargo:rerun-if-changed=build.rs), this path will appear unchanged in dep info files of my crate.

This path can then not be resolved by external build tools.

Steps

  1. Create a new cargo project (cargo new --bin dep-info-test && cd dep-info-test)
  2. Add a dependency that outputs a cargo:rerun-if-changed=<relative path>, e.g., libc: echo 'libc = "0.2"' >> Cargo.toml
  3. Build the project and check the resulting dep-info file: cargo build && cat target/debug/dep-info-test.d:
[...]
/abs/path/to/dep-info-test/target/debug/dep-info-test: /abs/path/to/dep-info-test/src/main.rs build.rs

Possible Solution(s)
It seems that cargo's internal change-detection mechanism (something with fingerprints?) resolves relative paths output by build scripts as relative to their CARGO_MANIFEST_DIR (I think), which should probably explicitly also be done for dep-info files.

Also, in the case of crates.io- & git-dependencies, cargo doesn't write paths to the dependencies' files itself into the dep-info file, as it regards such dependencies as 'read-only'. So for non-path dependencies absolute paths that point into a dependency's CARGO_MANIFEST_DIR should probably not appear in dep-info files anymore (but should still appear for path-dependencies).

Notes

Output of cargo version:

$ cargo version
cargo 1.53.0-nightly (0ed318d18 2021-04-23)

Same behavior with current stable:

$ cargo version
cargo 1.51.0 (43b129a20 2021-03-16)

Extra discussion material

I think the dep-info files are currently misleading, as they don't capture all conditions under which cargo needs to rebuild a project. For example, environment variables registered using cargo:rerun-if-env-changed are not captured in this file. Another example are .cargo/config files, which often don't exist, but influence compilation, so they would need to be in every dep-info file. These can also appear outside the project, i.e., in every parent directory down to the root-directory.

The fact that this file is incomplete is not mentioned in the current docs, but maybe should be mentioned there.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions