Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rustc cache #5359

Merged
merged 11 commits into from
Apr 16, 2018
2 changes: 1 addition & 1 deletion src/bin/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Run with 'cargo -Z [FLAG] [SUBCOMMAND]'"
}

if let Some(ref code) = args.value_of("explain") {
let mut procss = config.rustc()?.process();
let mut procss = config.new_rustc()?.process();
procss.arg("--explain").arg(code).exec()?;
return Ok(());
}
Expand Down
8 changes: 6 additions & 2 deletions src/cargo/core/compiler/compilation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,17 @@ pub struct Compilation<'cfg> {
/// Flags to pass to rustdoc when invoked from cargo test, per package.
pub rustdocflags: HashMap<PackageId, Vec<String>>,

pub host: String,
pub target: String,

config: &'cfg Config,
rustc_process: ProcessBuilder,

target_runner: LazyCell<Option<(PathBuf, Vec<String>)>>,
}

impl<'cfg> Compilation<'cfg> {
pub fn new(config: &'cfg Config) -> Compilation<'cfg> {
pub fn new(config: &'cfg Config, rustc_process: ProcessBuilder) -> Compilation<'cfg> {
Compilation {
libraries: HashMap::new(),
native_dirs: BTreeSet::new(), // TODO: deprecated, remove
Expand All @@ -81,14 +83,16 @@ impl<'cfg> Compilation<'cfg> {
cfgs: HashMap::new(),
rustdocflags: HashMap::new(),
config,
rustc_process,
host: String::new(),
target: String::new(),
target_runner: LazyCell::new(),
}
}

/// See `process`.
pub fn rustc_process(&self, pkg: &Package) -> CargoResult<ProcessBuilder> {
self.fill_env(self.config.rustc()?.process(), pkg, true)
self.fill_env(self.rustc_process.clone(), pkg, true)
}

/// See `process`.
Expand Down
4 changes: 1 addition & 3 deletions src/cargo/core/compiler/context/compilation_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,9 +434,7 @@ fn compute_metadata<'a, 'cfg>(
unit.target.name().hash(&mut hasher);
unit.target.kind().hash(&mut hasher);

if let Ok(rustc) = cx.config.rustc() {
rustc.verbose_version.hash(&mut hasher);
}
cx.build_config.rustc.verbose_version.hash(&mut hasher);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my perception, it seemed that build_config should probably stay immutable over the lifetime of the Context (and in fact that is enforced, I think, by #5358).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, not sure I understand this comment :) build_config is not mutated here at all?


// Seed the contents of __CARGO_DEFAULT_LIB_METADATA to the hasher if present.
// This should be the release channel, to get a different hash for each channel.
Expand Down
5 changes: 3 additions & 2 deletions src/cargo/core/compiler/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
let _p = profile::start("Context::probe_target_info");
debug!("probe_target_info");
let host_target_same = match build_config.requested_target {
Some(ref s) if s != &config.rustc()?.host => false,
Some(ref s) if s != &build_config.host_triple => false,
_ => true,
};

Expand All @@ -150,7 +150,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
config,
target_info,
host_info,
compilation: Compilation::new(config),
compilation: Compilation::new(config, build_config.rustc.process()),
build_state: Arc::new(BuildState::new(&build_config)),
build_config,
fingerprints: HashMap::new(),
Expand Down Expand Up @@ -302,6 +302,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
self.compilation.native_dirs.insert(dir.clone());
}
}
self.compilation.host = self.build_config.host_triple.clone();
self.compilation.target = self.build_config.target_triple().to_string();
Ok(self.compilation)
}
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/core/compiler/context/target_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl FileType {
impl TargetInfo {
pub fn new(config: &Config, build_config: &BuildConfig, kind: Kind) -> CargoResult<TargetInfo> {
let rustflags = env_args(config, build_config, None, kind, "RUSTFLAGS")?;
let mut process = config.rustc()?.process();
let mut process = build_config.rustc.process();
process
.arg("-")
.arg("--crate-name")
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/core/compiler/custom_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoRes
},
)
.env("HOST", &cx.build_config.host_triple)
.env("RUSTC", &cx.config.rustc()?.path)
.env("RUSTC", &cx.build_config.rustc.path)
.env("RUSTDOC", &*cx.config.rustdoc()?)
.inherit_jobserver(&cx.jobserver);

Expand Down
16 changes: 6 additions & 10 deletions src/cargo/core/compiler/fingerprint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,7 @@ impl Fingerprint {
match *local {
LocalFingerprint::MtimeBased(ref slot, ref path) => {
let path = root.join(path);
let meta = fs::metadata(&path)
.chain_err(|| internal(format!("failed to stat `{}`", path.display())))?;
let mtime = FileTime::from_last_modification_time(&meta);
let mtime = paths::mtime(&path)?;
*slot.0.lock().unwrap() = Some(mtime);
}
LocalFingerprint::EnvBased(..) | LocalFingerprint::Precalculated(..) => continue,
Expand Down Expand Up @@ -457,7 +455,7 @@ fn calculate<'a, 'cfg>(
cx.rustflags_args(unit)?
};
let fingerprint = Arc::new(Fingerprint {
rustc: util::hash_u64(&cx.config.rustc()?.verbose_version),
rustc: util::hash_u64(&cx.build_config.rustc.verbose_version),
target: util::hash_u64(&unit.target),
profile: util::hash_u64(&(&unit.profile, cx.incremental_args(unit)?)),
// Note that .0 is hashed here, not .1 which is the cwd. That doesn't
Expand Down Expand Up @@ -718,22 +716,20 @@ where
I: IntoIterator,
I::Item: AsRef<Path>,
{
let meta = match fs::metadata(output) {
Ok(meta) => meta,
let mtime = match paths::mtime(output) {
Ok(mtime) => mtime,
Err(..) => return None,
};
let mtime = FileTime::from_last_modification_time(&meta);

let any_stale = paths.into_iter().any(|path| {
let path = path.as_ref();
let meta = match fs::metadata(path) {
Ok(meta) => meta,
let mtime2 = match paths::mtime(path) {
Ok(mtime) => mtime,
Err(..) => {
info!("stale: {} -- missing", path.display());
return true;
}
};
let mtime2 = FileTime::from_last_modification_time(&meta);
if mtime2 > mtime {
info!("stale: {} -- {} vs {}", path.display(), mtime2, mtime);
true
Expand Down
15 changes: 9 additions & 6 deletions src/cargo/core/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ use serde_json;
use core::{Feature, PackageId, Profile, Target};
use core::manifest::Lto;
use core::shell::ColorChoice;
use util::{self, machine_message, Config, ProcessBuilder};
use util::{self, machine_message, Config, ProcessBuilder, Rustc, Freshness};
use util::{internal, join_paths, profile};
use util::paths;
use util::errors::{CargoResult, CargoResultExt, Internal};
use util::Freshness;

use self::job::{Job, Work};
use self::job_queue::JobQueue;
Expand Down Expand Up @@ -48,8 +47,8 @@ pub enum Kind {
}

/// Configuration information for a rustc build.
#[derive(Default, Clone)]
pub struct BuildConfig {
pub rustc: Rustc,
/// The host arch triple
///
/// e.g. x86_64-unknown-linux-gnu, would be
Expand Down Expand Up @@ -125,20 +124,24 @@ impl BuildConfig {
None => None,
};
let jobs = jobs.or(cfg_jobs).unwrap_or(::num_cpus::get() as u32);

let host_triple = config.rustc()?.host.clone();
let rustc = config.new_rustc()?;
let host_triple = rustc.host.clone();
let host_config = TargetConfig::new(config, &host_triple)?;
let target_config = match target.as_ref() {
Some(triple) => TargetConfig::new(config, triple)?,
None => host_config.clone(),
};
Ok(BuildConfig {
rustc,
host_triple,
requested_target: target,
jobs,
host: host_config,
target: target_config,
..Default::default()
release: false,
test: false,
doc_all: false,
json_messages: false,
})
}

Expand Down
2 changes: 1 addition & 1 deletion src/cargo/ops/cargo_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ fn run_doc_tests(
let config = options.compile_opts.config;

// We don't build/rust doctests if target != host
if config.rustc()?.host != compilation.target {
if compilation.host != compilation.target {
return Ok((Test::Doc, errors));
}

Expand Down
5 changes: 2 additions & 3 deletions src/cargo/sources/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use ignore::gitignore::GitignoreBuilder;
use core::{Dependency, Package, PackageId, Registry, Source, SourceId, Summary};
use ops;
use util::{self, internal, CargoResult};
use util::paths;
use util::Config;

pub struct PathSource<'cfg> {
Expand Down Expand Up @@ -529,9 +530,7 @@ impl<'cfg> Source for PathSource<'cfg> {
// condition where this path was rm'ed - either way,
// we can ignore the error and treat the path's mtime
// as 0.
let mtime = fs::metadata(&file)
.map(|meta| FileTime::from_last_modification_time(&meta))
.unwrap_or(FileTime::zero());
let mtime = paths::mtime(&file).unwrap_or(FileTime::zero());
warn!("{} {}", mtime, file.display());
if mtime > max {
max = mtime;
Expand Down
12 changes: 5 additions & 7 deletions src/cargo/util/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,11 @@ impl Config {
}

/// Get the path to the `rustc` executable
pub fn rustc(&self) -> CargoResult<&Rustc> {
self.rustc.try_borrow_with(|| {
Rustc::new(
self.get_tool("rustc")?,
self.maybe_get_tool("rustc_wrapper")?,
)
})
pub fn new_rustc(&self) -> CargoResult<Rustc> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why rename this here? Is that just cosmetic? Maybe extract it into a separate commit that explains why this makes sense on its own?

Rustc::new(
self.get_tool("rustc")?,
self.maybe_get_tool("rustc_wrapper")?,
)
}

/// Get the path to the `cargo` executable
Expand Down
8 changes: 8 additions & 0 deletions src/cargo/util/paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use std::io;
use std::io::prelude::*;
use std::path::{Component, Path, PathBuf};

use filetime::FileTime;

use util::{internal, CargoResult};
use util::errors::{CargoError, CargoResultExt, Internal};

Expand Down Expand Up @@ -129,6 +131,12 @@ pub fn append(path: &Path, contents: &[u8]) -> CargoResult<()> {
Ok(())
}

pub fn mtime(path: &Path) -> CargoResult<FileTime> {
let meta = fs::metadata(path)
.chain_err(|| internal(format!("failed to stat `{}`", path.display())))?;
Ok(FileTime::from_last_modification_time(&meta))
}

#[cfg(unix)]
pub fn path2bytes(path: &Path) -> CargoResult<&[u8]> {
use std::os::unix::prelude::*;
Expand Down