Skip to content

build: Add CMake-based build system (1 of N)

This is split from https://github.com/bitcoin/bitcoin/pull/25797 which is a full implementation with an Autotools feature parity and has more than 80 commits.

A bit rehashed list of benefits of a CMake-based build system over an Autotools-based one:

General benefits

  1. Integration with developer tools like clang-tidy, IWYU etc.

  2. CTest tool with a bunch of useful features, including coverage analysis, integration with sanitizers and memory check tools like valgrind.

  3. CPack, a powerful packaging tool.

  4. Integration with IDEs.

  5. The concept of a "target with assosiated properties" is better than Autotools' global variables in many ways (robustness, readability, maintanability).

  6. [social] A great community. CMake is actively developed.

The Bitcoin Core specific benefits

A preliminary note. Two arguments (a) "nobody cares about X platform" and (b) "nobody cares about Y binary" are out of this PR scope, as long as the X platform is promised to be supported by the Bitcoin Core project, and the Y binary is a part of the Bitcoin Core project.

  1. Native Windows support. No longer need to maintain build_msvc subdirectory.

  2. Correctness with Windows DLLs out-of-the-box. In comparison, the current build system has 3 (three!) hacks of libtool. And it is still broken:

  1. CMake is a native build system of Qt 6.

  2. [social] It is expected that more current and new developers are/will be able/willing to review/contribute/maintain CMake code rather Autotools stuff.

Roadmap

There are two goals:

  • merge all CMake code by v25.0 and test it
  • switch to the CMake-based build system by v26.0

Implementation details

In particular, this PR establishes the minimum required CMake version. As it looks non-productive to support Ubuntu Bionic as a build platform, version 3.13 has been chosen. Benefits of v3.13 over v3.10 which affect our CMake code directly are as follow:

#  - 3.11: add_library() and add_executable() commands can now be called without any sources
#          and will not complain as long as sources are added later via the target_sources()
#          command.
#  - 3.11: The target_*() commands learned to set the INTERFACE properties on Imported Targets.
#  - 3.12: The add_compile_definitions() command was added to set preprocessor definitions
#          at directory level. This supersedes add_definitions().
#  - 3.12: If the CONFIGURE_DEPENDS flag is specified, CMake will add logic to the main
#          build system check target to rerun the flagged GLOB commands at build time.
#  - 3.12: The target_link_libraries() command now supports Object Libraries.
#  - 3.12: A new $<TARGET_EXISTS:...> generator expression has been added.
#  - 3.12: A new FindPython3 module has been added to provide a new way to locate python
#          environments.
#  - 3.13: The install(TARGETS) command learned to install targets created outside the current
#          directory.
#  - 3.13: The target_link_options() command was created to specify link options for targets
#          and their dependents.
#  - 3.13: The target_link_libraries() command may now be called to modify targets created
#          outside the current directory.

Notes for reviewers

To configure a build system, one can run in their local repo root:

  • on Linux / *BSD / macOS:
cmake -S . -B  build
  • on Windows:
cmake -G "Visual Studio 17 2022" -A x64 -S . -B build

To re-configure, it is recommended to use the clean build tree, for example:

rm -rf build

For now, the only artifact we explicitly create in the build tree is a bitcoin-config.h header:

cat build/src/config/bitcoin-config.h

Merge request reports

Loading