Skip to content

Commit 643f12e

Browse files
committed
Address review feedback
1 parent 6820015 commit 643f12e

File tree

2 files changed

+55
-21
lines changed

2 files changed

+55
-21
lines changed

src/cargo/core/compiler/fingerprint.rs

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,9 @@
106106
//! used to log details about *why* a fingerprint is considered dirty.
107107
//! `CARGO_LOG=cargo::core::compiler::fingerprint=trace cargo build` can be
108108
//! used to display this log information.
109-
//! - A "dep-info" file which contains a list of source filenames for the
110-
//! target. See below for details.
109+
//! - A "dep-info" file which is a translation of rustc's `*.d` dep-info files
110+
//! to a Cargo-specific format that tweaks file names and is optimized for
111+
//! reading quickly.
111112
//! - An `invoked.timestamp` file whose filesystem mtime is updated every time
112113
//! the Unit is built. This is used for capturing the time when the build
113114
//! starts, to detect if files are changed in the middle of the build. See
@@ -146,7 +147,10 @@
146147
//! directory (`translate_dep_info`). The mtime of the fingerprint dep-info
147148
//! file itself is used as the reference for comparing the source files to
148149
//! determine if any of the source files have been modified (see below for
149-
//! more detail).
150+
//! more detail). Note that Cargo parses the special `# env-var:...` comments in
151+
//! dep-info files to learn about environment variables that the rustc compile
152+
//! depends on. Cargo then later uses this to trigger a recompile if a
153+
//! referenced env var changes (even if the source didn't change).
150154
//!
151155
//! There is also a third dep-info file. Cargo will extend the file created by
152156
//! rustc with some additional information and saves this into the output
@@ -692,21 +696,29 @@ enum StaleItem {
692696

693697
impl LocalFingerprint {
694698
/// Checks dynamically at runtime if this `LocalFingerprint` has a stale
695-
/// file.
699+
/// item inside of it.
696700
///
697-
/// This will use the absolute root paths passed in if necessary to guide
698-
/// file accesses.
701+
/// The main purpose of this function is to handle two different ways
702+
/// fingerprints can be invalidated:
703+
///
704+
/// * One is a dependency listed in rustc's dep-info files is invalid. Note
705+
/// that these could either be env vars or files. We check both here.
706+
///
707+
/// * Another is the `rerun-if-changed` directive from build scripts. This
708+
/// is where we'll find whether files have actually changed
699709
fn find_stale_item(
700710
&self,
701711
mtime_cache: &mut HashMap<PathBuf, FileTime>,
702712
pkg_root: &Path,
703713
target_root: &Path,
704714
) -> CargoResult<Option<StaleItem>> {
705715
match self {
706-
// We need to parse `dep_info`, learn about all the files the crate
707-
// depends on, and then see if any of them are newer than the
708-
// dep_info file itself. If the `dep_info` file is missing then this
709-
// unit has never been compiled!
716+
// We need to parse `dep_info`, learn about the crate's dependencies.
717+
//
718+
// For each env var we see if our current process's env var still
719+
// matches, and for each file we see if any of them are newer than
720+
// the `dep_info` file itself whose mtime represents the start of
721+
// rustc.
710722
LocalFingerprint::CheckDepInfo { dep_info } => {
711723
let dep_info = target_root.join(dep_info);
712724
let info = match parse_dep_info(pkg_root, target_root, &dep_info)? {
@@ -1620,7 +1632,17 @@ fn log_compare(unit: &Unit, compare: &CargoResult<()>) {
16201632
info!(" err: {:?}", ce);
16211633
}
16221634

1623-
// Parse the dep-info into a list of paths
1635+
/// Parses Cargo's internal `EncodedDepInfo` structure that was previously
1636+
/// serialized to disk.
1637+
///
1638+
/// Note that this is not rustc's `*.d` files.
1639+
///
1640+
/// Also note that rustc's `*.d` files are translated to Cargo-specific
1641+
/// `EncodedDepInfo` files after compilations have finished in
1642+
/// `translate_dep_info`.
1643+
///
1644+
/// Returns `None` if the file is corrupt or couldn't be read from disk. This
1645+
/// indicates that the crate should likely be rebuilt.
16241646
pub fn parse_dep_info(
16251647
pkg_root: &Path,
16261648
target_root: &Path,
@@ -1630,9 +1652,12 @@ pub fn parse_dep_info(
16301652
Ok(data) => data,
16311653
Err(_) => return Ok(None),
16321654
};
1633-
let info = match OnDiskDepInfo::parse(&data) {
1655+
let info = match EncodedDepInfo::parse(&data) {
16341656
Some(info) => info,
1635-
None => return Ok(None),
1657+
None => {
1658+
log::warn!("failed to parse cargo's dep-info at {:?}", dep_info);
1659+
return Ok(None);
1660+
}
16361661
};
16371662
let mut ret = RustcDepInfo::default();
16381663
ret.env = info.env;
@@ -1721,7 +1746,6 @@ where
17211746
None
17221747
}
17231748

1724-
#[derive(Serialize, Deserialize)]
17251749
enum DepInfoPathType {
17261750
// src/, e.g. src/lib.rs
17271751
PackageRootRelative,
@@ -1766,7 +1790,7 @@ pub fn translate_dep_info(
17661790

17671791
let target_root = target_root.canonicalize()?;
17681792
let pkg_root = pkg_root.canonicalize()?;
1769-
let mut on_disk_info = OnDiskDepInfo::default();
1793+
let mut on_disk_info = EncodedDepInfo::default();
17701794
on_disk_info.env = depinfo.env;
17711795

17721796
// This is a bit of a tricky statement, but here we're *removing* the
@@ -1831,17 +1855,27 @@ pub struct RustcDepInfo {
18311855
pub files: Vec<PathBuf>,
18321856
/// The list of environment variables we found that the rustc compilation
18331857
/// depends on.
1858+
///
1859+
/// The first element of the pair is the name of the env var and the second
1860+
/// item is the value. `Some` means that the env var was set, and `None`
1861+
/// means that the env var wasn't actually set and the compilation depends
1862+
/// on it not being set.
18341863
pub env: Vec<(String, Option<String>)>,
18351864
}
18361865

1866+
// Same as `RustcDepInfo` except avoids absolute paths as much as possible to
1867+
// allow moving around the target directory.
1868+
//
1869+
// This is also stored in an optimized format to make parsing it fast because
1870+
// Cargo will read it for crates on all future compilations.
18371871
#[derive(Default)]
1838-
struct OnDiskDepInfo {
1872+
struct EncodedDepInfo {
18391873
files: Vec<(DepInfoPathType, PathBuf)>,
18401874
env: Vec<(String, Option<String>)>,
18411875
}
18421876

1843-
impl OnDiskDepInfo {
1844-
fn parse(mut bytes: &[u8]) -> Option<OnDiskDepInfo> {
1877+
impl EncodedDepInfo {
1878+
fn parse(mut bytes: &[u8]) -> Option<EncodedDepInfo> {
18451879
let bytes = &mut bytes;
18461880
let nfiles = read_usize(bytes)?;
18471881
let mut files = Vec::with_capacity(nfiles as usize);
@@ -1866,7 +1900,7 @@ impl OnDiskDepInfo {
18661900
};
18671901
env.push((key, val));
18681902
}
1869-
return Some(OnDiskDepInfo { files, env });
1903+
return Some(EncodedDepInfo { files, env });
18701904

18711905
fn read_usize(bytes: &mut &[u8]) -> Option<usize> {
18721906
let ret = bytes.get(..4)?;

tests/testsuite/freshness.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2475,7 +2475,7 @@ fn lld_is_fresh() {
24752475

24762476
#[cargo_test]
24772477
fn env_in_code_causes_rebuild() {
2478-
// Only nightly has support in dep-info files for this
2478+
// Only nightly 1.46 has support in dep-info files for this
24792479
if !cargo_test_support::is_nightly() {
24802480
return;
24812481
}
@@ -2531,7 +2531,7 @@ fn env_in_code_causes_rebuild() {
25312531

25322532
#[cargo_test]
25332533
fn env_build_script_no_rebuild() {
2534-
// Only nightly has support in dep-info files for this
2534+
// Only nightly 1.46 has support in dep-info files for this
25352535
if !cargo_test_support::is_nightly() {
25362536
return;
25372537
}

0 commit comments

Comments
 (0)