Fast Builds

nearcore is implemented in Rust and is a fairly sizable project, so it takes a while to build. This chapter collects various tips to make the process faster.

Optimizing build times is a bit of a black art, so please do benchmarks on your machine to verify that the improvement work for you. Changing some configuration and making some type, which prevents it from improving build times is an extremely common failure mode!

Rust Perf Book contains a section on compilation time as well!

Obviously, cargo build --release is slower than cargo build. What's not entirely obvious is that cargo build -r is not as slow as it could be: our --release profile is somewhat optimized for fast builds, as it doesn't enable full LTO.

When building production binaries, we use lto=true and codegen-units=1 options, which make the build significantly slower (but the resulting binary somewhat faster). Keep this in mind when running benchmarks or parameter estimation.

Linker

By default, rustc uses system's linker, which might be quite slow. Using lld (LLVM linker) or mold (very new, very fast linker) is usually a big win.

I don't know what's the official source of truth for using alternative linkers, I usually refer to this comment.

Usually, adding

[build]
rustflags = ["-C", "link-arg=-fuse-ld=lld"]

to ~/.cargo/config is the most convenient approach.

lld itself can be installed with sudo apt install lld.

Prebuilt RocksDB

By default, we compile RocksDB (a C++ project) from source, which takes a lot of time. A faster alternative is to link to a prebuilt copy of RocksDB. This is a huge win, especially if you clean ./target directory frequently.

To use prebuilt RocksDB set ROCKSDB_LIB_DIR environment variable to location where librocksdb.a file is installed:

$ export ROCKSDB_LIB_DIR=/usr/lib/x86_64-linux-gnu
$ cargo build -p neard

Note that the system must provide a recent version of the library which, depending on operating system you’re using, may require installing packages from testing branches. For example, on Debian it requires installing librocksdb-dev from experimental version:

echo 'deb http://ftp.debian.org/debian experimental main contrib non-free' |
    sudo tee -a /etc/apt/sources.list
sudo apt update
sudo apt -t experimental install librocksdb-dev

ROCKSDB_LIB_DIR=/usr/lib/x86_64-linux-gnu
export ROCKSDB_LIB_DIR

Global Compilation Cache

By default, Rust uses incremental compilation, with intermediate artifacts stored in the project-local ./target directory.

sccache utility can be used to add a global compilation to the mix:

$ cargo install sccache
$ export RUSTC_WRAPPER="sccache"
$ export SCCACHE_CACHE_SIZE="30G"
$ cargo build -p neard

sccache intercepts calls to rustc and pattern-matches compiler's command line to get a cached result.

IDEs Are Bad For Environment

Generally, the knobs in this section are controlled either via global configuration in ~/.cargo/config or environmental variables.

Environmental variables are notoriously easy to lose, especially if you are working both from a command line and from a graphical IDE. Double check that you are not missing any of our build optimizations, the failure mode here is nasty, as the stuff just takes longer to compile without givin any visual indication of an error.

direnv sometimes can be used to conveniently manage project-specific environmentalvariable.