cmake: Check dependencies after build option interaction
What changed, and why it matters
This commit reorganizes the CMake build scripts so that dependency checks happen after build options have been finalized. It is a build-system correctness and maintainability improvement, not a security fix. There is no indication it addresses a vulnerability or changes runtime behavior of Bitcoin Core.
No security action required. Treat as a normal build-system refactoring commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch moves all find_package() dependency resolution and related option-interaction logic (e.g., BUILD_FOR_FUZZING overriding other targets) to a single section that runs after options are fully resolved. Previously, some dependencies were checked immediately when their option was declared, which could lead to inconsistent dependency checking if a later option changed the effective build configuration. The change also removes redundant -DBUILD_GUI=OFF / -DWITH_ZMQ=OFF flags from the Windows CI fuzz configuration because BUILD_FOR_FUZZING=ON now disables those targets automatically. No runtime code, cryptographic logic, or network behavior is modified.
Changed components
CMake build system (CMakeLists.txt)Windows CI fuzz job configuration (.github/ci-windows.py)Inspect captured patch +95 / −79
diff --git a/.github/ci-windows.py b/.github/ci-windows.py
index 964558a2..38bd7b1d 100755
--- a/.github/ci-windows.py
+++ b/.github/ci-windows.py
@@ -34,8 +34,6 @@ GENERATE_OPTIONS = {
"fuzz": [
"-DVCPKG_MANIFEST_NO_DEFAULT_FEATURES=ON",
"-DVCPKG_MANIFEST_FEATURES=wallet",
- "-DBUILD_GUI=OFF",
- "-DWITH_ZMQ=OFF",
"-DBUILD_FOR_FUZZING=ON",
"-DCMAKE_COMPILE_WARNING_AS_ERROR=ON",
],
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 36644bd2..02db4c75 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -111,84 +111,33 @@ option(BUILD_CLI "Build bitcoin-cli executable." ON)
option(BUILD_TESTS "Build test_bitcoin and other unit test executables." ON)
option(BUILD_TX "Build bitcoin-tx executable." ${BUILD_TESTS})
option(BUILD_UTIL "Build bitcoin-util executable." ${BUILD_TESTS})
+cmake_dependent_option(BUILD_GUI_TESTS "Build test_bitcoin-qt executable." ON "BUILD_GUI;BUILD_TESTS" OFF)
option(BUILD_UTIL_CHAINSTATE "Build experimental bitcoin-chainstate executable." OFF)
option(BUILD_KERNEL_LIB "Build experimental bitcoinkernel library." ${BUILD_UTIL_CHAINSTATE})
cmake_dependent_option(BUILD_KERNEL_TEST "Build tests for the experimental bitcoinkernel library." ON "BUILD_KERNEL_LIB" OFF)
option(ENABLE_WALLET "Enable wallet." ON)
-if(ENABLE_WALLET)
- if(VCPKG_TARGET_TRIPLET)
- # Use of the `unofficial::` namespace is a vcpkg package manager convention.
- find_package(unofficial-sqlite3 CONFIG REQUIRED)
- add_library(SQLite3::SQLite3 ALIAS unofficial::sqlite3::sqlite3)
- else()
- find_package(SQLite3 3.7.17 REQUIRED)
- if(NOT TARGET SQLite3::SQLite3) # CMake < 4.3
- add_library(SQLite3::SQLite3 ALIAS SQLite::SQLite3)
- endif()
- endif()
-endif()
cmake_dependent_option(BUILD_WALLET_TOOL "Build bitcoin-wallet tool." ${BUILD_TESTS} "ENABLE_WALLET" OFF)
-option(REDUCE_EXPORTS "Attempt to reduce exported symbols in the resulting executables." OFF)
-option(CMAKE_COMPILE_WARNING_AS_ERROR "Treat compiler warnings as errors." OFF)
-option(WITH_CCACHE "Attempt to use ccache for compiling." ON)
-
+option(ENABLE_EXTERNAL_SIGNER "Enable external signer support." ON)
option(WITH_ZMQ "Enable ZMQ notifications." OFF)
-if(WITH_ZMQ)
- find_package(ZeroMQ 4.0.0 MODULE REQUIRED)
-endif()
-
+cmake_dependent_option(ENABLE_IPC "Build multiprocess bitcoin-node and bitcoin-gui executables in addition to monolithic bitcoind and bitcoin-qt executables." ON "NOT WIN32" OFF)
+cmake_dependent_option(WITH_EXTERNAL_LIBMULTIPROCESS "Build with external libmultiprocess library instead of with local git subtree when ENABLE_IPC is enabled. This is not normally recommended, but can be useful for developing libmultiprocess itself." OFF "ENABLE_IPC" OFF)
option(WITH_EMBEDDED_ASMAP "Embed default ASMap data." ON)
-
option(WITH_USDT "Enable tracepoints for Userspace, Statically Defined Tracing." OFF)
-if(WITH_USDT)
- find_package(USDT MODULE REQUIRED)
-endif()
-
-option(ENABLE_EXTERNAL_SIGNER "Enable external signer support." ON)
cmake_dependent_option(WITH_QRENCODE "Enable QR code support." ON "BUILD_GUI" OFF)
-if(WITH_QRENCODE)
- find_package(QRencode MODULE REQUIRED)
- set(USE_QRCODE TRUE)
-endif()
-
cmake_dependent_option(WITH_DBUS "Enable DBus support." ON "NOT CMAKE_SYSTEM_NAME MATCHES \"(Windows|Darwin)\" AND BUILD_GUI" OFF)
-cmake_dependent_option(ENABLE_IPC "Build multiprocess bitcoin-node and bitcoin-gui executables in addition to monolithic bitcoind and bitcoin-qt executables." ON "NOT WIN32" OFF)
-cmake_dependent_option(WITH_EXTERNAL_LIBMULTIPROCESS "Build with external libmultiprocess library instead of with local git subtree when ENABLE_IPC is enabled. This is not normally recommended, but can be useful for developing libmultiprocess itself." OFF "ENABLE_IPC" OFF)
-if(ENABLE_IPC AND WITH_EXTERNAL_LIBMULTIPROCESS)
- find_package(Libmultiprocess REQUIRED COMPONENTS Lib)
- find_package(LibmultiprocessNative REQUIRED COMPONENTS Bin
- NAMES Libmultiprocess
- )
-endif()
-
-cmake_dependent_option(BUILD_GUI_TESTS "Build test_bitcoin-qt executable." ON "BUILD_GUI;BUILD_TESTS" OFF)
-if(BUILD_GUI)
- set(qt_components Core Gui Widgets LinguistTools)
- if(ENABLE_WALLET)
- list(APPEND qt_components Network)
- endif()
- if(WITH_DBUS)
- list(APPEND qt_components DBus)
- set(USE_DBUS TRUE)
- endif()
- if(BUILD_GUI_TESTS)
- list(APPEND qt_components Test)
- endif()
- find_package(Qt 6.2 MODULE REQUIRED
- COMPONENTS ${qt_components}
- )
- unset(qt_components)
-endif()
-
option(BUILD_BENCH "Build bench_bitcoin executable." OFF)
option(BUILD_FUZZ_BINARY "Build fuzz binary." OFF)
option(BUILD_FOR_FUZZING "Build for fuzzing. Enabling this will disable all other targets and override BUILD_FUZZ_BINARY." OFF)
+option(REDUCE_EXPORTS "Attempt to reduce exported symbols in the resulting executables." OFF)
+option(CMAKE_COMPILE_WARNING_AS_ERROR "Treat compiler warnings as errors." OFF)
+option(WITH_CCACHE "Attempt to use ccache for compiling." ON)
+
option(INSTALL_MAN "Install man pages." ON)
set(APPEND_CPPFLAGS "" CACHE STRING "Preprocessor flags that are appended to the command line after all other flags added by the build system. This variable is intended for debugging and special builds.")
@@ -209,11 +158,9 @@ string(APPEND CMAKE_CXX_LINK_EXECUTABLE " ${APPEND_LDFLAGS}")
include(CheckCXXFeatures)
check_cxx_features()
-set(configure_warnings)
-
-include(CheckLinkerSupportsPIE)
-check_linker_supports_pie(configure_warnings)
-
+#=============================
+# Core interface library
+#=============================
# The core_interface library aims to encapsulate common build flags.
# It is a usage requirement for all targets except for secp256k1, which
# gets its flags by other means.
@@ -225,6 +172,15 @@ target_link_libraries(core_interface INTERFACE
$<$<CONFIG:Debug>:core_interface_debug>
)
+#=============================
+# Option interaction
+#=============================
+# Compute the final state of build options.
+# This must be done after all options have been initially set,
+# as some options (e.g., BUILD_FOR_FUZZING) may override or adjust others.
+# It must also come before any dependency checks to ensure that the set
+# of dependencies checked is consistent with the final option values,
+# that is, that all required, and only the required, dependencies are tested.
if(BUILD_FOR_FUZZING)
message(WARNING "BUILD_FOR_FUZZING=ON will disable all other targets and force BUILD_FUZZ_BINARY=ON.")
set(BUILD_BITCOIN_BIN OFF)
@@ -251,6 +207,81 @@ if(BUILD_FOR_FUZZING)
)
endif()
+#=============================
+# Check and set PIC/PIE
+#=============================
+set(configure_warnings)
+include(CheckLinkerSupportsPIE)
+# Set CMAKE_POSITION_INDEPENDENT_CODE early so it applies to all
+# subsequent checks, including dependency packages and tool flags.
+check_linker_supports_pie(configure_warnings)
+
+#=============================
+# Find dependencies
+#=============================
+set(THREADS_PREFER_PTHREAD_FLAG ON)
+find_package(Threads REQUIRED)
+target_link_libraries(core_interface INTERFACE
+ Threads::Threads
+)
+
+include(AddBoostIfNeeded)
+add_boost_if_needed()
+
+if(BUILD_DAEMON OR BUILD_GUI OR BUILD_CLI OR BUILD_TESTS OR BUILD_BENCH OR BUILD_FUZZ_BINARY)
+ find_package(Libevent 2.1.8 MODULE REQUIRED)
+endif()
+
+if(ENABLE_WALLET)
+ if(VCPKG_TARGET_TRIPLET)
+ # Use of the `unofficial::` namespace is a vcpkg package manager convention.
+ find_package(unofficial-sqlite3 CONFIG REQUIRED)
+ add_library(SQLite3::SQLite3 ALIAS unofficial::sqlite3::sqlite3)
+ else()
+ find_package(SQLite3 3.7.17 REQUIRED)
+ if(NOT TARGET SQLite3::SQLite3) # CMake < 4.3
+ add_library(SQLite3::SQLite3 ALIAS SQLite::SQLite3)
+ endif()
+ endif()
+endif()
+
+if(WITH_ZMQ)
+ find_package(ZeroMQ 4.0.0 MODULE REQUIRED)
+endif()
+
+if(ENABLE_IPC AND WITH_EXTERNAL_LIBMULTIPROCESS)
+ find_package(Libmultiprocess REQUIRED COMPONENTS Lib)
+ find_package(LibmultiprocessNative REQUIRED COMPONENTS Bin
+ NAMES Libmultiprocess
+ )
+endif()
+
+if(WITH_USDT)
+ find_package(USDT MODULE REQUIRED)
+endif()
+
+if(BUILD_GUI)
+ set(qt_components Core Gui Widgets LinguistTools)
+ if(ENABLE_WALLET)
+ list(APPEND qt_components Network)
+ endif()
+ if(WITH_DBUS)
+ list(APPEND qt_components DBus)
+ set(USE_DBUS TRUE)
+ endif()
+ if(BUILD_GUI_TESTS)
+ list(APPEND qt_components Test)
+ endif()
+ find_package(Qt 6.2 MODULE REQUIRED
+ COMPONENTS ${qt_components}
+ )
+ unset(qt_components)
+ if(WITH_QRENCODE)
+ find_package(QRencode MODULE REQUIRED)
+ set(USE_QRCODE TRUE)
+ endif()
+endif()
+
include(TryAppendCXXFlags)
include(TryAppendLinkerFlag)
@@ -361,12 +392,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
endif()
endif()
-set(THREADS_PREFER_PTHREAD_FLAG ON)
-find_package(Threads REQUIRED)
-target_link_libraries(core_interface INTERFACE
- Threads::Threads
-)
-
# Define sanitize_interface with -fsanitize flags intended to apply to all
# libraries and executables.
add_library(sanitize_interface INTERFACE)
@@ -436,13 +461,6 @@ if(BUILD_FUZZ_BINARY)
target_link_libraries(fuzzer_interface INTERFACE ${FUZZ_LIBS})
endif()
-include(AddBoostIfNeeded)
-add_boost_if_needed()
-
-if(BUILD_DAEMON OR BUILD_GUI OR BUILD_CLI OR BUILD_TESTS OR BUILD_BENCH OR BUILD_FUZZ_BINARY)
- find_package(Libevent 2.1.8 MODULE REQUIRED)
-endif()
-
include(cmake/introspection.cmake)
include(cmake/ccache.cmake)
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.