Here are some benefits of using CMake in the Bitcoin Core project:
- an opportunity to drop the
build_msvc
subdirectory from the repo altogether (being a cross-platform tool, CMake is able to create input files for a wide range of build systems, including Unix Makefiles and Visual Studio project files) - no hacks required to build
dll
s for Windows, even withDEBUG=1
(see #19772) - better maintainability (say bye to global variables)
- easy integration with Qt 5
- easy integration with Qt 6 in the nearest future (also see bitcoin/bitcoin#24798 and bitcoin/bitcoin#25191)
More Qt-specific details see below.
Also there is a non-technical/social benefit. Over time, the Autotools community shrinks, but CMake community grows. New contributors, who join this project in the future, will readily support a CMake-based system rather an Autotools-based one.
Native building has been tested on the following OSes:
- Ubuntu 22.04 (
x86_64
,aarch64
~, backward compatible with Ubuntu Bionic 18.04 using adjusted invocation~) - macOS Monterey (
x86_64
,arm64
) - FreeBSD 12.3
- OpenBSD 7.1
0cmake -S . -B build
1cd build
2make
3make check
4make install # optional
Native building on Windows (MSVC + vcpkg)
Dependency packages are provided by the vcpkg package manager (“Mandatory ASLR” in Windows Security must be disabled to install qt5-*
packages):
0vcpkg --triplet=x64-windows-static install pkgconf boost-multi-index boost-process boost-signals2 boost-test libevent berkeleydb sqlite3 miniupnpc zeromq qt5-base qt5-tools
To build on Windows with Visual Studio, a proper generator must be specified for a new build tree. The following example assumes using of “Developer Command Prompt for VS 2022” and CMake v3.21+.
0cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static -S . -B build
1cmake --build build --config Release
HINT. To leverage Multi-ToolTask and use <N>
CPU cores, run
0cmake --build build --config Release -j <N> -- /p:CL_MPcount=<N>
Cross building for Windows on Ubuntu 22.04
0make -C depends HOST=x86_64-w64-mingw32
1cmake --toolchain depends/x86_64-w64-mingw32/share/toolchain.cmake -S . -B build
2cmake --build build
Cross building for Windows on Ubuntu 22.04 with DEBUG=1
, see #19772
0make -C depends HOST=x86_64-w64-mingw32 DEBUG=1
1cmake --toolchain depends/x86_64-w64-mingw32/share/toolchain.cmake -S . -B build
2cmake --build build
Cross building for macOS (Intel) on Ubuntu 22.04
0make -C depends HOST=x86_64-apple-darwin
1cmake --toolchain depends/x86_64-apple-darwin/share/toolchain.cmake -S . -B build
2cmake --build build
Cross building for macOS (Apple Silicon) on Ubuntu 22.04
0make -C depends HOST=arm64-apple-darwin
1cmake --toolchain depends/arm64-apple-darwin/share/toolchain.cmake -S . -B build
2cmake --build build
Cross building for Android using NDK r23 LTS on Ubuntu 22.04
0export ANDROID_SDK=/home/hebasto/Android/Sdk
1export ANDROID_NDK=${ANDROID_SDK}/ndk/23.2.8568313
2export ANDROID_API_LEVEL=28
3make -C depends ANDROID_TOOLCHAIN_BIN=${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin/ HOST=aarch64-linux-android
4cmake --toolchain depends/aarch64-linux-android/share/toolchain.cmake -S . -B build
5cmake --build build
NOTE: Building in the source tree is not supported.
Functional Tests
Functional tests can be run in exactly the same way as when building with Autotools out of the source tree, i.e.:
0./build/test/functional/test_runner.py
Guix builds
Cirrus CI – 16 of 16
- lint [jammy]
- tidy [jammy]
- Win64 native [vs2022]
- ARM [unit tests, no functional tests] [bullseye]
- Win64 [unit tests, no gui tests, no boost::process, no functional tests] [jammy]
- 32-bit + dash [gui] [CentOS 8]
- [previous releases, uses qt5 dev package and some depends packages, DEBUG] [unsigned char] [buster]
- [TSan, depends, gui] [jammy]
- [MSan, depends] [focal]
- [ASan + LSan + UBSan + integer, no depends, USDT] [jammy]
- [fuzzer,address,undefined,integer, no depends] [jammy]
- [multiprocess, i686, DEBUG] [focal]
- [no wallet, libbitcoinkernel] [buster]
- macOS 10.15 [gui, no tests] [focal]
- macOS 13 native arm64 [gui, sqlite only] [no depends]
- ARM64 Android APK [jammy]
Additional notes.
- There is a branch/PR in my repo which includes Qt 6 integration and CMake-specific CI tasks.
- A similar PR has been open in https://github.com/bitcoin-core/secp256k1.
The plan is to have it in the repo shortly after branching 24.x
off, and make CMake-based build system a drop-in replacement of Autotools-based one during the next ~2 or 3~ release cycle~s~.
Qt-specific details
What happened before?
CMake is the build system for Qt 6
We made a big decision to start using CMake to build Qt 6 one and a half years ago.
The Qt 5 build system was built on top of qmake. In Qt 6, we ported the build system to CMake.
It is important to note that CMake has extensive support for Qt, including Qt-specific tools such as MOC, RCC, UIC.
Why Qt 6 build system does matter if the Bitcoin Core GUI uses Qt 5?
For release builds we use Qt 5.15.5 LTS, the latest Qt 5 version available under a free-software license.
For dynamic linking users can use Qt 5.11.3+, which allows them to use packages provided in Debian Buster and Ubuntu Focal.
On the other hand, Qt 6 packages are available in the following systems/package managers:
As long as Qt GUI is a part of Bitcoin Core, it is inevitable to embrace Qt 6 support, sooner or later.
Can we just adjust our current build system to handle Qt 6?
The main problem with integration of Qt 6 into the current build system is lacking of pkg-config *.pc
files for static builds (please note that a patch from QTBUG-86080 works for non-static builds only).
To handle Qt 6 with our current build system we need to:
- patch Qt, which looks like a non-trivial task, or
- apply some nasty hacks to our own build system
- keep in our repo the required
*.pc
files
All approaches imply maintaining burden for a long time. And last two are pretty ugly :)
Autotools – CMake Feature Parity Table
Autotool-based build system (AT) features being listed according to the ./configure --help
output.
AT feature | CM feature |
---|---|
--prefix |
-DCMAKE_INSTALL_PREFIX |
--enable-c++20 |
-DCXX20 |
--enable-shared |
-DBUILD_SHARED |
--enable-static |
-DBUILD_STATIC |
--disable-wallet |
-DENABLE_WALLET |
--enable-usdt |
-DWITH_USDT |
--enable-upnp-default |
-DENABLE_UPNP_DEFAULT |
--enable-natpmp-default |
-DENABLE_NATPMP_DEFAULT |
--disable-tests |
-DBUILD_TESTS |
--disable-gui-tests |
TBD |
--disable-bench |
-DBUILD_BENCH |
--enable-extended-functional-tests |
TBD |
--enable-fuzz |
-DFUZZ |
--enable-fuzz-binary |
-DBUILD_FUZZ_BINARY |
--disable-hardening |
-DHARDENING |
--enable-reduce-exports |
-DREDUCE_EXPORTS |
--disable-ccache |
-DCCACHE |
--enable-suppress-external-warnings |
N/A |
--enable-lcov |
TBD |
--enable-lcov-branch-coverage |
TBD |
--enable-threadlocal |
TBD |
--disable-asm |
-DASM |
--disable-zmq |
-DWITH_ZMQ |
--enable-multiprocess |
-DMULTIPROCESS |
--disable-man |
-DINSTALL_MAN |
--enable-debug |
-DCMAKE_BUILD_TYPE=Debug |
--enable-gprof |
TBD |
--enable-werror |
-DWERROR |
--enable-external-signer |
-DWITH_EXTERNAL_SIGNER |
--enable-lto |
TBD |
--enable-util-cli |
-DBUILD_CLI |
--enable-util-tx |
-DBUILD_TX |
--enable-util-wallet |
-DBUILD_WALLET_TOOL |
--enable-util-util |
-DBUILD_UTIL |
--enable-experimental-util-chainstate |
-DBUILD_UTIL_CHAINSTATE |
--with-seccomp |
-DWITH_SECCOMP |
--with-sqlite |
-DWITH_SQLITE |
--without-bdb |
-DWITH_BDB |
--with-miniupnpc |
-DWITH_MINIUPNPC |
--with-natpmp |
-DWITH_NATPMP |
--with-qrencode |
-DWITH_QRENCODE |
--with-libmultiprocess |
N/A |
--with-mpgen |
-DMPGEN_PREFIX |
--with-sanitizers |
-DSANITIZERS |
--with-utils |
individual options |
--with-libs |
individual options |
--with-experimental-kernel-lib |
-DBUILD_BITCOINKERNEL_LIB |
--with-daemon |
-DBUILD_DAEMON |
--with-gui |
-DWITH_GUI |
IRC meeting discussions: