Giter Site home page Giter Site logo

mozilla / sccache Goto Github PK

View Code? Open in Web Editor NEW
5.2K 45.0 513.0 5.67 MB

Sccache is a ccache-like tool. It is used as a compiler wrapper and avoids compilation when possible. Sccache has the capability to utilize caching in remote storage environments, including various cloud storage options, or alternatively, in local storage.

License: Apache License 2.0

Shell 1.19% Rust 98.23% C 0.08% C++ 0.40% Makefile 0.01% M4 0.02% CMake 0.03% Cuda 0.05%

sccache's Introduction

Build Status Crates.io Matrix Crates.io dependency status

CodeCov

sccache - Shared Compilation Cache

sccache is a ccache-like compiler caching tool. It is used as a compiler wrapper and avoids compilation when possible, storing cached results either on local disk or in one of several cloud storage backends.

sccache includes support for caching the compilation of C/C++ code, Rust, as well as NVIDIA's CUDA using nvcc, and clang.

sccache also provides icecream-style distributed compilation (automatic packaging of local toolchains) for all supported compilers (including Rust). The distributed compilation system includes several security features that icecream lacks such as authentication, transport layer encryption, and sandboxed compiler execution on build servers. See the distributed quickstart guide for more information.

sccache is also available as a GitHub Actions to facilitate the deployment using GitHub Actions cache.


Table of Contents (ToC)


Installation

There are prebuilt x86-64 binaries available for Windows, Linux (a portable binary compiled against musl), and macOS on the releases page. Several package managers also include sccache packages, you can install the latest release from source using cargo, or build directly from a source checkout.

macOS

On macOS sccache can be installed via Homebrew:

brew install sccache

or via MacPorts:

sudo port install sccache

Windows

On Windows, sccache can be installed via scoop:

scoop install sccache

Via cargo

If you have a Rust toolchain installed you can install sccache using cargo. Note that this will compile sccache from source which is fairly resource-intensive. For CI purposes you should use prebuilt binary packages.

cargo install sccache --locked

Usage

Running sccache is like running ccache: prefix your compilation commands with it, like so:

sccache gcc -o foo.o -c foo.c

If you want to use sccache for caching Rust builds you can define build.rustc-wrapper in the cargo configuration file. For example, you can set it globally in $HOME/.cargo/config.toml by adding:

[build]
rustc-wrapper = "/path/to/sccache"

Note that you need to use cargo 1.40 or newer for this to work.

Alternatively you can use the environment variable RUSTC_WRAPPER:

export RUSTC_WRAPPER=/path/to/sccache
cargo build

sccache supports gcc, clang, MSVC, rustc, NVCC, NVC++, and Wind River's diab compiler. Both gcc and msvc support Response Files, read more about their implementation here.

If you don't specify otherwise, sccache will use a local disk cache.

sccache works using a client-server model, where the server runs locally on the same machine as the client. The client-server model allows the server to be more efficient by keeping some state in memory. The sccache command will spawn a server process if one is not already running, or you can run sccache --start-server to start the background server process without performing any compilation.

You can run sccache --stop-server to terminate the server. It will also terminate after (by default) 10 minutes of inactivity.

Running sccache --show-stats will print a summary of cache statistics.

Some notes about using sccache with Jenkins are here.

To use sccache with cmake, provide the following command line arguments to cmake 3.4 or newer:

-DCMAKE_C_COMPILER_LAUNCHER=sccache
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache

The process for using sccache with MSVC and cmake, depends on which version of cmake you're using. For versions of cmake 3.24 and earlier, to generate PDB files for debugging with MSVC, you can use the /Z7 option. Alternatively, the /Zi option together with /Fd can work if /Fd names a different PDB file name for each object file created. Note that CMake sets /Zi by default, so if you use CMake, you can use /Z7 by adding code like this in your CMakeLists.txt:

