CMakeLists.txt raw
1 # Copyright (c) 2023-present The Bitcoin Core developers
2 # Distributed under the MIT software license, see the accompanying
3 # file COPYING or https://opensource.org/license/mit/.
4
5 # Ubuntu 22.04 LTS Jammy Jellyfish, https://wiki.ubuntu.com/Releases, EOSS in June 2027:
6 # - CMake 3.22.1, https://packages.ubuntu.com/jammy/cmake
7 #
8 # Centos Stream 9, https://www.centos.org/cl-vs-cs/#end-of-life, EOL in May 2027:
9 # - CMake 3.26.5, https://mirror.stream.centos.org/9-stream/AppStream/x86_64/os/Packages/
10 cmake_minimum_required(VERSION 3.22)
11
12 if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
13 message(FATAL_ERROR "In-source builds are not allowed.")
14 endif()
15
16 if(POLICY CMP0171)
17 # `codegen` is a reserved target name.
18 # See: https://cmake.org/cmake/help/latest/policy/CMP0171.html
19 cmake_policy(SET CMP0171 NEW)
20 endif()
21
22 # When adjusting CMake flag variables, we must not override those explicitly
23 # set by the user. These are a subset of the CACHE_VARIABLES property.
24 get_directory_property(precious_variables CACHE_VARIABLES)
25
26 #=============================
27 # Project / Package metadata
28 #=============================
29 set(CLIENT_NAME "Bitcoin Core")
30 set(CLIENT_VERSION_MAJOR 31)
31 set(CLIENT_VERSION_MINOR 99)
32 set(CLIENT_VERSION_BUILD 0)
33 set(CLIENT_VERSION_RC 0)
34 set(CLIENT_VERSION_IS_RELEASE "false")
35 set(COPYRIGHT_YEAR "2026")
36
37 # During the enabling of the CXX and CXXOBJ languages, we modify
38 # CMake's compiler/linker invocation strings by appending the content
39 # of the user-defined `APPEND_*` variables, which allows overriding
40 # any flag. We also ensure that the APPEND_* flags are considered
41 # during CMake's tests, which use the `try_compile()` command.
42 #
43 # CMake's docs state that the `CMAKE_TRY_COMPILE_PLATFORM_VARIABLES`
44 # variable "is meant to be set by CMake's platform information modules
45 # for the current toolchain, or by a toolchain file." We do our best
46 # to set it before the `project()` command.
47 set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES
48 CMAKE_CXX_COMPILE_OBJECT
49 CMAKE_OBJCXX_COMPILE_OBJECT
50 CMAKE_CXX_LINK_EXECUTABLE
51 )
52
53 project(BitcoinCore
54 VERSION ${CLIENT_VERSION_MAJOR}.${CLIENT_VERSION_MINOR}.${CLIENT_VERSION_BUILD}
55 DESCRIPTION "Bitcoin client software"
56 HOMEPAGE_URL "https://bitcoincore.org/"
57 LANGUAGES NONE
58 )
59
60 set(CLIENT_VERSION_STRING ${PROJECT_VERSION})
61 if(CLIENT_VERSION_RC GREATER 0)
62 string(APPEND CLIENT_VERSION_STRING "rc${CLIENT_VERSION_RC}")
63 endif()
64
65 set(COPYRIGHT_HOLDERS "The %s developers")
66 set(COPYRIGHT_HOLDERS_FINAL "The ${CLIENT_NAME} developers")
67 set(CLIENT_BUGREPORT "https://github.com/bitcoin/bitcoin/issues")
68
69 #=============================
70 # Language setup
71 #=============================
72 if(CMAKE_VERSION VERSION_LESS 4.2 AND CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT CMAKE_HOST_APPLE)
73 # We do not use the install_name_tool when cross-compiling for macOS.
74 # However, CMake < 4.2 still searches for Apple's version of the tool,
75 # which causes an error during configuration.
76 # See:
77 # - https://gitlab.kitware.com/cmake/cmake/-/issues/27069
78 # - https://gitlab.kitware.com/cmake/cmake/-/merge_requests/10955
79 # So disable this tool check in further enable_language() commands.
80 set(CMAKE_INSTALL_NAME_TOOL "${CMAKE_COMMAND} -E true")
81 endif()
82 enable_language(CXX)
83
84 set(CMAKE_CXX_STANDARD 20)
85 set(CMAKE_CXX_STANDARD_REQUIRED ON)
86 set(CMAKE_CXX_EXTENSIONS OFF)
87
88 list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/module)
89 include(ProcessConfigurations)
90
91 # Flatten static lib dependencies.
92 # Without this, if libfoo.a depends on libbar.a, libfoo's objects can't begin
93 # to be compiled until libbar.a has been created.
94 if (NOT DEFINED CMAKE_OPTIMIZE_DEPENDENCIES)
95 set(CMAKE_OPTIMIZE_DEPENDENCIES TRUE)
96 endif()
97
98 #=============================
99 # Configurable options
100 #=============================
101 include(CMakeDependentOption)
102 # When adding a new option, end the <help_text> with a full stop for consistency.
103 option(BUILD_BITCOIN_BIN "Build bitcoin executable." ON)
104 option(BUILD_DAEMON "Build bitcoind executable." ON)
105 option(BUILD_GUI "Build bitcoin-qt executable." OFF)
106 option(BUILD_CLI "Build bitcoin-cli executable." ON)
107
108 option(BUILD_TESTS "Build test_bitcoin and other unit test executables." ON)
109 option(BUILD_TX "Build bitcoin-tx executable." ${BUILD_TESTS})
110 option(BUILD_UTIL "Build bitcoin-util executable." ${BUILD_TESTS})
111 cmake_dependent_option(BUILD_GUI_TESTS "Build test_bitcoin-qt executable." ON "BUILD_GUI;BUILD_TESTS" OFF)
112
113 option(BUILD_UTIL_CHAINSTATE "Build experimental bitcoin-chainstate executable." OFF)
114 option(BUILD_KERNEL_LIB "Build experimental bitcoinkernel library." ${BUILD_UTIL_CHAINSTATE})
115 cmake_dependent_option(BUILD_KERNEL_TEST "Build tests for the experimental bitcoinkernel library." ON "BUILD_KERNEL_LIB" OFF)
116
117 option(ENABLE_WALLET "Enable wallet." ON)
118 cmake_dependent_option(BUILD_WALLET_TOOL "Build bitcoin-wallet tool." ${BUILD_TESTS} "ENABLE_WALLET" OFF)
119
120 option(ENABLE_EXTERNAL_SIGNER "Enable external signer support." ON)
121 option(WITH_ZMQ "Enable ZMQ notifications." OFF)
122 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)
123 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)
124 option(WITH_EMBEDDED_ASMAP "Embed default ASMap data." ON)
125 option(WITH_USDT "Enable tracepoints for Userspace, Statically Defined Tracing." OFF)
126
127 cmake_dependent_option(WITH_QRENCODE "Enable QR code support." ON "BUILD_GUI" OFF)
128 cmake_dependent_option(WITH_DBUS "Enable DBus support." ON "NOT CMAKE_SYSTEM_NAME MATCHES \"(Windows|Darwin)\" AND BUILD_GUI" OFF)
129
130 option(BUILD_BENCH "Build bench_bitcoin executable." OFF)
131 option(BUILD_FUZZ_BINARY "Build fuzz binary." OFF)
132 option(BUILD_FOR_FUZZING "Build for fuzzing. Enabling this will disable all other targets and override BUILD_FUZZ_BINARY." OFF)
133
134 option(REDUCE_EXPORTS "Attempt to reduce exported symbols in the resulting executables." OFF)
135 option(CMAKE_COMPILE_WARNING_AS_ERROR "Treat compiler warnings as errors." OFF)
136 option(WITH_CCACHE "Attempt to use ccache for compiling." ON)
137
138 option(INSTALL_MAN "Install man pages." ON)
139
140 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.")
141 set(APPEND_CFLAGS "" CACHE STRING "C compiler 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.")
142 set(APPEND_CXXFLAGS "" CACHE STRING "(Objective) C++ compiler 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.")
143 set(APPEND_LDFLAGS "" CACHE STRING "Linker 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.")
144 # Appending to this low-level rule variables is the only way to
145 # guarantee that the flags appear at the end of the command line.
146 string(APPEND CMAKE_CXX_COMPILE_OBJECT " ${APPEND_CPPFLAGS} ${APPEND_CXXFLAGS}")
147 string(APPEND CMAKE_CXX_CREATE_SHARED_LIBRARY " ${APPEND_LDFLAGS}")
148 string(APPEND CMAKE_CXX_LINK_EXECUTABLE " ${APPEND_LDFLAGS}")
149
150 # Check required C++ toolchain features early.
151 include(CheckCXXFeatures)
152 check_cxx_features()
153
154 #=============================
155 # Core interface library
156 #=============================
157 # The core_interface library aims to encapsulate common build flags.
158 # It is a usage requirement for all targets except for secp256k1, which
159 # gets its flags by other means.
160 add_library(core_interface INTERFACE)
161 add_library(core_interface_relwithdebinfo INTERFACE)
162 add_library(core_interface_debug INTERFACE)
163 target_link_libraries(core_interface INTERFACE
164 $<$<CONFIG:RelWithDebInfo>:core_interface_relwithdebinfo>
165 $<$<CONFIG:Debug>:core_interface_debug>
166 )
167
168 #=============================
169 # Option interaction
170 #=============================
171 # Compute the final state of build options.
172 # This must be done after all options have been initially set,
173 # as some options (e.g., BUILD_FOR_FUZZING) may override or adjust others.
174 # It must also come before any dependency checks to ensure that the set
175 # of dependencies checked is consistent with the final option values,
176 # that is, that all required, and only the required, dependencies are tested.
177 if(BUILD_FOR_FUZZING)
178 message(WARNING "BUILD_FOR_FUZZING=ON will disable all other targets and force BUILD_FUZZ_BINARY=ON.")
179 set(BUILD_BITCOIN_BIN OFF)
180 set(BUILD_DAEMON OFF)
181 set(BUILD_CLI OFF)
182 set(BUILD_TX OFF)
183 set(BUILD_UTIL OFF)
184 set(BUILD_UTIL_CHAINSTATE OFF)
185 set(BUILD_KERNEL_LIB OFF)
186 set(BUILD_KERNEL_TEST OFF)
187 set(BUILD_WALLET_TOOL OFF)
188 set(BUILD_GUI OFF)
189 set(ENABLE_EXTERNAL_SIGNER OFF)
190 set(WITH_ZMQ OFF)
191 set(WITH_EMBEDDED_ASMAP OFF)
192 set(BUILD_TESTS OFF)
193 set(BUILD_GUI_TESTS OFF)
194 set(BUILD_BENCH OFF)
195 set(BUILD_FUZZ_BINARY ON)
196
197 target_compile_definitions(core_interface INTERFACE
198 FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
199 )
200 endif()
201
202 #=============================
203 # Check and set PIC/PIE
204 #=============================
205 set(configure_warnings)
206 if(NOT CMAKE_SYSTEM_NAME STREQUAL "Generic")
207 include(CheckLinkerSupportsPIE)
208 # Set CMAKE_POSITION_INDEPENDENT_CODE early so it applies to all
209 # subsequent checks, including dependency packages and tool flags.
210 check_linker_supports_pie(configure_warnings)
211 endif()
212
213 #=============================
214 # Find dependencies
215 #=============================
216 if(NOT CMAKE_SYSTEM_NAME STREQUAL "Generic")
217 set(THREADS_PREFER_PTHREAD_FLAG ON)
218 find_package(Threads REQUIRED)
219 target_link_libraries(core_interface INTERFACE
220 Threads::Threads
221 )
222 endif()
223
224 if(NOT CMAKE_SYSTEM_NAME STREQUAL "Generic")
225 include(AddBoostIfNeeded)
226 add_boost_if_needed()
227 endif()
228
229 if(ENABLE_WALLET)
230 if(VCPKG_TARGET_TRIPLET)
231 # Use of the `unofficial::` namespace is a vcpkg package manager convention.
232 find_package(unofficial-sqlite3 CONFIG REQUIRED)
233 add_library(SQLite3::SQLite3 ALIAS unofficial::sqlite3::sqlite3)
234 else()
235 find_package(SQLite3 3.7.17 REQUIRED)
236 if(NOT TARGET SQLite3::SQLite3) # CMake < 4.3
237 add_library(SQLite3::SQLite3 ALIAS SQLite::SQLite3)
238 endif()
239 endif()
240 endif()
241
242 if(WITH_ZMQ)
243 find_package(ZeroMQ 4.0.0 MODULE REQUIRED)
244 endif()
245
246 if(ENABLE_IPC AND WITH_EXTERNAL_LIBMULTIPROCESS)
247 find_package(Libmultiprocess REQUIRED COMPONENTS Lib)
248 find_package(LibmultiprocessNative REQUIRED COMPONENTS Bin
249 NAMES Libmultiprocess
250 )
251 endif()
252
253 if(WITH_USDT)
254 find_package(USDT MODULE REQUIRED)
255 endif()
256
257 if(BUILD_GUI)
258 set(qt_components Core Gui Widgets LinguistTools)
259 if(ENABLE_WALLET)
260 list(APPEND qt_components Network)
261 endif()
262 if(WITH_DBUS)
263 list(APPEND qt_components DBus)
264 set(USE_DBUS TRUE)
265 endif()
266 if(BUILD_GUI_TESTS)
267 list(APPEND qt_components Test)
268 endif()
269 find_package(Qt 6.2 MODULE REQUIRED
270 COMPONENTS ${qt_components}
271 )
272 unset(qt_components)
273 if(WITH_QRENCODE)
274 find_package(QRencode MODULE REQUIRED)
275 set(USE_QRCODE TRUE)
276 endif()
277 endif()
278
279 include(TryAppendCXXFlags)
280 include(TryAppendLinkerFlag)
281
282 # Redefine/adjust per-configuration flags.
283 target_compile_definitions(core_interface_debug INTERFACE
284 DEBUG
285 DEBUG_LOCKORDER
286 DEBUG_LOCKCONTENTION
287 RPC_DOC_CHECK
288 ABORT_ON_FAILED_ASSUME
289 )
290
291 if(WIN32)
292 #[=[
293 This build system supports two ways to build binaries for Windows.
294
295 1. Building on Windows using MSVC.
296 Implementation notes:
297 - /DWIN32 and /D_WINDOWS definitions are included into the CMAKE_CXX_FLAGS_INIT
298 and CMAKE_CXX_FLAGS_INIT variables by default.
299 - A run-time library is selected using the CMAKE_MSVC_RUNTIME_LIBRARY variable.
300 - MSVC-specific options, for example, /Zc:__cplusplus, are additionally required.
301
302 2. Cross-compiling using MinGW.
303 Implementation notes:
304 - WIN32 and _WINDOWS definitions must be provided explicitly.
305 - A run-time library must be specified explicitly using _MT definition.
306 ]=]
307
308 target_compile_definitions(core_interface INTERFACE
309 _WIN32_WINNT=0x0A00
310 _WIN32_IE=0x0A00
311 WIN32_LEAN_AND_MEAN
312 NOMINMAX
313 )
314
315 if(MSVC)
316 if(VCPKG_TARGET_TRIPLET MATCHES "-static")
317 set(msvc_library_linkage "")
318 else()
319 set(msvc_library_linkage "DLL")
320 endif()
321 set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>${msvc_library_linkage}")
322 unset(msvc_library_linkage)
323
324 target_compile_definitions(core_interface INTERFACE
325 _UNICODE;UNICODE
326 )
327 target_compile_options(core_interface INTERFACE
328 /utf-8
329 /Zc:preprocessor
330 /Zc:__cplusplus
331 /sdl
332 )
333 target_link_options(core_interface INTERFACE
334 # We embed our own manifests.
335 /MANIFEST:NO
336 )
337 # Improve parallelism in MSBuild.
338 # See: https://devblogs.microsoft.com/cppblog/improved-parallelism-in-msbuild/.
339 list(APPEND CMAKE_VS_GLOBALS "UseMultiToolTask=true")
340 endif()
341
342 if(MINGW)
343 target_compile_definitions(core_interface INTERFACE
344 WIN32
345 _WINDOWS
346 _MT
347 )
348 # Avoid the use of aligned vector instructions when building for Windows.
349 # See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54412.
350 try_append_cxx_flags("-Wa,-muse-unaligned-vector-move" TARGET core_interface SKIP_LINK)
351 try_append_linker_flag("-static" TARGET core_interface)
352 # We support Windows 10+, however it's not possible to set these values accordingly,
353 # due to a bug in mingw-w64. See https://sourceforge.net/p/mingw-w64/bugs/968/.
354 # As a best effort, target Windows 8.
355 try_append_linker_flag("-Wl,--major-subsystem-version,6" TARGET core_interface)
356 try_append_linker_flag("-Wl,--minor-subsystem-version,2" TARGET core_interface)
357 endif()
358
359 # Workaround producing large object files, which cannot be handled by the assembler.
360 # More likely to happen with no, or lower levels of optimisation.
361 # See discussion in https://github.com/bitcoin/bitcoin/issues/28109.
362 if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
363 try_append_cxx_flags("/bigobj" TARGET core_interface_debug SKIP_LINK)
364 else()
365 try_append_cxx_flags("-Wa,-mbig-obj" TARGET core_interface_debug SKIP_LINK)
366 endif()
367 endif()
368
369 # Use 64-bit off_t on 32-bit Linux.
370 if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SIZEOF_VOID_P EQUAL 4)
371 # Ensure 64-bit offsets are used for filesystem accesses for 32-bit compilation.
372 target_compile_definitions(core_interface INTERFACE
373 _FILE_OFFSET_BITS=64
374 )
375 endif()
376
377 if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
378 target_compile_definitions(core_interface INTERFACE OBJC_OLD_DISPATCH_PROTOTYPES=0)
379 # These flags are specific to ld64, and may cause issues with other linkers.
380 # For example: GNU ld will interpret -dead_strip as -de and then try and use
381 # "ad_strip" as the symbol for the entry point.
382 try_append_linker_flag("-Wl,-dead_strip" TARGET core_interface)
383 try_append_linker_flag("-Wl,-dead_strip_dylibs" TARGET core_interface)
384 if(CMAKE_HOST_APPLE)
385 try_append_linker_flag("-Wl,-headerpad_max_install_names" TARGET core_interface)
386 endif()
387 endif()
388
389 # Define sanitize_interface with -fsanitize flags intended to apply to all
390 # libraries and executables.
391 add_library(sanitize_interface INTERFACE)
392 target_link_libraries(core_interface INTERFACE sanitize_interface)
393 if(SANITIZERS)
394 # Transform list of sanitizers into -fsanitize flags, replacing "fuzzer" with
395 # "fuzzer-no-link" in sanitize_interface flags, and moving "fuzzer" to
396 # fuzzer_interface flags. If -DSANITIZERS=fuzzer is specified, the fuzz test
397 # binary should be built with -fsanitize=fuzzer (so it can use libFuzzer's
398 # main function), but libraries should be built with -fsanitize=fuzzer-no-link
399 # (so they can be linked into other executables that have their own main
400 # functions).
401 string(REGEX REPLACE "(^|,)fuzzer($|,)" "\\1fuzzer-no-link\\2" sanitize_opts "${SANITIZERS}")
402 set(fuzz_flag "")
403 if(NOT sanitize_opts STREQUAL SANITIZERS)
404 set(fuzz_flag "-fsanitize=fuzzer")
405 endif()
406
407 # First check if the compiler accepts flags. If an incompatible pair like
408 # -fsanitize=address,thread is used here, this check will fail. This will also
409 # fail if a bad argument is passed, e.g. -fsanitize=undfeined
410 try_append_cxx_flags("-fsanitize=${sanitize_opts}" TARGET sanitize_interface
411 RESULT_VAR cxx_supports_sanitizers
412 SKIP_LINK
413 )
414 if(NOT cxx_supports_sanitizers)
415 message(FATAL_ERROR "Compiler did not accept requested flags.")
416 endif()
417
418 # Some compilers (e.g. GCC) require additional libraries like libasan,
419 # libtsan, libubsan, etc. Make sure linking still works with the sanitize
420 # flag. This is a separate check so we can give a better error message when
421 # the sanitize flags are supported by the compiler but the actual sanitizer
422 # libs are missing.
423 try_append_linker_flag("-fsanitize=${sanitize_opts}" VAR SANITIZER_LDFLAGS
424 SOURCE "
425 #include <cstdint>
426 #include <cstddef>
427 extern \"C\" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return 0; }
428 int main() { return 0; }
429 "
430 RESULT_VAR linker_supports_sanitizers
431 NO_CACHE_IF_FAILED
432 )
433 if(NOT linker_supports_sanitizers)
434 message(FATAL_ERROR "Linker did not accept requested flags, you are missing required libraries.")
435 endif()
436 endif()
437 target_link_options(sanitize_interface INTERFACE ${SANITIZER_LDFLAGS})
438
439 # Define fuzzer_interface with flags intended to apply to the fuzz test binary,
440 # and perform a test compilation to determine correct value of
441 # FUZZ_BINARY_LINKS_WITHOUT_MAIN_FUNCTION.
442 if(BUILD_FUZZ_BINARY)
443 include(CheckSourceCompilesWithFlags)
444 check_cxx_source_compiles_with_flags("
445 #include <cstdint>
446 #include <cstddef>
447 extern \"C\" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return 0; }
448 // No main() function.
449 " FUZZ_BINARY_LINKS_WITHOUT_MAIN_FUNCTION
450 LDFLAGS ${SANITIZER_LDFLAGS} ${fuzz_flag}
451 LINK_LIBRARIES ${FUZZ_LIBS}
452 )
453 add_library(fuzzer_interface INTERFACE)
454 target_link_options(fuzzer_interface INTERFACE ${fuzz_flag})
455 target_link_libraries(fuzzer_interface INTERFACE ${FUZZ_LIBS})
456 endif()
457
458 include(cmake/introspection.cmake)
459
460 include(cmake/ccache.cmake)
461
462 add_library(warn_interface INTERFACE)
463 target_link_libraries(core_interface INTERFACE warn_interface)
464 if(MSVC)
465 try_append_cxx_flags("/W3" TARGET warn_interface SKIP_LINK)
466 try_append_cxx_flags("/wd4018" TARGET warn_interface SKIP_LINK)
467 try_append_cxx_flags("/wd4146" TARGET warn_interface SKIP_LINK)
468 try_append_cxx_flags("/wd4244" TARGET warn_interface SKIP_LINK)
469 try_append_cxx_flags("/wd4267" TARGET warn_interface SKIP_LINK)
470 try_append_cxx_flags("/wd4715" TARGET warn_interface SKIP_LINK)
471 try_append_cxx_flags("/wd4805" TARGET warn_interface SKIP_LINK)
472 target_compile_definitions(warn_interface INTERFACE
473 _CRT_SECURE_NO_WARNINGS
474 _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING
475 )
476 else()
477 try_append_cxx_flags("-Wall" TARGET warn_interface SKIP_LINK)
478 try_append_cxx_flags("-Wextra" TARGET warn_interface SKIP_LINK)
479 try_append_cxx_flags("-Wgnu" TARGET warn_interface SKIP_LINK)
480 try_append_cxx_flags("-Wcovered-switch-default" TARGET warn_interface SKIP_LINK)
481 # Some compilers will ignore -Wformat-security without -Wformat, so just combine the two here.
482 try_append_cxx_flags("-Wformat -Wformat-security" TARGET warn_interface SKIP_LINK)
483 try_append_cxx_flags("-Wvla" TARGET warn_interface SKIP_LINK)
484 try_append_cxx_flags("-Wshadow-field" TARGET warn_interface SKIP_LINK)
485 try_append_cxx_flags("-Wthread-safety" TARGET warn_interface SKIP_LINK)
486 try_append_cxx_flags("-Wthread-safety-pointer" TARGET warn_interface SKIP_LINK)
487 try_append_cxx_flags("-Wloop-analysis" TARGET warn_interface SKIP_LINK)
488 try_append_cxx_flags("-Wredundant-decls" TARGET warn_interface SKIP_LINK)
489 try_append_cxx_flags("-Wunused-member-function" TARGET warn_interface SKIP_LINK)
490 try_append_cxx_flags("-Wdate-time" TARGET warn_interface SKIP_LINK)
491 try_append_cxx_flags("-Wconditional-uninitialized" TARGET warn_interface SKIP_LINK)
492 try_append_cxx_flags("-Wduplicated-branches" TARGET warn_interface SKIP_LINK)
493 try_append_cxx_flags("-Wduplicated-cond" TARGET warn_interface SKIP_LINK)
494 try_append_cxx_flags("-Wlogical-op" TARGET warn_interface SKIP_LINK)
495 try_append_cxx_flags("-Woverloaded-virtual" TARGET warn_interface SKIP_LINK)
496 try_append_cxx_flags("-Wsuggest-override" TARGET warn_interface SKIP_LINK)
497 try_append_cxx_flags("-Wimplicit-fallthrough" TARGET warn_interface SKIP_LINK)
498 try_append_cxx_flags("-Wunreachable-code" TARGET warn_interface SKIP_LINK)
499 try_append_cxx_flags("-Wdocumentation" TARGET warn_interface SKIP_LINK)
500 try_append_cxx_flags("-Wself-assign" TARGET warn_interface SKIP_LINK)
501 try_append_cxx_flags("-Wbidi-chars=any" TARGET warn_interface SKIP_LINK)
502 try_append_cxx_flags("-Wundef" TARGET warn_interface SKIP_LINK)
503 try_append_cxx_flags("-Wleading-whitespace=spaces" TARGET warn_interface SKIP_LINK)
504 try_append_cxx_flags("-Wtrailing-whitespace=any" TARGET warn_interface SKIP_LINK)
505
506 # Some compilers (gcc) ignore unknown -Wno-* options, but warn about all
507 # unknown options if any other warning is produced. Test the -Wfoo case, and
508 # set the -Wno-foo case if it works.
509 try_append_cxx_flags("-Wunused-parameter" TARGET warn_interface SKIP_LINK
510 IF_CHECK_PASSED "-Wno-unused-parameter"
511 )
512 endif()
513
514 configure_file(cmake/script/Coverage.cmake Coverage.cmake USE_SOURCE_PERMISSIONS COPYONLY)
515 configure_file(cmake/script/CoverageFuzz.cmake CoverageFuzz.cmake USE_SOURCE_PERMISSIONS COPYONLY)
516 configure_file(cmake/script/CoverageInclude.cmake.in CoverageInclude.cmake USE_SOURCE_PERMISSIONS @ONLY)
517 configure_file(cmake/script/cov_tool_wrapper.sh.in cov_tool_wrapper.sh.in USE_SOURCE_PERMISSIONS COPYONLY)
518 configure_file(contrib/filter-lcov.py filter-lcov.py USE_SOURCE_PERMISSIONS COPYONLY)
519
520 # Don't allow extended (non-ASCII) symbols in identifiers. This is easier for code review.
521 try_append_cxx_flags("-fno-extended-identifiers" TARGET core_interface SKIP_LINK)
522
523 # Set `-fmacro-prefix-map`, so that source file names are expanded without the
524 # src prefix.
525 try_append_cxx_flags("-fmacro-prefix-map=A=B" TARGET core_interface SKIP_LINK
526 IF_CHECK_PASSED "-fmacro-prefix-map=${PROJECT_SOURCE_DIR}/src=."
527 )
528
529 # GCC versions 13.2 (and earlier) are subject to a class of bugs, see
530 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90348 and the meta bug
531 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111843. To work around that, set
532 # -fstack-reuse=none for all gcc builds. (Only gcc understands this flag).
533 try_append_cxx_flags("-fstack-reuse=none" TARGET core_interface)
534
535 if(MSVC)
536 try_append_linker_flag("/DYNAMICBASE" TARGET core_interface)
537 try_append_linker_flag("/HIGHENTROPYVA" TARGET core_interface)
538 try_append_linker_flag("/NXCOMPAT" TARGET core_interface)
539 else()
540
541 # _FORTIFY_SOURCE requires that there is some level of optimization,
542 # otherwise it does nothing and just creates a compiler warning.
543 try_append_cxx_flags("-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3"
544 RESULT_VAR cxx_supports_fortify_source
545 SOURCE "int main() {
546 # if !defined __OPTIMIZE__ || __OPTIMIZE__ <= 0
547 #error
548 #endif
549 }"
550 )
551 if(cxx_supports_fortify_source)
552 target_compile_options(core_interface INTERFACE
553 -U_FORTIFY_SOURCE
554 -D_FORTIFY_SOURCE=3
555 )
556 endif()
557 unset(cxx_supports_fortify_source)
558
559 try_append_cxx_flags("-Wstack-protector" TARGET core_interface SKIP_LINK)
560 try_append_cxx_flags("-fstack-protector-all" TARGET core_interface)
561 try_append_cxx_flags("-fcf-protection=full" TARGET core_interface)
562
563 if(MINGW)
564 # stack-clash-protection is a no-op for Windows.
565 # See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90458 for more details.
566 else()
567 try_append_cxx_flags("-fstack-clash-protection" TARGET core_interface)
568 endif()
569
570 if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
571 if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
572 try_append_cxx_flags("-mbranch-protection=bti" TARGET core_interface SKIP_LINK)
573 else()
574 try_append_cxx_flags("-mbranch-protection=standard" TARGET core_interface SKIP_LINK)
575 endif()
576 endif()
577
578 try_append_linker_flag("-Wl,--enable-reloc-section" TARGET core_interface)
579 try_append_linker_flag("-Wl,--dynamicbase" TARGET core_interface)
580 try_append_linker_flag("-Wl,--nxcompat" TARGET core_interface)
581 try_append_linker_flag("-Wl,--high-entropy-va" TARGET core_interface)
582 try_append_linker_flag("-Wl,-z,relro" TARGET core_interface)
583 try_append_linker_flag("-Wl,-z,now" TARGET core_interface)
584 # TODO: This can be dropped once Bitcoin Core no longer supports
585 # NetBSD 10.0 or if upstream fix is backported.
586 # NetBSD's dynamic linker ld.elf_so < 11.0 supports exactly 2
587 # `PT_LOAD` segments and binaries linked with `-z separate-code`
588 # have 4 `PT_LOAD` segments.
589 # Relevant discussions:
590 # - https://github.com/bitcoin/bitcoin/pull/28724#issuecomment-2589347934
591 # - https://mail-index.netbsd.org/tech-userlevel/2023/01/05/msg013666.html
592 if(CMAKE_SYSTEM_NAME STREQUAL "NetBSD" AND CMAKE_SYSTEM_VERSION VERSION_LESS 11.0)
593 try_append_linker_flag("-Wl,-z,noseparate-code" TARGET core_interface)
594 else()
595 try_append_linker_flag("-Wl,-z,separate-code" TARGET core_interface)
596 endif()
597 if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
598 try_append_linker_flag("-Wl,-fixup_chains" TARGET core_interface)
599 endif()
600 endif()
601
602 if(REDUCE_EXPORTS)
603 set(CMAKE_CXX_VISIBILITY_PRESET hidden)
604 try_append_linker_flag("-Wl,--exclude-libs,ALL" TARGET core_interface)
605 try_append_linker_flag("-Wl,-no_exported_symbols" VAR CMAKE_EXE_LINKER_FLAGS)
606 endif()
607
608 # Prefer Unix-style package components over frameworks on macOS.
609 # This improves compatibility with Python version managers.
610 set(Python3_FIND_FRAMEWORK LAST CACHE STRING "")
611 # Search for generic names before more specialized ones. This
612 # improves compatibility with Python version managers that use shims.
613 set(Python3_FIND_UNVERSIONED_NAMES FIRST CACHE STRING "")
614 mark_as_advanced(Python3_FIND_FRAMEWORK Python3_FIND_UNVERSIONED_NAMES)
615 find_package(Python3 3.10 COMPONENTS Interpreter)
616 if(NOT TARGET Python3::Interpreter)
617 list(APPEND configure_warnings
618 "Minimum required Python not found."
619 )
620 endif()
621
622 target_compile_definitions(core_interface INTERFACE ${DEPENDS_COMPILE_DEFINITIONS})
623 target_compile_definitions(core_interface_relwithdebinfo INTERFACE ${DEPENDS_COMPILE_DEFINITIONS_RELWITHDEBINFO})
624 target_compile_definitions(core_interface_debug INTERFACE ${DEPENDS_COMPILE_DEFINITIONS_DEBUG})
625
626 # If the {CXX,LD}FLAGS environment variables are defined during building depends
627 # and configuring this build system, their content might be duplicated.
628 if(DEFINED ENV{CXXFLAGS})
629 deduplicate_flags(CMAKE_CXX_FLAGS)
630 endif()
631 if(DEFINED ENV{LDFLAGS})
632 deduplicate_flags(CMAKE_EXE_LINKER_FLAGS)
633 endif()
634
635 if(BUILD_TESTS)
636 enable_testing()
637 endif()
638
639 if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.29)
640 # have "make test" depend on "make all"
641 set(CMAKE_SKIP_TEST_ALL_DEPENDENCY FALSE)
642 endif()
643
644 add_subdirectory(test)
645 add_subdirectory(doc)
646
647 add_subdirectory(src)
648
649 include(Maintenance)
650 setup_split_debug_script()
651 add_windows_deploy_target()
652 add_macos_deploy_target()
653
654 message("\n")
655 message("Configure summary")
656 message("=================")
657 message("Executables:")
658 message(" bitcoin ............................. ${BUILD_BITCOIN_BIN}")
659 message(" bitcoind ............................ ${BUILD_DAEMON}")
660 if(BUILD_DAEMON AND ENABLE_IPC)
661 set(bitcoin_daemon_status ON)
662 else()
663 set(bitcoin_daemon_status OFF)
664 endif()
665 message(" bitcoin-node (multiprocess) ......... ${bitcoin_daemon_status}")
666 message(" bitcoin-qt (GUI) .................... ${BUILD_GUI}")
667 if(BUILD_GUI AND ENABLE_IPC)
668 set(bitcoin_gui_status ON)
669 else()
670 set(bitcoin_gui_status OFF)
671 endif()
672 message(" bitcoin-gui (GUI, multiprocess) ..... ${bitcoin_gui_status}")
673 message(" bitcoin-cli ......................... ${BUILD_CLI}")
674 message(" bitcoin-tx .......................... ${BUILD_TX}")
675 message(" bitcoin-util ........................ ${BUILD_UTIL}")
676 message(" bitcoin-wallet ...................... ${BUILD_WALLET_TOOL}")
677 message(" bitcoin-chainstate (experimental) ... ${BUILD_UTIL_CHAINSTATE}")
678 message(" libbitcoinkernel (experimental) ..... ${BUILD_KERNEL_LIB}")
679 message(" kernel-test (experimental) .......... ${BUILD_KERNEL_TEST}")
680 message("Optional features:")
681 message(" wallet support ...................... ${ENABLE_WALLET}")
682 message(" external signer ..................... ${ENABLE_EXTERNAL_SIGNER}")
683 message(" ZeroMQ .............................. ${WITH_ZMQ}")
684 if(ENABLE_IPC)
685 if (WITH_EXTERNAL_LIBMULTIPROCESS)
686 set(ipc_status "ON (with external libmultiprocess)")
687 else()
688 set(ipc_status ON)
689 endif()
690 else()
691 set(ipc_status OFF)
692 endif()
693 message(" IPC ................................. ${ipc_status}")
694 message(" Embedded ASMap ...................... ${WITH_EMBEDDED_ASMAP}")
695 message(" USDT tracing ........................ ${WITH_USDT}")
696 message(" QR code (GUI) ....................... ${WITH_QRENCODE}")
697 message(" DBus (GUI) .......................... ${WITH_DBUS}")
698 message("Tests:")
699 message(" test_bitcoin ........................ ${BUILD_TESTS}")
700 message(" test_bitcoin-qt ..................... ${BUILD_GUI_TESTS}")
701 message(" bench_bitcoin ....................... ${BUILD_BENCH}")
702 message(" fuzz binary ......................... ${BUILD_FUZZ_BINARY}")
703 message("")
704 if(CMAKE_CROSSCOMPILING)
705 set(cross_status "TRUE, for ${CMAKE_SYSTEM_NAME}, ${CMAKE_SYSTEM_PROCESSOR}")
706 else()
707 set(cross_status "FALSE")
708 endif()
709 message("Cross compiling ....................... ${cross_status}")
710 message("C++ compiler .......................... ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}, ${CMAKE_CXX_COMPILER}")
711 include(FlagsSummary)
712 flags_summary()
713 message("Treat compiler warnings as errors ..... ${CMAKE_COMPILE_WARNING_AS_ERROR}")
714 message("Use ccache for compiling .............. ${WITH_CCACHE}")
715 message("\n")
716 if(configure_warnings)
717 message(" ******\n")
718 foreach(warning IN LISTS configure_warnings)
719 message(WARNING "${warning}")
720 endforeach()
721 message(" ******\n")
722 message(AUTHOR_WARNING "Warnings have been encountered!")
723 endif()
724
725 # We want all build properties to be encapsulated properly.
726 include(WarnAboutGlobalProperties)
727