fn calculate<'a, 'cfg>(
    cx: &mut Context<'a, 'cfg>,
    unit: &Unit<'a>,
) -> CargoResult<Arc<Fingerprint>> {
    let bcx = cx.bcx;
    if let Some(s) = cx.fingerprints.get(unit) {
        return Ok(Arc::clone(s));
    }

    // Next, recursively calculate the fingerprint for all of our dependencies.
    //
    // Skip the fingerprints of build scripts, they are included below in the
    // `local` vec. Also skip fingerprints of binaries because they don't
    // actually induce a recompile, they're just dependencies in the sense
    // that they need to be built.
    let mut deps = cx
        .dep_targets(unit)
        .iter()
        .filter(|u| !u.target.is_custom_build() && !u.target.is_bin())
        .map(|dep| {
            calculate(cx, dep).and_then(|fingerprint| {
                let name = cx.bcx.extern_crate_name(unit, dep)?;
                Ok(DepFingerprint {
                    pkg_id: dep.pkg.package_id().to_string(),
                    name,
                    fingerprint,
                })
            })
        })
        .collect::<CargoResult<Vec<_>>>()?;
    deps.sort_by(|a, b| a.pkg_id.cmp(&b.pkg_id));

    // And finally, calculate what our own local fingerprint is.
    let local = if use_dep_info(unit) {
        let dep_info = dep_info_loc(cx, unit);
        let mtime = dep_info_mtime_if_fresh(unit.pkg, &dep_info)?;
        let mut local = vec![LocalFingerprint::mtime(
            cx.files().target_root(),
            mtime,
            &dep_info,
        )];
        // Include the fingerprint of the build script.
        //
        // This is not included for dependencies (Precalculated below) because
        // Docker zeros the nanosecond part of the mtime when the image is
        // saved, which prevents built dependencies from being cached.
        // This has the consequence that if a dependency needs to be rebuilt
        // (such as an environment variable tracked via rerun-if-env-changed),
        // and you run two separate commands (`build` then `test`), the second
        // command will erroneously think it is fresh.
        // See: https://github.com/rust-lang/cargo/issues/6733
        local.extend(
            cx.dep_targets(unit)
                .iter()
                .filter(|u| u.mode.is_run_custom_build())
                .map(|dep| {
                    // If the build script is overridden, use the override info as
                    // the override. Otherwise, use the last invocation time of
                    // the build script. If the build script re-runs during this
                    // run, dirty propagation within the JobQueue will ensure that
                    // this gets invalidated. This is only here to catch the
                    // situation when cargo is run a second time for another
                    // target that wasn't built previously (such as `cargo build`
                    // then `cargo test`).
                    build_script_override_fingerprint(cx, unit).unwrap_or_else(|| {
                        let ts_path = cx
                            .files()
                            .build_script_run_dir(dep)
                            .join("invoked.timestamp");
                        let ts_path_mtime = paths::mtime(&ts_path).ok();
                        LocalFingerprint::mtime(cx.files().target_root(), ts_path_mtime, &ts_path)
                    })
                }),
        );
        local
    } else {
        let fingerprint = pkg_fingerprint(&cx.bcx, unit.pkg)?;
        vec![LocalFingerprint::Precalculated(fingerprint)]
    };

    let extra_flags = if unit.mode.is_doc() {
        bcx.rustdocflags_args(unit)?
    } else {
        bcx.rustflags_args(unit)?
    };
    let profile_hash = util::hash_u64(&(&unit.profile, unit.mode, bcx.extra_args_for(unit)));
    let fingerprint = Arc::new(Fingerprint {
        rustc: util::hash_u64(&bcx.rustc.verbose_version),
        target: util::hash_u64(&unit.target),
        profile: profile_hash,
        // Note that .0 is hashed here, not .1 which is the cwd. That doesn't
        // actually affect the output artifact so there's no need to hash it.
        path: util::hash_u64(&super::path_args(&cx.bcx, unit).0),
        features: format!("{:?}", bcx.resolve.features_sorted(unit.pkg.package_id())),
        deps,
        local,
        memoized_hash: Mutex::new(None),
        edition: unit.target.edition(),
        rustflags: extra_flags,
    });
    cx.fingerprints.insert(*unit, Arc::clone(&fingerprint));
    Ok(fingerprint)
}
/// Calculates the fingerprint for a package/target pair.
///
/// This fingerprint is used by Cargo to learn about when information such as:
///
/// * A non-path package changes (changes version, changes revision, etc).
/// * Any dependency changes
/// * The compiler changes
/// * The set of features a package is built with changes
/// * The profile a target is compiled with changes (e.g., opt-level changes)
///
/// Information like file modification time is only calculated for path
/// dependencies and is calculated in `calculate_target_fresh`.
Calculates the fingerprint for a package/target pair.
This fingerprint is used by Cargo to learn about when information such as.

