diff options
author | Versus Void | 2017-11-12 20:26:18 +0000 |
---|---|---|
committer | Versus Void | 2017-11-12 20:26:18 +0000 |
commit | 8e2fc1d0a0f0645ca52e33acf109022b9525fa9c (patch) | |
tree | d7ddc10dada79524e0b4e0725616092dcfe12807 | |
download | aur-8e2fc1d0a0f0645ca52e33acf109022b9525fa9c.tar.gz |
Initial
-rw-r--r-- | .SRCINFO | 20 | ||||
-rw-r--r-- | PKGBUILD | 43 | ||||
-rw-r--r-- | color.patch | 171 | ||||
-rw-r--r-- | cross-package-cache.patch | 62 | ||||
-rw-r--r-- | sccache.install | 3 |
5 files changed, 299 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO new file mode 100644 index 000000000000..f28005995ec4 --- /dev/null +++ b/.SRCINFO @@ -0,0 +1,20 @@ +pkgbase = sccache-git + pkgdesc = ccache-like tool. Wraps compiler and avoids compilation when possible. Supports rustc + pkgver = r412.cbb72b8 + pkgrel = 1 + url = https://github.com/mozilla/sccache + install = sccache.install + arch = i686 + arch = x86_64 + license = Apache + makedepends = git + makedepends = rust + source = git+https://github.com/mozilla/sccache/ + source = color.patch + source = cross-package-cache.patch + sha256sums = SKIP + sha256sums = 82ed21e16bb38274bdc4f5ae2e3941c487ddf1859de4984a2610a065928806f5 + sha256sums = 43a7c03ddc6c9a957ad330de2a938aebafebbae350869ad76302ebf8e0719a5d + +pkgname = sccache-git + diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 000000000000..d8e6d387975a --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,43 @@ +# Maintainer: Versus Void <chaoskeeper@mail.ru> +pkgname=sccache-git +pkgver=r412.cbb72b8 +pkgrel=1 +pkgdesc="ccache-like tool. Wraps compiler and avoids compilation when possible. Supports rustc" +arch=(i686 x86_64) +url="https://github.com/mozilla/sccache" +license=('Apache') +makedepends=('git' 'rust') +install=sccache.install +source=('git+https://github.com/mozilla/sccache/' + 'color.patch' + 'cross-package-cache.patch') +sha256sums=('SKIP' + '82ed21e16bb38274bdc4f5ae2e3941c487ddf1859de4984a2610a065928806f5' + '43a7c03ddc6c9a957ad330de2a938aebafebbae350869ad76302ebf8e0719a5d') + +pkgver() { + cd "$srcdir/${pkgname%-git}" + printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)" +} + +prepare() { + cd "$srcdir/${pkgname%-git}" + git apply "$srcdir/color.patch" + git apply "$srcdir/cross-package-cache.patch" +} + +build() { + cd "$srcdir/${pkgname%-git}" + cargo build --release +} + +check() { + cd "$srcdir/${pkgname%-git}" + cargo test --release +} + +package() { + cd "$srcdir/${pkgname%-git}" + cargo install --root "$pkgdir/usr" + rm -f "$pkgdir/usr/.crates.toml" +} diff --git a/color.patch b/color.patch new file mode 100644 index 000000000000..55db31047c1b --- /dev/null +++ b/color.patch @@ -0,0 +1,171 @@ +diff --git a/src/commands.rs b/src/commands.rs +index d5d5e08..3535d6c 100644 +--- a/src/commands.rs ++++ b/src/commands.rs +@@ -36,6 +36,8 @@ use std::io::{ + }; + #[cfg(unix)] + use std::os::unix::process::ExitStatusExt; ++#[cfg(unix)] ++use std::os::unix::io::AsRawFd; + use std::path::{ + Path, + }; +@@ -435,16 +437,64 @@ fn status_signal(_status : process::ExitStatus) -> Option<i32> { + None + } + ++/// Write content of `buf` to `out` assuming it is ANSI colored text ++/// and strip color formatting. ++fn write_all_stripping_colors(out: &mut Write, buf: Vec<u8>) -> Result<()> { ++ let mut start = 0; ++ let mut color_description = false; ++ for (i, &c) in buf.iter().enumerate() { ++ if color_description { ++ if c == b'm' { ++ color_description = false; ++ start = i + 1; ++ } ++ } else { ++ if c == b'\x1b' { ++ color_description = true; ++ if i > start { ++ out.write_all(&buf[start..i])?; ++ } ++ } ++ } ++ } ++ Ok(()) ++} ++ ++/// Check if stream handle is "connected" to terminal. ++#[cfg(unix)] ++fn isatty<T: AsRawFd>(stream: T) -> bool { ++ use libc; ++ unsafe { ++ let res = libc::isatty(stream.as_raw_fd()); ++ return res != 0; ++ } ++} ++ ++#[cfg(not(unix))] ++fn isatty<T>(_: T) -> bool { ++ false ++} ++ + /// Handle `response`, the output from running a compile on the server. Return the compiler exit status. + fn handle_compile_finished(response: CompileFinished, + stdout: &mut Write, +- stderr: &mut Write) -> Result<i32> { ++ stderr: &mut Write, ++ colored_output: Option<bool>) -> Result<i32> { + trace!("handle_compile_finished"); + // It might be nice if the server sent stdout/stderr as the process + // ran, but then it would have to also save them in the cache as + // interleaved streams to really make it work. +- stdout.write_all(&response.stdout)?; +- stderr.write_all(&response.stderr)?; ++ if colored_output.unwrap_or(isatty(io::stdout())) { ++ stdout.write_all(&response.stdout)?; ++ } else { ++ write_all_stripping_colors(stdout, response.stdout)?; ++ } ++ ++ if colored_output.unwrap_or(isatty(io::stderr())) { ++ stderr.write_all(&response.stderr)?; ++ } else { ++ write_all_stripping_colors(stderr, response.stderr)?; ++ } + + if let Some(ret) = response.retcode { + trace!("compiler exited with status {}", ret); +@@ -458,6 +508,34 @@ fn handle_compile_finished(response: CompileFinished, + } + } + ++/// Examines compiler's `cmdline` to decide if we should pass colored output or strip colors from it. ++/// Some(true), None, Some(false) corresponds to "always", "auto", "never" ++fn want_color(cmdline: &Vec<OsString>) -> Option<bool> { ++ for i in 1..cmdline.len() { ++ let arg = cmdline[i].to_str(); ++ // TODO: process -fdiagnostics-color and -fno-diagnostics-color ++ if !arg.map(|s| s.starts_with("--color")).unwrap_or(false) { ++ continue; ++ } ++ ++ let mut arg = arg.unwrap(); ++ if !arg.contains('=') { ++ let s = cmdline[i + 1].to_str(); ++ if s.is_none() { ++ return None; ++ } ++ arg = s.unwrap(); ++ } ++ if arg.ends_with("always") { ++ return Some(true); ++ } else if arg.ends_with("never") { ++ return Some(false); ++ } ++ break; ++ } ++ None ++} ++ + /// Handle `response`, the response from sending a `Compile` request to the server. Return the compiler exit status. + /// + /// If the server returned `CompileStarted`, wait for a `CompileFinished` and +@@ -482,7 +560,7 @@ fn handle_compile_response<T>(mut creator: T, + // Wait for CompileFinished. + match conn.read_one_response() { + Ok(Response::CompileFinished(result)) => { +- return handle_compile_finished(result, stdout, stderr) ++ return handle_compile_finished(result, stdout, stderr, want_color(&cmdline)) + } + Ok(_) => bail!("unexpected response from server"), + Err(Error(ErrorKind::Io(ref e), _)) +diff --git a/src/compiler/rust.rs b/src/compiler/rust.rs +index 608e307..d3c8b4a 100644 +--- a/src/compiler/rust.rs ++++ b/src/compiler/rust.rs +@@ -367,7 +367,6 @@ fn parse_arguments(arguments: &[OsString], cwd: &Path) -> CompilerArguments<Pars + let mut static_link_paths: Vec<PathBuf> = vec![]; + + for item in ArgsIter::new(arguments.iter().map(|s| s.clone()), &ARGS[..]) { +- let arg = item.arg.to_os_string(); + let value = match item.arg.get_value() { + Some(v) => { + if let Ok(v) = OsString::from(v).into_string() { +@@ -378,7 +377,6 @@ fn parse_arguments(arguments: &[OsString], cwd: &Path) -> CompilerArguments<Pars + } + None => None, + }; +- args.push((arg, item.arg.get_value().map(|s| s.into()))); + match item.data { + Some(TooHard) => { + return CompilerArguments::CannotCache(item.arg.to_str().expect( +@@ -458,7 +456,14 @@ fn parse_arguments(arguments: &[OsString], cwd: &Path) -> CompilerArguments<Pars + } + } + } +- Some(PassThrough) => {} ++ Some(PassThrough) => { ++ match item.arg.to_str() { ++ // Skip --color argument, as we unconditionaly add --color=always ++ // and strip color when necessary. ++ Some("--color") => continue, ++ _ => {}, ++ } ++ } + None => { + match item.arg { + Argument::Raw(ref val) => { +@@ -473,7 +478,9 @@ fn parse_arguments(arguments: &[OsString], cwd: &Path) -> CompilerArguments<Pars + } + } + } ++ args.push((item.arg.to_os_string(), item.arg.get_value().map(|s| s.into()))); + } ++ args.push((OsString::from("--color"), Some(OsString::from("always")))); + + // Unwrap required values. + macro_rules! req { diff --git a/cross-package-cache.patch b/cross-package-cache.patch new file mode 100644 index 000000000000..29da43844f02 --- /dev/null +++ b/cross-package-cache.patch @@ -0,0 +1,62 @@ +diff --git a/src/compiler/rust.rs b/src/compiler/rust.rs +index 608e307..5606f24 100644 +--- a/src/compiler/rust.rs ++++ b/src/compiler/rust.rs +@@ -589,6 +596,25 @@ impl<T> CompilerHasher<T> for RustHasher + let cwd = cwd.to_owned(); + let env_vars = env_vars.to_vec(); + let hashes = source_hashes.join3(extern_hashes, staticlib_hashes); ++ ++ // Absolute path to package (crate) being compiled. Usually contains "Cargo.toml" and "target". ++ let mut package_absolute_path = None; ++ // If output directory specified as absolute path ++ if output_dir.has_root() { ++ let mut i = None; ++ // .. find last component with name "target" ++ for (j, p) in output_dir.iter().enumerate() { ++ if p == r"target" { ++ i = Some(j); ++ } ++ } ++ if i.is_some() { ++ // .. and take "target"'s parent as path to package ++ let p : PathBuf = output_dir.iter().take(i.unwrap()).collect(); ++ package_absolute_path = p.to_str().map(|s| s.to_owned()); ++ } ++ } ++ + Box::new(hashes.and_then(move |(source_hashes, extern_hashes, staticlib_hashes)| + -> SFuture<_> { + // If you change any of the inputs to the hash, you should change `CACHE_VERSION`. +@@ -601,8 +627,7 @@ impl<T> CompilerHasher<T> for RustHasher + m.update(d.as_bytes()); + } + // 3. The full commandline (self.arguments) +- // TODO: there will be full paths here, it would be nice to +- // normalize them so we can get cross-machine cache hits. ++ // TODO: normalize paths in arguments so we can get cross-machine cache hits. + // A few argument types are not passed in a deterministic order + // by cargo: --extern, -L, --cfg. We'll filter those out, sort them, + // and append them to the rest of the arguments. +@@ -616,7 +641,20 @@ impl<T> CompilerHasher<T> for RustHasher + iter::once(arg).chain(val.as_ref()) + }) + .fold(OsString::new(), |mut a, b| { +- a.push(b); ++ match package_absolute_path { ++ // If we know absolute path of compiled package ++ Some(ref prefix) => { ++ let b = b.to_str().unwrap_or(""); ++ // .. remove it from all arguments ++ for p in b.split(prefix) { ++ a.push(p); ++ } ++ }, ++ // Otherwise hash args as-is ++ None => { ++ a.push(b); ++ } ++ } + a + }) + }; diff --git a/sccache.install b/sccache.install new file mode 100644 index 000000000000..18619c4d9e85 --- /dev/null +++ b/sccache.install @@ -0,0 +1,3 @@ +post_remove() { + echo 'sccache is removed. You may want to remove $SCCACHE_DIR (~/.cache/sccache by default)' +} |