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
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
693697impl 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.
16241646pub 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 ) ]
17251749enum 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 ) ?;
0 commit comments