diff --git a/.travis.yml b/.travis.yml index a3fdd804fb8..a421a7b9334 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,6 +22,7 @@ matrix: - env: TARGET=x86_64-apple-darwin ALT=i686-apple-darwin os: osx + osx_image: xcode9.2 if: branch != master OR type = pull_request - env: TARGET=x86_64-unknown-linux-gnu diff --git a/tests/testsuite/metabuild.rs b/tests/testsuite/metabuild.rs index 6420edac657..c96f0c4b6b6 100644 --- a/tests/testsuite/metabuild.rs +++ b/tests/testsuite/metabuild.rs @@ -2,7 +2,8 @@ use glob::glob; use serde_json; use std::str; use support::{ - basic_lib_manifest, basic_manifest, project, registry::Package, rustc_host, Project, + basic_lib_manifest, basic_manifest, is_coarse_mtime, project, registry::Package, rustc_host, + Project, }; #[test] @@ -212,6 +213,14 @@ fn metabuild_lib_name() { #[test] fn metabuild_fresh() { + if is_coarse_mtime() { + // This test doesn't work on coarse mtimes very well. Because the + // metabuild script is created at build time, its mtime is almost + // always equal to the mtime of the output. The second call to `build` + // will then think it needs to be rebuilt when it should be fresh. + return; + } + // Check that rebuild is fresh. let p = project() .file( diff --git a/tests/testsuite/support/mod.rs b/tests/testsuite/support/mod.rs index f9ddb5380b4..9d818070ce6 100644 --- a/tests/testsuite/support/mod.rs +++ b/tests/testsuite/support/mod.rs @@ -113,11 +113,12 @@ use std::os; use std::path::{Path, PathBuf}; use std::process::{Command, Output}; use std::str; -use std::time::Duration; +use std::time::{self, Duration}; use std::usize; use cargo; use cargo::util::{CargoResult, ProcessBuilder, ProcessError, Rustc}; +use filetime; use serde_json::{self, Value}; use url::Url; @@ -279,8 +280,19 @@ impl ProjectBuilder { self._file(Path::new("Cargo.toml"), &basic_manifest("foo", "0.0.1")) } + let past = time::SystemTime::now() - Duration::new(1, 0); + let ftime = filetime::FileTime::from_system_time(past); + for file in self.files.iter() { file.mk(); + if is_coarse_mtime() { + // Place the entire project 1 second in the past to ensure + // that if cargo is called multiple times, the 2nd call will + // see targets as "fresh". Without this, if cargo finishes in + // under 1 second, the second call will see the mtime of + // source == mtime of output and consider it dirty. + filetime::set_file_times(&file.path, ftime, ftime).unwrap(); + } } for symlink in self.symlinks.iter() { @@ -1510,3 +1522,11 @@ pub fn git_process(s: &str) -> ProcessBuilder { pub fn sleep_ms(ms: u64) { ::std::thread::sleep(Duration::from_millis(ms)); } + +/// Returns true if the local filesystem has low-resolution mtimes. +pub fn is_coarse_mtime() -> bool { + // This should actually be a test that $CARGO_TARGET_DIR is on an HFS + // filesystem, (or any filesystem with low-resolution mtimes). However, + // that's tricky to detect, so for now just deal with CI. + cfg!(target_os = "macos") && env::var("CI").is_ok() +}