recc is the Remote Execution Caching Compiler. It is a cross between ccache and distcc using the Remote Execution APIs.
When invoked with a C/C++ compilation command, it will use the APIs to communicate with a Remote Execution service (such as BuildGrid) to
first determine whether the same build has been done before and is cached. If the build is cached remotely, download the result. Otherwise, enqueue
the build to be executed remotely using the same execution service which will then dispatch the job to a worker, such as buildbox-worker.
More information about recc and BuildGrid can be found in the presentation we gave at Bazelcon 2018, and on this blog post.
recc is in active development and in use at Bloomberg. On Linux it primarily supports gcc; and on Solaris/Aix it supports vendor compilers.
Clang support is currently (very) experimental.
For information regarding contributing to this project, please read the Contribution guide.
Currently recc relies on:
Follow the instructions to install buildbox-common using the README located here: https://gitlab.com/BuildGrid/buildbox/buildbox-common
Once buildbox-common is installed, you should have the necessary dependencies to run recc.
Once you've installed the dependencies, you can compile recc using the following commands:
$ mkdir build
$ cd build
$ cmake .. && makeIf you want to set the instance name at compile time, then you may pass in a special flag:
cmake -DDEFAULT_RECC_INSTANCE=name_you_want ../ && makeNote that on macOS, you'll need to manually specify the locations of OpenSSL and GoogleTest when running CMake:
$ cmake -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -DGTEST_SOURCE_ROOT=/wherever/you/unzipped/googletest/to .. && makeThe optional flag -DRECC_VERSION allows setting the version string that recc
will attach as metadata to its request headers. If none is set, CMake will try
to determine the current git commit and use the short SHA as a version value.
(If that fails, the version will be set to "unknown".)
You can define RECC_DEBUG while running cmake to include additional debugging info in the final binaries.
Just include -DRECC_DEBUG when invoking cmake.
Compiling with this flag will include the function name and line number every time RECC_LOG_VERBOSE is called.
(Note that you still need to run in verbose mode to receive the output)
To run tests, first compile the project (see above), then run:
$ make test/usr/include/'s has been deprecated on Mojave, for certain tests to work, you must install Apple command line tools.
$ xcode-select --install
$ sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /You can compile recc statically with the -DBUILD_STATIC=ON option. All of recc's dependencies must be available as static libraries (.afiles) and visible in ${CMAKE_MODULE_PATH}.
recc is a command-line utility that runs compile commands on a Remote
Execution server. To run it, you'll first need to set up an execution server
for it to talk to. Then, set the appropriate configuration options and call
recc with a compile command.
recc should be compatible with any server that implements Bazel's
Remote Execution API V2. It is primarily tested against BuildGrid,
so follow the instructions there to start a server.
The Bazel Buildfarm project is also working on a Remote Execution server,
but at time of writing it uses version 1 of the API and so cannot be used with
recc.
You'll also need to set up a build worker to actually run the build jobs you submit. BuildGrid provides one you can use.
This repository used to contain a reference worker called
reccworker, but that has since been deprecated and removed.
Some examples of workers are: buildbox-worker, bgd-bot
recc’s default behavior can be overridden by configuration file settings,
which in turn can be overridden by environment variables with names starting
with RECC_. recc by default reads configuration options from the following
places, applying settings bottom-up, with 1 being the last applied
configuration (i.e. if an option is set in multiple files, the one higher on
this list will be the effective one):
-
Environment variables
-
${cwd}/recc/recc.conf -
~/.recc/recc.conf -
${RECC_CONFIG_PREFIX_DIR}/recc.confwhen specified at compile time with-DRECC_CONFIG_PREFIX_DIR=/path/to/custom/prefix -
${INSTALL_DIR}/../etc/recc/recc.conf
Configuration files are in a simple “key=value” format, one setting per line. Lines starting with a hash sign are comments. Blank lines are ignored.
At minimum, you'll need to set RECC_SERVER to the URI of your Remote:
# set execution server to http://localhost:12345
server=http://localhost:12345
Map configuration variables can be set similarly
# set OS and compiler architecture targets for remote build.
remote_platform_OSFamily=linux
remote_platform_arch=x86_64
For a full list of the environment/configuration variables recc accepts and what they do, run
recc --help.
If variables are specified in the configuration file, the prefix RECC_ should not be included.
If you'd like to set environment variables, an example is specified below:
$ export RECC_SERVER=localhost:12345You may also want to set RECC_VERBOSE=1 to enable verbose output.
A common problem that can hinder reproducibility and cacheabilty of remote builds, are dependencies that are local to the user, system, and set of machines the build command is sent from. To solve this issue, recc supports specifying the RECC_PREFIX_MAP configuration variable, allowing changing a prefix in a path, with another one. For example, replacing all paths with prefixes including /usr/local/bin with /usr/bin can be done by specifying:
export RECC_PREFIX_MAP=/usr/local/bin=/usr/binSupports multiple prefixes by specifying : as a delimiter.
Guidelines for replacement are:
- Both keys/values for RECC_PREFIX_MAP must be absolute paths.
- Prefix candidates are matched from left to right, and once a match is found it is replaced and no more prefix replacement is done.
- Path prefix replacement happens before absolute to relative path conversion.
When using RECC_DEPS_GLOBAL_PATHS, paths to system files (/usr/include, /opt/rh/devtoolset-7, etc) are included as part of the input root. To avoid these system dependencies potential conflicting with downstream build environment dependencies, there is now a method to filter out dependencies based on a set of paths. Setting the RECC_DEPS_EXCLUDE_PATHS environment variable with a comma-delimited set of paths(used as path prefixes) will be used as a filter to exclude those dependencies:
export RECC_DEPS_EXCLUDE_PATHS=/usr/include,/opt/rh/devtoolset-7NOTE: At time of writing, RBE is still in alpha and instructions are subject to change
To run recc against Google's RBE instead of a self hosted Remote Execution
Server, the following options need to be set:
RECC_SERVER_AUTH_GOOGLEAPI=1to enable using Google's default authenticationRECC_INSTANCE=projects/<project_ID>/instances/default_instanceWhere <project_ID> is the id of your Google Cloud Platform projectRECC_SERVER=remotebuildexecution.googleapis.comRECC_REMOTE_PLATFORM_CONTAINER_IMAGE=docker://gcr.io/cloud-marketplace/...The Docker image from google's cloud registry for the worker to run in
You will also need to be authenticated with GCP, which can happen several ways. See https://cloud.google.com/docs/authentication/ for instructions on how to do that.
Once you've started the server and set the environment variables, you're ready
to call recc with a compile command:
$ recc /usr/bin/gcc -c hello.c -o hello.orecc only supports compilation, not linking, so be sure to include the -c
argument in your command. If recc doesn't think your command is a compile
command, it'll just run it locally:
$ recc /usr/bin/echo hello
hello
$ RECC_VERBOSE=1 recc /usr/bin/echo hello
Not a compiler command, so running locally.
(use RECC_FORCE_REMOTE=1 to force remote execution)
hello
$To integrate recc with CMake, replace/set these variables in your toolchain file.
set(CMAKE_C_COMPILER_LAUNCHER ${LOCATION_OF_RECC})
set(CMAKE_CXX_COMPILER_LAUNCHER ${LOCATION_OF_RECC})Setting these flags will invoke recc, with the compiler and generated arguments.
This repo includes a couple of additional utilities that may be useful for
debugging. They aren't installed by default, but running make will place
them in the bin subdirectory of the project root.
deps [command]- Print the names of the files needed to run the given command. (reccuses this to decide which files to send to the Remote Execution server.)