if(CMAKE_BUILD_TYPE STREQUAL "Debug")
  string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
  string(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
  string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
  string(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
elseif(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
  string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
  string(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
endif()

By default, sccache will fail your build if it fails to successfully communicate with its associated server. To have sccache instead gracefully failover to the local compiler without stopping, set the environment variable SCCACHE_IGNORE_SERVER_IO_ERROR=1.

For versions of cmake 3.25 and later, to compile with MSVC, you have to use the new CMAKE_MSVC_DEBUG_INFORMATION_FORMAT option, meant to configure the -Z7 flag. Additionally, you must set the cmake policy number 0141 to the NEW setting:

set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT Embedded)
cmake_policy(SET CMP0141 NEW)

Example configuration where we automatically look for sccache in the PATH:

find_program(SCCACHE sccache REQUIRED)

set(CMAKE_C_COMPILER_LAUNCHER ${SCCACHE})
set(CMAKE_CXX_COMPILER_LAUNCHER ${SCCACHE})
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT Embedded)
cmake_policy(SET CMP0141 NEW)

Alternatively, if configuring cmake with MSVC on the command line, assuming that sccache is on the default search path:

cmake -DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache -DCMAKE_MSVC_DEBUG_INFORMATION_FORMAT=Embedded -DCMAKE_POLICY_CMP0141=NEW [...]

And you can build code as usual without any additional flags in the command line, which is useful for IDEs.


Build Requirements

sccache is a Rust program. Building it requires cargo (and thusrustc). sccache currently requires Rust 1.70.0. We recommend you install Rust via Rustup.

Build

If you are building sccache for non-development purposes make sure you use cargo build --release to get optimized binaries:

cargo build --release [--no-default-features --features=s3|redis|gcs|memcached|azure|gha|webdav|oss]

List of actual list of available features can be found in the Cargo.toml file, [features] section.

By default, sccache builds with support for all storage backends, but individual backends may be disabled by resetting the list of features and enabling all the other backends. Refer the Cargo Documentation for details on how to select features with Cargo.

Feature vendored-openssl can be used to statically link with openssl if feature openssl is enabled.

Building portable binaries

When building with the dist-server feature, sccache will depend on OpenSSL, which can be an annoyance if you want to distribute portable binaries. It is possible to statically link against OpenSSL using the openssl/vendored feature.

Linux

Build with cargo and use ldd to check that the resulting binary does not depend on OpenSSL anymore.

macOS

Build with cargo and use otool -L to check that the resulting binary does not depend on OpenSSL anymore.

Windows

On Windows, the binary might also depend on a few MSVC CRT DLLs that are not available on older Windows versions.

It is possible to statically link against the CRT using a .cargo/config.toml file with the following contents.

[target.x86_64-pc-windows-msvc]
rustflags = ["-Ctarget-feature=+crt-static"]

Build with cargo and use dumpbin /dependents to check that the resulting binary does not depend on MSVC CRT DLLs anymore.

When statically linking with OpenSSL, you will need Perl available in your $PATH.


Separating caches between invocations

In situations where several different compilation invocations should not reuse the cached results from each other, one can set SCCACHE_C_CUSTOM_CACHE_BUSTER to a unique value that'll be mixed into the hash. MACOSX_DEPLOYMENT_TARGET and IPHONEOS_DEPLOYMENT_TARGET variables already exhibit such reuse-suppression behaviour. There are currently no such variables for compiling Rust.


Overwriting the cache

In situations where the cache contains broken build artifacts, it can be necessary to overwrite the contents in the cache. That can be achieved by setting the SCCACHE_RECACHE environment variable.


Debugging

You can set the SCCACHE_ERROR_LOG environment variable to a path and set SCCACHE_LOG to get the server process to redirect its logging there (including the output of unhandled panics, since the server sets RUST_BACKTRACE=1 internally).

SCCACHE_ERROR_LOG=/tmp/sccache_log.txt SCCACHE_LOG=debug sccache

You can also set these environment variables for your build system, for example

SCCACHE_ERROR_LOG=/tmp/sccache_log.txt SCCACHE_LOG=debug cmake --build /path/to/cmake/build/directory

Alternatively, if you are compiling locally, you can run the server manually in foreground mode by running SCCACHE_START_SERVER=1 SCCACHE_NO_DAEMON=1 sccache, and send logging to stderr by setting the SCCACHE_LOG environment variable for example. This method is not suitable for CI services because you need to compile in another shell at the same time.

SCCACHE_LOG=debug SCCACHE_START_SERVER=1 SCCACHE_NO_DAEMON=1 sccache

Interaction with GNU make jobserver

sccache provides support for a GNU make jobserver. When the server is started from a process that provides a jobserver, sccache will use that jobserver and provide it to any processes it spawns. (If you are running sccache from a GNU make recipe, you will need to prefix the command with + to get this behavior.) If the sccache server is started without a jobserver present it will create its own with the number of slots equal to the number of available CPU cores.

This is most useful when using sccache for Rust compilation, as rustc supports using a jobserver for parallel codegen, so this ensures that rustc will not overwhelm the system with codegen tasks. Cargo implements its own jobserver (see the information on NUM_JOBS in the cargo documentation) for rustc to use, so using sccache for Rust compilation in cargo via RUSTC_WRAPPER should do the right thing automatically.


Known Caveats

General

  • Absolute paths to files must match to get a cache hit. This means that even if you are using a shared cache, everyone will have to build at the same absolute path (i.e. not in $HOME) in order to benefit each other. In Rust this includes the source for third party crates which are stored in $HOME/.cargo/registry/cache by default.

Rust

  • Crates that invoke the system linker cannot be cached. This includes bin, dylib, cdylib, and proc-macro crates. You may be able to improve compilation time of large bin crates by converting them to a lib crate with a thin bin wrapper.
  • Incrementally compiled crates cannot be cached. By default, in the debug profile Cargo will use incremental compilation for workspace members and path dependencies. You can disable incremental compilation.

More details on Rust caveats

Symbolic links

  • Symbolic links to sccache won't work. Use hardlinks: ln sccache /usr/local/bin/cc

Storage Options

sccache's People

Contributors

aidanhs avatar ajiob avatar alexcrichton avatar alexei-barnes avatar alphare avatar chmanchester avatar cosmichorrordev avatar cramertj avatar dependabot[bot] avatar drahnr avatar emabrey avatar emilio avatar figsoda avatar flxo avatar foobarwidget avatar froydnj avatar glandium avatar jdygert-spok avatar jschwe avatar luser avatar messense avatar nobodyxu avatar robertmaynard avatar ry avatar saviq avatar sigiesec avatar sylvestre avatar tottoto avatar xanewok avatar xuanwo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sccache's Issues

Add support for JSON stats output

I'd like to have the Firefox build system parse the stats so we can get the cache hit rate into our Perfherder metrics, but I don't really want to parse the current text output. It'd be nicer if we could make it spit out the stats as JSON. If clap supports it, it'd be cool to turn the option into --show-stats[=FORMAT], where FORMAT defaults to text, but also accepts json.

Clarify which Rust version is required

In .travis.yml I see that testing is done on Rust 1.13, while the README says that Rust 1.12 is required.

So there are two possible cases now:

  • README is wrong, and indeed Rust 1.13 is required. Then it should be changed.
  • README is correct, and Rust 1.12 suffices. Then however testing should be done on 1.12 to make sure nothing regresses.

[feature-request] Support for S3 prefixes

Hi,

I was discussing TC support for sscache with @gregarndt recently, and we found that it would be extremely nice if sscache supported S3 prefixes.

Essentially, instead of giving sscache just a bucket we would like to give it bucket and a prefix.
Such that all keys are stored under the given prefix in the bucket.

In taskcluster-auth we have an end-point that given a scope auth:aws-s3:read-write:<bucket>/<prefix> will return temporary S3 credentials with read-write access to a specific subfolder/prefix on S3.
We already need a bucket for every region, not having to do separate buckets for try and production, would be nice. Instead we could just use separate prefixes, which we can grant access to using scopes.

Notably, this will make it a lot easier if someone wanted to experiment with sscache and wanted isolated storage to avoid poisoning try or production. As giving such isolated storage would be a matter of issuing a scope, rather than creating a new bucket in every region.

http://docs.taskcluster.net/auth/api-docs/#awsS3Credentials

Support compiling and fetching from cache in parallel

If we implement #30 to let local developers pull from the S3 cache, performance is going to be variable depending on network timings. It'd be nice as a future optimization if we could run a compilation in parallel with a cache fetch, and use whichever result returns first. We might want this to have a heuristic where if it finds that some percentage of the time one strategy wins that it will prefer that strategy. Like if someone is building with a decent CPU and slow network, we might want to limit the number of concurrent fetches from S3 and just run local builds for any other compile requests that come in.

Document minimum required version of Rust + Cargo in README

I trying to build on ubuntu 16.04 and getting and error. Is there any chance you could provide some more detailed instruction about what dependencies need to be installed. rust, docker? what is the prefered install method?

Unable to find image 'luser/rust-musl-builder:latest' locally
latest: Pulling from luser/rust-musl-builder
357ea8c3d80b: Pull complete
a3ed95caeb02: Pull complete
17eec89006f1: Pull complete
b90aacaf5477: Pull complete
09416fd865ce: Pull complete
5e7229b6f848: Pull complete
92f5a003f128: Pull complete
859d74d4ebb3: Pull complete
caabe158e9f8: Pull complete
Digest: sha256:60e50d539670cc756ef95f686ec82fe848e4d341c6017313876332cc737f137c
Status: Downloaded newer image for luser/rust-musl-builder:latest
error: Permission denied (os error 13)

tried modifying the build script to run with sudo but no luck. i'm new to rust and docker so could be i'm missing something very obvious.

CI checklist

  • Travis-CI builds+tests for Linux
  • Travis-CI builds+tests for OS X
  • Appveyor builds+tests for Windows

Add `SCCACHE_RECACHE` support

@glandium points out that we shouldn't start using sccache2 in production without adding support for SCCACHE_RECACHE, which forces compiles to rebuild even if a cache entry is available. This is useful for times when bad data gets into the cache.

Rusoto now has a standalone credentials module

It looks like rusoto support was dropped in 657cb89 for various reasons. However, you retained the rusoto credentials code in the form of an extracted file (src/simples3/credential.rs).

It might interest you to know that rusoto now has a standalone credentials module, which is published and functions independently of the main rusoto module. If you are interested in using it in your project, I can look into porting the modifications you've made to your version of the module into ours.

Implement an equivalent to `CCACHE_BASEDIR`

CCACHE_BASEDIR allows ccache to get cache hits for the same source files stored at different paths, which is useful for developers building from different source trees:
https://ccache.samba.org/manual.html#_configuration_settings

We want this so that we can get cross-branch cache hits on our buildbot builds, which have the branch name in their build directory, and we also want this so we can get cache hits from the S3 cache for local developers' builds.

Use `bytes` crate for buffering data

I left a pair of FIXME comments in the server source:
https://github.com/luser/sccache2/blob/1fb11fc53ec7ddae4663ea6dea6ad3afa29b01a9/src/server.rs#L695
https://github.com/luser/sccache2/blob/1fb11fc53ec7ddae4663ea6dea6ad3afa29b01a9/src/server.rs#L742

I didn't get around to sorting those out, but it'd be nice to use the bytes crate for buffering data:
https://github.com/carllerche/bytes

We probably want to use MutByteBuf in this case:
http://carllerche.github.io/bytes/bytes/buf/struct.MutByteBuf.html

test::system::test_sccache_command fails

	thread 'test::system::test_sccache_command' panicked at 'Error: sccache binary not found at `"/home/glandium/sccache/target/debug/deps/sccache". Do you need to run `cargo build`?', src/test/system.rs:197

Interestingly, there is no sccache executable in that directory, only sccache-somehash, so the assumption in system.rs doesn't work on my system (using rust/cargo Debian packages).

Support caching MSVC compiles with -showIncludes

We currently treat -showIncludes as a non-cacheable MSVC option. I ported this directly from the Python implementation. Unfortunately a lot of build tools use this to produce dependency info, and it may not be possible to work around that. @alexcrichton ran into this trying to get sccache working for the LLVM build in Rust.

I suspect the issue here is that the output from -showIncludes is generated when we run the preprocessor, but we cache the output of running the compiler on the already-preprocessed output. It might be a little weird, but I think we could save all the extra output lines and just prepend them to the compiler output if the original command included -showIncludes.

@glandium, is there anything I'm missing there?

building locally on windows spawns window for every cl.exe invocation

I am trying to use sccache2 on my local windows 10 machine. I put this in my mozconfig:

ac_add_options --with-ccache=sccache.exe
export _DEPEND_CFLAGS='-deps$(MDDEPDIR)/$(@F).pp'
mk_add_options "export CC_WRAPPER="
mk_add_options "export CXX_WRAPPER="
mk_add_options "export COMPILE_PDB_FLAG="
mk_add_options "export HOST_PDB_FLAG="
mk_add_options "export MOZ_DEBUG_FLAGS=-Z7"

It seems to be working, but there is a major usability problem. Every invocation of cl.exe spawns a new window. These appear and disappear rapidly changing the focus constantly. This makes the machine pretty useless until the compile ends.

Release on crates.io

I actually did this. I am happy to pull it down but I got sick of checking out the github in scripts.

diff --git a/Cargo.toml b/Cargo.toml
index b985929..8193bd1 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -2,6 +2,10 @@
 name = "sccache"
 version = "0.1.0"
 authors = ["Ted Mielczarek <[email protected]>"]
+license = "Apache-2.0"
+description = "Sccache is a ccache-like tool. It is used as a compiler wrapper and avoids compilation when possible, storing a cache in a remote storage using the S3 API."
+repository = "https://github.com/mozilla/sccache/"
+
 
 [dependencies]
 app_dirs = "1.1.1"

Was all I needed. Now I can cargo install sccache

Fix background server invocation on Windows

Right now if you run sccache and a server isn't already running it spawns a process to start one:
https://github.com/luser/sccache2/blob/cd0689587de98ee720a0b5acba4e078721e7a87d/src/commands.rs#L141

Unfortunately Rust doesn't provide an API to detach that process from the current console on Windows. It has support for doing so internally, but that's not exposed via API, and the way it's implemented it's not possible to trigger that codepath without unsafe casts or some other horrible thing:
https://github.com/rust-lang/rust/blob/db2939409db26ab4904372c82492cd3488e4c44e/src/libstd/sys/windows/process.rs#L59

This breaks using sccache for an actual build without having an existing server running, because configure will hang on the first compiler invocation.

Global logging panic with windows

I get this after I install sccache as a user on windows

C:\Program Files (x86)\Google\Cloud SDK>set RUST_BACKTRACE=1

C:\Program Files (x86)\Google\Cloud SDK>sccache
thread 'main' panicked at 'Failed to initialize logging', C:\Users\posix4e\.cargo\registry\src\github.com-1ecc6299db9ec823\sccache-0.1.0\src\main.rs:94
stack backtrace:
   0:     0x7ff7562ed7ea - <unknown>
   1:     0x7ff7562eb07a - <unknown>
   2:     0x7ff7562eba5d - <unknown>
   3:     0x7ff7560c6f49 - <unknown>
   4:     0x7ff7561357f8 - <unknown>
   5:     0x7ff7562f0311 - <unknown>
   6:     0x7ff7562ec04a - <unknown>
   7:     0x7ff7563142e8 - <unknown>
   8:     0x7ff9d1428363 - BaseThreadInitThunk

Startup of server fails on OSX because of set_read_timeout

The set_read_timeout on the Unix socket fd with a duration of 500ms fails on OSX. This is probably the reason why the OSX Travis builds fails atm. I also wrote comment in the path.

misc/rust/sccache ‹master› export SCCACHE_LOG_LEVEL=trace
misc/rust/sccache ‹master› export SCCACHE_ERROR_LOG=/dev/stdout
misc/rust/sccache ‹master› ./target/debug/sccache --start-server
[2017-01-28][17:15:50][TRACE] parse
[2017-01-28][17:15:50][TRACE] Command::StartServer
Starting sccache server...
[2017-01-28][17:15:50][TRACE] run_server_process
[2017-01-28][17:15:50][TRACE] parse
[2017-01-28][17:15:50][TRACE] Command::InternalStartServer
Failed to start server: Invalid argument (os error 22)

commands.rs:

156             let (mut stream, _) = try!(listener.accept());
157             try!(stream.set_read_timeout(Some(Duration::from_millis(500))));
158             let mut buffer = [0; 1];
159             try!(stream.read_exact(&mut buffer));

Change Github Project Description

It's currently "Rewrite of sccache in Rust", but this became the defacto sccache, so we should probably have a description saying what it is.

Submit data to cache after returning compilation results

There's a TODO in the compiler code for this:
https://github.com/luser/sccache2/blob/0535bf514947f68e6aa26a53bb9fd4d9da9bb1e2/src/compiler/compiler.rs#L276

The original sccache returns the compile results and then does the submission, so that the latency of submitting to S3 doesn't block the compiler invocation. sccache2 should do the same thing.

This will require reworking the invocation of this function a bit:
https://github.com/luser/sccache2/blob/0946c5190375be3a9dc73d1433a0e9c9d9ad7dff/src/server.rs#L455

Currently it's run on a background thread from the server, and the result is sent back over a channel. We'd have to perhaps allow for multiple results from a task, maybe by having their return type be something that implements Iterator? It's not going to look quite as nice as the Python code since that's using a generator and Rust doesn't have a straight equivalent.

Support rustup overrides properly

For the initial cut at Rust support we're not handling rustup overrides, since we're caching compiler info purely by compiler path. With rustup, the same compiler binary can invoke different Rust toolchains depending on the cwd, so we'll have to handle that somehow.

I was thinking of using a two-tier cache where we cache the "is this a Rust compiler?" result in the server code as we currently do, but then internally check for the presence of a rustup binary next to rustc and run rustup which rustc or something in the compile cwd to locate the actual compiler in use, and then have a cache of compilers using that path.

Fail compiles on misconfigured S3 bucket

We discussed this on IRC, but a nifty feature to help debug misconfiguration of S3 credentials would be to fail compilations (perhaps with an error message) if the S3 cache management fails.

I ran into two separate problems during integration:

  • First I forgot to make the whole S3 bucket public-readable
  • Next, I used the wrong credentials by accident

I think both cases have a fairly predictable error which can flag "misconfiguration" as opposed to transient error, and it'd definitely help working through the setup!

Save stats to disk

Currently the stats are only saved in-memory, so when the server shuts down they're lost. We should save them to disk like the Python sccache did. This is mostly useful for local developers, where they might expect the stats to be persistent like ccache's stats. If we do this we should also add a --zero-stats option to match ccache.

sccache crashes

Sccache is crashing during compilation, back-trace and full log is in the attachment.

It is reproducable by running sccache:

env RUST_BACKTRACE=1 SCCACHE_START_SERVER=1 SCCACHE_NO_DAEMON=1 SCCACHE_BUCKET=foo SCCACHE_LOG_LEVEL=trace SCCACHE_ENDPOINT=127.0.0.1 ./sccache

and compiling Qt5 (dev), the first compilation error is caused by:

g++ -c -pipe -pthread -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -O3 -std=c++1z -fvisibility=hidden -fvisibility-inlines-hidden -Wall -W -Wvla -Wdate-time -Wshift-overflow=2 -Wduplicated-cond -Werror -Wno-error=cpp -Wno-error=deprecated-declarations -Wno-error=strict-overflow -D_REENTRANT -fPIC -DQT_NO_LIBINPUT -DQT_NO_TSLIB -DQT_NO_USING_NAMESPACE -DQT_NO_FOREACH -DQT_USE_COMBINED_ALLOCATOR=1 -DELF_INTERPRETER=\"/lib64/ld-linux-x86-64.so.2\" -DQT_USE_ICU -DQT_HAVE_POLL -DQT_HAVE_PPOLL -DQT_BUILD_CORE_LIB -DQT_BUILDING_QT -DQT_NO_CAST_TO_ASCII -DQT_ASCII_CAST_WARNINGS -DQT_MOC_COMPAT -DQT_USE_QSTRINGBUILDER -DQT_DEPRECATED_WARNINGS -DQT_DISABLE_DEPRECATED_BEFORE=0x050000 -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -DQT_NO_DEBUG -I/home/nierob/dev/qtbase/src/corelib -I. -Iglobal -I/home/nierob/dev/qtbase/src/3rdparty/harfbuzz/src -I/home/nierob/dev/qtbase/src/3rdparty/md5 -I/home/nierob/dev/qtbase/src/3rdparty/md4 -I/home/nierob/dev/qtbase/src/3rdparty/sha3 -I/home/nierob/dev/qtbase/src/3rdparty/double-conversion/include -I/home/nierob/dev/qtbase/src/3rdparty/double-conversion/include/double-conversion -I/home/nierob/dev/qtbase/src/3rdparty/forkfd -I../../include -I../../include/QtCore -I../../include/QtCore/5.8.0 -I../../include/QtCore/5.8.0/QtCore -I.moc -I/home/nierob/dev/qtbase/mkspecs/linux-g++ -o .obj/qglobal.o /home/nierob/dev/qtbase/src/corelib/global/qglobal.cpp

sha1: 8c083df
rustc 1.14.0 (e8a012324 2016-12-16)
Linux, Debian 64

sccache.log.gz

Support MSVC compiler options starting with "/"

There already is a TODO in msvc.rs mentioning this, but I think it is good to have an issue open for better visibility.

It seems quite straight-forward to add support for options starting with / as well.

See: https://msdn.microsoft.com/en-us/library/610ecb4h.aspx

Options are specified by either a forward slash (/) or a dash (–).

Additionally, it might be good to also support options that accept arguments after a space.

If an option takes an argument, the option's description documents whether a space is allowed between the option and the arguments

For example, I have encountered defines being set like /D WIN32 instead of /DWIN32. Maybe this should have a separate issue.

Look into replacing protobuf with serde

We're using protobuf for the client/server protocol right now. It's kind of a pain. We should look into just using serde instead, and defining a few Rust structs to serialize over the socket. I know serde is a bit difficult to use in non-nightly Rust, but if we get it working with nightly and it looks good we can jump through the hoops to make it work in stable Rust.

Auto-detect S3 bucket region instead of requiring `SCCACHE_REGION`

The Python implementation takes SCCACHE_BUCKET and somehow uses the right region, or there's something I'm missing. It's possible to detect the region for a bucket (HEAD bucket will return it in the headers), but I can't figure out a straightforward way to do this in rusoto.

@glandium is there anything I'm missing here in the Python implementation?

Preprocessor warnings are hidden

sccache hides preprocessor warnings. In the following snippet a two line c file is compiled with and without sccache using clang (Apple LLVM version 8.0.0 (clang-800.0.42.1)) and the current HEAD of sccache. As you can see the warning from the #warning directive is not on stdout/stderr. The second run with sccache shows that the behaviour is the same with or without a hit. I did the same test with a double #define - same result.

~/tmp  cat test.c
#warning foo
int bar() {}

~/tmp  clang -c -o test.o test.c
test.c:1:2: warning: foo [-W#warnings]
#warning foo
 ^
test.c:2:12: warning: control reaches end of non-void function [-Wreturn-type]
int bar() {}
           ^
2 warnings generated.
~/tmp  sccache clang -c -o test.o test.c
test.c:2:12: warning: control reaches end of non-void function [-Wreturn-type]
int bar() {}
           ^
1 warning generated.
~/tmp  sccache clang -c -o test.o test.c
test.c:2:12: warning: control reaches end of non-void function [-Wreturn-type]
int bar() {}
           ^
1 warning generated.

A possible solution could be to concat stderr from the preprocessor run with stdou/stderr from the compilation step. I'm not 100% sure whether this would give the exact same output as compiling the original file.

Add tests for S3 storage using minio

We don't currently have any automated tests for S3 storage, because we currently hardcode the AWS endpoint URL and I didn't feel like writing tests that ran against a live S3 bucket. Someone recently pointed out minio as a useful mock S3 implementation. Once we get #27 landed we should be able to write some tests that run against a local minio instance.

I don't know if there's a convention for Rust tests that require additional programs--it'd be great to be able to skip the tests if minio is not available.

Send environment variables from client to server for compiler invocations

@alexcrichton noted that sccache breaks an assumption that the Rust build system has about invoking MSVC, namely that it can set environment variables like INCLUDE and LIB on a per-compile basis to avoid having to have them set in the shell. Currently sccache uses the environment that the server process was invoked with as the environment for running all compiler processes, but that doesn't have to be the case. We can send the environment over with the compile request and use it for invoking the compiler.

We might need to add certain environment variables to the hash key to make this work, I'd have to look into it. INCLUDE should only affect the preprocessor, and that output is already included in the hash key. Looking at the other CL environment variables, it doesn't look like there's anything else that would cause problems.

Store cache timing statistics

The storage backend should store cache timing statistics, especially for S3 requests. We'll probably have to add something to the Storage trait to expose this data.

[question] Does this support STS credentials?

AWS temporary credentials STS comes with a SessionToken that must be attached to all requests.
It would be rather nice if sscache was to supports this.

Note: I know this is work in progress. But ideally the readme should document the command line arguments, so it's easy to deploy and configure.

Trace not tracee enough

I'm getting a hang building brave. It'd be nice if trace showd every command running through sccache? What do you think?

Feature parity with sccache1

  • Client/server protocol
  • Detect known compilers
  • Execute compilation on server
  • Fallback compilation on client
  • Support compilers in $PATH
  • Cache compiler output from hash of preprocessor
  • Parse compiler commandline, reject commands with uncacheable options
  • Local disk cache
  • Support GCC
  • Support MSVC
  • Support -deps for MSVC
  • may_cache result for MSVC
  • Support clang
  • Retry with clang when -Werror causes failure compiling preprocessed output
  • Configurable options for automation
  • Amazon S3 cache
  • Server shutdown after 600s of no activity

Switch to using `which` crate

There's a which crate on crates.io: https://crates.io/crates/which

I originally looked at using it but it didn't support all the things I needed, so I wrote my own implementation in commands.rs. I submitted my changes upstream and they've been merged and made it to the latest release, so we can remove the implementation in sccache2 and just use the external crate now.

Improve formatting of `--show-stats`

The formatting of the output of sccache --show-stats is kind of wonky since I added the Cache Location field. On my Linux machine it looks like:

$ ./target/debug/sccache --show-stats
Cache location                                    Local disk: "/tmp/sccache_cache"
Compile requests                                                                 1
Compile requests executed                                                        1
Cache hits                                                                       0
Cache misses                                                                     1
Cache read errors                                                                0
Compilation failures                                                             0
Cache errors                                                                     0
Successful compilations which could not be cached                                0
Non-cacheable calls                                                              0
Non-compilation calls                                                            0
Unsupported compiler calls                                                       0

On my Windows machine it's even worse:

$ ./target/debug/sccache.exe --show-stats
Cache location                                    Local disk: "C:\\Users\\TEDMIE~1\\AppData\\Local\\
Temp\\sccache_cache"
Compile requests
                   0
Compile requests executed
                   0
Cache hits
                   0
Cache misses
                   0
Cache read errors
                   0
Compilation failures
                   0
Cache errors
                   0
Successful compilations which could not be cached
                   0
Non-cacheable calls
                   0
Non-compilation calls
                   0
Unsupported compiler calls
                   0

The code that prints the stats output is here:
https://github.com/luser/sccache2/blob/8b8bbc339c7430583a0e48da9e3715084e5b0e77/src/commands.rs#L265

It tries to be fancy and align all of the values, but it'd probably be better to only align values that are a number and not a string (like the cache location). Also, we should probably change the name of Successful compilations which could not be cached, since that makes the output a bit longer than it needs to. Those strings are defined here:
https://github.com/luser/sccache2/blob/8b8bbc339c7430583a0e48da9e3715084e5b0e77/src/server.rs#L129

I don't know exactly what ccache does to align its output, but it looks nicer:

$ ccache -s
cache directory                     /home/luser/.ccache
cache hit (direct)                 14043
cache hit (preprocessed)           62635
cache miss                        382817
called for link                    55946
called for preprocessing            5417
multiple source files                703
compile failed                      7642
preprocessor error                  5592
bad compiler arguments              1578
unsupported source language         7729
autoconf compile/link              32244
unsupported compiler option          980
no input file                      96810
files in cache                     23731
cache size                           8.9 Gbytes
max cache size                      10.0 Gbytes

Add support for caching Rust crate compilation

I outlined a plan for this in a cargo issue.

The big items here are:

  • make sccache able to detect rustc as a compiler
  • Write a hash function for rustc compiler invocations that uses the things listed in that plan as input. We'll need to refactor the cache lookup code slightly since it currently expects to run a preprocessor and hash that output. We will probably want to make the "generate a hash key" bit generic per-compiler, and then provide a default implementation that does what we currently do for C++ compilers, and a separate implementation for rustc.

Get rid of `Storage::start_put`

The start_put / finish_put API is a lot less useful than it used to be. Originally DiskCache would return a CacheWrite that was writing directly to a File, so it didn't have to buffer the zip in-memory first. When I added the LRUDiskCache I wound up making DiskCache just hand out a Cursor from start_put instead, so all the cache implementations are returning the same thing from start_put now.

We should probably just get rid of start_put and make the code that currently calls it just call CacheWrite::new() directly.

support for gcc compiler options being a file via @file option

we are using a file to specify our compiler options to gcc via the @file option. I have tested a trivial compilation and as soon as I do this I see the stats counting this compile as Non-cacheable calls. I believe it's hitting the gcc.rs:109. What I find misleading the the comment in the previous line talking about using a response file.

any command line parameter starting with @ should be a file with the gcc options. Would be awesome to have support for that.

https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html#Overall-Options
@file
Read command-line options from file. The options read are inserted in place of the original @file option. If file does not exist, or cannot be read, then the option will be treated literally, and not removed.
Options in file are separated by whitespace. A whitespace character may be included in an option by surrounding the entire option in either single or double quotes. Any character (including a backslash) may be included by prefixing the character to be included with a backslash. The file may itself contain additional @file options; any such options will be processed recursively.

SCCACHE_ERROR_LOG + trace logs == doesn't work on windows

Unfortuantely with SCCACHE_ERROR_LOG and a trace log level nothing's actually emitted on Windows.

In libstd we fetch and cache stderr in a global. This means that when the process starts with a missing handle (via the spawning of the server process in sccache) if stderr() is used then libstd will cache a missing handle and forever not print anything to stderr.

That means that later when SetStdHandle is called this doesn't actually propagate back into the standard library and logs still don't show up.

Conveniently debug logs don't attempt to print anything until after SetStdHandle is called, but trace logs cause attempts to print (and caching a stale value) ahead of time and cache an empty handle.

I'd consider this also a bug in libtsd, but figured I'd open here as well if anyone's running into the issue.

Fix Windows compiler invocation to not create new console windows

235239a changed how we spawn the sccache server process on Windows to make it detached, but in the process it made it so that when the server spawns a compiler process it creates a new console window. This is noticeable if you run cargo test test_sccache_command on Windows, you'll see several console windows pop up.

Rework server to use tokio

In the intervening time since I started writing sccache2, the futures crate had its first release, and the tokio-core crate was released alongside it. The API for that is much nicer than the mio 0.5 API that sccache2 is currently using, and it'd mean we could use Futures instead of my half-baked Task implementation. I've already pulled in future for one thing, we might as well just refactor the whole server to use tokio.

Silent fails building brave on windows with sccache

Here at www.brave.com we build our product on OSX and linux with sccache support. On windows setting the env for logging to trace seems to get us no extra logging. Also it seems as though all the calls are not supported

browser-laptop-bootstrap>type npm-debug.log.2956940901 D:\browser-laptop-bootstrap>sccache -s Max cache size 10 GiB Cache size 0 bytes Cache location Local disk: "C:\\Users\\posix4e\\AppData\\Local\\Mozilla\\sccache" Compile requests 657 Compile requests executed 0 Cache hits 0 Cache misses 0 Forced recaches 0 Cache read errors 0 Cache write errors 0 Compilation failures 0 Cache errors 0 Successful compilations which could not be cached 0 Non-cacheable calls 0 Non-compilation calls 0 Unsupported compiler calls 657 Average cache write 0.000 s Average cache read miss 0.000 s Average cache read hit 0.000 s

How do i begin to debug this?

Two-tier caching / Multiple cache levels

We'd like to be able to use a two-tier cache setup, where sccache can use one cache source as a read-only cache, and another as a read+write cache. This would be useful for two scenarios:

  1. Allowing try server builds to get cache hits from the tier-3 branch buckets.
  2. Allowing local developers to get cache hits from the buckets we use for CI.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.