Last updated: 24 October 2020
How to compile Bitcoin Core and run the unit and functional tests

This is a summary of the documentation in the Bitcoin Core repository. Don't hesitate to read it for more information.

All steps are to be run from your terminal emulator, i.e. the command line.

  1. Ensure the dependencies are installed. Note that `ccache` at the end of the list isn't strictly required, but you'll probably want to install it (see below).
    • Linux: sudo apt-get install build-essential libtool autotools-dev automake pkg-config bsdmainutils python3 libssl-dev libevent-dev libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev libminiupnpc-dev libzmq3-dev libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler git libsqlite3-dev ccache
    • macOS (with command line tools and Homebrew already installed): brew install automake berkeley-db4 libtool boost miniupnpc pkg-config python qt libevent qrencode sqlite ccache
  2. Download the Bitcoin source files by git cloning the repository.
    • git clone https://github.com/bitcoin/bitcoin.git
  3. Install Berkeley DB (BDB) v4.8, a backward-compatible version needed for the wallet, using the installation script included in the Bitcoin Core contrib directory. If you have another version of BDB already installed that you wish to use, skip this section and add --with-incompatible-bdb to your ./configure options below instead.
    • Enter your local copy of the bitcoin repository: cd bitcoin
    • Now that you are in the root of the bitcoin repository, run ./contrib/install_db4.sh `pwd`
    • Take note of the instructions displayed in the terminal at the end of the BDB installation process:
        db4 build complete.
        When compiling bitcoind, run `./configure` in the following way:
        export BDB_PREFIX='<PATH-TO>/db4'
        ./configure BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" BDB_CFLAGS="-I${BDB_PREFIX}/include" ...
  4. Compile from a tagged release branch, unless you wish to test a specific branch or PR.
    • git tag -n | sort -V to see tags and descriptions ordered by most recent last
    • git checkout <TAG> to use a tagged release, for example: git checkout v0.20.0rc1
    • If you want to pull down a PR or specific branch from the remote repository to build and test locally, here is how.
  5. Compile Bitcoin from source.
    • export BDB_PREFIX='<PATH-TO>/db4' (you can use the output from the BDB build above). Skip this step if you plan to configure with --with-incompatible-bdb.
    • ./autogen.sh
    • ./configure BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" BDB_CFLAGS="-I${BDB_PREFIX}/include" if using BDB 4.8, otherwise ./configure --with-incompatible-bdb
    • make, or if you have multiple CPU cores, which is the usual case nowadays, you can tell make to use all of them and reduce compile time significantly with
    • make -j "$(($(nproc)+1))" on Linux, or
    • make -j "$(($(sysctl -n hw.physicalcpu)+1))" on macOS
  6. Pro tips.

    You can run ./configure --help to see all the various configuration options. It's a long list, so it may be more practical to search for what you want with grep: ./configure --help | grep -A1 "your-search-term"

    If you're re-compiling frequently (e.g. for testing small changes), as long as you're not changing the build configuration you can skip directly to the make -j <n> step for subsequent builds.

    On the other hand, when you change the build configuration, and in some cases when testing different PRs, or when the build isn't working, it's often best to start with a clean slate using make clean or make distclean before configuring. Here's a complete example:

    ./autogen.sh && ./configure <flags> && make clean && make -j <n>

    To compile with Clang instead of GCC (e.g. for fuzzing, sanitizers, better warnings/errors, or to use less resources), add CC=clang CXX=clang++ to your configure flags:

    ./configure CC=clang CXX=clang++

    To compile for fuzz testing, build with Clang using the following:

    ./autogen.sh ; ./configure --enable-c++17 --enable-fuzz --with-sanitizers=address,fuzzer,undefined CC=clang CXX=clang++ && make clean && make -j <n>

    Be sure to use ccache to speed up your builds. You can also gain time by building only what you need. See the Bitcoin Core productivity notes for more.

    If you build often, bash aliases may be helpful for abstracting the repetitive details down to short commands. These are probably not a great example, but here are mine.

  7. Run the unit tests.
    • make check, or
    • make -j"$(($(nproc)+1))" check to use multithreading on Linux, or
    • make -j"$(($(sysctl -n hw.physicalcpu)+1))" check to use multithreading on macOS
    • See the Bitcoin Core unit tests documentation for more info.
  8. Run the functional tests. From the repository root:
    • test/functional/test_runner.py to run the standard test suite
    • test/functional/test_runner.py --extended to run the extended test suite
    • test/functional/test_runner.py --help to see the various options for running tests
    • See the Bitcoin Core functional tests documentation for more info.

Cheers,

Jon Atack