diff --git a/Cargo.lock b/Cargo.lock index 08ab0affd61..4f5f08f1753 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,6 +6,7 @@ dependencies = [ "atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "cargotest 0.1.0", + "core-foundation 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "crates-io 0.11.0", "crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "curl 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -162,6 +163,23 @@ dependencies = [ "custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "core-foundation" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "core-foundation-sys 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.28 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "core-foundation-sys" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.28 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crates-io" version = "0.11.0" @@ -1003,6 +1021,8 @@ dependencies = [ "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum cmake 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b8ebbb35d3dc9cd09497168f33de1acb79b265d350ab0ac34133b98f8509af1f" "checksum conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299" +"checksum core-foundation 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5909502e547762013619f4c4e01cc7393c20fe2d52d7fa471c1210adb2320dc7" +"checksum core-foundation-sys 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bc9fb3d6cb663e6fd7cf1c63f9b144ee2b1e4a78595a0451dd34bff85b9a3387" "checksum crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97" "checksum curl 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7034c534a1d7d22f7971d6088aa9d281d219ef724026c3428092500f41ae9c2c" "checksum curl-sys 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d5481162dc4f424d088581db2f979fa7d4c238fe9794595de61d8d7522e277de" diff --git a/Cargo.toml b/Cargo.toml index 97914d2cd3a..8bfd2fb52aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,6 +54,9 @@ url = "1.1" [target.'cfg(unix)'.dependencies] openssl = "0.9" +[target.'cfg(target_os = "macos")'.dependencies] +core-foundation = { version = "0.4.4", features = ["mac_os_10_7_support"] } + [target.'cfg(windows)'.dependencies] advapi32-sys = "0.2" kernel32-sys = "0.2" diff --git a/src/cargo/lib.rs b/src/cargo/lib.rs index bfaf0d1bd96..118776c6cfe 100755 --- a/src/cargo/lib.rs +++ b/src/cargo/lib.rs @@ -34,6 +34,8 @@ extern crate tempdir; extern crate termcolor; extern crate toml; extern crate url; +#[cfg(target_os = "macos")] +extern crate core_foundation; use std::fmt; use std::error::Error; diff --git a/src/cargo/ops/cargo_rustc/layout.rs b/src/cargo/ops/cargo_rustc/layout.rs index 83c66e85a07..e5b2baec3f5 100644 --- a/src/cargo/ops/cargo_rustc/layout.rs +++ b/src/cargo/ops/cargo_rustc/layout.rs @@ -108,11 +108,42 @@ impl Layout { }) } + #[cfg(not(target_os = "macos"))] + fn exclude_from_backups(&self, _: &Path) {} + + #[cfg(target_os = "macos")] + /// Marks files or directories as excluded from Time Machine on macOS + /// + /// This is recommended to prevent derived/temporary files from bloating backups. + fn exclude_from_backups(&self, path: &Path) { + use std::ptr; + use core_foundation::{url, number, string}; + use core_foundation::base::TCFType; + + // For compatibility with 10.7 a string is used instead of global kCFURLIsExcludedFromBackupKey + let is_excluded_key: Result = "NSURLIsExcludedFromBackupKey".parse(); + match (url::CFURL::from_path(path, false), is_excluded_key) { + (Some(path), Ok(is_excluded_key)) => unsafe { + url::CFURLSetResourcePropertyForKey( + path.as_concrete_TypeRef(), + is_excluded_key.as_concrete_TypeRef(), + number::kCFBooleanTrue as *const _, + ptr::null_mut(), + ); + }, + // Errors are ignored, since it's an optional feature and failure + // doesn't prevent Cargo from working + _ => {} + } + } + pub fn prepare(&mut self) -> io::Result<()> { if fs::metadata(&self.root).is_err() { fs::create_dir_all(&self.root)?; } + self.exclude_from_backups(&self.root); + mkdir(&self.deps)?; mkdir(&self.native)?; mkdir(&self.incremental)?;