106
106
//! used to log details about *why* a fingerprint is considered dirty.
107
107
//! `CARGO_LOG=cargo::core::compiler::fingerprint=trace cargo build` can be
108
108
//! 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.
111
112
//! - An `invoked.timestamp` file whose filesystem mtime is updated every time
112
113
//! the Unit is built. This is used for capturing the time when the build
113
114
//! starts, to detect if files are changed in the middle of the build. See
146
147
//! directory (`translate_dep_info`). The mtime of the fingerprint dep-info
147
148
//! file itself is used as the reference for comparing the source files to
148
149
//! 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).
150
154
//!
151
155
//! There is also a third dep-info file. Cargo will extend the file created by
152
156
//! rustc with some additional information and saves this into the output
@@ -692,21 +696,29 @@ enum StaleItem {
692
696
693
697
impl LocalFingerprint {
694
698
/// Checks dynamically at runtime if this `LocalFingerprint` has a stale
695
- /// file .
699
+ /// item inside of it .
696
700
///
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
699
709
fn find_stale_item (
700
710
& self ,
701
711
mtime_cache : & mut HashMap < PathBuf , FileTime > ,
702
712
pkg_root : & Path ,
703
713
target_root : & Path ,
704
714
) -> CargoResult < Option < StaleItem > > {
705
715
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.
710
722
LocalFingerprint :: CheckDepInfo { dep_info } => {
711
723
let dep_info = target_root. join ( dep_info) ;
712
724
let info = match parse_dep_info ( pkg_root, target_root, & dep_info) ? {
@@ -1620,7 +1632,17 @@ fn log_compare(unit: &Unit, compare: &CargoResult<()>) {
1620
1632
info ! ( " err: {:?}" , ce) ;
1621
1633
}
1622
1634
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.
1624
1646
pub fn parse_dep_info (
1625
1647
pkg_root : & Path ,
1626
1648
target_root : & Path ,
@@ -1630,9 +1652,12 @@ pub fn parse_dep_info(
1630
1652
Ok ( data) => data,
1631
1653
Err ( _) => return Ok ( None ) ,
1632
1654
} ;
1633
- let info = match OnDiskDepInfo :: parse ( & data) {
1655
+ let info = match EncodedDepInfo :: parse ( & data) {
1634
1656
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
+ }
1636
1661
} ;
1637
1662
let mut ret = RustcDepInfo :: default ( ) ;
1638
1663
ret. env = info. env ;
@@ -1721,7 +1746,6 @@ where
1721
1746
None
1722
1747
}
1723
1748
1724
- #[ derive( Serialize , Deserialize ) ]
1725
1749
enum DepInfoPathType {
1726
1750
// src/, e.g. src/lib.rs
1727
1751
PackageRootRelative ,
@@ -1766,7 +1790,7 @@ pub fn translate_dep_info(
1766
1790
1767
1791
let target_root = target_root. canonicalize ( ) ?;
1768
1792
let pkg_root = pkg_root. canonicalize ( ) ?;
1769
- let mut on_disk_info = OnDiskDepInfo :: default ( ) ;
1793
+ let mut on_disk_info = EncodedDepInfo :: default ( ) ;
1770
1794
on_disk_info. env = depinfo. env ;
1771
1795
1772
1796
// This is a bit of a tricky statement, but here we're *removing* the
@@ -1831,17 +1855,27 @@ pub struct RustcDepInfo {
1831
1855
pub files : Vec < PathBuf > ,
1832
1856
/// The list of environment variables we found that the rustc compilation
1833
1857
/// 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.
1834
1863
pub env : Vec < ( String , Option < String > ) > ,
1835
1864
}
1836
1865
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.
1837
1871
#[ derive( Default ) ]
1838
- struct OnDiskDepInfo {
1872
+ struct EncodedDepInfo {
1839
1873
files : Vec < ( DepInfoPathType , PathBuf ) > ,
1840
1874
env : Vec < ( String , Option < String > ) > ,
1841
1875
}
1842
1876
1843
- impl OnDiskDepInfo {
1844
- fn parse ( mut bytes : & [ u8 ] ) -> Option < OnDiskDepInfo > {
1877
+ impl EncodedDepInfo {
1878
+ fn parse ( mut bytes : & [ u8 ] ) -> Option < EncodedDepInfo > {
1845
1879
let bytes = & mut bytes;
1846
1880
let nfiles = read_usize ( bytes) ?;
1847
1881
let mut files = Vec :: with_capacity ( nfiles as usize ) ;
@@ -1866,7 +1900,7 @@ impl OnDiskDepInfo {
1866
1900
} ;
1867
1901
env. push ( ( key, val) ) ;
1868
1902
}
1869
- return Some ( OnDiskDepInfo { files, env } ) ;
1903
+ return Some ( EncodedDepInfo { files, env } ) ;
1870
1904
1871
1905
fn read_usize ( bytes : & mut & [ u8 ] ) -> Option < usize > {
1872
1906
let ret = bytes. get ( ..4 ) ?;
0 commit comments