A non-path package changes (changes version, changes revision, etc).
Any dependency changes
The compiler changes
The set of features a package is built with changes
The profile a target is compiled with changes

Information like file modification time is only calculated for path
dependencies and is calculated in `calculate_target_fresh`.
Calculates the fingerprint for a package / target pair . This fingerprint is used by Cargo to learn about when information such as . A non - path package changes ( changes version changes revision etc ) . Any dependency changes The compiler changes The set of features a package is built with changes The profile a target is compiled with changes Information like file modification time is only calculated for path dependencies and is calculated in ` calculate_target_fresh ` .
fn calculate<'a, 'cfg>(
    cx: &mut Context<'a, 'cfg>,
    unit: &Unit<'a>,
) -> CargoResult<Arc<Fingerprint>> {
    let bcx = cx.bcx;
    if let Some(s) = cx.fingerprints.get(unit) {
        return Ok(Arc::clone(s));
    }
    // Next, recursively calculate the fingerprint for all of our dependencies.
    //
    // Skip the fingerprints of build scripts, they are included below in the
    // `local` vec. Also skip fingerprints of binaries because they don't
    // actually induce a recompile, they're just dependencies in the sense
    // that they need to be built.
    let mut deps = cx
        .dep_targets(unit)
        .iter()
        .filter(|u| !u.target.is_custom_build() && !u.target.is_bin())
        .map(|dep| {
            calculate(cx, dep).and_then(|fingerprint| {
                let name = cx.bcx.extern_crate_name(unit, dep)?;
                Ok(DepFingerprint {
                    pkg_id: dep.pkg.package_id().to_string(),
                    name,
                    fingerprint,
                })
            })
        })
        .collect::<CargoResult<Vec<_>>>()?;
    deps.sort_by(|a, b| a.pkg_id.cmp(&b.pkg_id));
    // And finally, calculate what our own local fingerprint is.
    let local = if use_dep_info(unit) {
        let dep_info = dep_info_loc(cx, unit);
        let mtime = dep_info_mtime_if_fresh(unit.pkg, &dep_info)?;
        let mut local = vec![LocalFingerprint::mtime(
            cx.files().target_root(),
            mtime,
            &dep_info,
        )];
        // Include the fingerprint of the build script.
        //
        // This is not included for dependencies (Precalculated below) because
        // Docker zeros the nanosecond part of the mtime when the image is
        // saved, which prevents built dependencies from being cached.
        // This has the consequence that if a dependency needs to be rebuilt
        // (such as an environment variable tracked via rerun-if-env-changed),
        // and you run two separate commands (`build` then `test`), the second
        // command will erroneously think it is fresh.
        // See: https://github.com/rust-lang/cargo/issues/6733
        local.extend(
            cx.dep_targets(unit)
                .iter()
                .filter(|u| u.mode.is_run_custom_build())
                .map(|dep| {
                    // If the build script is overridden, use the override info as
                    // the override. Otherwise, use the last invocation time of
                    // the build script. If the build script re-runs during this
                    // run, dirty propagation within the JobQueue will ensure that
                    // this gets invalidated. This is only here to catch the
                    // situation when cargo is run a second time for another
                    // target that wasn't built previously (such as `cargo build`
                    // then `cargo test`).
                    build_script_override_fingerprint(cx, unit).unwrap_or_else(|| {
                        let ts_path = cx
                            .files()
                            .build_script_run_dir(dep)
                            .join("invoked.timestamp");
                        let ts_path_mtime = paths::mtime(&ts_path).ok();
                        LocalFingerprint::mtime(cx.files().target_root(), ts_path_mtime, &ts_path)
                    })
                }),
        );
        local
    } else {
        let fingerprint = pkg_fingerprint(&cx.bcx, unit.pkg)?;
        vec![LocalFingerprint::Precalculated(fingerprint)]
    };
    let extra_flags = if unit.mode.is_doc() {
        bcx.rustdocflags_args(unit)?
    } else {
        bcx.rustflags_args(unit)?
    };
    let profile_hash = util::hash_u64(&(&unit.profile, unit.mode, bcx.extra_args_for(unit)));
    let fingerprint = Arc::new(Fingerprint {
        rustc: util::hash_u64(&bcx.rustc.verbose_version),
        target: util::hash_u64(&unit.target),
        profile: profile_hash,
        // Note that .0 is hashed here, not .1 which is the cwd. That doesn't
        // actually affect the output artifact so there's no need to hash it.
        path: util::hash_u64(&super::path_args(&cx.bcx, unit).0),
        features: format!("{:?}", bcx.resolve.features_sorted(unit.pkg.package_id())),
        deps,
        local,
        memoized_hash: Mutex::new(None),
        edition: unit.target.edition(),
        rustflags: extra_flags,
    });
    cx.fingerprints.insert(*unit, Arc::clone(&fingerprint));
    Ok(fingerprint)
}
fn calculate < ' a , ' cfg > ( cx : & mut Context < ' a , ' cfg > , unit : & Unit < ' a > , ) -> CargoResult < Arc < Fingerprint > > { let bcx = cx . bcx ; if let Some ( s ) = cx . fingerprints . get ( unit ) { return Ok ( Arc :: clone ( s ) ) ; } // Next, recursively calculate the fingerprint for all of our dependencies. // // Skip the fingerprints of build scripts, they are included below in the // `local` vec. Also skip fingerprints of binaries because they don't // actually induce a recompile, they're just dependencies in the sense // that they need to be built. let mut deps = cx . dep_targets ( unit ) . iter ( ) . filter ( | u | ! u . target . is_custom_build ( ) && ! u . target . is_bin ( ) ) . map ( | dep | { calculate ( cx , dep ) . and_then ( | fingerprint | { let name = cx . bcx . extern_crate_name ( unit , dep ) ? ; Ok ( DepFingerprint { pkg_id : dep . pkg . package_id ( ) . to_string ( ) , name , fingerprint , } ) } ) } ) . collect :: < CargoResult < Vec < _ > > > ( ) ? ; deps . sort_by ( | a , b | a . pkg_id . cmp ( & b . pkg_id ) ) ; // And finally, calculate what our own local fingerprint is. let local = if use_dep_info ( unit ) { let dep_info = dep_info_loc ( cx , unit ) ; let mtime = dep_info_mtime_if_fresh ( unit . pkg , & dep_info ) ? ; let mut local = vec ! [ LocalFingerprint mtime ( cx files ( ) target_root ( ) mtime dep_info ) ] ; // Include the fingerprint of the build script. // // This is not included for dependencies (Precalculated below) because // Docker zeros the nanosecond part of the mtime when the image is // saved, which prevents built dependencies from being cached. // This has the consequence that if a dependency needs to be rebuilt // (such as an environment variable tracked via rerun-if-env-changed), // and you run two separate commands (`build` then `test`), the second // command will erroneously think it is fresh. // See: https://github.com/rust-lang/cargo/issues/6733 local . extend ( cx . dep_targets ( unit ) . iter ( ) . filter ( | u | u . mode . is_run_custom_build ( ) ) . map ( | dep | { // If the build script is overridden, use the override info as // the override. Otherwise, use the last invocation time of // the build script. If the build script re-runs during this // run, dirty propagation within the JobQueue will ensure that // this gets invalidated. This is only here to catch the // situation when cargo is run a second time for another // target that wasn't built previously (such as `cargo build` // then `cargo test`). build_script_override_fingerprint ( cx , unit ) . unwrap_or_else ( | | { let ts_path = cx . files ( ) . build_script_run_dir ( dep ) . join ( " " ) ; let ts_path_mtime = paths :: mtime ( & ts_path ) . ok ( ) ; LocalFingerprint :: mtime ( cx . files ( ) . target_root ( ) , ts_path_mtime , & ts_path ) } ) } ) , ) ; local } else { let fingerprint = pkg_fingerprint ( & cx . bcx , unit . pkg ) ? ; vec ! [ LocalFingerprint Precalculated ( fingerprint ) ] } ; let extra_flags = if unit . mode . is_doc ( ) { bcx . rustdocflags_args ( unit ) ? } else { bcx . rustflags_args ( unit ) ? } ; let profile_hash = util :: hash_u64 ( & ( & unit . profile , unit . mode , bcx . extra_args_for ( unit ) ) ) ; let fingerprint = Arc :: new ( Fingerprint { rustc : util :: hash_u64 ( & bcx . rustc . verbose_version ) , target : util :: hash_u64 ( & unit . target ) , profile : profile_hash , // Note that .0 is hashed here, not .1 which is the cwd. That doesn't // actually affect the output artifact so there's no need to hash it. path : util :: hash_u64 ( & super :: path_args ( & cx . bcx , unit ) . 0 ) , features : format ! ( " " bcx resolve features_sorted ( unit pkg package_id ( ) ) ) , deps , local , memoized_hash : Mutex :: new ( None ) , edition : unit . target . edition ( ) , rustflags : extra_flags , } ) ; cx . fingerprints . insert ( * unit , Arc :: clone ( & fingerprint ) ) ; Ok ( fingerprint ) }
Calculates the fingerprint for a package/target pair.
Calculates the fingerprint for a package / target pair .
cx
&mut Context<'a, 'cfg>
unit
&Unit<'a>
cx
&mut Context<'a, 'cfg>
unit
&Unit<'a>