From b817f51ee1b0c1ec55c742522fa5be1efe5f0075 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Fri, 8 Dec 2023 19:50:24 +0000 Subject: [PATCH 01/47] cmake: Add root `CMakeLists.txt` file --- CMakeLists.txt | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000000000..fee87cd161142 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,79 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# IMPORTANT: Changes which affect binary results may not be quietly gated +# by CMake version. +# +# Ubuntu 20.04 LTS Focal Fossa, https://wiki.ubuntu.com/Releases, EOSS in April 2025: +# - CMake 3.16.3, https://packages.ubuntu.com/focal/cmake +# +# Centos Stream 8, EOL in May 2024: +# - CMake 3.20.2, http://mirror.centos.org/centos/8-stream/AppStream/x86_64/os/Packages/ +# +# All policies known to the running version of CMake and introduced +# in the 3.28 version or earlier will be set to use NEW behavior. +# All policies introduced in later versions will be unset. +# See: https://cmake.org/cmake/help/latest/manual/cmake-policies.7.html +cmake_minimum_required(VERSION 3.16...3.28) + +project("Bitcoin Core" + VERSION 26.99.0 + DESCRIPTION "Bitcoin client software" + HOMEPAGE_URL "https://bitcoincore.org/" + LANGUAGES CXX ASM +) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +set(configure_warnings) + +message("\n") +message("Configure summary") +message("=================") +get_directory_property(definitions COMPILE_DEFINITIONS) +string(REPLACE ";" " " definitions "${definitions}") +message("Preprocessor defined macros ........... ${definitions}") +message("C compiler ............................ ${CMAKE_C_COMPILER}") +message("CFLAGS ................................ ${CMAKE_C_FLAGS}") +message("C++ compiler .......................... ${CMAKE_CXX_COMPILER}") +message("CXXFLAGS .............................. ${CMAKE_CXX_FLAGS}") +get_directory_property(common_compile_options COMPILE_OPTIONS) +string(REPLACE ";" " " common_compile_options "${common_compile_options}") +message("Common compile options ................ ${common_compile_options}") +get_directory_property(common_link_options LINK_OPTIONS) +string(REPLACE ";" " " common_link_options "${common_link_options}") +message("Common link options ................... ${common_link_options}") +message("Linker flags for executables .......... ${CMAKE_EXE_LINKER_FLAGS}") +message("Linker flags for shared libraries ..... ${CMAKE_SHARED_LINKER_FLAGS}") +if(DEFINED CMAKE_BUILD_TYPE) + message("Build type:") + message(" - CMAKE_BUILD_TYPE ................... ${CMAKE_BUILD_TYPE}") + string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type) + message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_${build_type}}") + message(" - CXXFLAGS ........................... ${CMAKE_CXX_FLAGS_${build_type}}") + message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_${build_type}}") + message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_${build_type}}") +else() + message("Available configurations .............. ${CMAKE_CONFIGURATION_TYPES}") + message("Debug configuration:") + message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_DEBUG}") + message(" - CXXFLAGS ........................... ${CMAKE_CXX_FLAGS_DEBUG}") + message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_DEBUG}") + message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}") + message("Release configuration:") + message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_RELEASE}") + message(" - CXXFLAGS ........................... ${CMAKE_CXX_FLAGS_RELEASE}") + message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_RELEASE}") + message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") +endif() +message("\n") +if(configure_warnings) + message(" ******\n") + foreach(warning IN LISTS configure_warnings) + message(WARNING "${warning}") + endforeach() + message(" ******\n") +endif() From dd0a86f5dca6f728df6f638662c3dcf6e732bc41 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sat, 2 Sep 2023 17:40:13 +0100 Subject: [PATCH 02/47] cmake: Warn about not encapsulated build properties --- CMakeLists.txt | 3 ++ cmake/module/WarnAboutGlobalProperties.cmake | 35 ++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 cmake/module/WarnAboutGlobalProperties.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index fee87cd161142..84f15fe98c0c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,3 +77,6 @@ if(configure_warnings) endforeach() message(" ******\n") endif() + +# We want all build properties to be encapsulated properly. +include(WarnAboutGlobalProperties) diff --git a/cmake/module/WarnAboutGlobalProperties.cmake b/cmake/module/WarnAboutGlobalProperties.cmake new file mode 100644 index 0000000000000..1cf3a6be86742 --- /dev/null +++ b/cmake/module/WarnAboutGlobalProperties.cmake @@ -0,0 +1,35 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +include_guard(GLOBAL) + +# Avoid the directory-wide add_definitions() and add_compile_definitions() commands. +# Instead, prefer the target-specific target_compile_definitions() one. +get_directory_property(global_compile_definitions COMPILE_DEFINITIONS) +if(global_compile_definitions) + message(AUTHOR_WARNING "The directory's COMPILE_DEFINITIONS property is not empty: ${global_compile_definitions}") +endif() + +# Avoid the directory-wide add_compile_options() command. +# Instead, prefer the target-specific target_compile_options() one. +get_directory_property(global_compile_options COMPILE_OPTIONS) +if(global_compile_options) + message(AUTHOR_WARNING "The directory's COMPILE_OPTIONS property is not empty: ${global_compile_options}") +endif() + +# Avoid the directory-wide add_link_options() command. +# Instead, prefer the target-specific target_link_options() one. +get_directory_property(global_link_options LINK_OPTIONS) +if(global_link_options) + message(AUTHOR_WARNING "The directory's LINK_OPTIONS property is not empty: ${global_link_options}") +endif() + +# Avoid the directory-wide link_libraries() command. +# Instead, prefer the target-specific target_link_libraries() one. +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dummy_cxx_source.cpp "#error") +add_library(check_loose_linked_libraries OBJECT EXCLUDE_FROM_ALL ${CMAKE_CURRENT_BINARY_DIR}/dummy_cxx_source.cpp) +get_target_property(global_linked_libraries check_loose_linked_libraries LINK_LIBRARIES) +if(global_linked_libraries) + message(AUTHOR_WARNING "There are libraries linked with `link_libraries` commands: ${global_linked_libraries}") +endif() From c5964fea692db5a218f60f4ae82b8ea4a12958b9 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Wed, 15 Feb 2023 18:24:07 +0000 Subject: [PATCH 03/47] cmake: Add `config/bitcoin-config.h` support --- CMakeLists.txt | 8 +++++++ cmake/bitcoin-config.h.in | 45 +++++++++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 7 ++++++ 3 files changed, 60 insertions(+) create mode 100644 cmake/bitcoin-config.h.in create mode 100644 src/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 84f15fe98c0c5..fa815ad0aba2f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,12 +24,20 @@ project("Bitcoin Core" LANGUAGES CXX ASM ) +set(CLIENT_VERSION_IS_RELEASE "false") +set(COPYRIGHT_YEAR "2023") +set(COPYRIGHT_HOLDERS "The %s developers") +set(COPYRIGHT_HOLDERS_FINAL "The ${PROJECT_NAME} developers") +set(PACKAGE_BUGREPORT "https://github.com/bitcoin/bitcoin/issues") + set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) set(configure_warnings) +add_subdirectory(src) + message("\n") message("Configure summary") message("=================") diff --git a/cmake/bitcoin-config.h.in b/cmake/bitcoin-config.h.in new file mode 100644 index 0000000000000..3195c6a526c3d --- /dev/null +++ b/cmake/bitcoin-config.h.in @@ -0,0 +1,45 @@ +// Copyright (c) 2023 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_CONFIG_H + +#define BITCOIN_CONFIG_H + +/* Version Build */ +#define CLIENT_VERSION_BUILD @PROJECT_VERSION_PATCH@ + +/* Version is release */ +#define CLIENT_VERSION_IS_RELEASE @CLIENT_VERSION_IS_RELEASE@ + +/* Major version */ +#define CLIENT_VERSION_MAJOR @PROJECT_VERSION_MAJOR@ + +/* Minor version */ +#define CLIENT_VERSION_MINOR @PROJECT_VERSION_MINOR@ + +/* Copyright holder(s) before %s replacement */ +#define COPYRIGHT_HOLDERS "@COPYRIGHT_HOLDERS@" + +/* Copyright holder(s) */ +#define COPYRIGHT_HOLDERS_FINAL "@COPYRIGHT_HOLDERS_FINAL@" + +/* Replacement for %s in copyright holders string */ +#define COPYRIGHT_HOLDERS_SUBSTITUTION "@PROJECT_NAME@" + +/* Copyright year */ +#define COPYRIGHT_YEAR @COPYRIGHT_YEAR@ + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "@PROJECT_NAME@" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "@PROJECT_HOMEPAGE_URL@" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "@PROJECT_VERSION@" + +#endif //BITCOIN_CONFIG_H diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000000000..1937b787f19ff --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +configure_file(${CMAKE_SOURCE_DIR}/cmake/bitcoin-config.h.in config/bitcoin-config.h @ONLY) +add_compile_definitions(HAVE_CONFIG_H) +include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) From 56fb65deb133923c18411697783a06fff5e4fb7e Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Fri, 31 Mar 2023 23:20:44 +0100 Subject: [PATCH 04/47] cmake: Add `cmake/introspection.cmake` file --- CMakeLists.txt | 2 ++ cmake/bitcoin-config.h.in | 4 ++++ cmake/introspection.cmake | 7 +++++++ 3 files changed, 13 insertions(+) create mode 100644 cmake/introspection.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index fa815ad0aba2f..99190ddff738f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,8 @@ set(CMAKE_CXX_EXTENSIONS OFF) set(configure_warnings) +include(cmake/introspection.cmake) + add_subdirectory(src) message("\n") diff --git a/cmake/bitcoin-config.h.in b/cmake/bitcoin-config.h.in index 3195c6a526c3d..1f0ff4d17a582 100644 --- a/cmake/bitcoin-config.h.in +++ b/cmake/bitcoin-config.h.in @@ -42,4 +42,8 @@ /* Define to the version of this package. */ #define PACKAGE_VERSION "@PROJECT_VERSION@" +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#cmakedefine WORDS_BIGENDIAN 1 + #endif //BITCOIN_CONFIG_H diff --git a/cmake/introspection.cmake b/cmake/introspection.cmake new file mode 100644 index 0000000000000..edb09d22c1fed --- /dev/null +++ b/cmake/introspection.cmake @@ -0,0 +1,7 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +include(TestBigEndian) + +test_big_endian(WORDS_BIGENDIAN) From 9f07e9035baff23d84eb4bd27bb4265cd1b1bcb1 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Tue, 21 Feb 2023 20:30:08 +0000 Subject: [PATCH 05/47] cmake: Check system headers --- cmake/bitcoin-config.h.in | 21 +++++++++++++++++++++ cmake/introspection.cmake | 10 ++++++++++ 2 files changed, 31 insertions(+) diff --git a/cmake/bitcoin-config.h.in b/cmake/bitcoin-config.h.in index 1f0ff4d17a582..4bcf82df9899d 100644 --- a/cmake/bitcoin-config.h.in +++ b/cmake/bitcoin-config.h.in @@ -30,6 +30,27 @@ /* Copyright year */ #define COPYRIGHT_YEAR @COPYRIGHT_YEAR@ +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_BYTESWAP_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ENDIAN_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_ENDIAN_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_PRCTL_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_RESOURCES_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_VMMETER_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_VM_VM_PARAM_H 1 + /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@" diff --git a/cmake/introspection.cmake b/cmake/introspection.cmake index edb09d22c1fed..5c399d1cf1872 100644 --- a/cmake/introspection.cmake +++ b/cmake/introspection.cmake @@ -2,6 +2,16 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. +include(CheckIncludeFileCXX) include(TestBigEndian) test_big_endian(WORDS_BIGENDIAN) + +# The following HAVE_{HEADER}_H variables go to the bitcoin-config.h header. +check_include_file_cxx(byteswap.h HAVE_BYTESWAP_H) +check_include_file_cxx(endian.h HAVE_ENDIAN_H) +check_include_file_cxx(sys/endian.h HAVE_SYS_ENDIAN_H) +check_include_file_cxx(sys/prctl.h HAVE_SYS_PRCTL_H) +check_include_file_cxx(sys/resources.h HAVE_SYS_RESOURCES_H) +check_include_file_cxx(sys/vmmeter.h HAVE_SYS_VMMETER_H) +check_include_file_cxx(vm/vm_param.h HAVE_VM_VM_PARAM_H) From 110f42e274a362e4e77efbded5223c3c5809814b Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Fri, 8 Dec 2023 20:19:09 +0000 Subject: [PATCH 06/47] cmake: Check system symbols Co-authored-by: Cory Fields Co-authored-by: Vasil Dimov --- CMakeLists.txt | 3 + cmake/bitcoin-config.h.in | 126 +++++++++++ cmake/introspection.cmake | 208 ++++++++++++++++++ .../module/CheckSourceCompilesAndLinks.cmake | 38 ++++ .../module/TestAppendRequiredLibraries.cmake | 77 +++++++ 5 files changed, 452 insertions(+) create mode 100644 cmake/module/CheckSourceCompilesAndLinks.cmake create mode 100644 cmake/module/TestAppendRequiredLibraries.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 99190ddff738f..6332e7bdbadd9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,8 +34,11 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/module) + set(configure_warnings) +include(CheckSourceCompilesAndLinks) include(cmake/introspection.cmake) add_subdirectory(src) diff --git a/cmake/bitcoin-config.h.in b/cmake/bitcoin-config.h.in index 4bcf82df9899d..759bcb8d1cb28 100644 --- a/cmake/bitcoin-config.h.in +++ b/cmake/bitcoin-config.h.in @@ -30,15 +30,138 @@ /* Copyright year */ #define COPYRIGHT_YEAR @COPYRIGHT_YEAR@ +/* Define this symbol if you have __builtin_clzl */ +#cmakedefine HAVE_BUILTIN_CLZL 1 + +/* Define this symbol if you have __builtin_clzll */ +#cmakedefine HAVE_BUILTIN_CLZLL 1 + /* Define to 1 if you have the header file. */ #cmakedefine HAVE_BYTESWAP_H 1 +/* Define to 1 if you have the declaration of `be16toh', and to 0 if you + don't. */ +#cmakedefine01 HAVE_DECL_BE16TOH + +/* Define to 1 if you have the declaration of `be32toh', and to 0 if you + don't. */ +#cmakedefine01 HAVE_DECL_BE32TOH + +/* Define to 1 if you have the declaration of `be64toh', and to 0 if you + don't. */ +#cmakedefine01 HAVE_DECL_BE64TOH + +/* Define to 1 if you have the declaration of `bswap_16', and to 0 if you + don't. */ +#cmakedefine01 HAVE_DECL_BSWAP_16 + +/* Define to 1 if you have the declaration of `bswap_32', and to 0 if you + don't. */ +#cmakedefine01 HAVE_DECL_BSWAP_32 + +/* Define to 1 if you have the declaration of `bswap_64', and to 0 if you + don't. */ +#cmakedefine01 HAVE_DECL_BSWAP_64 + +/* Define to 1 if you have the declaration of `fork', and to 0 if you don't. + */ +#cmakedefine01 HAVE_DECL_FORK + +/* Define to 1 if you have the declaration of `freeifaddrs', and to 0 if you + don't. */ +#cmakedefine01 HAVE_DECL_FREEIFADDRS + +/* Define to 1 if you have the declaration of `getifaddrs', and to 0 if you + don't. */ +#cmakedefine01 HAVE_DECL_GETIFADDRS + +/* Define to 1 if you have the declaration of `htobe16', and to 0 if you + don't. */ +#cmakedefine01 HAVE_DECL_HTOBE16 + +/* Define to 1 if you have the declaration of `htobe32', and to 0 if you + don't. */ +#cmakedefine01 HAVE_DECL_HTOBE32 + +/* Define to 1 if you have the declaration of `htobe64', and to 0 if you + don't. */ +#cmakedefine01 HAVE_DECL_HTOBE64 + +/* Define to 1 if you have the declaration of `htole16', and to 0 if you + don't. */ +#cmakedefine01 HAVE_DECL_HTOLE16 + +/* Define to 1 if you have the declaration of `htole32', and to 0 if you + don't. */ +#cmakedefine01 HAVE_DECL_HTOLE32 + +/* Define to 1 if you have the declaration of `htole64', and to 0 if you + don't. */ +#cmakedefine01 HAVE_DECL_HTOLE64 + +/* Define to 1 if you have the declaration of `le16toh', and to 0 if you + don't. */ +#cmakedefine01 HAVE_DECL_LE16TOH + +/* Define to 1 if you have the declaration of `le32toh', and to 0 if you + don't. */ +#cmakedefine01 HAVE_DECL_LE32TOH + +/* Define to 1 if you have the declaration of `le64toh', and to 0 if you + don't. */ +#cmakedefine01 HAVE_DECL_LE64TOH + +/* Define to 1 if you have the declaration of `pipe2', and to 0 if you don't. + */ +#cmakedefine01 HAVE_DECL_PIPE2 + +/* Define to 1 if you have the declaration of `setsid', and to 0 if you don't. + */ +#cmakedefine01 HAVE_DECL_SETSID + /* Define to 1 if you have the header file. */ #cmakedefine HAVE_ENDIAN_H 1 +/* Define to 1 if fdatasync is available. */ +#cmakedefine HAVE_FDATASYNC 1 + +/* Define this symbol if the BSD getentropy system call is available with + sys/random.h */ +#cmakedefine HAVE_GETENTROPY_RAND 1 + +/* Define this symbol if gmtime_r is available */ +#cmakedefine HAVE_GMTIME_R 1 + +/* Define this symbol if you have malloc_info */ +#cmakedefine HAVE_MALLOC_INFO 1 + +/* Define this symbol if you have mallopt with M_ARENA_MAX */ +#cmakedefine HAVE_MALLOPT_ARENA_MAX 1 + +/* Define to 1 if O_CLOEXEC flag is available. */ +#cmakedefine01 HAVE_O_CLOEXEC + +/* Define this symbol if you have posix_fallocate */ +#cmakedefine HAVE_POSIX_FALLOCATE 1 + +/* Define this symbol to build code that uses getauxval) */ +#cmakedefine HAVE_STRONG_GETAUXVAL 1 + +/* Define this symbol if the BSD sysctl() is available */ +#cmakedefine HAVE_SYSCTL 1 + +/* Define this symbol if the BSD sysctl(KERN_ARND) is available */ +#cmakedefine HAVE_SYSCTL_ARND 1 + +/* Define to 1 if std::system or ::wsystem is available. */ +#cmakedefine HAVE_SYSTEM 1 + /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_ENDIAN_H 1 +/* Define this symbol if the Linux getrandom system call is available */ +#cmakedefine HAVE_SYS_GETRANDOM 1 + /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_PRCTL_H 1 @@ -63,6 +186,9 @@ /* Define to the version of this package. */ #define PACKAGE_VERSION "@PROJECT_VERSION@" +/* Define to 1 if strerror_r returns char *. */ +#cmakedefine STRERROR_R_CHAR_P 1 + /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #cmakedefine WORDS_BIGENDIAN 1 diff --git a/cmake/introspection.cmake b/cmake/introspection.cmake index 5c399d1cf1872..313060f371a7e 100644 --- a/cmake/introspection.cmake +++ b/cmake/introspection.cmake @@ -2,6 +2,8 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. +include(CheckCXXSourceCompiles) +include(CheckCXXSymbolExists) include(CheckIncludeFileCXX) include(TestBigEndian) @@ -15,3 +17,209 @@ check_include_file_cxx(sys/prctl.h HAVE_SYS_PRCTL_H) check_include_file_cxx(sys/resources.h HAVE_SYS_RESOURCES_H) check_include_file_cxx(sys/vmmeter.h HAVE_SYS_VMMETER_H) check_include_file_cxx(vm/vm_param.h HAVE_VM_VM_PARAM_H) + +check_cxx_source_compiles(" + int main() + { + (void) __builtin_clzl(0); + } + " HAVE_BUILTIN_CLZL +) + +check_cxx_source_compiles(" + int main() + { + (void) __builtin_clzll(0); + } + " HAVE_BUILTIN_CLZLL +) + +check_cxx_symbol_exists(O_CLOEXEC "fcntl.h" HAVE_O_CLOEXEC) + +if(HAVE_BYTESWAP_H) + check_cxx_symbol_exists(bswap_16 "byteswap.h" HAVE_DECL_BSWAP_16) + check_cxx_symbol_exists(bswap_32 "byteswap.h" HAVE_DECL_BSWAP_32) + check_cxx_symbol_exists(bswap_64 "byteswap.h" HAVE_DECL_BSWAP_64) +endif() + +if(HAVE_ENDIAN_H OR HAVE_SYS_ENDIAN_H) + if(HAVE_ENDIAN_H) + set(ENDIAN_HEADER "endian.h") + else() + set(ENDIAN_HEADER "sys/endian.h") + endif() + check_cxx_symbol_exists(be16toh ${ENDIAN_HEADER} HAVE_DECL_BE16TOH) + check_cxx_symbol_exists(be32toh ${ENDIAN_HEADER} HAVE_DECL_BE32TOH) + check_cxx_symbol_exists(be64toh ${ENDIAN_HEADER} HAVE_DECL_BE64TOH) + check_cxx_symbol_exists(htobe16 ${ENDIAN_HEADER} HAVE_DECL_HTOBE16) + check_cxx_symbol_exists(htobe32 ${ENDIAN_HEADER} HAVE_DECL_HTOBE32) + check_cxx_symbol_exists(htobe64 ${ENDIAN_HEADER} HAVE_DECL_HTOBE64) + check_cxx_symbol_exists(htole16 ${ENDIAN_HEADER} HAVE_DECL_HTOLE16) + check_cxx_symbol_exists(htole32 ${ENDIAN_HEADER} HAVE_DECL_HTOLE32) + check_cxx_symbol_exists(htole64 ${ENDIAN_HEADER} HAVE_DECL_HTOLE64) + check_cxx_symbol_exists(le16toh ${ENDIAN_HEADER} HAVE_DECL_LE16TOH) + check_cxx_symbol_exists(le32toh ${ENDIAN_HEADER} HAVE_DECL_LE32TOH) + check_cxx_symbol_exists(le64toh ${ENDIAN_HEADER} HAVE_DECL_LE64TOH) +endif() + +check_include_file_cxx(unistd.h HAVE_UNISTD_H) +if(HAVE_UNISTD_H) + check_cxx_symbol_exists(fdatasync "unistd.h" HAVE_FDATASYNC) + check_cxx_symbol_exists(fork "unistd.h" HAVE_DECL_FORK) + check_cxx_symbol_exists(pipe2 "unistd.h" HAVE_DECL_PIPE2) + check_cxx_symbol_exists(setsid "unistd.h" HAVE_DECL_SETSID) +endif() + +check_include_file_cxx(sys/types.h HAVE_SYS_TYPES_H) +check_include_file_cxx(ifaddrs.h HAVE_IFADDRS_H) +if(HAVE_SYS_TYPES_H AND HAVE_IFADDRS_H) + check_cxx_symbol_exists(freeifaddrs "sys/types.h;ifaddrs.h" HAVE_DECL_FREEIFADDRS) + check_cxx_symbol_exists(getifaddrs "sys/types.h;ifaddrs.h" HAVE_DECL_GETIFADDRS) + if(HAVE_DECL_GETIFADDRS AND HAVE_DECL_FREEIFADDRS) + include(TestAppendRequiredLibraries) + test_append_socket_library(core) + endif() +endif() + +include(TestAppendRequiredLibraries) +test_append_atomic_library(core) + +# Check for gmtime_r(), fallback to gmtime_s() if that is unavailable. +# Fail if neither are available. +check_cxx_source_compiles(" + #include + + int main() + { + gmtime_r((const time_t*)nullptr, (struct tm*)nullptr); + } + " HAVE_GMTIME_R +) +if(NOT HAVE_GMTIME_R) + check_cxx_source_compiles(" + #include + + int main() + { + gmtime_s((struct tm*)nullptr, (const time_t*)nullptr); + } + " HAVE_GMTIME_S + ) + if(NOT HAVE_GMTIME_S) + message(FATAL_ERROR "Both gmtime_r and gmtime_s are unavailable.") + endif() +endif() + +check_cxx_symbol_exists(std::system "cstdlib" HAVE_STD_SYSTEM) +check_cxx_symbol_exists(::_wsystem "stdlib.h" HAVE__WSYSTEM) +if(HAVE_STD_SYSTEM OR HAVE__WSYSTEM) + set(HAVE_SYSTEM 1) +endif() + +check_include_file_cxx(string.h HAVE_STRING_H) +if(HAVE_STRING_H) + check_cxx_source_compiles(" + #include + + int main() + { + char buf[100]; + char* p{strerror_r(0, buf, sizeof buf)}; + (void)p; + } + " STRERROR_R_CHAR_P + ) +endif() + +# Check for malloc_info (for memory statistics information in getmemoryinfo). +check_cxx_symbol_exists(malloc_info "malloc.h" HAVE_MALLOC_INFO) + +# Check for mallopt(M_ARENA_MAX) (to set glibc arenas). +check_cxx_source_compiles(" + #include + + int main() + { + mallopt(M_ARENA_MAX, 1); + } + " HAVE_MALLOPT_ARENA_MAX +) + +# Check for posix_fallocate(). +check_cxx_source_compiles(" + // same as in src/util/fs_helpers.cpp + #ifdef __linux__ + #ifdef _POSIX_C_SOURCE + #undef _POSIX_C_SOURCE + #endif + #define _POSIX_C_SOURCE 200112L + #endif // __linux__ + #include + + int main() + { + return posix_fallocate(0, 0, 0); + } + " HAVE_POSIX_FALLOCATE +) + +# Check for strong getauxval() support in the system headers. +check_cxx_source_compiles(" + #include + + int main() + { + getauxval(AT_HWCAP); + } + " HAVE_STRONG_GETAUXVAL +) + +# Check for different ways of gathering OS randomness: +# - Linux getrandom() +check_cxx_source_compiles(" + #include + #include + #include + + int main() + { + syscall(SYS_getrandom, nullptr, 32, 0); + } + " HAVE_SYS_GETRANDOM +) + +# - BSD getentropy() +check_cxx_symbol_exists(getentropy "unistd.h;sys/random.h" HAVE_GETENTROPY_RAND) + +# - BSD sysctl() +check_cxx_source_compiles(" + #include + #include + + #ifdef __linux__ + #error Don't use sysctl on Linux, it's deprecated even when it works + #endif + + int main() + { + sysctl(nullptr, 2, nullptr, nullptr, nullptr, 0); + } + " HAVE_SYSCTL +) + +# - BSD sysctl(KERN_ARND) +check_cxx_source_compiles(" + #include + #include + + #ifdef __linux__ + #error Don't use sysctl on Linux, it's deprecated even when it works + #endif + + int main() + { + static int name[2] = {CTL_KERN, KERN_ARND}; + sysctl(name, 2, nullptr, nullptr, nullptr, 0); + } + " HAVE_SYSCTL_ARND +) diff --git a/cmake/module/CheckSourceCompilesAndLinks.cmake b/cmake/module/CheckSourceCompilesAndLinks.cmake new file mode 100644 index 0000000000000..d1cd42a500561 --- /dev/null +++ b/cmake/module/CheckSourceCompilesAndLinks.cmake @@ -0,0 +1,38 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +include(CheckCXXSourceCompiles) +include(CMakePushCheckState) + +# This avoids running the linker. +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + +macro(check_cxx_source_links source) + set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE) + check_cxx_source_compiles("${source}" ${ARGN}) + set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) +endmacro() + +macro(check_cxx_source_compiles_with_flags flags source) + cmake_push_check_state(RESET) + set(CMAKE_REQUIRED_FLAGS ${flags}) + list(JOIN CMAKE_REQUIRED_FLAGS " " CMAKE_REQUIRED_FLAGS) + check_cxx_source_compiles("${source}" ${ARGN}) + cmake_pop_check_state() +endmacro() + +macro(check_cxx_source_links_with_flags flags source) + cmake_push_check_state(RESET) + set(CMAKE_REQUIRED_FLAGS ${flags}) + list(JOIN CMAKE_REQUIRED_FLAGS " " CMAKE_REQUIRED_FLAGS) + check_cxx_source_links("${source}" ${ARGN}) + cmake_pop_check_state() +endmacro() + +macro(check_cxx_source_links_with_libs libs source) + cmake_push_check_state(RESET) + set(CMAKE_REQUIRED_LIBRARIES "${libs}") + check_cxx_source_links("${source}" ${ARGN}) + cmake_pop_check_state() +endmacro() diff --git a/cmake/module/TestAppendRequiredLibraries.cmake b/cmake/module/TestAppendRequiredLibraries.cmake new file mode 100644 index 0000000000000..c6dc93742a519 --- /dev/null +++ b/cmake/module/TestAppendRequiredLibraries.cmake @@ -0,0 +1,77 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +include_guard(GLOBAL) + +# Illumos/SmartOS requires linking with -lsocket if +# using getifaddrs & freeifaddrs. +# See: https://github.com/bitcoin/bitcoin/pull/21486 +function(test_append_socket_library target) + set(check_socket_source " + #include + #include + + int main() { + struct ifaddrs* ifaddr; + getifaddrs(&ifaddr); + freeifaddrs(ifaddr); + } + ") + + include(CheckSourceCompilesAndLinks) + check_cxx_source_links("${check_socket_source}" IFADDR_LINKS_WITHOUT_LIBSOCKET) + if(IFADDR_LINKS_WITHOUT_LIBSOCKET) + return() + endif() + + check_cxx_source_links_with_libs(socket "${check_socket_source}" IFADDR_NEEDS_LINK_TO_LIBSOCKET) + if(IFADDR_NEEDS_LINK_TO_LIBSOCKET) + target_link_libraries(${target} INTERFACE socket) + else() + message(FATAL_ERROR "Cannot figure out how to use getifaddrs/freeifaddrs.") + endif() +endfunction() + +# Clang prior to version 15, when building for 32-bit, +# and linking against libstdc++, requires linking with +# -latomic if using the C++ atomic library. +# Can be tested with: clang++ test.cpp -m32 +# +# Sourced from http://bugs.debian.org/797228 +function(test_append_atomic_library target) + set(check_atomic_source " + #include + #include + #include + + using namespace std::chrono_literals; + + int main() { + std::atomic lock{true}; + lock.exchange(false); + + std::atomic t{0s}; + t.store(2s); + + std::atomic a{}; + + int64_t v = 5; + int64_t r = a.fetch_add(v); + return static_cast(r); + } + ") + + include(CheckSourceCompilesAndLinks) + check_cxx_source_links("${check_atomic_source}" STD_ATOMIC_LINKS_WITHOUT_LIBATOMIC) + if(STD_ATOMIC_LINKS_WITHOUT_LIBATOMIC) + return() + endif() + + check_cxx_source_links_with_libs(atomic "${check_atomic_source}" STD_ATOMIC_NEEDS_LINK_TO_LIBATOMIC) + if(STD_ATOMIC_NEEDS_LINK_TO_LIBATOMIC) + target_link_libraries(${target} INTERFACE atomic) + else() + message(FATAL_ERROR "Cannot figure out how to use std::atomic.") + endif() +endfunction() From 17839ed492ca7725c56085898f26eea7ad6e4262 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sun, 17 Sep 2023 16:27:18 +0100 Subject: [PATCH 07/47] cmake: Check compiler features --- cmake/bitcoin-config.h.in | 9 +++++++++ cmake/introspection.cmake | 23 +++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/cmake/bitcoin-config.h.in b/cmake/bitcoin-config.h.in index 759bcb8d1cb28..7a3cf24f440a5 100644 --- a/cmake/bitcoin-config.h.in +++ b/cmake/bitcoin-config.h.in @@ -6,6 +6,9 @@ #define BITCOIN_CONFIG_H +/* Define this symbol if type char equals int8_t */ +#cmakedefine CHAR_EQUALS_INT8 1 + /* Version Build */ #define CLIENT_VERSION_BUILD @PROJECT_VERSION_PATCH@ @@ -119,6 +122,12 @@ */ #cmakedefine01 HAVE_DECL_SETSID +/* Define if the visibility attribute is supported. */ +#cmakedefine HAVE_DEFAULT_VISIBILITY_ATTRIBUTE 1 + +/* Define if the dllexport attribute is supported. */ +#cmakedefine HAVE_DLLEXPORT_ATTRIBUTE 1 + /* Define to 1 if you have the header file. */ #cmakedefine HAVE_ENDIAN_H 1 diff --git a/cmake/introspection.cmake b/cmake/introspection.cmake index 313060f371a7e..2e30bdf8bbc8c 100644 --- a/cmake/introspection.cmake +++ b/cmake/introspection.cmake @@ -223,3 +223,26 @@ check_cxx_source_compiles(" } " HAVE_SYSCTL_ARND ) + +check_cxx_source_compiles(" + #include + #include + + int main() + { + static_assert(std::is_same::value); + } + " CHAR_EQUALS_INT8 +) + +check_cxx_source_compiles(" + int foo(void) __attribute__((visibility(\"default\"))); + int main(){} + " HAVE_DEFAULT_VISIBILITY_ATTRIBUTE +) + +check_cxx_source_compiles(" + __declspec(dllexport) int foo(void); + int main(){} + " HAVE_DLLEXPORT_ATTRIBUTE +) From 8575887e9c8100983de49e877fac95de76d1506f Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sun, 17 Sep 2023 16:31:06 +0100 Subject: [PATCH 08/47] cmake: Add position independent code support --- CMakeLists.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6332e7bdbadd9..b951107ed5bbf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,6 +38,16 @@ list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/module) set(configure_warnings) +include(CheckPIESupported) +check_pie_supported(OUTPUT_VARIABLE check_pie_output LANGUAGES CXX) +if(CMAKE_CXX_LINK_PIE_SUPPORTED) + set(CMAKE_POSITION_INDEPENDENT_CODE ON) +else() + message(WARNING "PIE is not supported at link time: ${check_pie_output}") + list(APPEND configure_warnings "Position independent code disabled.") +endif() +unset(check_pie_output) + include(CheckSourceCompilesAndLinks) include(cmake/introspection.cmake) From 8d0dfeacc9d069416ce23b6c92f3980851525018 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Wed, 13 Sep 2023 20:15:17 +0100 Subject: [PATCH 09/47] cmake: Build `crc32c` static library --- CMakeLists.txt | 2 + cmake/crc32c.cmake | 115 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 cmake/crc32c.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index b951107ed5bbf..a5cb2aa0560e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,8 @@ unset(check_pie_output) include(CheckSourceCompilesAndLinks) include(cmake/introspection.cmake) +include(cmake/crc32c.cmake) + add_subdirectory(src) message("\n") diff --git a/cmake/crc32c.cmake b/cmake/crc32c.cmake new file mode 100644 index 0000000000000..478f8e5e268d6 --- /dev/null +++ b/cmake/crc32c.cmake @@ -0,0 +1,115 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# This file is part of the transition from Autotools to CMake. Once CMake +# support has been merged we should switch to using the upstream CMake +# buildsystem. + +include(CheckCXXSourceCompiles) + +# Check for __builtin_prefetch support in the compiler. +check_cxx_source_compiles(" + int main() { + char data = 0; + const char* address = &data; + __builtin_prefetch(address, 0, 0); + return 0; + } + " HAVE_BUILTIN_PREFETCH +) + +# Check for _mm_prefetch support in the compiler. +check_cxx_source_compiles(" + #if defined(_MSC_VER) + #include + #else + #include + #endif + + int main() { + char data = 0; + const char* address = &data; + _mm_prefetch(address, _MM_HINT_NTA); + return 0; + } + " HAVE_MM_PREFETCH +) + +# Check for SSE4.2 support in the compiler. +if(MSVC) + set(SSE42_CXXFLAGS /arch:AVX) +else() + set(SSE42_CXXFLAGS -msse4.2) +endif() +check_cxx_source_compiles_with_flags("${SSE42_CXXFLAGS}" " + #include + #if defined(_MSC_VER) + #include + #elif defined(__GNUC__) && defined(__SSE4_2__) + #include + #endif + + int main() { + uint64_t l = 0; + l = _mm_crc32_u8(l, 0); + l = _mm_crc32_u32(l, 0); + l = _mm_crc32_u64(l, 0); + return l; + } + " HAVE_SSE42 +) + +# Check for ARMv8 w/ CRC and CRYPTO extensions support in the compiler. +set(ARM_CRC_CXXFLAGS -march=armv8-a+crc+crypto) +check_cxx_source_compiles_with_flags("${ARM_CRC_CXXFLAGS}" " + #include + #include + + int main() { + #ifdef __aarch64__ + __crc32cb(0, 0); __crc32ch(0, 0); __crc32cw(0, 0); __crc32cd(0, 0); + vmull_p64(0, 0); + #else + #error crc32c library does not support hardware acceleration on 32-bit ARM + #endif + return 0; + } + " HAVE_ARM64_CRC32C +) + +add_library(crc32c STATIC EXCLUDE_FROM_ALL + ${PROJECT_SOURCE_DIR}/src/crc32c/src/crc32c.cc + ${PROJECT_SOURCE_DIR}/src/crc32c/src/crc32c_portable.cc +) + +target_compile_definitions(crc32c + PRIVATE + HAVE_BUILTIN_PREFETCH=$ + HAVE_MM_PREFETCH=$ + HAVE_STRONG_GETAUXVAL=$ + HAVE_SSE42=$ + HAVE_ARM64_CRC32C=$ + BYTE_ORDER_BIG_ENDIAN=${WORDS_BIGENDIAN} +) + +target_include_directories(crc32c + PUBLIC + $ +) + +if(HAVE_SSE42) + target_sources(crc32c PRIVATE ${PROJECT_SOURCE_DIR}/src/crc32c/src/crc32c_sse42.cc) + set_property(SOURCE ${PROJECT_SOURCE_DIR}/src/crc32c/src/crc32c_sse42.cc + APPEND PROPERTY COMPILE_OPTIONS ${SSE42_CXXFLAGS} + ) +endif() + +if(HAVE_ARM64_CRC32C) + target_sources(crc32c PRIVATE ${PROJECT_SOURCE_DIR}/src/crc32c/src/crc32c_arm64.cc) + set_property(SOURCE ${PROJECT_SOURCE_DIR}/src/crc32c/src/crc32c_arm64.cc + APPEND PROPERTY COMPILE_OPTIONS ${ARM_CRC_CXXFLAGS} + ) +endif() + +target_link_libraries(crc32c PRIVATE core) From 0b92c4661a3eb95b796302b36bba9a68dfa2a939 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Wed, 13 Sep 2023 20:17:11 +0100 Subject: [PATCH 10/47] cmake: Build `leveldb` static library Co-authored-by: Cory Fields --- CMakeLists.txt | 1 + cmake/leveldb.cmake | 94 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 cmake/leveldb.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index a5cb2aa0560e8..843978c65267e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,6 +52,7 @@ include(CheckSourceCompilesAndLinks) include(cmake/introspection.cmake) include(cmake/crc32c.cmake) +include(cmake/leveldb.cmake) add_subdirectory(src) diff --git a/cmake/leveldb.cmake b/cmake/leveldb.cmake new file mode 100644 index 0000000000000..ae13ccbf09753 --- /dev/null +++ b/cmake/leveldb.cmake @@ -0,0 +1,94 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +# This file is part of the transition from Autotools to CMake. Once CMake +# support has been merged we should switch to using the upstream CMake +# buildsystem. + +include(CheckCXXSymbolExists) +check_cxx_symbol_exists(F_FULLFSYNC "fcntl.h" HAVE_FULLFSYNC) + +add_library(leveldb STATIC EXCLUDE_FROM_ALL + ${PROJECT_SOURCE_DIR}/src/leveldb/db/builder.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/db/c.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/db/db_impl.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/db/db_iter.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/db/dbformat.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/db/dumpfile.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/db/filename.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/db/log_reader.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/db/log_writer.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/db/memtable.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/db/repair.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/db/table_cache.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/db/version_edit.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/db/version_set.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/db/write_batch.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/table/block.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/table/block_builder.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/table/filter_block.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/table/format.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/table/iterator.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/table/merger.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/table/table.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/table/table_builder.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/table/two_level_iterator.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/util/arena.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/util/bloom.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/util/cache.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/util/coding.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/util/comparator.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/util/crc32c.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/util/env.cc + $<$>:${PROJECT_SOURCE_DIR}/src/leveldb/util/env_posix.cc> + $<$:${PROJECT_SOURCE_DIR}/src/leveldb/util/env_windows.cc> + ${PROJECT_SOURCE_DIR}/src/leveldb/util/filter_policy.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/util/hash.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/util/histogram.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/util/logging.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/util/options.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/util/status.cc + ${PROJECT_SOURCE_DIR}/src/leveldb/helpers/memenv/memenv.cc +) + +target_compile_definitions(leveldb + PRIVATE + HAVE_SNAPPY=0 + HAVE_CRC32C=1 + HAVE_FDATASYNC=$ + HAVE_FULLFSYNC=$ + HAVE_O_CLOEXEC=$ + FALLTHROUGH_INTENDED=[[fallthrough]] + LEVELDB_IS_BIG_ENDIAN=${WORDS_BIGENDIAN} + $<$>:LEVELDB_PLATFORM_POSIX> + $<$:LEVELDB_PLATFORM_WINDOWS> + $<$:_UNICODE;UNICODE> + $<$:__USE_MINGW_ANSI_STDIO=1> +) + +target_include_directories(leveldb + PRIVATE + $ + PUBLIC + $ +) + +if(MSVC) + target_compile_options(leveldb + PRIVATE + /wd4244 + /wd4267 + $<$:/wd4722> + ) + target_compile_definitions(leveldb + PRIVATE + _CRT_NONSTDC_NO_DEPRECATE + _CRT_SECURE_NO_WARNINGS + ) +endif() + +#TODO: figure out how to filter out: +# -Wconditional-uninitialized -Werror=conditional-uninitialized -Wsuggest-override -Werror=suggest-override + +target_link_libraries(leveldb PRIVATE core crc32c) From 015c6ea1da98f39478c00a9d87605765cb5334ab Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Wed, 13 Sep 2023 20:52:14 +0100 Subject: [PATCH 11/47] cmake: Add platform-specific definitions and properties --- CMakeLists.txt | 93 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 89 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 843978c65267e..04fdac652859f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,82 @@ else() endif() unset(check_pie_output) +# The core interface library aims to encapsulate all common build flags. +# It is intended to be a usage requirement for all other targets. +add_library(core INTERFACE) + +if(WIN32) + #[=[ + This build system supports two ways to build binaries for Windows. + + 1. Building on Windows using MSVC. + Implementation notes: + - /DWIN32 and /D_WINDOWS definitions are included into the CMAKE_CXX_FLAGS_INIT + and CMAKE_CXX_FLAGS_INIT variables by default. + - A run-time library is selected using the CMAKE_MSVC_RUNTIME_LIBRARY variable. + - MSVC-specific options, for example, /Zc:__cplusplus, are additionally required. + + 2. Cross-compiling using MinGW. + Implementation notes: + - WIN32 and _WINDOWS definitions must be provided explicitly. + - A run-time library must be specified explicitly using _MT definition. + ]=] + + target_compile_definitions(core INTERFACE + _WIN32_WINNT=0x0601 + _WIN32_IE=0x0501 + WIN32_LEAN_AND_MEAN + NOMINMAX + ) + + if(MSVC) + target_compile_definitions(core INTERFACE + _UNICODE;UNICODE + ) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") + target_compile_options(core INTERFACE + /utf-8 + /Zc:__cplusplus + ) + # Improve parallelism in MSBuild. + # See: https://devblogs.microsoft.com/cppblog/improved-parallelism-in-msbuild/. + list(APPEND CMAKE_VS_GLOBALS "UseMultiToolTask=true") + + try_append_cxx_flags("/W3" TARGET core) + try_append_cxx_flags("/wd4018" TARGET core) + try_append_cxx_flags("/wd4244" TARGET core) + try_append_cxx_flags("/wd4267" TARGET core) + try_append_cxx_flags("/wd4715" TARGET core) + try_append_cxx_flags("/wd4805" TARGET core) + target_compile_definitions(core INTERFACE + _CRT_SECURE_NO_WARNINGS + _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING + ) + endif() + + if(MINGW) + target_compile_definitions(core INTERFACE + WIN32 + _WINDOWS + _MT + ) + endif() +endif() + +# Use 64-bit off_t on 32-bit Linux. +if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SIZEOF_VOID_P EQUAL 4) + # Ensure 64-bit offsets are used for filesystem accesses for 32-bit compilation. + target_compile_definitions(core INTERFACE + _FILE_OFFSET_BITS=64 + ) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + target_compile_definitions(core INTERFACE + MAC_OSX + ) +endif() + include(CheckSourceCompilesAndLinks) include(cmake/introspection.cmake) @@ -66,11 +142,20 @@ message("C compiler ............................ ${CMAKE_C_COMPILER}") message("CFLAGS ................................ ${CMAKE_C_FLAGS}") message("C++ compiler .......................... ${CMAKE_CXX_COMPILER}") message("CXXFLAGS .............................. ${CMAKE_CXX_FLAGS}") -get_directory_property(common_compile_options COMPILE_OPTIONS) -string(REPLACE ";" " " common_compile_options "${common_compile_options}") +get_target_property(common_compile_options core INTERFACE_COMPILE_OPTIONS) +if(common_compile_options) + list(JOIN common_compile_options " " common_compile_options) +else() + set(common_compile_options) +endif() +string(GENEX_STRIP "${common_compile_options}" common_compile_options) message("Common compile options ................ ${common_compile_options}") -get_directory_property(common_link_options LINK_OPTIONS) -string(REPLACE ";" " " common_link_options "${common_link_options}") +get_target_property(common_link_options core INTERFACE_LINK_OPTIONS) +if(common_link_options) + list(JOIN common_link_options " " common_link_options) +else() + set(common_link_options) +endif() message("Common link options ................... ${common_link_options}") message("Linker flags for executables .......... ${CMAKE_EXE_LINKER_FLAGS}") message("Linker flags for shared libraries ..... ${CMAKE_SHARED_LINKER_FLAGS}") From b80bfe21390aa3abd46c3fead5054b03961cfd90 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sun, 17 Sep 2023 21:06:20 +0100 Subject: [PATCH 12/47] cmake: Build `minisketch` static library --- CMakeLists.txt | 1 + cmake/minisketch.cmake | 85 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 cmake/minisketch.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 04fdac652859f..31bc5248d6a1c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -129,6 +129,7 @@ include(cmake/introspection.cmake) include(cmake/crc32c.cmake) include(cmake/leveldb.cmake) +include(cmake/minisketch.cmake) add_subdirectory(src) diff --git a/cmake/minisketch.cmake b/cmake/minisketch.cmake new file mode 100644 index 0000000000000..43f9f9217740e --- /dev/null +++ b/cmake/minisketch.cmake @@ -0,0 +1,85 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +# Check for clmul instructions support. +if(MSVC) + set(CLMUL_CXXFLAGS) +else() + set(CLMUL_CXXFLAGS -mpclmul) +endif() +check_cxx_source_compiles_with_flags("${CLMUL_CXXFLAGS}" " + #include + #include + + int main() + { + __m128i a = _mm_cvtsi64_si128((uint64_t)7); + __m128i b = _mm_clmulepi64_si128(a, a, 37); + __m128i c = _mm_srli_epi64(b, 41); + __m128i d = _mm_xor_si128(b, c); + uint64_t e = _mm_cvtsi128_si64(d); + return e == 0; + } + " HAVE_CLMUL +) + +add_library(minisketch_common INTERFACE) +target_compile_definitions(minisketch_common INTERFACE + DISABLE_DEFAULT_FIELDS + ENABLE_FIELD_32 + $<$,$>:HAVE_CLZ> +) +if(MSVC) + target_compile_options(minisketch_common INTERFACE + /wd4060 + /wd4065 + /wd4146 + /wd4244 + /wd4267 + ) +endif() + +if(HAVE_CLMUL) + add_library(minisketch_clmul OBJECT EXCLUDE_FROM_ALL + ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/clmul_1byte.cpp + ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/clmul_2bytes.cpp + ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/clmul_3bytes.cpp + ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/clmul_4bytes.cpp + ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/clmul_5bytes.cpp + ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/clmul_6bytes.cpp + ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/clmul_7bytes.cpp + ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/clmul_8bytes.cpp + ) + target_compile_definitions(minisketch_clmul PUBLIC HAVE_CLMUL) + target_compile_options(minisketch_clmul PRIVATE ${CLMUL_CXXFLAGS}) + target_link_libraries(minisketch_clmul + PRIVATE + core + minisketch_common + ) +endif() + +add_library(minisketch STATIC EXCLUDE_FROM_ALL + ${PROJECT_SOURCE_DIR}/src/minisketch/src/minisketch.cpp + ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/generic_1byte.cpp + ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/generic_2bytes.cpp + ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/generic_3bytes.cpp + ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/generic_4bytes.cpp + ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/generic_5bytes.cpp + ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/generic_6bytes.cpp + ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/generic_7bytes.cpp + ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/generic_8bytes.cpp +) + +target_include_directories(minisketch + PUBLIC + $ +) + +target_link_libraries(minisketch + PRIVATE + core + minisketch_common + $ +) From a8da6eeadd632f1d54081838cca0f4f598758c2e Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sat, 16 Sep 2023 21:54:21 +0100 Subject: [PATCH 13/47] cmake: Build `secp256k1` static library --- CMakeLists.txt | 1 + cmake/secp256k1.cmake | 60 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 cmake/secp256k1.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 31bc5248d6a1c..f8e8f25d8f6fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,6 +130,7 @@ include(cmake/introspection.cmake) include(cmake/crc32c.cmake) include(cmake/leveldb.cmake) include(cmake/minisketch.cmake) +include(cmake/secp256k1.cmake) add_subdirectory(src) diff --git a/cmake/secp256k1.cmake b/cmake/secp256k1.cmake new file mode 100644 index 0000000000000..e8ee7c4a5b60e --- /dev/null +++ b/cmake/secp256k1.cmake @@ -0,0 +1,60 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +# This file is part of the transition from Autotools to CMake. Once CMake +# support has been merged we should switch to using the upstream CMake +# buildsystem. + +enable_language(C) +set(CMAKE_C_STANDARD 90) +set(CMAKE_C_EXTENSIONS OFF) + +if(ASM) + include(CheckCSourceCompiles) + check_c_source_compiles(" + #include + + int main() + { + uint64_t a = 11, tmp; + __asm__ __volatile__(\"movq $0x100000000,%1; mulq %%rsi\" : \"+a\"(a) : \"S\"(tmp) : \"cc\", \"%rdx\"); + } + " HAVE_64BIT_ASM + ) +endif() + +add_library(secp256k1 STATIC EXCLUDE_FROM_ALL + ${PROJECT_SOURCE_DIR}/src/secp256k1/src/secp256k1.c + ${PROJECT_SOURCE_DIR}/src/secp256k1/src/precomputed_ecmult.c + ${PROJECT_SOURCE_DIR}/src/secp256k1/src/precomputed_ecmult_gen.c +) + +target_compile_definitions(secp256k1 + PRIVATE + ECMULT_GEN_PREC_BITS=4 + ECMULT_WINDOW_SIZE=15 + ENABLE_MODULE_RECOVERY + ENABLE_MODULE_SCHNORRSIG + ENABLE_MODULE_EXTRAKEYS + ENABLE_MODULE_ELLSWIFT + $<$:USE_ASM_X86_64=1> + INTERFACE + $<$:SECP256K1_STATIC> +) + +target_include_directories(secp256k1 + PUBLIC + $ +) + +if(MSVC) + target_compile_options(secp256k1 + PRIVATE + /wd4146 + /wd4244 + /wd4267 + ) +endif() + +target_link_libraries(secp256k1 PRIVATE core) From 46ac7c1296732224504c7bdd96fb6aa89485a2e8 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sun, 17 Sep 2023 21:06:47 +0100 Subject: [PATCH 14/47] cmake: Build `univalue` static library --- src/CMakeLists.txt | 2 ++ src/univalue/CMakeLists.txt | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 src/univalue/CMakeLists.txt diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1937b787f19ff..bab1b22aa1467 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,3 +5,5 @@ configure_file(${CMAKE_SOURCE_DIR}/cmake/bitcoin-config.h.in config/bitcoin-config.h @ONLY) add_compile_definitions(HAVE_CONFIG_H) include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) + +add_subdirectory(univalue) diff --git a/src/univalue/CMakeLists.txt b/src/univalue/CMakeLists.txt new file mode 100644 index 0000000000000..fdaa652dcfae3 --- /dev/null +++ b/src/univalue/CMakeLists.txt @@ -0,0 +1,17 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +add_library(univalue STATIC EXCLUDE_FROM_ALL + lib/univalue.cpp + lib/univalue_get.cpp + lib/univalue_read.cpp + lib/univalue_write.cpp +) + +target_include_directories(univalue + PUBLIC + $ +) + +target_link_libraries(univalue PRIVATE core) From f878edde88e77204e276ea33f159ab9c27f7b01b Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Fri, 8 Dec 2023 20:22:27 +0000 Subject: [PATCH 15/47] cmake: Build `bitcoin_crypto` library --- CMakeLists.txt | 5 ++ src/CMakeLists.txt | 1 + src/crypto/CMakeLists.txt | 124 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+) create mode 100644 src/crypto/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index f8e8f25d8f6fd..de7a3e0e1ecbd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,10 @@ set(CMAKE_CXX_EXTENSIONS OFF) list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/module) +# Configurable options. +# When adding a new option, end the with a full stop for consistency. +option(ASM "Use assembly routines." ON) + set(configure_warnings) include(CheckPIESupported) @@ -182,6 +186,7 @@ else() message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_RELEASE}") message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") endif() +message("Use assembly routines ................. ${ASM}") message("\n") if(configure_warnings) message(" ******\n") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bab1b22aa1467..ca87241c8f0b1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,4 +6,5 @@ configure_file(${CMAKE_SOURCE_DIR}/cmake/bitcoin-config.h.in config/bitcoin-conf add_compile_definitions(HAVE_CONFIG_H) include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) +add_subdirectory(crypto) add_subdirectory(univalue) diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt new file mode 100644 index 0000000000000..8ac54980de6d4 --- /dev/null +++ b/src/crypto/CMakeLists.txt @@ -0,0 +1,124 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +if(ASM AND NOT MSVC) + # Check for SSE4.1 intrinsics. + set(SSE41_CXXFLAGS -msse4.1) + check_cxx_source_compiles_with_flags("${SSE41_CXXFLAGS}" " + #include + + int main() + { + __m128i l = _mm_set1_epi32(0); + return _mm_extract_epi32(l, 3); + } + " HAVE_SSE41 + ) + + # Check for AVX2 intrinsics. + set(AVX2_CXXFLAGS -mavx -mavx2) + check_cxx_source_compiles_with_flags("${AVX2_CXXFLAGS}" " + #include + + int main() + { + __m256i l = _mm256_set1_epi32(0); + return _mm256_extract_epi32(l, 7); + } + " HAVE_AVX2 + ) + + # Check for x86 SHA-NI intrinsics. + set(X86_SHANI_CXXFLAGS -msse4 -msha) + check_cxx_source_compiles_with_flags("${X86_SHANI_CXXFLAGS}" " + #include + + int main() + { + __m128i i = _mm_set1_epi32(0); + __m128i j = _mm_set1_epi32(1); + __m128i k = _mm_set1_epi32(2); + return _mm_extract_epi32(_mm_sha256rnds2_epu32(i, j, k), 0); + } + " HAVE_X86_SHANI + ) + + # Check for ARMv8 SHA-NI intrinsics. + set(ARM_SHANI_CXXFLAGS -march=armv8-a+crypto) + check_cxx_source_compiles_with_flags("${ARM_SHANI_CXXFLAGS}" " + #include + + int main() + { + uint32x4_t a, b, c; + vsha256h2q_u32(a, b, c); + vsha256hq_u32(a, b, c); + vsha256su0q_u32(a, b); + vsha256su1q_u32(a, b, c); + } + " HAVE_ARM_SHANI + ) +endif() + +include(CheckCXXSymbolExists) +check_cxx_symbol_exists(timingsafe_bcmp "string.h" HAVE_TIMINGSAFE_BCMP) + +# The `bitcoin_crypto` must be of an `OBJECT` type to include +# its object files into the output static library archives. +add_library(bitcoin_crypto OBJECT EXCLUDE_FROM_ALL + $<$:sha256_sse4.cpp> + aes.cpp + chacha20.cpp + chacha20poly1305.cpp + hkdf_sha256_32.cpp + hmac_sha256.cpp + hmac_sha512.cpp + poly1305.cpp + muhash.cpp + ripemd160.cpp + sha1.cpp + sha256.cpp + sha3.cpp + sha512.cpp + siphash.cpp +) +target_compile_definitions(bitcoin_crypto + PRIVATE + $<$:USE_ASM> + $<$:ENABLE_SSE41> + $<$:ENABLE_AVX2> + $<$:ENABLE_X86_SHANI> + $<$:ENABLE_ARM_SHANI> + $<$:HAVE_TIMINGSAFE_BCMP> +) + +if(HAVE_SSE41) + target_sources(bitcoin_crypto PRIVATE sha256_sse41.cpp) + set_property(SOURCE sha256_sse41.cpp + APPEND PROPERTY COMPILE_OPTIONS ${SSE41_CXXFLAGS} + ) +endif() + +if(HAVE_AVX2) + target_sources(bitcoin_crypto PRIVATE sha256_avx2.cpp) + set_property(SOURCE sha256_avx2.cpp + APPEND PROPERTY COMPILE_OPTIONS ${AVX2_CXXFLAGS} + ) +endif() + +if(HAVE_X86_SHANI) + target_sources(bitcoin_crypto PRIVATE sha256_x86_shani.cpp) + set_property(SOURCE sha256_x86_shani.cpp + APPEND PROPERTY COMPILE_OPTIONS ${X86_SHANI_CXXFLAGS} + ) +endif() + +if(HAVE_ARM_SHANI) + target_sources(bitcoin_crypto PRIVATE sha256_arm_shani.cpp) + set_property(SOURCE sha256_arm_shani.cpp + APPEND PROPERTY COMPILE_OPTIONS ${ARM_SHANI_CXXFLAGS} + ) +endif() + +target_link_libraries(bitcoin_crypto PRIVATE core) From 19196f9c9c75ebccb93140ae2dd7e3d53b429907 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Wed, 13 Sep 2023 20:27:57 +0100 Subject: [PATCH 16/47] cmake: Build `bitcoin_util` static library --- CMakeLists.txt | 4 ++ cmake/module/AddThreadsIfNeeded.cmake | 42 +++++++++++++++++++ src/CMakeLists.txt | 1 + src/util/CMakeLists.txt | 58 +++++++++++++++++++++++++++ 4 files changed, 105 insertions(+) create mode 100644 cmake/module/AddThreadsIfNeeded.cmake create mode 100644 src/util/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index de7a3e0e1ecbd..ea3d97df45609 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,7 @@ list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/module) # Configurable options. # When adding a new option, end the with a full stop for consistency. option(ASM "Use assembly routines." ON) +option(THREADLOCAL "Enable features that depend on the C++ thread_local keyword (currently just thread names in debug logs)." ON) set(configure_warnings) @@ -128,6 +129,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") ) endif() +include(AddThreadsIfNeeded) +add_threads_if_needed() + include(CheckSourceCompilesAndLinks) include(cmake/introspection.cmake) diff --git a/cmake/module/AddThreadsIfNeeded.cmake b/cmake/module/AddThreadsIfNeeded.cmake new file mode 100644 index 0000000000000..2939f1a0c6fcb --- /dev/null +++ b/cmake/module/AddThreadsIfNeeded.cmake @@ -0,0 +1,42 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +function(add_threads_if_needed) + # TODO: Not all targets, which will be added in the future, + # require Threads. Therefore, a proper check will be + # appropriate here. + + if(CMAKE_C_COMPILER_LOADED) + message(FATAL_ERROR [=[ + To make FindThreads check C++ language features, C language must be + disabled. This is essential, at least, when cross-compiling for MinGW-w64 + because two different threading models are available. + ]=] ) + endif() + + set(THREADS_PREFER_PTHREAD_FLAG ON) + find_package(Threads REQUIRED) + set_target_properties(Threads::Threads PROPERTIES IMPORTED_GLOBAL TRUE) + + set(thread_local) + if(MINGW) + #[=[ + mingw32's implementation of thread_local has been shown to behave + erroneously under concurrent usage. + See: + - https://github.com/bitcoin/bitcoin/pull/15849 + - https://gist.github.com/jamesob/fe9a872051a88b2025b1aa37bfa98605 + ]=] + elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + #[=[ + FreeBSD's implementation of thread_local is buggy. + See: + - https://github.com/bitcoin/bitcoin/pull/16059 + - https://groups.google.com/d/msg/bsdmailinglist/22ncTZAbDp4/Dii_pII5AwAJ + ]=] + elseif(THREADLOCAL) + set(thread_local "$<$:HAVE_THREAD_LOCAL>") + endif() + set(THREAD_LOCAL_IF_AVAILABLE "${thread_local}" PARENT_SCOPE) +endfunction() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ca87241c8f0b1..e447461fcd0a2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,3 +8,4 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) add_subdirectory(crypto) add_subdirectory(univalue) +add_subdirectory(util) diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt new file mode 100644 index 0000000000000..dc7eec69a6f43 --- /dev/null +++ b/src/util/CMakeLists.txt @@ -0,0 +1,58 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +add_library(bitcoin_util STATIC EXCLUDE_FROM_ALL + asmap.cpp + batchpriority.cpp + bip32.cpp + bytevectorhash.cpp + chaintype.cpp + check.cpp + error.cpp + exception.cpp + fees.cpp + fs.cpp + fs_helpers.cpp + getuniquepath.cpp + hasher.cpp + message.cpp + moneystr.cpp + rbf.cpp + readwritefile.cpp + serfloat.cpp + signalinterrupt.cpp + sock.cpp + spanparsing.cpp + strencodings.cpp + string.cpp + syserror.cpp + thread.cpp + threadinterrupt.cpp + threadnames.cpp + time.cpp + tokenpipe.cpp + ../chainparamsbase.cpp + ../clientversion.cpp + ../logging.cpp + ../random.cpp + ../randomenv.cpp + ../streams.cpp + ../support/cleanse.cpp + ../support/lockedpool.cpp + ../sync.cpp +) + +target_compile_definitions(bitcoin_util + PRIVATE + ${THREAD_LOCAL_IF_AVAILABLE} + $<$:_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING> +) + +target_link_libraries(bitcoin_util + PRIVATE + core + bitcoin_crypto + Threads::Threads + $<$:ws2_32> +) From 76a7d2fc4345e0fe787c36d155ec0d66e4ba7387 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Wed, 13 Sep 2023 20:22:53 +0100 Subject: [PATCH 17/47] cmake: Build `bitcoin_consensus` library --- src/CMakeLists.txt | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e447461fcd0a2..0c1814ad9be8f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,3 +9,26 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) add_subdirectory(crypto) add_subdirectory(univalue) add_subdirectory(util) + + +# Stable, backwards-compatible consensus functionality +# also exposed as a shared library and/or a static one. +add_library(bitcoin_consensus OBJECT EXCLUDE_FROM_ALL + arith_uint256.cpp + consensus/merkle.cpp + consensus/tx_check.cpp + hash.cpp + primitives/block.cpp + primitives/transaction.cpp + pubkey.cpp + script/interpreter.cpp + script/script.cpp + script/script_error.cpp + uint256.cpp + util/strencodings.cpp +) +target_link_libraries(bitcoin_consensus + PRIVATE + core + secp256k1 +) From 9c2efdab3bee8b4734edd1ca9ad7838bdd2881da Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Tue, 7 Nov 2023 13:12:43 +0000 Subject: [PATCH 18/47] cmake: Build `bitcoind` executable --- CMakeLists.txt | 11 ++ cmake/introspection.cmake | 4 + cmake/module/AddBoostIfNeeded.cmake | 29 ++++ cmake/module/AddLibeventIfNeeded.cmake | 60 ++++++++ src/CMakeLists.txt | 186 +++++++++++++++++++++++++ 5 files changed, 290 insertions(+) create mode 100644 cmake/module/AddBoostIfNeeded.cmake create mode 100644 cmake/module/AddLibeventIfNeeded.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index ea3d97df45609..6f469da4aa220 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,6 +38,7 @@ list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/module) # Configurable options. # When adding a new option, end the with a full stop for consistency. +option(BUILD_DAEMON "Build bitcoind executable." ON) option(ASM "Use assembly routines." ON) option(THREADLOCAL "Enable features that depend on the C++ thread_local keyword (currently just thread names in debug logs)." ON) @@ -132,7 +133,14 @@ endif() include(AddThreadsIfNeeded) add_threads_if_needed() +include(AddBoostIfNeeded) +add_boost_if_needed() + include(CheckSourceCompilesAndLinks) + +include(AddLibeventIfNeeded) +add_libevent_if_needed() + include(cmake/introspection.cmake) include(cmake/crc32c.cmake) @@ -145,6 +153,9 @@ add_subdirectory(src) message("\n") message("Configure summary") message("=================") +message("Executables:") +message(" bitcoind ............................ ${BUILD_DAEMON}") +message("") get_directory_property(definitions COMPILE_DEFINITIONS) string(REPLACE ";" " " definitions "${definitions}") message("Preprocessor defined macros ........... ${definitions}") diff --git a/cmake/introspection.cmake b/cmake/introspection.cmake index 2e30bdf8bbc8c..c4d4c9a24a139 100644 --- a/cmake/introspection.cmake +++ b/cmake/introspection.cmake @@ -246,3 +246,7 @@ check_cxx_source_compiles(" int main(){} " HAVE_DLLEXPORT_ATTRIBUTE ) + +if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin") + find_program(BREW_COMMAND brew) +endif() diff --git a/cmake/module/AddBoostIfNeeded.cmake b/cmake/module/AddBoostIfNeeded.cmake new file mode 100644 index 0000000000000..bad58e154f33b --- /dev/null +++ b/cmake/module/AddBoostIfNeeded.cmake @@ -0,0 +1,29 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +function(add_boost_if_needed) + #[=[ + TODO: Not all targets, which will be added in the future, require + Boost. Therefore, a proper check will be appropriate here. + + Implementation notes: + Although only Boost headers are used to build Bitcoin Core, + we still leverage a standard CMake's approach to handle + dependencies, i.e., the Boost::headers "library". + A command target_link_libraries(target PRIVATE Boost::headers) + will propagate Boost::headers usage requirements to the target. + For Boost::headers such usage requirements is an include + directory and other added INTERFACE properties. + ]=] + + set(Boost_NO_BOOST_CMAKE ON) + find_package(Boost 1.64.0 REQUIRED) + set_target_properties(Boost::headers PROPERTIES IMPORTED_GLOBAL TRUE) + target_compile_definitions(Boost::headers INTERFACE + # We don't use multi_index serialization. + BOOST_MULTI_INDEX_DISABLE_SERIALIZATION + ) + + mark_as_advanced(Boost_INCLUDE_DIR) +endfunction() diff --git a/cmake/module/AddLibeventIfNeeded.cmake b/cmake/module/AddLibeventIfNeeded.cmake new file mode 100644 index 0000000000000..e2efc240196e5 --- /dev/null +++ b/cmake/module/AddLibeventIfNeeded.cmake @@ -0,0 +1,60 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# Check whether evhttp_connection_get_peer expects const char**. +# See https://github.com/libevent/libevent/commit/a18301a2bb160ff7c3ffaf5b7653c39ffe27b385 +macro(check_evhttp_connection_get_peer target) + cmake_push_check_state(RESET) + set(CMAKE_REQUIRED_LIBRARIES ${target}) + check_cxx_source_compiles(" + #include + #include + + int main() + { + evhttp_connection* conn = (evhttp_connection*)1; + const char* host; + uint16_t port; + evhttp_connection_get_peer(conn, &host, &port); + } + " HAVE_EVHTTP_CONNECTION_GET_PEER_CONST_CHAR + ) + cmake_pop_check_state() + target_compile_definitions(${target} INTERFACE + $<$:HAVE_EVHTTP_CONNECTION_GET_PEER_CONST_CHAR=1> + ) +endmacro() + +function(add_libevent_if_needed) + # TODO: Not all targets, which will be added in the future, + # require libevent. Therefore, a proper check will be + # appropriate here. + + set(libevent_minimum_version 2.1.8) + + if(MSVC) + find_package(Libevent ${libevent_minimum_version} REQUIRED COMPONENTS extra CONFIG) + check_evhttp_connection_get_peer(libevent::extra) + add_library(libevent::libevent ALIAS libevent::extra) + return() + endif() + + find_package(PkgConfig) + pkg_check_modules(libevent + REQUIRED IMPORTED_TARGET GLOBAL + libevent>=${libevent_minimum_version} + ) + check_evhttp_connection_get_peer(PkgConfig::libevent) + target_link_libraries(PkgConfig::libevent INTERFACE + $<$:iphlpapi;ssp;ws2_32> + ) + add_library(libevent::libevent ALIAS PkgConfig::libevent) + + if(NOT WIN32) + pkg_check_modules(libevent_pthreads + REQUIRED IMPORTED_TARGET GLOBAL + libevent_pthreads>=${libevent_minimum_version} + ) + endif() +endfunction() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0c1814ad9be8f..bc90c7cbb8eba 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -32,3 +32,189 @@ target_link_libraries(bitcoin_consensus core secp256k1 ) + + +# Home for common functionality shared by different executables and libraries. +# Similar to `bitcoin_util` library, but higher-level. +add_library(bitcoin_common STATIC EXCLUDE_FROM_ALL + addresstype.cpp + base58.cpp + bech32.cpp + chainparams.cpp + coins.cpp + common/args.cpp + common/bloom.cpp + common/config.cpp + common/init.cpp + common/interfaces.cpp + common/run_command.cpp + common/settings.cpp + common/system.cpp + $<$:common/url.cpp> + compressor.cpp + core_read.cpp + core_write.cpp + deploymentinfo.cpp + external_signer.cpp + init/common.cpp + kernel/chainparams.cpp + key.cpp + key_io.cpp + merkleblock.cpp + net_types.cpp + netaddress.cpp + netbase.cpp + net_permissions.cpp + outputtype.cpp + policy/feerate.cpp + policy/policy.cpp + protocol.cpp + psbt.cpp + rpc/rawtransaction_util.cpp + rpc/request.cpp + rpc/external_signer.cpp + rpc/util.cpp + scheduler.cpp + script/descriptor.cpp + script/miniscript.cpp + script/sign.cpp + script/signingprovider.cpp + script/solver.cpp + warnings.cpp +) +target_compile_definitions(bitcoin_common + PRIVATE + ${THREAD_LOCAL_IF_AVAILABLE} +) +target_link_libraries(bitcoin_common + PRIVATE + core + bitcoin_consensus + bitcoin_util + univalue + secp256k1 + Boost::headers + $ +) + + +# P2P and RPC server functionality used by `bitcoind` and `bitcoin-qt` executables. +add_library(bitcoin_node STATIC EXCLUDE_FROM_ALL + addrdb.cpp + addrman.cpp + banman.cpp + bip324.cpp + blockencodings.cpp + blockfilter.cpp + chain.cpp + consensus/tx_verify.cpp + dbwrapper.cpp + deploymentstatus.cpp + flatfile.cpp + headerssync.cpp + httprpc.cpp + httpserver.cpp + i2p.cpp + index/base.cpp + index/blockfilterindex.cpp + index/coinstatsindex.cpp + index/txindex.cpp + init.cpp + kernel/chain.cpp + kernel/checks.cpp + kernel/coinstats.cpp + kernel/context.cpp + kernel/cs_main.cpp + kernel/disconnected_transactions.cpp + kernel/mempool_persist.cpp + kernel/mempool_removal_reason.cpp + mapport.cpp + net.cpp + net_processing.cpp + netgroup.cpp + node/abort.cpp + node/blockmanager_args.cpp + node/blockstorage.cpp + node/caches.cpp + node/chainstate.cpp + node/chainstatemanager_args.cpp + node/coin.cpp + node/coins_view_args.cpp + node/connection_types.cpp + node/context.cpp + node/database_args.cpp + node/eviction.cpp + node/interface_ui.cpp + node/interfaces.cpp + node/kernel_notifications.cpp + node/mempool_args.cpp + node/mempool_persist_args.cpp + node/miner.cpp + node/mini_miner.cpp + node/minisketchwrapper.cpp + node/peerman_args.cpp + node/psbt.cpp + node/transaction.cpp + node/txreconciliation.cpp + node/utxo_snapshot.cpp + node/validation_cache_args.cpp + noui.cpp + policy/fees.cpp + policy/fees_args.cpp + policy/packages.cpp + policy/rbf.cpp + policy/settings.cpp + pow.cpp + rest.cpp + rpc/blockchain.cpp + rpc/fees.cpp + rpc/mempool.cpp + rpc/mining.cpp + rpc/net.cpp + rpc/node.cpp + rpc/output_script.cpp + rpc/rawtransaction.cpp + rpc/server.cpp + rpc/server_util.cpp + rpc/signmessage.cpp + rpc/txoutproof.cpp + script/sigcache.cpp + shutdown.cpp + signet.cpp + timedata.cpp + torcontrol.cpp + txdb.cpp + txmempool.cpp + txorphanage.cpp + txrequest.cpp + validation.cpp + validationinterface.cpp + versionbits.cpp + + dummywallet.cpp +) +target_link_libraries(bitcoin_node + PRIVATE + core + bitcoin_common + bitcoin_util + leveldb + minisketch + univalue + Boost::headers + libevent::libevent + $ +) + + +# Bitcoin Core bitcoind. +if(BUILD_DAEMON) + add_executable(bitcoind + bitcoind.cpp + init/bitcoind.cpp + ) + target_link_libraries(bitcoind + core + bitcoin_node + ) +endif() From d080623e99c602a34286578185d4d9ac9205d177 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sun, 17 Sep 2023 16:16:12 +0100 Subject: [PATCH 19/47] build: Generate `share/toolchain.cmake` in depends --- depends/Makefile | 32 ++++++++- depends/toolchain.cmake.in | 137 +++++++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 depends/toolchain.cmake.in diff --git a/depends/Makefile b/depends/Makefile index 319c3498dfc6a..68d4214965877 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -191,6 +191,7 @@ $(host_arch)_$(host_os)_native_toolchain?=$($(host_os)_native_toolchain) include funcs.mk final_build_id_long+=$(shell $(build_SHA256SUM) config.site.in) +final_build_id_long+=$(shell $(build_SHA256SUM) toolchain.cmake.in) final_build_id+=$(shell echo -n "$(final_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH)) $(host_prefix)/.stamp_$(final_build_id): $(native_packages) $(packages) rm -rf $(@D) @@ -259,6 +260,34 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_ $< > $@ touch $@ +$(host_prefix)/share/toolchain.cmake : toolchain.cmake.in $(host_prefix)/.stamp_$(final_build_id) + @mkdir -p $(@D) + sed -e 's|@host_system@|$($(host_os)_cmake_system)|' \ + -e 's|@host_arch@|$(host_arch)|' \ + -e 's|@CC@|$(host_CC)|' \ + -e 's|@CXX@|$(host_CXX)|' \ + -e 's|@AR@|$(host_AR)|' \ + -e 's|@RANLIB@|$(host_RANLIB)|' \ + -e 's|@STRIP@|$(host_STRIP)|' \ + -e 's|@OBJCOPY@|$(host_OBJCOPY)|' \ + -e 's|@INSTALL_NAME_TOOL@|$(host_INSTALL_NAME_TOOL)|' \ + -e 's|@OTOOL@|$(host_OTOOL)|' \ + -e 's|@depends_prefix@|$(host_prefix)|' \ + -e 's|@CFLAGS@|$(strip $(host_CFLAGS) $(host_$(release_type)_CFLAGS))|' \ + -e 's|@CXXFLAGS@|$(strip $(host_CXXFLAGS) $(host_$(release_type)_CXXFLAGS))|' \ + -e 's|@CPPFLAGS@|$(strip $(host_CPPFLAGS) $(host_$(release_type)_CPPFLAGS))|' \ + -e 's|@allow_host_packages@|$(ALLOW_HOST_PACKAGES)|' \ + -e 's|@no_qt@|$(NO_QT)|' \ + -e 's|@no_qr@|$(NO_QR)|' \ + -e 's|@no_zmq@|$(NO_ZMQ)|' \ + -e 's|@no_wallet@|$(NO_WALLET)|' \ + -e 's|@no_bdb@|$(NO_BDB)|' \ + -e 's|@no_sqlite@|$(NO_SQLITE)|' \ + -e 's|@no_upnp@|$(NO_UPNP)|' \ + -e 's|@no_natpmp@|$(NO_NATPMP)|' \ + -e 's|@no_usdt@|$(NO_USDT)|' \ + $< > $@ + touch $@ define check_or_remove_cached mkdir -p $(BASE_CACHE)/$(host)/$(package) && cd $(BASE_CACHE)/$(host)/$(package); \ @@ -280,6 +309,7 @@ check-sources: @$(foreach package,$(all_packages),$(call check_or_remove_sources,$(package));) $(host_prefix)/share/config.site: check-packages +$(host_prefix)/share/toolchain.cmake: check-packages check-packages: check-sources @@ -289,7 +319,7 @@ clean-all: clean clean: @rm -rf $(WORK_PATH) $(BASE_CACHE) $(BUILD) *.log -install: check-packages $(host_prefix)/share/config.site +install: check-packages $(host_prefix)/share/config.site $(host_prefix)/share/toolchain.cmake download-one: check-sources $(all_sources) diff --git a/depends/toolchain.cmake.in b/depends/toolchain.cmake.in new file mode 100644 index 0000000000000..e13b5541060bd --- /dev/null +++ b/depends/toolchain.cmake.in @@ -0,0 +1,137 @@ +# This file is expected to be highly volatile and may still change substantially. + +set(CMAKE_SYSTEM_NAME @host_system@) +set(CMAKE_SYSTEM_PROCESSOR @host_arch@) + +function(split_compiler_launcher env_compiler launcher compiler) + set(${launcher}) + list(GET ${env_compiler} 0 start_token) + if(start_token STREQUAL "env") + set(${compiler}) + set(env_arg_parsing TRUE) + foreach(token IN LISTS ${env_compiler}) + if(env_arg_parsing) + list(APPEND ${launcher} ${token}) + set(env_arg_parsing FALSE) + continue() + elseif(token STREQUAL "-u") + list(APPEND ${launcher} ${token}) + set(env_arg_parsing TRUE) + continue() + endif() + list(APPEND ${compiler} ${token}) + endforeach() + else() + set(${compiler} ${${env_compiler}}) + endif() + set(${launcher} ${${launcher}} PARENT_SCOPE) + set(${compiler} ${${compiler}} PARENT_SCOPE) +endfunction() + +if(NOT CMAKE_C_COMPILER) + set(DEPENDS_C_COMPILER_WITH_LAUNCHER @CC@) + split_compiler_launcher(DEPENDS_C_COMPILER_WITH_LAUNCHER CMAKE_C_COMPILER_LAUNCHER CMAKE_C_COMPILER) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.21) + set(CMAKE_C_LINKER_LAUNCHER ${CMAKE_C_COMPILER_LAUNCHER}) + endif() + if(CMAKE_VERSION VERSION_LESS 3.19) + # Being provided with CC="compiler -arg1 -arg2", the old CMake cannot + # store the compiler arguments in the CMAKE_C_COMPILER variable. + # Therefore, we have to store them separately. + set(mandatory_c_compiler_flags ${CMAKE_C_COMPILER}) + list(POP_FRONT mandatory_c_compiler_flags CMAKE_C_COMPILER) + list(JOIN mandatory_c_compiler_flags " " mandatory_c_compiler_flags) + string(PREPEND CMAKE_C_FLAGS_INIT "${mandatory_c_compiler_flags} ") + unset(mandatory_c_compiler_flags) + endif() + set(DEPENDS_C_COMPILER_FLAGS @CFLAGS@) +endif() + +if(NOT CMAKE_CXX_COMPILER) + set(DEPENDS_CXX_COMPILER_WITH_LAUNCHER @CXX@) + split_compiler_launcher(DEPENDS_CXX_COMPILER_WITH_LAUNCHER CMAKE_CXX_COMPILER_LAUNCHER CMAKE_CXX_COMPILER) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.21) + set(CMAKE_CXX_LINKER_LAUNCHER ${CMAKE_CXX_COMPILER_LAUNCHER}) + endif() + if(CMAKE_VERSION VERSION_LESS 3.19) + # Being provided with CXX="compiler -arg1 -arg2", the old CMake cannot + # store the compiler arguments in the CMAKE_CXX_COMPILER variable. + # Therefore, we have to store them separately. + set(mandatory_cxx_compiler_flags ${CMAKE_CXX_COMPILER}) + list(POP_FRONT mandatory_cxx_compiler_flags CMAKE_CXX_COMPILER) + list(JOIN mandatory_cxx_compiler_flags " " mandatory_cxx_compiler_flags) + string(PREPEND CMAKE_CXX_FLAGS_INIT "${mandatory_cxx_compiler_flags} ") + string(PREPEND CMAKE_OBJCXX_FLAGS_INIT "${mandatory_cxx_compiler_flags} ") + string(PREPEND CMAKE_EXE_LINKER_FLAGS_INIT "${mandatory_cxx_compiler_flags} ") + string(PREPEND CMAKE_SHARED_LINKER_FLAGS_INIT "${mandatory_cxx_compiler_flags} ") + unset(mandatory_cxx_compiler_flags) + endif() + set(DEPENDS_CXX_COMPILER_FLAGS @CXXFLAGS@) + + set(CMAKE_OBJCXX_COMPILER ${CMAKE_CXX_COMPILER}) + set(CMAKE_OBJCXX_COMPILER_LAUNCHER ${CMAKE_CXX_COMPILER_LAUNCHER}) + set(CMAKE_OBJCXX_LINKER_LAUNCHER ${CMAKE_CXX_LINKER_LAUNCHER}) +endif() + +set(DEPENDS_COMPILE_DEFINITIONS @CPPFLAGS@) + +if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(CMAKE_EXE_LINKER_FLAGS_INIT "-static") +endif() + +set(CMAKE_AR "@AR@") +set(CMAKE_RANLIB "@RANLIB@") +set(CMAKE_STRIP "@STRIP@") +set(CMAKE_OBJCOPY "@OBJCOPY@") +set(CMAKE_INSTALL_NAME_TOOL "@INSTALL_NAME_TOOL@") +set(OTOOL "@OTOOL@") + +set(CMAKE_FIND_ROOT_PATH "@depends_prefix@") +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) +set(PKG_CONFIG_PATH "@depends_prefix@/lib/pkgconfig") +if("@allow_host_packages@" STREQUAL "1") + set(DEPENDS_ALLOW_HOST_PACKAGES TRUE) +else() + set(DEPENDS_ALLOW_HOST_PACKAGES FALSE) + set(PKG_CONFIG_LIBDIR "${PKG_CONFIG_PATH}") +endif() +set(QT_TRANSLATIONS_DIR "@depends_prefix@/translations") + +if(NOT WITH_GUI AND "@no_qt@" STREQUAL "1") + set(WITH_GUI "no" CACHE STRING "") +endif() + +if(NOT WITH_QRENCODE AND "@no_qr@" STREQUAL "1") + set(WITH_QRENCODE OFF CACHE STRING "") +endif() + +if(NOT WITH_ZMQ AND "@no_zmq@" STREQUAL "1") + set(WITH_ZMQ OFF CACHE STRING "") +endif() + +if(NOT ENABLE_WALLET AND "@no_wallet@" STREQUAL "1") + set(ENABLE_WALLET OFF CACHE BOOL "") +endif() + +if(NOT WITH_BDB AND "@no_bdb@" STREQUAL "1") + set(WITH_BDB OFF CACHE STRING "") +endif() + +if(NOT WITH_SQLITE AND "@no_sqlite@" STREQUAL "1") + set(WITH_SQLITE OFF CACHE STRING "") +endif() + +if(NOT WITH_MINIUPNPC AND "@no_upnp@" STREQUAL "1") + set(WITH_MINIUPNPC OFF CACHE STRING "") +endif() + +if(NOT WITH_NATPMP AND "@no_natpmp@" STREQUAL "1") + set(WITH_NATPMP OFF CACHE STRING "") +endif() + +if(NOT WITH_USDT AND "@no_usdt@" STREQUAL "1") + set(WITH_USDT OFF CACHE STRING "") +endif() From 51f6956174591fc99dd6e360528ff05af84bbe4e Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Wed, 13 Sep 2023 20:45:31 +0100 Subject: [PATCH 20/47] cmake: Add cross-compiling support To configure CMake for cross-compiling, use `--toolchain depends/${HOST}/share/toolchain.cmake` command-line option. --- CMakeLists.txt | 23 ++++++++++-- cmake/module/AddLibeventIfNeeded.cmake | 6 ++-- cmake/module/CrossPkgConfig.cmake | 49 ++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 cmake/module/CrossPkgConfig.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f469da4aa220..711423f708f75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,6 +130,15 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") ) endif() +if(CMAKE_CROSSCOMPILING) + target_compile_definitions(core INTERFACE ${DEPENDS_COMPILE_DEFINITIONS}) + target_compile_options(core INTERFACE "$<$:${DEPENDS_C_COMPILER_FLAGS}>") + target_compile_options(core INTERFACE "$<$:${DEPENDS_CXX_COMPILER_FLAGS}>") + if(DEPENDS_ALLOW_HOST_PACKAGES) + list(APPEND CMAKE_FIND_ROOT_PATH "${CMAKE_SYSTEM_PREFIX_PATH}") + endif() +endif() + include(AddThreadsIfNeeded) add_threads_if_needed() @@ -156,13 +165,23 @@ message("=================") message("Executables:") message(" bitcoind ............................ ${BUILD_DAEMON}") message("") +if(CMAKE_CROSSCOMPILING) + set(cross_status "TRUE, for ${CMAKE_SYSTEM_NAME}, ${CMAKE_SYSTEM_PROCESSOR}") +else() + set(cross_status "FALSE") +endif() +message("Cross compiling ....................... ${cross_status}") get_directory_property(definitions COMPILE_DEFINITIONS) string(REPLACE ";" " " definitions "${definitions}") message("Preprocessor defined macros ........... ${definitions}") message("C compiler ............................ ${CMAKE_C_COMPILER}") -message("CFLAGS ................................ ${CMAKE_C_FLAGS}") +list(JOIN DEPENDS_C_COMPILER_FLAGS " " depends_c_flags) +string(STRIP "${CMAKE_C_FLAGS} ${depends_c_flags}" combined_c_flags) +message("CFLAGS ................................ ${combined_c_flags}") message("C++ compiler .......................... ${CMAKE_CXX_COMPILER}") -message("CXXFLAGS .............................. ${CMAKE_CXX_FLAGS}") +list(JOIN DEPENDS_CXX_COMPILER_FLAGS " " depends_cxx_flags) +string(STRIP "${CMAKE_CXX_FLAGS} ${depends_cxx_flags}" combined_cxx_flags) +message("CXXFLAGS .............................. ${combined_cxx_flags}") get_target_property(common_compile_options core INTERFACE_COMPILE_OPTIONS) if(common_compile_options) list(JOIN common_compile_options " " common_compile_options) diff --git a/cmake/module/AddLibeventIfNeeded.cmake b/cmake/module/AddLibeventIfNeeded.cmake index e2efc240196e5..302d068fe916c 100644 --- a/cmake/module/AddLibeventIfNeeded.cmake +++ b/cmake/module/AddLibeventIfNeeded.cmake @@ -40,8 +40,8 @@ function(add_libevent_if_needed) return() endif() - find_package(PkgConfig) - pkg_check_modules(libevent + include(CrossPkgConfig) + cross_pkg_check_modules(libevent REQUIRED IMPORTED_TARGET GLOBAL libevent>=${libevent_minimum_version} ) @@ -52,7 +52,7 @@ function(add_libevent_if_needed) add_library(libevent::libevent ALIAS PkgConfig::libevent) if(NOT WIN32) - pkg_check_modules(libevent_pthreads + cross_pkg_check_modules(libevent_pthreads REQUIRED IMPORTED_TARGET GLOBAL libevent_pthreads>=${libevent_minimum_version} ) diff --git a/cmake/module/CrossPkgConfig.cmake b/cmake/module/CrossPkgConfig.cmake new file mode 100644 index 0000000000000..cbd6f3c27b288 --- /dev/null +++ b/cmake/module/CrossPkgConfig.cmake @@ -0,0 +1,49 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +find_package(PkgConfig REQUIRED) + +function(remove_isystem_from_include_directories_internal target) + #[=[ + A workaround for https://gitlab.kitware.com/cmake/cmake/-/issues/20652. + + When the pkg-config provides CFLAGS with -isystem options, for instance: + + $ pkg-config --cflags-only-I libzmq + -isystem /usr/include/mit-krb5 -I/usr/include/pgm-5.3 -I/usr/include/libxml2 + + an old CMake fails to parse them properly and the INTERFACE_INCLUDE_DIRECTORIES + property contains "-isystem" as a separated element: + + -isystem;/usr/include/mit-krb5;/usr/include/pgm-5.3;/usr/include/libxml2 + + which ends with an error "Imported target includes non-existent path". + + Fixing by removing the "-isystem" element from the INTERFACE_INCLUDE_DIRECTORIES. + ]=] + + get_target_property(include_directories ${target} INTERFACE_INCLUDE_DIRECTORIES) + if(include_directories) + list(REMOVE_ITEM include_directories -isystem) + set_target_properties(${target} PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${include_directories}") + endif() +endfunction() + +macro(cross_pkg_check_modules prefix) + if(CMAKE_CROSSCOMPILING) + set(pkg_config_path_saved "$ENV{PKG_CONFIG_PATH}") + set(pkg_config_libdir_saved "$ENV{PKG_CONFIG_LIBDIR}") + set(ENV{PKG_CONFIG_PATH} ${PKG_CONFIG_PATH}) + set(ENV{PKG_CONFIG_LIBDIR} ${PKG_CONFIG_LIBDIR}) + pkg_check_modules(${prefix} ${ARGN}) + set(ENV{PKG_CONFIG_PATH} ${pkg_config_path_saved}) + set(ENV{PKG_CONFIG_LIBDIR} ${pkg_config_libdir_saved}) + else() + pkg_check_modules(${prefix} ${ARGN}) + endif() + + if(CMAKE_VERSION VERSION_LESS 3.17.3 AND TARGET PkgConfig::${prefix}) + remove_isystem_from_include_directories_internal(PkgConfig::${prefix}) + endif() +endmacro() From 9e9f9bf923814d2f6f340322715b993aa59e3a34 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Thu, 13 Apr 2023 16:43:51 +0100 Subject: [PATCH 21/47] cmake: Add `TristateOption` module --- cmake/module/TristateOption.cmake | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 cmake/module/TristateOption.cmake diff --git a/cmake/module/TristateOption.cmake b/cmake/module/TristateOption.cmake new file mode 100644 index 0000000000000..1bff5bd14aeb2 --- /dev/null +++ b/cmake/module/TristateOption.cmake @@ -0,0 +1,21 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# A tri-state option with three possible values: AUTO, OFF and ON (case-insensitive). +# TODO: This function will be removed before merging into master. +function(tristate_option variable description_text auto_means_on_condition_text default_value) + set(${variable} ${default_value} CACHE STRING + "${description_text} \"AUTO\" means \"ON\" ${auto_means_on_condition_text}" + ) + + set(expected_values AUTO OFF ON) + set_property(CACHE ${variable} PROPERTY STRINGS ${expected_values}) + + string(TOUPPER "${${variable}}" value) + if(NOT value IN_LIST expected_values) + message(FATAL_ERROR "${variable} value is \"${${variable}}\", but must be one of \"AUTO\", \"OFF\" or \"ON\".") + endif() + + set(${${variable}} ${value} PARENT_SCOPE) +endfunction() From 5975d8530a2e33f80ae0f30d503c3aaba74bfbd6 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Wed, 13 Sep 2023 19:56:12 +0100 Subject: [PATCH 22/47] cmake: Add `ccache` support --- CMakeLists.txt | 8 ++++++++ cmake/optional.cmake | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 cmake/optional.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 711423f708f75..630ffa749446e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,6 +42,11 @@ option(BUILD_DAEMON "Build bitcoind executable." ON) option(ASM "Use assembly routines." ON) option(THREADLOCAL "Enable features that depend on the C++ thread_local keyword (currently just thread names in debug logs)." ON) +# TODO: These tri-state options will be removed and most features +# will become opt-in by default before merging into master. +include(TristateOption) +tristate_option(CCACHE "Use ccache for compiling." "if ccache is found." AUTO) + set(configure_warnings) include(CheckPIESupported) @@ -157,6 +162,8 @@ include(cmake/leveldb.cmake) include(cmake/minisketch.cmake) include(cmake/secp256k1.cmake) +include(cmake/optional.cmake) + add_subdirectory(src) message("\n") @@ -221,6 +228,7 @@ else() message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") endif() message("Use assembly routines ................. ${ASM}") +message("Use ccache for compiling .............. ${CCACHE}") message("\n") if(configure_warnings) message(" ******\n") diff --git a/cmake/optional.cmake b/cmake/optional.cmake new file mode 100644 index 0000000000000..9c819eae5f60b --- /dev/null +++ b/cmake/optional.cmake @@ -0,0 +1,42 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# Optional features and packages. + +if(CCACHE) + find_program(CCACHE_COMMAND ccache) + if(CCACHE_COMMAND) + if(MSVC) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24) + # ccache >= 4.8 requires compile batching turned off that is available since CMake 3.24. + # See https://github.com/ccache/ccache/wiki/MS-Visual-Studio + set(CCACHE ON) + set(MSVC_CCACHE_WRAPPER_CONTENT "\"${CCACHE_COMMAND}\" \"${CMAKE_CXX_COMPILER}\"") + set(MSVC_CCACHE_WRAPPER_FILENAME wrapped-cl.bat) + file(WRITE ${CMAKE_BINARY_DIR}/${MSVC_CCACHE_WRAPPER_FILENAME} "${MSVC_CCACHE_WRAPPER_CONTENT} %*") + list(APPEND CMAKE_VS_GLOBALS + "CLToolExe=${MSVC_CCACHE_WRAPPER_FILENAME}" + "CLToolPath=${CMAKE_BINARY_DIR}" + "DebugInformationFormat=OldStyle" + ) + set(CMAKE_VS_NO_COMPILE_BATCHING ON) + elseif(CCACHE STREQUAL "AUTO") + message(WARNING "ccache requested and found, but CMake >= 3.24 is required to use it properly. Disabling.\n" + "To skip ccache check, use \"-DCCACHE=OFF\".\n") + set(CCACHE OFF) + else() + message(FATAL_ERROR "ccache requested and found, but CMake >= 3.24 is required to use it properly.") + endif() + else() + set(CCACHE ON) + list(APPEND CMAKE_C_COMPILER_LAUNCHER ${CCACHE_COMMAND}) + list(APPEND CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_COMMAND}) + endif() + elseif(CCACHE STREQUAL "AUTO") + set(CCACHE OFF) + else() + message(FATAL_ERROR "ccache requested, but not found.") + endif() + mark_as_advanced(CCACHE_COMMAND) +endif() From 576fd362732fe244482348378479319e093a9a8e Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Thu, 6 Apr 2023 10:23:01 +0100 Subject: [PATCH 23/47] cmake: Add `libnatpmp` optional package support --- CMakeLists.txt | 3 +++ cmake/module/FindNATPMP.cmake | 32 ++++++++++++++++++++++++++++++++ cmake/optional.cmake | 13 +++++++++++++ src/CMakeLists.txt | 1 + 4 files changed, 49 insertions(+) create mode 100644 cmake/module/FindNATPMP.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 630ffa749446e..87c45a2fdf883 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,6 +46,7 @@ option(THREADLOCAL "Enable features that depend on the C++ thread_local keyword # will become opt-in by default before merging into master. include(TristateOption) tristate_option(CCACHE "Use ccache for compiling." "if ccache is found." AUTO) +tristate_option(WITH_NATPMP "Enable NAT-PMP." "if libnatpmp is found." AUTO) set(configure_warnings) @@ -171,6 +172,8 @@ message("Configure summary") message("=================") message("Executables:") message(" bitcoind ............................ ${BUILD_DAEMON}") +message("Optional packages:") +message(" NAT-PMP ............................. ${WITH_NATPMP}") message("") if(CMAKE_CROSSCOMPILING) set(cross_status "TRUE, for ${CMAKE_SYSTEM_NAME}, ${CMAKE_SYSTEM_PROCESSOR}") diff --git a/cmake/module/FindNATPMP.cmake b/cmake/module/FindNATPMP.cmake new file mode 100644 index 0000000000000..973fb9b0d06cd --- /dev/null +++ b/cmake/module/FindNATPMP.cmake @@ -0,0 +1,32 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +find_path(NATPMP_INCLUDE_DIR + NAMES natpmp.h +) + +find_library(NATPMP_LIBRARY + NAMES natpmp +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(NATPMP + REQUIRED_VARS NATPMP_LIBRARY NATPMP_INCLUDE_DIR +) + +if(NATPMP_FOUND AND NOT TARGET NATPMP::NATPMP) + add_library(NATPMP::NATPMP UNKNOWN IMPORTED) + set_target_properties(NATPMP::NATPMP PROPERTIES + IMPORTED_LOCATION "${NATPMP_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${NATPMP_INCLUDE_DIR}" + ) + set_property(TARGET NATPMP::NATPMP PROPERTY + INTERFACE_COMPILE_DEFINITIONS USE_NATPMP=1 $<$:NATPMP_STATICLIB> + ) +endif() + +mark_as_advanced( + NATPMP_INCLUDE_DIR + NATPMP_LIBRARY +) diff --git a/cmake/optional.cmake b/cmake/optional.cmake index 9c819eae5f60b..a94fa99485907 100644 --- a/cmake/optional.cmake +++ b/cmake/optional.cmake @@ -40,3 +40,16 @@ if(CCACHE) endif() mark_as_advanced(CCACHE_COMMAND) endif() + +if(WITH_NATPMP) + find_package(NATPMP MODULE) + if(NATPMP_FOUND) + set(WITH_NATPMP ON) + elseif(WITH_NATPMP STREQUAL "AUTO") + message(WARNING "libnatpmp not found, disabling.\n" + "To skip libnatpmp check, use \"-DWITH_NATPMP=OFF\".\n") + set(WITH_NATPMP OFF) + else() + message(FATAL_ERROR "libnatpmp requested, but not found.") + endif() +endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bc90c7cbb8eba..1ebd8371c5c20 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -204,6 +204,7 @@ target_link_libraries(bitcoin_node Boost::headers libevent::libevent $ + $ ) From ff20d2c576605bc90c3455e3506a4e0a71088616 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Thu, 6 Apr 2023 13:50:33 +0100 Subject: [PATCH 24/47] cmake: Add `libminiupnpc` optional package support --- CMakeLists.txt | 2 + cmake/module/FindMiniUPnPc.cmake | 84 ++++++++++++++++++++++++++++++++ cmake/optional.cmake | 13 +++++ src/CMakeLists.txt | 1 + 4 files changed, 100 insertions(+) create mode 100644 cmake/module/FindMiniUPnPc.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 87c45a2fdf883..51755cb5f4f30 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,6 +47,7 @@ option(THREADLOCAL "Enable features that depend on the C++ thread_local keyword include(TristateOption) tristate_option(CCACHE "Use ccache for compiling." "if ccache is found." AUTO) tristate_option(WITH_NATPMP "Enable NAT-PMP." "if libnatpmp is found." AUTO) +tristate_option(WITH_MINIUPNPC "Enable UPnP." "if libminiupnpc is found." AUTO) set(configure_warnings) @@ -174,6 +175,7 @@ message("Executables:") message(" bitcoind ............................ ${BUILD_DAEMON}") message("Optional packages:") message(" NAT-PMP ............................. ${WITH_NATPMP}") +message(" UPnP ................................ ${WITH_MINIUPNPC}") message("") if(CMAKE_CROSSCOMPILING) set(cross_status "TRUE, for ${CMAKE_SYSTEM_NAME}, ${CMAKE_SYSTEM_PROCESSOR}") diff --git a/cmake/module/FindMiniUPnPc.cmake b/cmake/module/FindMiniUPnPc.cmake new file mode 100644 index 0000000000000..dd3a223104b1c --- /dev/null +++ b/cmake/module/FindMiniUPnPc.cmake @@ -0,0 +1,84 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +if(NOT MSVC) + include(CrossPkgConfig) + cross_pkg_check_modules(PC_MiniUPnPc QUIET miniupnpc) +endif() + +find_path(MiniUPnPc_INCLUDE_DIR + NAMES miniupnpc/miniupnpc.h + PATHS ${PC_MiniUPnPc_INCLUDE_DIRS} +) + +if(MiniUPnPc_INCLUDE_DIR) + file( + STRINGS "${MiniUPnPc_INCLUDE_DIR}/miniupnpc/miniupnpc.h" version_strings + REGEX "^#define[\t ]+MINIUPNPC_API_VERSION[\t ]+[0-9]+" + ) + string(REGEX REPLACE "^#define[\t ]+MINIUPNPC_API_VERSION[\t ]+([0-9]+)" "\\1" MiniUPnPc_API_VERSION "${version_strings}") + + # The minimum supported miniUPnPc API version is set to 17. This excludes + # versions with known vulnerabilities. + if(MiniUPnPc_API_VERSION GREATER_EQUAL 17) + set(MiniUPnPc_API_VERSION_OK TRUE) + endif() +endif() + +if(MSVC) + cmake_path(GET MiniUPnPc_INCLUDE_DIR PARENT_PATH MiniUPnPc_IMPORTED_PATH) + find_library(MiniUPnPc_LIBRARY_DEBUG + NAMES miniupnpc PATHS ${MiniUPnPc_IMPORTED_PATH}/debug/lib + NO_DEFAULT_PATH + ) + find_library(MiniUPnPc_LIBRARY_RELEASE + NAMES miniupnpc PATHS ${MiniUPnPc_IMPORTED_PATH}/lib + NO_DEFAULT_PATH + ) + set(MiniUPnPc_required MiniUPnPc_IMPORTED_PATH) +else() + find_library(MiniUPnPc_LIBRARY + NAMES miniupnpc + PATHS ${PC_MiniUPnPc_LIBRARY_DIRS} + ) + set(MiniUPnPc_required MiniUPnPc_LIBRARY) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(MiniUPnPc + REQUIRED_VARS ${MiniUPnPc_required} MiniUPnPc_INCLUDE_DIR MiniUPnPc_API_VERSION_OK +) + +if(MiniUPnPc_FOUND AND NOT TARGET MiniUPnPc::MiniUPnPc) + add_library(MiniUPnPc::MiniUPnPc UNKNOWN IMPORTED) + set_target_properties(MiniUPnPc::MiniUPnPc PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${MiniUPnPc_INCLUDE_DIR}" + ) + if(MSVC) + if(MiniUPnPc_LIBRARY_DEBUG) + set_property(TARGET MiniUPnPc::MiniUPnPc APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) + set_target_properties(MiniUPnPc::MiniUPnPc PROPERTIES + IMPORTED_LOCATION_DEBUG "${MiniUPnPc_LIBRARY_DEBUG}" + ) + endif() + if(MiniUPnPc_LIBRARY_RELEASE) + set_property(TARGET MiniUPnPc::MiniUPnPc APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) + set_target_properties(MiniUPnPc::MiniUPnPc PROPERTIES + IMPORTED_LOCATION_RELEASE "${MiniUPnPc_LIBRARY_RELEASE}" + ) + endif() + else() + set_target_properties(MiniUPnPc::MiniUPnPc PROPERTIES + IMPORTED_LOCATION "${MiniUPnPc_LIBRARY}" + ) + endif() + set_property(TARGET MiniUPnPc::MiniUPnPc PROPERTY + INTERFACE_COMPILE_DEFINITIONS USE_UPNP=1 $<$:MINIUPNP_STATICLIB> + ) +endif() + +mark_as_advanced( + MiniUPnPc_INCLUDE_DIR + MiniUPnPc_LIBRARY +) diff --git a/cmake/optional.cmake b/cmake/optional.cmake index a94fa99485907..8b02582a22f53 100644 --- a/cmake/optional.cmake +++ b/cmake/optional.cmake @@ -53,3 +53,16 @@ if(WITH_NATPMP) message(FATAL_ERROR "libnatpmp requested, but not found.") endif() endif() + +if(WITH_MINIUPNPC) + find_package(MiniUPnPc MODULE) + if(MiniUPnPc_FOUND) + set(WITH_MINIUPNPC ON) + elseif(WITH_MINIUPNPC STREQUAL "AUTO") + message(WARNING "libminiupnpc not found, disabling.\n" + "To skip libminiupnpc check, use \"-DWITH_MINIUPNPC=OFF\".\n") + set(WITH_MINIUPNPC OFF) + else() + message(FATAL_ERROR "libminiupnpc requested, but not found.") + endif() +endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1ebd8371c5c20..bcfaf5fa5d603 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -205,6 +205,7 @@ target_link_libraries(bitcoin_node libevent::libevent $ $ + $ ) From c3d855e8099de64a22cdd49758b4bd81f13239ae Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sat, 16 Sep 2023 21:57:47 +0100 Subject: [PATCH 25/47] cmake: Add `libzmq` optional package support --- CMakeLists.txt | 2 ++ cmake/optional.cmake | 28 ++++++++++++++++++++++++++++ src/CMakeLists.txt | 4 ++++ src/zmq/CMakeLists.txt | 22 ++++++++++++++++++++++ 4 files changed, 56 insertions(+) create mode 100644 src/zmq/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 51755cb5f4f30..5cfedc30f0b13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,7 @@ include(TristateOption) tristate_option(CCACHE "Use ccache for compiling." "if ccache is found." AUTO) tristate_option(WITH_NATPMP "Enable NAT-PMP." "if libnatpmp is found." AUTO) tristate_option(WITH_MINIUPNPC "Enable UPnP." "if libminiupnpc is found." AUTO) +tristate_option(WITH_ZMQ "Enable ZMQ notifications." "if libzmq is found." AUTO) set(configure_warnings) @@ -176,6 +177,7 @@ message(" bitcoind ............................ ${BUILD_DAEMON}") message("Optional packages:") message(" NAT-PMP ............................. ${WITH_NATPMP}") message(" UPnP ................................ ${WITH_MINIUPNPC}") +message(" ZeroMQ .............................. ${WITH_ZMQ}") message("") if(CMAKE_CROSSCOMPILING) set(cross_status "TRUE, for ${CMAKE_SYSTEM_NAME}, ${CMAKE_SYSTEM_PROCESSOR}") diff --git a/cmake/optional.cmake b/cmake/optional.cmake index 8b02582a22f53..7aebd2db72ce6 100644 --- a/cmake/optional.cmake +++ b/cmake/optional.cmake @@ -66,3 +66,31 @@ if(WITH_MINIUPNPC) message(FATAL_ERROR "libminiupnpc requested, but not found.") endif() endif() + +if(WITH_ZMQ) + if(MSVC) + find_package(ZeroMQ CONFIG) + else() + # The ZeroMQ project has provided config files since v4.2.2. + # TODO: Switch to find_package(ZeroMQ) at some point in the future. + include(CrossPkgConfig) + cross_pkg_check_modules(libzmq IMPORTED_TARGET libzmq>=4) + if(libzmq_FOUND AND TARGET PkgConfig::libzmq) + target_compile_definitions(PkgConfig::libzmq INTERFACE + $<$:ZMQ_STATIC> + ) + target_link_libraries(PkgConfig::libzmq INTERFACE + $<$:iphlpapi;ws2_32> + ) + endif() + endif() + if(TARGET libzmq OR TARGET PkgConfig::libzmq) + set(WITH_ZMQ ON) + elseif(WITH_ZMQ STREQUAL "AUTO") + message(WARNING "libzmq not found, disabling.\n" + "To skip libzmq check, use \"-DWITH_ZMQ=OFF\".\n") + set(WITH_ZMQ OFF) + else() + message(FATAL_ERROR "libzmq requested, but not found.") + endif() +endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bcfaf5fa5d603..bc16af7ef153c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -33,6 +33,9 @@ target_link_libraries(bitcoin_consensus secp256k1 ) +if(WITH_ZMQ) + add_subdirectory(zmq EXCLUDE_FROM_ALL) +endif() # Home for common functionality shared by different executables and libraries. # Similar to `bitcoin_util` library, but higher-level. @@ -206,6 +209,7 @@ target_link_libraries(bitcoin_node $ $ $ + $ ) diff --git a/src/zmq/CMakeLists.txt b/src/zmq/CMakeLists.txt new file mode 100644 index 0000000000000..683b683ee0ce1 --- /dev/null +++ b/src/zmq/CMakeLists.txt @@ -0,0 +1,22 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +add_library(bitcoin_zmq STATIC + zmqabstractnotifier.cpp + zmqnotificationinterface.cpp + zmqpublishnotifier.cpp + zmqrpc.cpp + zmqutil.cpp +) +target_compile_definitions(bitcoin_zmq + INTERFACE + ENABLE_ZMQ=1 +) +target_link_libraries(bitcoin_zmq + PRIVATE + core + univalue + $ + $ +) From c8014378be329e7e2f067c73ce194047ef61384e Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Mon, 10 Jul 2023 09:36:30 +0100 Subject: [PATCH 26/47] cmake: Add `systemtap-sdt` optional package support --- CMakeLists.txt | 6 ++++++ cmake/bitcoin-config.h.in | 4 ++++ cmake/optional.cmake | 40 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5cfedc30f0b13..3bedcad36be46 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,11 @@ tristate_option(CCACHE "Use ccache for compiling." "if ccache is found." AUTO) tristate_option(WITH_NATPMP "Enable NAT-PMP." "if libnatpmp is found." AUTO) tristate_option(WITH_MINIUPNPC "Enable UPnP." "if libminiupnpc is found." AUTO) tristate_option(WITH_ZMQ "Enable ZMQ notifications." "if libzmq is found." AUTO) +tristate_option(WITH_USDT + "Enable tracepoints for Userspace, Statically Defined Tracing." + "if sys/sdt.h is found." + AUTO +) set(configure_warnings) @@ -178,6 +183,7 @@ message("Optional packages:") message(" NAT-PMP ............................. ${WITH_NATPMP}") message(" UPnP ................................ ${WITH_MINIUPNPC}") message(" ZeroMQ .............................. ${WITH_ZMQ}") +message(" USDT tracing ........................ ${WITH_USDT}") message("") if(CMAKE_CROSSCOMPILING) set(cross_status "TRUE, for ${CMAKE_SYSTEM_NAME}, ${CMAKE_SYSTEM_PROCESSOR}") diff --git a/cmake/bitcoin-config.h.in b/cmake/bitcoin-config.h.in index 7a3cf24f440a5..ed70bb5e8f8c8 100644 --- a/cmake/bitcoin-config.h.in +++ b/cmake/bitcoin-config.h.in @@ -33,6 +33,10 @@ /* Copyright year */ #define COPYRIGHT_YEAR @COPYRIGHT_YEAR@ +/* Define to 1 to enable tracepoints for Userspace, Statically Defined Tracing + */ +#cmakedefine ENABLE_TRACING 1 + /* Define this symbol if you have __builtin_clzl */ #cmakedefine HAVE_BUILTIN_CLZL 1 diff --git a/cmake/optional.cmake b/cmake/optional.cmake index 7aebd2db72ce6..c5a8d13447a2c 100644 --- a/cmake/optional.cmake +++ b/cmake/optional.cmake @@ -94,3 +94,43 @@ if(WITH_ZMQ) message(FATAL_ERROR "libzmq requested, but not found.") endif() endif() + +if(WITH_USDT) + find_path(SystemTap_INCLUDE_DIR + NAMES sys/sdt.h + ) + mark_as_advanced(SystemTap_INCLUDE_DIR) + + if(SystemTap_INCLUDE_DIR) + include(CMakePushCheckState) + cmake_push_check_state(RESET) + + include(CheckCXXSourceCompiles) + set(CMAKE_REQUIRED_INCLUDES ${SystemTap_INCLUDE_DIR}) + check_cxx_source_compiles(" + #include + + int main() + { + DTRACE_PROBE(context, event); + int a, b, c, d, e, f, g; + DTRACE_PROBE7(context, event, a, b, c, d, e, f, g); + } + " HAVE_USDT_H + ) + + cmake_pop_check_state() + endif() + + if(HAVE_USDT_H) + target_include_directories(core INTERFACE + ${SystemTap_INCLUDE_DIR} + ) + set(ENABLE_TRACING TRUE) + set(WITH_USDT ON) + elseif(WITH_USDT STREQUAL "AUTO") + set(WITH_USDT OFF) + else() + message(FATAL_ERROR "sys/sdt.h requested, but not found.") + endif() +endif() From 2e914a1be9116973b62bec58456672684a5090ef Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Wed, 13 Sep 2023 20:20:06 +0100 Subject: [PATCH 27/47] cmake: Build `bitcoin-cli` executable --- CMakeLists.txt | 2 ++ src/CMakeLists.txt | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3bedcad36be46..cc5bfa5ced9b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,7 @@ list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/module) # Configurable options. # When adding a new option, end the with a full stop for consistency. option(BUILD_DAEMON "Build bitcoind executable." ON) +option(BUILD_CLI "Build bitcoin-cli executable." ON) option(ASM "Use assembly routines." ON) option(THREADLOCAL "Enable features that depend on the C++ thread_local keyword (currently just thread names in debug logs)." ON) @@ -179,6 +180,7 @@ message("Configure summary") message("=================") message("Executables:") message(" bitcoind ............................ ${BUILD_DAEMON}") +message(" bitcoin-cli ......................... ${BUILD_CLI}") message("Optional packages:") message(" NAT-PMP ............................. ${WITH_NATPMP}") message(" UPnP ................................ ${WITH_MINIUPNPC}") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bc16af7ef153c..30245c181ce1a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -224,3 +224,27 @@ if(BUILD_DAEMON) bitcoin_node ) endif() + + +add_library(bitcoin_cli STATIC EXCLUDE_FROM_ALL + compat/stdin.cpp + rpc/client.cpp +) +target_link_libraries(bitcoin_cli + PUBLIC + core + univalue +) + + +# Bitcoin Core RPC client +if(BUILD_CLI) + add_executable(bitcoin-cli bitcoin-cli.cpp) + target_link_libraries(bitcoin-cli + core + bitcoin_cli + bitcoin_common + bitcoin_util + libevent::libevent + ) +endif() From 4f87e1d1d59aa60fa13821aab2c92adf125b9c22 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Wed, 13 Sep 2023 20:20:40 +0100 Subject: [PATCH 28/47] cmake: Build `bitcoin-tx` executable --- CMakeLists.txt | 2 ++ src/CMakeLists.txt | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index cc5bfa5ced9b8..2648d8cd2b1e2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,7 @@ list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/module) # When adding a new option, end the with a full stop for consistency. option(BUILD_DAEMON "Build bitcoind executable." ON) option(BUILD_CLI "Build bitcoin-cli executable." ON) +option(BUILD_TX "Build bitcoin-tx executable." ON) option(ASM "Use assembly routines." ON) option(THREADLOCAL "Enable features that depend on the C++ thread_local keyword (currently just thread names in debug logs)." ON) @@ -181,6 +182,7 @@ message("=================") message("Executables:") message(" bitcoind ............................ ${BUILD_DAEMON}") message(" bitcoin-cli ......................... ${BUILD_CLI}") +message(" bitcoin-tx .......................... ${BUILD_TX}") message("Optional packages:") message(" NAT-PMP ............................. ${WITH_NATPMP}") message(" UPnP ................................ ${WITH_MINIUPNPC}") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 30245c181ce1a..0778a7ee83323 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -248,3 +248,14 @@ if(BUILD_CLI) libevent::libevent ) endif() + + +if(BUILD_TX) + add_executable(bitcoin-tx bitcoin-tx.cpp) + target_link_libraries(bitcoin-tx + core + bitcoin_common + bitcoin_util + univalue + ) +endif() From e6b0aa7b5b3b02b4b39b30175845ce65e125b076 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Wed, 13 Sep 2023 20:21:23 +0100 Subject: [PATCH 29/47] cmake: Build `bitcoin-util` executable --- CMakeLists.txt | 2 ++ src/CMakeLists.txt | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2648d8cd2b1e2..7df4d5b1b694e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,6 +41,7 @@ list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/module) option(BUILD_DAEMON "Build bitcoind executable." ON) option(BUILD_CLI "Build bitcoin-cli executable." ON) option(BUILD_TX "Build bitcoin-tx executable." ON) +option(BUILD_UTIL "Build bitcoin-util executable." ON) option(ASM "Use assembly routines." ON) option(THREADLOCAL "Enable features that depend on the C++ thread_local keyword (currently just thread names in debug logs)." ON) @@ -183,6 +184,7 @@ message("Executables:") message(" bitcoind ............................ ${BUILD_DAEMON}") message(" bitcoin-cli ......................... ${BUILD_CLI}") message(" bitcoin-tx .......................... ${BUILD_TX}") +message(" bitcoin-util ........................ ${BUILD_UTIL}") message("Optional packages:") message(" NAT-PMP ............................. ${WITH_NATPMP}") message(" UPnP ................................ ${WITH_MINIUPNPC}") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0778a7ee83323..71f83dde23fb9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -259,3 +259,13 @@ if(BUILD_TX) univalue ) endif() + + +if(BUILD_UTIL) + add_executable(bitcoin-util bitcoin-util.cpp) + target_link_libraries(bitcoin-util + core + bitcoin_common + bitcoin_util + ) +endif() From b656c64407f5900deeca381fe768974d6a806cb5 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Wed, 13 Sep 2023 20:19:33 +0100 Subject: [PATCH 30/47] cmake: Add wallet functionality --- CMakeLists.txt | 14 ++++- cmake/bitcoin-config.h.in | 9 ++++ cmake/module/FindBerkeleyDB.cmake | 87 +++++++++++++++++++++++++++++++ cmake/optional.cmake | 47 +++++++++++++++++ src/CMakeLists.txt | 25 ++++++++- src/wallet/CMakeLists.txt | 57 ++++++++++++++++++++ 6 files changed, 236 insertions(+), 3 deletions(-) create mode 100644 cmake/module/FindBerkeleyDB.cmake create mode 100644 src/wallet/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 7df4d5b1b694e..b3c505dcd489b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,11 +43,19 @@ option(BUILD_CLI "Build bitcoin-cli executable." ON) option(BUILD_TX "Build bitcoin-tx executable." ON) option(BUILD_UTIL "Build bitcoin-util executable." ON) option(ASM "Use assembly routines." ON) -option(THREADLOCAL "Enable features that depend on the C++ thread_local keyword (currently just thread names in debug logs)." ON) +option(ENABLE_WALLET "Enable wallet." ON) # TODO: These tri-state options will be removed and most features # will become opt-in by default before merging into master. include(TristateOption) +tristate_option(WITH_SQLITE "Enable SQLite wallet support." "if libsqlite3 is found." AUTO) +tristate_option(WITH_BDB "Enable Berkeley DB (BDB) wallet support." "if libdb_cxx is found." AUTO) +option(WARN_INCOMPATIBLE_BDB "Warn when using a Berkeley DB (BDB) version other than 4.8." ON) +include(CMakeDependentOption) +cmake_dependent_option(BUILD_WALLET_TOOL "Build bitcoin-wallet tool." ON "ENABLE_WALLET" OFF) + +option(THREADLOCAL "Enable features that depend on the C++ thread_local keyword (currently just thread names in debug logs)." ON) + tristate_option(CCACHE "Use ccache for compiling." "if ccache is found." AUTO) tristate_option(WITH_NATPMP "Enable NAT-PMP." "if libnatpmp is found." AUTO) tristate_option(WITH_MINIUPNPC "Enable UPnP." "if libminiupnpc is found." AUTO) @@ -185,6 +193,10 @@ message(" bitcoind ............................ ${BUILD_DAEMON}") message(" bitcoin-cli ......................... ${BUILD_CLI}") message(" bitcoin-tx .......................... ${BUILD_TX}") message(" bitcoin-util ........................ ${BUILD_UTIL}") +message(" bitcoin-wallet ...................... ${BUILD_WALLET_TOOL}") +message("Wallet support:") +message(" SQLite, descriptor wallets .......... ${WITH_SQLITE}") +message(" Berkeley DB, legacy wallets ......... ${WITH_BDB}") message("Optional packages:") message(" NAT-PMP ............................. ${WITH_NATPMP}") message(" UPnP ................................ ${WITH_MINIUPNPC}") diff --git a/cmake/bitcoin-config.h.in b/cmake/bitcoin-config.h.in index ed70bb5e8f8c8..ebbb97562cdb0 100644 --- a/cmake/bitcoin-config.h.in +++ b/cmake/bitcoin-config.h.in @@ -206,4 +206,13 @@ significant byte first (like Motorola and SPARC, unlike Intel). */ #cmakedefine WORDS_BIGENDIAN 1 +/* Define to 1 to enable wallet functions. */ +#cmakedefine ENABLE_WALLET 1 + +/* Define if SQLite support should be compiled in. */ +#cmakedefine USE_SQLITE + +/* Define if Berkeley DB (BDB) support should be compiled in. */ +#cmakedefine USE_BDB + #endif //BITCOIN_CONFIG_H diff --git a/cmake/module/FindBerkeleyDB.cmake b/cmake/module/FindBerkeleyDB.cmake new file mode 100644 index 0000000000000..712fcb3decfbd --- /dev/null +++ b/cmake/module/FindBerkeleyDB.cmake @@ -0,0 +1,87 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +if(CMAKE_HOST_APPLE) + execute_process( + COMMAND brew --prefix berkeley-db@4 + OUTPUT_VARIABLE bdb4_brew_prefix + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) +endif() + +find_path(BerkeleyDB_INCLUDE_DIR + NAMES db.h + HINTS ${bdb4_brew_prefix}/include + PATH_SUFFIXES 4.8 48 4 db4 5 5.3 db5 +) + +if(BerkeleyDB_INCLUDE_DIR) + file( + STRINGS "${BerkeleyDB_INCLUDE_DIR}/db.h" version_strings + REGEX ".*DB_VERSION_(MAJOR|MINOR)[ \t]+[0-9]+.*" + ) + string(REGEX REPLACE ".*DB_VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" BerkeleyDB_VERSION_MAJOR "${version_strings}") + string(REGEX REPLACE ".*DB_VERSION_MINOR[ \t]+([0-9]+).*" "\\1" BerkeleyDB_VERSION_MINOR "${version_strings}") + set(BerkeleyDB_VERSION ${BerkeleyDB_VERSION_MAJOR}.${BerkeleyDB_VERSION_MINOR}) +endif() + +if(MSVC) + cmake_path(GET BerkeleyDB_INCLUDE_DIR PARENT_PATH BerkeleyDB_IMPORTED_PATH) + find_library(BerkeleyDB_LIBRARY_DEBUG + NAMES libdb48 PATHS ${BerkeleyDB_IMPORTED_PATH}/debug/lib + NO_DEFAULT_PATH + ) + find_library(BerkeleyDB_LIBRARY_RELEASE + NAMES libdb48 PATHS ${BerkeleyDB_IMPORTED_PATH}/lib + NO_DEFAULT_PATH + ) + if(BerkeleyDB_LIBRARY_DEBUG OR BerkeleyDB_LIBRARY_RELEASE) + set(BerkeleyDB_required BerkeleyDB_IMPORTED_PATH) + endif() +else() + find_library(BerkeleyDB_LIBRARY + NAMES db_cxx-4.8 libdb48 db4_cxx db_cxx db_cxx-5 + HINTS ${bdb4_brew_prefix}/lib + ) + set(BerkeleyDB_required BerkeleyDB_LIBRARY) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(BerkeleyDB + REQUIRED_VARS ${BerkeleyDB_required} BerkeleyDB_INCLUDE_DIR + VERSION_VAR BerkeleyDB_VERSION +) + +if(BerkeleyDB_FOUND AND NOT TARGET BerkeleyDB::BerkeleyDB) + add_library(BerkeleyDB::BerkeleyDB UNKNOWN IMPORTED) + set_target_properties(BerkeleyDB::BerkeleyDB PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${BerkeleyDB_INCLUDE_DIR}" + ) + if(MSVC) + if(BerkeleyDB_LIBRARY_DEBUG) + set_property(TARGET BerkeleyDB::BerkeleyDB APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) + set_target_properties(BerkeleyDB::BerkeleyDB PROPERTIES + IMPORTED_LOCATION_DEBUG "${BerkeleyDB_LIBRARY_DEBUG}" + ) + endif() + if(BerkeleyDB_LIBRARY_RELEASE) + set_property(TARGET BerkeleyDB::BerkeleyDB APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) + set_target_properties(BerkeleyDB::BerkeleyDB PROPERTIES + IMPORTED_LOCATION_RELEASE "${BerkeleyDB_LIBRARY_RELEASE}" + ) + endif() + else() + set_target_properties(BerkeleyDB::BerkeleyDB PROPERTIES + IMPORTED_LOCATION "${BerkeleyDB_LIBRARY}" + ) + endif() +endif() + +mark_as_advanced( + BerkeleyDB_INCLUDE_DIR + BerkeleyDB_LIBRARY + BerkeleyDB_LIBRARY_DEBUG + BerkeleyDB_LIBRARY_RELEASE +) diff --git a/cmake/optional.cmake b/cmake/optional.cmake index c5a8d13447a2c..4ad779380cf4f 100644 --- a/cmake/optional.cmake +++ b/cmake/optional.cmake @@ -134,3 +134,50 @@ if(WITH_USDT) message(FATAL_ERROR "sys/sdt.h requested, but not found.") endif() endif() + +if(ENABLE_WALLET) + if(WITH_SQLITE) + # TODO: Consider using the FindSQLite3 module after bumping + # the minimum required CMake version up to 3.14+. + if(MSVC) + # Use of the `unofficial::` namespace is a vcpkg package manager convention. + find_package(unofficial-sqlite3 CONFIG) + else() + include(CrossPkgConfig) + cross_pkg_check_modules(sqlite3 sqlite3>=3.7.17 IMPORTED_TARGET) + endif() + if(TARGET unofficial::sqlite3::sqlite3 OR TARGET PkgConfig::sqlite3) + set(WITH_SQLITE ON) + set(USE_SQLITE ON) + elseif(WITH_SQLITE STREQUAL "AUTO") + set(WITH_SQLITE OFF) + else() + message(FATAL_ERROR "SQLite requested, but not found.") + endif() + endif() + + if(WITH_BDB) + find_package(BerkeleyDB 4.8 MODULE) + if(BerkeleyDB_FOUND) + set(WITH_BDB ON) + set(USE_BDB ON) + if(NOT BerkeleyDB_VERSION VERSION_EQUAL 4.8) + message(WARNING "Found Berkeley DB (BDB) other than 4.8.") + if(WARN_INCOMPATIBLE_BDB) + message(WARNING "BDB (legacy) wallets opened by this build would not be portable!\n" + "If this is intended, pass \"-DWARN_INCOMPATIBLE_BDB=OFF\".\n" + "Passing \"-DWITH_BDB=OFF\" will suppress this warning.\n") + else() + message(WARNING "BDB (legacy) wallets opened by this build will not be portable!") + endif() + endif() + else() + message(WARNING "Berkeley DB (BDB) required for legacy wallet support, but not found.\n" + "Passing \"-DWITH_BDB=OFF\" will suppress this warning.\n") + set(WITH_BDB OFF) + endif() + endif() +else() + set(WITH_SQLITE OFF) + set(WITH_BDB OFF) +endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 71f83dde23fb9..4c291e41b7c73 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -101,6 +101,26 @@ target_link_libraries(bitcoin_common ) +if(ENABLE_WALLET) + add_subdirectory(wallet) + + if(BUILD_WALLET_TOOL) + add_executable(bitcoin-wallet + bitcoin-wallet.cpp + init/bitcoin-wallet.cpp + wallet/wallettool.cpp + ) + target_link_libraries(bitcoin-wallet + core + bitcoin_wallet + bitcoin_common + bitcoin_util + Boost::headers + ) + endif() +endif() + + # P2P and RPC server functionality used by `bitcoind` and `bitcoin-qt` executables. add_library(bitcoin_node STATIC EXCLUDE_FROM_ALL addrdb.cpp @@ -193,8 +213,8 @@ add_library(bitcoin_node STATIC EXCLUDE_FROM_ALL validation.cpp validationinterface.cpp versionbits.cpp - - dummywallet.cpp + $<$:wallet/init.cpp> + $<$>:dummywallet.cpp> ) target_link_libraries(bitcoin_node PRIVATE @@ -222,6 +242,7 @@ if(BUILD_DAEMON) target_link_libraries(bitcoind core bitcoin_node + $ ) endif() diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt new file mode 100644 index 0000000000000..34a0379408dfa --- /dev/null +++ b/src/wallet/CMakeLists.txt @@ -0,0 +1,57 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# Wallet functionality used by bitcoind and bitcoin-wallet executables. +add_library(bitcoin_wallet STATIC EXCLUDE_FROM_ALL + coincontrol.cpp + coinselection.cpp + context.cpp + crypter.cpp + db.cpp + dump.cpp + external_signer_scriptpubkeyman.cpp + feebumper.cpp + fees.cpp + interfaces.cpp + load.cpp + receive.cpp + rpc/addresses.cpp + rpc/backup.cpp + rpc/coins.cpp + rpc/encrypt.cpp + rpc/spend.cpp + rpc/signmessage.cpp + rpc/transactions.cpp + rpc/util.cpp + rpc/wallet.cpp + scriptpubkeyman.cpp + spend.cpp + transaction.cpp + wallet.cpp + walletdb.cpp + walletutil.cpp +) +target_link_libraries(bitcoin_wallet + PRIVATE + core + bitcoin_common + univalue + Boost::headers +) + +if(NOT USE_SQLITE AND NOT USE_BDB) + message(FATAL_ERROR "Wallet functionality requested but no BDB or SQLite support available.") +endif() +if(USE_SQLITE) + target_sources(bitcoin_wallet PRIVATE sqlite.cpp) + target_link_libraries(bitcoin_wallet + PRIVATE + $ + $ + ) +endif() +if(USE_BDB) + target_sources(bitcoin_wallet PRIVATE bdb.cpp salvage.cpp) + target_link_libraries(bitcoin_wallet PUBLIC BerkeleyDB::BerkeleyDB) +endif() From ee30452306e4e1bda16b7b0ecdd65b7511a712cd Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Mon, 10 Jul 2023 09:29:39 +0100 Subject: [PATCH 31/47] cmake: Add test config and runners --- CMakeLists.txt | 2 ++ test/CMakeLists.txt | 48 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 test/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index b3c505dcd489b..cbd2bf6c956d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,7 @@ project("Bitcoin Core" LANGUAGES CXX ASM ) +set(PACKAGE_NAME ${PROJECT_NAME}) set(CLIENT_VERSION_IS_RELEASE "false") set(COPYRIGHT_YEAR "2023") set(COPYRIGHT_HOLDERS "The %s developers") @@ -184,6 +185,7 @@ include(cmake/secp256k1.cmake) include(cmake/optional.cmake) add_subdirectory(src) +add_subdirectory(test) message("\n") message("Configure summary") diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000000000..fe832a92f26ba --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,48 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +function(create_test_config) + set(abs_top_srcdir ${PROJECT_SOURCE_DIR}) + set(abs_top_builddir ${PROJECT_BINARY_DIR}) + set(EXEEXT ${CMAKE_EXECUTABLE_SUFFIX}) + + macro(set_configure_variable var conf_var) + if(${var}) + set(${conf_var}_TRUE "") + else() + set(${conf_var}_TRUE "#") + endif() + endmacro() + + set_configure_variable(ENABLE_WALLET ENABLE_WALLET) + set_configure_variable(WITH_SQLITE USE_SQLITE) + set_configure_variable(WITH_BDB USE_BDB) + set_configure_variable(BUILD_CLI BUILD_BITCOIN_CLI) + set_configure_variable(BUILD_UTIL BUILD_BITCOIN_UTIL) + set_configure_variable(BUILD_WALLET_TOOL BUILD_BITCOIN_WALLET) + set_configure_variable(BUILD_DAEMON BUILD_BITCOIND_TRUE) + set_configure_variable(WITH_ZMQ ENABLE_ZMQ) + set_configure_variable(ENABLE_EXTERNAL_SIGNER ENABLE_EXTERNAL_SIGNER) + set_configure_variable(ENABLE_TRACING ENABLE_USDT_TRACEPOINTS) + + configure_file(config.ini.in config.ini @ONLY) +endfunction() + +create_test_config() + +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/functional) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/fuzz) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/util) + +function(create_test_script script) + if(MSVC) + file(CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/${script} ${CMAKE_CURRENT_BINARY_DIR}/${script} COPY_ON_ERROR) + else() + file(CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/${script} ${CMAKE_CURRENT_BINARY_DIR}/${script} COPY_ON_ERROR SYMBOLIC) + endif() +endfunction() + +foreach(script functional/test_runner.py fuzz/test_runner.py util/rpcauth-test.py util/test_runner.py) + create_test_script(${script}) +endforeach() From 4d568c7c2d92bf5b7317753b870ca428107ebbac Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Fri, 8 Dec 2023 20:29:45 +0000 Subject: [PATCH 32/47] cmake: Build `bench_bitcoin` executable --- CMakeLists.txt | 4 ++ cmake/module/GenerateHeaders.cmake | 21 +++++++ cmake/script/GenerateHeaderFromJson.cmake | 24 ++++++++ cmake/script/GenerateHeaderFromRaw.cmake | 22 ++++++++ src/CMakeLists.txt | 6 ++ src/bench/CMakeLists.txt | 69 +++++++++++++++++++++++ src/test/util/CMakeLists.txt | 29 ++++++++++ 7 files changed, 175 insertions(+) create mode 100644 cmake/module/GenerateHeaders.cmake create mode 100644 cmake/script/GenerateHeaderFromJson.cmake create mode 100644 cmake/script/GenerateHeaderFromRaw.cmake create mode 100644 src/bench/CMakeLists.txt create mode 100644 src/test/util/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index cbd2bf6c956d7..f2845f167c7f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,6 +67,8 @@ tristate_option(WITH_USDT AUTO ) +option(BUILD_BENCH "Build bench_bitcoin executable." ON) + set(configure_warnings) include(CheckPIESupported) @@ -204,6 +206,8 @@ message(" NAT-PMP ............................. ${WITH_NATPMP}") message(" UPnP ................................ ${WITH_MINIUPNPC}") message(" ZeroMQ .............................. ${WITH_ZMQ}") message(" USDT tracing ........................ ${WITH_USDT}") +message("Tests:") +message(" bench_bitcoin ....................... ${BUILD_BENCH}") message("") if(CMAKE_CROSSCOMPILING) set(cross_status "TRUE, for ${CMAKE_SYSTEM_NAME}, ${CMAKE_SYSTEM_PROCESSOR}") diff --git a/cmake/module/GenerateHeaders.cmake b/cmake/module/GenerateHeaders.cmake new file mode 100644 index 0000000000000..d8714771b4f6d --- /dev/null +++ b/cmake/module/GenerateHeaders.cmake @@ -0,0 +1,21 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +function(generate_header_from_json json_source_relpath) + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${json_source_relpath}.h + COMMAND ${CMAKE_COMMAND} -DJSON_SOURCE_PATH=${CMAKE_CURRENT_SOURCE_DIR}/${json_source_relpath} -DHEADER_PATH=${CMAKE_CURRENT_BINARY_DIR}/${json_source_relpath}.h -P ${CMAKE_SOURCE_DIR}/cmake/script/GenerateHeaderFromJson.cmake + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${json_source_relpath} ${CMAKE_SOURCE_DIR}/cmake/script/GenerateHeaderFromJson.cmake + VERBATIM + ) +endfunction() + +function(generate_header_from_raw raw_source_relpath) + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${raw_source_relpath}.h + COMMAND ${CMAKE_COMMAND} -DRAW_SOURCE_PATH=${CMAKE_CURRENT_SOURCE_DIR}/${raw_source_relpath} -DHEADER_PATH=${CMAKE_CURRENT_BINARY_DIR}/${raw_source_relpath}.h -P ${CMAKE_SOURCE_DIR}/cmake/script/GenerateHeaderFromRaw.cmake + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${raw_source_relpath} ${CMAKE_SOURCE_DIR}/cmake/script/GenerateHeaderFromRaw.cmake + VERBATIM + ) +endfunction() diff --git a/cmake/script/GenerateHeaderFromJson.cmake b/cmake/script/GenerateHeaderFromJson.cmake new file mode 100644 index 0000000000000..c13c9b1d40b7d --- /dev/null +++ b/cmake/script/GenerateHeaderFromJson.cmake @@ -0,0 +1,24 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +file(READ ${JSON_SOURCE_PATH} hex_content HEX) +string(REGEX MATCHALL "([A-Za-z0-9][A-Za-z0-9])" bytes "${hex_content}") + +file(WRITE ${HEADER_PATH} "#include \n") +file(APPEND ${HEADER_PATH} "namespace json_tests{\n") +get_filename_component(json_source_basename ${JSON_SOURCE_PATH} NAME_WE) +file(APPEND ${HEADER_PATH} "static const std::string ${json_source_basename}{\n") + +set(i 0) +foreach(byte ${bytes}) + math(EXPR i "${i} + 1") + math(EXPR remainder "${i} % 8") + if(remainder EQUAL 0) + file(APPEND ${HEADER_PATH} "0x${byte},\n") + else() + file(APPEND ${HEADER_PATH} "0x${byte}, ") + endif() +endforeach() + +file(APPEND ${HEADER_PATH} "\n};};") diff --git a/cmake/script/GenerateHeaderFromRaw.cmake b/cmake/script/GenerateHeaderFromRaw.cmake new file mode 100644 index 0000000000000..82a3a3c3a3199 --- /dev/null +++ b/cmake/script/GenerateHeaderFromRaw.cmake @@ -0,0 +1,22 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +file(READ ${RAW_SOURCE_PATH} hex_content HEX) +string(REGEX MATCHALL "([A-Za-z0-9][A-Za-z0-9])" bytes "${hex_content}") + +get_filename_component(raw_source_basename ${RAW_SOURCE_PATH} NAME_WE) +file(WRITE ${HEADER_PATH} "static unsigned const char ${raw_source_basename}_raw[] = {\n") + +set(i 0) +foreach(byte ${bytes}) + math(EXPR i "${i} + 1") + math(EXPR remainder "${i} % 8") + if(remainder EQUAL 0) + file(APPEND ${HEADER_PATH} "0x${byte},\n") + else() + file(APPEND ${HEADER_PATH} "0x${byte}, ") + endif() +endforeach() + +file(APPEND ${HEADER_PATH} "\n};") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4c291e41b7c73..10ec5d9dc5228 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -290,3 +290,9 @@ if(BUILD_UTIL) bitcoin_util ) endif() + + +add_subdirectory(test/util) +if(BUILD_BENCH) + add_subdirectory(bench) +endif() diff --git a/src/bench/CMakeLists.txt b/src/bench/CMakeLists.txt new file mode 100644 index 0000000000000..8ba583e131523 --- /dev/null +++ b/src/bench/CMakeLists.txt @@ -0,0 +1,69 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +include(GenerateHeaders) +generate_header_from_raw(data/block413567.raw) + +add_executable(bench_bitcoin + bench_bitcoin.cpp + bench.cpp + data.cpp + nanobench.cpp + ${CMAKE_CURRENT_BINARY_DIR}/data/block413567.raw.h +# Benchmarks: + addrman.cpp + base58.cpp + bech32.cpp + bip324_ecdh.cpp + block_assemble.cpp + ccoins_caching.cpp + chacha20.cpp + checkblock.cpp + checkqueue.cpp + crypto_hash.cpp + descriptors.cpp + disconnected_transactions.cpp + duplicate_inputs.cpp + ellswift.cpp + examples.cpp + gcs_filter.cpp + hashpadding.cpp + load_external.cpp + lockedpool.cpp + logging.cpp + mempool_eviction.cpp + mempool_stress.cpp + merkle_root.cpp + peer_eviction.cpp + poly1305.cpp + pool.cpp + prevector.cpp + rollingbloom.cpp + rpc_blockchain.cpp + rpc_mempool.cpp + streams_findbyte.cpp + strencodings.cpp + util_time.cpp + verify_script.cpp + xor.cpp +) + +target_link_libraries(bench_bitcoin + core + test_util + bitcoin_node + Boost::headers +) + +if(ENABLE_WALLET) + target_sources(bench_bitcoin + PRIVATE + coin_selection.cpp + wallet_balance.cpp + wallet_create.cpp + wallet_create_tx.cpp + wallet_loading.cpp + ) + target_link_libraries(bench_bitcoin bitcoin_wallet) +endif() diff --git a/src/test/util/CMakeLists.txt b/src/test/util/CMakeLists.txt new file mode 100644 index 0000000000000..c48c0a6d3606d --- /dev/null +++ b/src/test/util/CMakeLists.txt @@ -0,0 +1,29 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +add_library(test_util STATIC EXCLUDE_FROM_ALL + blockfilter.cpp + coins.cpp + index.cpp + json.cpp + logging.cpp + mining.cpp + net.cpp + random.cpp + script.cpp + setup_common.cpp + str.cpp + transaction_utils.cpp + txmempool.cpp + validation.cpp + $<$:${PROJECT_SOURCE_DIR}/src/wallet/test/util.cpp> +) + +target_link_libraries(test_util + PRIVATE + core + Boost::headers + PUBLIC + univalue +) From e8d7b09a7bcf52182689ead0dc91d57380230435 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Wed, 15 Nov 2023 18:15:31 +0000 Subject: [PATCH 33/47] cmake: Build `test_bitcoin` executable --- CMakeLists.txt | 2 + cmake/module/AddBoostIfNeeded.cmake | 23 ++++ src/CMakeLists.txt | 4 + src/test/CMakeLists.txt | 174 ++++++++++++++++++++++++++++ src/test/compilerbug_tests.cpp | 7 ++ 5 files changed, 210 insertions(+) create mode 100644 src/test/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index f2845f167c7f6..cb3f123e6de29 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,6 +67,7 @@ tristate_option(WITH_USDT AUTO ) +option(BUILD_TESTS "Build test_bitcoin executable." ON) option(BUILD_BENCH "Build bench_bitcoin executable." ON) set(configure_warnings) @@ -207,6 +208,7 @@ message(" UPnP ................................ ${WITH_MINIUPNPC}") message(" ZeroMQ .............................. ${WITH_ZMQ}") message(" USDT tracing ........................ ${WITH_USDT}") message("Tests:") +message(" test_bitcoin ........................ ${BUILD_TESTS}") message(" bench_bitcoin ....................... ${BUILD_BENCH}") message("") if(CMAKE_CROSSCOMPILING) diff --git a/cmake/module/AddBoostIfNeeded.cmake b/cmake/module/AddBoostIfNeeded.cmake index bad58e154f33b..e564404b29bc3 100644 --- a/cmake/module/AddBoostIfNeeded.cmake +++ b/cmake/module/AddBoostIfNeeded.cmake @@ -25,5 +25,28 @@ function(add_boost_if_needed) BOOST_MULTI_INDEX_DISABLE_SERIALIZATION ) + if(BUILD_TESTS) + include(CheckCXXSourceCompiles) + set(CMAKE_REQUIRED_INCLUDES ${Boost_INCLUDE_DIR}) + check_cxx_source_compiles(" + #define BOOST_TEST_MAIN + #include + " HAVE_BOOST_INCLUDED_UNIT_TEST_H + ) + if(NOT HAVE_BOOST_INCLUDED_UNIT_TEST_H) + message(FATAL_ERROR "Building test_bitcoin executable requested but boost/test/included/unit_test.hpp header not available.") + endif() + + check_cxx_source_compiles(" + #define BOOST_TEST_MAIN + #include + #include + " HAVE_BOOST_UNIT_TEST_H + ) + if(NOT HAVE_BOOST_UNIT_TEST_H) + message(FATAL_ERROR "Building test_bitcoin executable requested but boost/test/unit_test.hpp header not available.") + endif() + endif() + mark_as_advanced(Boost_INCLUDE_DIR) endfunction() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 10ec5d9dc5228..aa49eb77c60d8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -296,3 +296,7 @@ add_subdirectory(test/util) if(BUILD_BENCH) add_subdirectory(bench) endif() + +if(BUILD_TESTS) + add_subdirectory(test) +endif() diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt new file mode 100644 index 0000000000000..4c5f3ca5cf277 --- /dev/null +++ b/src/test/CMakeLists.txt @@ -0,0 +1,174 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +include(GenerateHeaders) +generate_header_from_json(data/base58_encode_decode.json) +generate_header_from_json(data/bip341_wallet_vectors.json) +generate_header_from_json(data/blockfilters.json) +generate_header_from_json(data/key_io_invalid.json) +generate_header_from_json(data/key_io_valid.json) +generate_header_from_json(data/script_tests.json) +generate_header_from_json(data/sighash.json) +generate_header_from_json(data/tx_invalid.json) +generate_header_from_json(data/tx_valid.json) +generate_header_from_raw(data/asmap.raw) + +add_executable(test_bitcoin + main.cpp + $ + ${CMAKE_CURRENT_BINARY_DIR}/data/asmap.raw.h + ${CMAKE_CURRENT_BINARY_DIR}/data/base58_encode_decode.json.h + ${CMAKE_CURRENT_BINARY_DIR}/data/bip341_wallet_vectors.json.h + ${CMAKE_CURRENT_BINARY_DIR}/data/blockfilters.json.h + ${CMAKE_CURRENT_BINARY_DIR}/data/key_io_invalid.json.h + ${CMAKE_CURRENT_BINARY_DIR}/data/key_io_valid.json.h + ${CMAKE_CURRENT_BINARY_DIR}/data/script_tests.json.h + ${CMAKE_CURRENT_BINARY_DIR}/data/sighash.json.h + ${CMAKE_CURRENT_BINARY_DIR}/data/tx_invalid.json.h + ${CMAKE_CURRENT_BINARY_DIR}/data/tx_valid.json.h +# Tests: + addrman_tests.cpp + allocator_tests.cpp + amount_tests.cpp + argsman_tests.cpp + arith_uint256_tests.cpp + banman_tests.cpp + base32_tests.cpp + base58_tests.cpp + base64_tests.cpp + bech32_tests.cpp + bip32_tests.cpp + bip324_tests.cpp + blockchain_tests.cpp + blockencodings_tests.cpp + blockfilter_index_tests.cpp + blockfilter_tests.cpp + blockmanager_tests.cpp + bloom_tests.cpp + bswap_tests.cpp + checkqueue_tests.cpp + coins_tests.cpp + coinstatsindex_tests.cpp + compilerbug_tests.cpp + compress_tests.cpp + crypto_tests.cpp + cuckoocache_tests.cpp + dbwrapper_tests.cpp + denialofservice_tests.cpp + descriptor_tests.cpp + disconnected_transactions.cpp + flatfile_tests.cpp + fs_tests.cpp + getarg_tests.cpp + hash_tests.cpp + headers_sync_chainwork_tests.cpp + httpserver_tests.cpp + i2p_tests.cpp + interfaces_tests.cpp + key_io_tests.cpp + key_tests.cpp + logging_tests.cpp + mempool_tests.cpp + merkle_tests.cpp + merkleblock_tests.cpp + miner_tests.cpp + miniminer_tests.cpp + miniscript_tests.cpp + minisketch_tests.cpp + multisig_tests.cpp + net_peer_connection_tests.cpp + net_peer_eviction_tests.cpp + net_tests.cpp + netbase_tests.cpp + orphanage_tests.cpp + pmt_tests.cpp + policy_fee_tests.cpp + policyestimator_tests.cpp + pool_tests.cpp + pow_tests.cpp + prevector_tests.cpp + raii_event_tests.cpp + random_tests.cpp + rbf_tests.cpp + rest_tests.cpp + result_tests.cpp + reverselock_tests.cpp + rpc_tests.cpp + sanity_tests.cpp + scheduler_tests.cpp + script_p2sh_tests.cpp + script_parse_tests.cpp + script_segwit_tests.cpp + script_standard_tests.cpp + script_tests.cpp + scriptnum_tests.cpp + serfloat_tests.cpp + serialize_tests.cpp + settings_tests.cpp + sighash_tests.cpp + sigopcount_tests.cpp + skiplist_tests.cpp + sock_tests.cpp + span_tests.cpp + streams_tests.cpp + sync_tests.cpp + system_tests.cpp + timedata_tests.cpp + torcontrol_tests.cpp + transaction_tests.cpp + translation_tests.cpp + txindex_tests.cpp + txpackage_tests.cpp + txreconciliation_tests.cpp + txrequest_tests.cpp + txvalidation_tests.cpp + txvalidationcache_tests.cpp + uint256_tests.cpp + util_tests.cpp + util_threadnames_tests.cpp + validation_block_tests.cpp + validation_chainstate_tests.cpp + validation_chainstatemanager_tests.cpp + validation_flush_tests.cpp + validation_tests.cpp + validationinterface_tests.cpp + versionbits_tests.cpp + xoroshiro128plusplus_tests.cpp +) + +target_link_libraries(test_bitcoin + core + test_util + bitcoin_cli + bitcoin_node + minisketch + Boost::headers +) + +if(ENABLE_WALLET) + target_sources(test_bitcoin + PRIVATE + ../wallet/test/init_test_fixture.cpp + ../wallet/test/wallet_test_fixture.cpp + + ../wallet/test/coinselector_tests.cpp + ../wallet/test/feebumper_tests.cpp + ../wallet/test/group_outputs_tests.cpp + ../wallet/test/init_tests.cpp + ../wallet/test/ismine_tests.cpp + ../wallet/test/psbt_wallet_tests.cpp + ../wallet/test/rpc_util_tests.cpp + ../wallet/test/scriptpubkeyman_tests.cpp + ../wallet/test/spend_tests.cpp + ../wallet/test/wallet_crypto_tests.cpp + ../wallet/test/wallet_tests.cpp + ../wallet/test/wallet_transaction_tests.cpp + ../wallet/test/walletdb_tests.cpp + ../wallet/test/walletload_tests.cpp + ) + target_link_libraries(test_bitcoin bitcoin_wallet) + if(USE_BDB) + target_sources(test_bitcoin PRIVATE ../wallet/test/db_tests.cpp) + endif() +endif() diff --git a/src/test/compilerbug_tests.cpp b/src/test/compilerbug_tests.cpp index ef558c1e32269..4492a9686c766 100644 --- a/src/test/compilerbug_tests.cpp +++ b/src/test/compilerbug_tests.cpp @@ -6,6 +6,13 @@ BOOST_AUTO_TEST_SUITE(compilerbug_tests) +// At least one test case is required to avoid the "Test setup error: no test +// cases matching filter or all test cases were disabled" errror. +BOOST_AUTO_TEST_CASE(dummy) +{ + BOOST_CHECK(true); +} + #if defined(__GNUC__) // This block will also be built under clang, which is fine (as it supports noinline) void __attribute__ ((noinline)) set_one(unsigned char* ptr) From 78e6f85c6cd4c5f00a0973eee6195f4f0a30c795 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Tue, 24 Oct 2023 20:57:07 +0100 Subject: [PATCH 34/47] cmake: Include CTest --- CMakeLists.txt | 5 +++++ cmake/tests.cmake | 55 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 cmake/tests.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index cb3f123e6de29..ec255e27c5da1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -187,9 +187,14 @@ include(cmake/secp256k1.cmake) include(cmake/optional.cmake) +find_package(Python3 3.9 COMPONENTS Interpreter) +set(PYTHON_COMMAND ${Python3_EXECUTABLE}) + add_subdirectory(src) add_subdirectory(test) +include(cmake/tests.cmake) + message("\n") message("Configure summary") message("=================") diff --git a/cmake/tests.cmake b/cmake/tests.cmake new file mode 100644 index 0000000000000..598af496387d2 --- /dev/null +++ b/cmake/tests.cmake @@ -0,0 +1,55 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +include(CTest) + +if(TARGET bitcoin-util AND TARGET bitcoin-tx) + add_test(NAME util_test_runner + COMMAND ${CMAKE_COMMAND} -E env BITCOINUTIL=$ BITCOINTX=$ ${PYTHON_COMMAND} ${CMAKE_BINARY_DIR}/test/util/test_runner.py + ) +endif() + +add_test(NAME util_rpcauth_test + COMMAND ${PYTHON_COMMAND} ${CMAKE_BINARY_DIR}/test/util/rpcauth-test.py +) + +if(TARGET bench_bitcoin) + add_test(NAME bench_sanity_check_high_priority + COMMAND bench_bitcoin -sanity-check -priority-level=high + ) +endif() + +if(TARGET test_bitcoin) + function(add_boost_test source_dir source_file) + set(source_file_path ${source_dir}/${source_file}) + if(NOT EXISTS ${source_file_path}) + return() + endif() + + file(READ "${source_file_path}" source_file_content) + string(REGEX + MATCH "(BOOST_FIXTURE_TEST_SUITE|BOOST_AUTO_TEST_SUITE)\\(([A-Za-z0-9_]+)" + test_suite_macro "${source_file_content}" + ) + string(REGEX + REPLACE "(BOOST_FIXTURE_TEST_SUITE|BOOST_AUTO_TEST_SUITE)\\(" "" + test_suite_name "${test_suite_macro}" + ) + if(test_suite_name) + add_test(NAME ${test_suite_name}:${source_file} + COMMAND test_bitcoin --run_test=${test_suite_name} --catch_system_error=no + ) + endif() + endfunction() + + function(add_all_test_targets) + get_target_property(test_source_dir test_bitcoin SOURCE_DIR) + get_target_property(test_sources test_bitcoin SOURCES) + foreach(test_source ${test_sources}) + add_boost_test(${test_source_dir} ${test_source}) + endforeach() + endfunction() + + add_all_test_targets() +endif() From 43a97c26645be519be4883825c75e1370373faee Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sat, 2 Sep 2023 18:12:43 +0100 Subject: [PATCH 35/47] cmake: Add `TryAppendCXXFlags` module --- cmake/module/TryAppendCXXFlags.cmake | 107 +++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 cmake/module/TryAppendCXXFlags.cmake diff --git a/cmake/module/TryAppendCXXFlags.cmake b/cmake/module/TryAppendCXXFlags.cmake new file mode 100644 index 0000000000000..9073bca9a7ece --- /dev/null +++ b/cmake/module/TryAppendCXXFlags.cmake @@ -0,0 +1,107 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +include_guard(GLOBAL) +include(CheckCXXSourceCompiles) + +#[=[ +Usage examples: + + try_append_cxx_flags("-Wformat -Wformat-security" VAR warn_cxx_flags) + + + try_append_cxx_flags("-Wsuggest-override" VAR warn_cxx_flags + SOURCE "struct A { virtual void f(); }; struct B : A { void f() final; };" + ) + + + try_append_cxx_flags("-fsanitize=${SANITIZERS}" TARGET core + RESULT_VAR cxx_supports_sanitizers + ) + if(NOT cxx_supports_sanitizers) + message(FATAL_ERROR "Compiler did not accept requested flags.") + endif() + + + try_append_cxx_flags("-Wunused-parameter" TARGET core + IF_CHECK_PASSED "-Wno-unused-parameter" + ) + + + try_append_cxx_flags("-Werror=return-type" TARGET core + IF_CHECK_FAILED "-Wno-error=return-type" + SOURCE "#include \nint f(){ assert(false); }" + ) + + +In configuration output, this function prints a string by the following pattern: + + -- Performing Test CXX_SUPPORTS_[flags] + -- Performing Test CXX_SUPPORTS_[flags] - Success + +]=] +function(try_append_cxx_flags flags) + cmake_parse_arguments(PARSE_ARGV 1 + TACXXF # prefix + "" # options + "TARGET;VAR;SOURCE;RESULT_VAR" # one_value_keywords + "IF_CHECK_PASSED;IF_CHECK_FAILED" # multi_value_keywords + ) + + string(MAKE_C_IDENTIFIER "${flags}" result) + string(TOUPPER "${result}" result) + string(PREPEND result CXX_SUPPORTS_) + + set(source "int main() { return 0; }") + if(DEFINED TACXXF_SOURCE AND NOT TACXXF_SOURCE STREQUAL source) + set(source "${TACXXF_SOURCE}") + string(SHA256 source_hash "${source}") + string(SUBSTRING ${source_hash} 0 4 source_hash_head) + string(APPEND result _${source_hash_head}) + endif() + + # This avoids running a linker. + set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + set(CMAKE_REQUIRED_FLAGS "${flags} ${working_compiler_werror_flag}") + check_cxx_source_compiles("${source}" ${result}) + + if(${result}) + if(DEFINED TACXXF_IF_CHECK_PASSED) + if(DEFINED TACXXF_TARGET) + target_compile_options(${TACXXF_TARGET} INTERFACE ${TACXXF_IF_CHECK_PASSED}) + endif() + if(DEFINED TACXXF_VAR) + string(STRIP "${${TACXXF_VAR}} ${TACXXF_IF_CHECK_PASSED}" ${TACXXF_VAR}) + endif() + else() + if(DEFINED TACXXF_TARGET) + target_compile_options(${TACXXF_TARGET} INTERFACE ${flags}) + endif() + if(DEFINED TACXXF_VAR) + string(STRIP "${${TACXXF_VAR}} ${flags}" ${TACXXF_VAR}) + endif() + endif() + elseif(DEFINED TACXXF_IF_CHECK_FAILED) + if(DEFINED TACXXF_TARGET) + target_compile_options(${TACXXF_TARGET} INTERFACE ${TACXXF_IF_CHECK_FAILED}) + endif() + if(DEFINED TACXXF_VAR) + string(STRIP "${${TACXXF_VAR}} ${TACXXF_IF_CHECK_FAILED}" ${TACXXF_VAR}) + endif() + endif() + + if(DEFINED TACXXF_VAR) + set(${TACXXF_VAR} "${${TACXXF_VAR}}" PARENT_SCOPE) + endif() + + if(DEFINED TACXXF_RESULT_VAR) + set(${TACXXF_RESULT_VAR} "${${result}}" PARENT_SCOPE) + endif() +endfunction() + +if(MSVC) + try_append_cxx_flags("/WX /options:strict" VAR working_compiler_werror_flag) +else() + try_append_cxx_flags("-Werror" VAR working_compiler_werror_flag) +endif() From 651c1fe13722caf00d8850bcbb517db2d2ebbef2 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sat, 2 Sep 2023 18:13:06 +0100 Subject: [PATCH 36/47] cmake: Add `TryAppendLinkerFlag` module --- cmake/module/TryAppendLinkerFlag.cmake | 85 ++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 cmake/module/TryAppendLinkerFlag.cmake diff --git a/cmake/module/TryAppendLinkerFlag.cmake b/cmake/module/TryAppendLinkerFlag.cmake new file mode 100644 index 0000000000000..ea3595f79bd88 --- /dev/null +++ b/cmake/module/TryAppendLinkerFlag.cmake @@ -0,0 +1,85 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +include_guard(GLOBAL) +include(CheckCXXSourceCompiles) + +#[=[ +Usage example: + + try_append_linker_flag("-Wl,--major-subsystem-version,6" TARGET core) + + +In configuration output, this function prints a string by the following pattern: + + -- Performing Test LINKER_SUPPORTS_[flag] + -- Performing Test LINKER_SUPPORTS_[flag] - Success + +]=] +function(try_append_linker_flag flag) + cmake_parse_arguments(PARSE_ARGV 1 + TALF # prefix + "" # options + "TARGET;VAR;SOURCE;RESULT_VAR" # one_value_keywords + "IF_CHECK_PASSED;IF_CHECK_FAILED" # multi_value_keywords + ) + + string(MAKE_C_IDENTIFIER "${flag}" result) + string(TOUPPER "${result}" result) + string(PREPEND result LINKER_SUPPORTS_) + + set(source "int main() { return 0; }") + if(DEFINED TALF_SOURCE AND NOT TALF_SOURCE STREQUAL source) + set(source "${TALF_SOURCE}") + string(SHA256 source_hash "${source}") + string(SUBSTRING ${source_hash} 0 4 source_hash_head) + string(APPEND result _${source_hash_head}) + endif() + + # This forces running a linker. + set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE) + set(CMAKE_REQUIRED_LINK_OPTIONS ${flag} ${working_linker_werror_flag}) + check_cxx_source_compiles("${source}" ${result}) + + if(${result}) + if(DEFINED TALF_IF_CHECK_PASSED) + if(DEFINED TALF_TARGET) + target_link_options(${TALF_TARGET} INTERFACE ${TALF_IF_CHECK_PASSED}) + endif() + if(DEFINED TALF_VAR) + string(STRIP "${${TALF_VAR}} ${TALF_IF_CHECK_PASSED}" ${TALF_VAR}) + endif() + else() + if(DEFINED TALF_TARGET) + target_link_options(${TALF_TARGET} INTERFACE ${flag}) + endif() + if(DEFINED TALF_VAR) + string(STRIP "${${TALF_VAR}} ${flag}" ${TALF_VAR}) + endif() + endif() + elseif(DEFINED TALF_IF_CHECK_FAILED) + if(DEFINED TALF_TARGET) + target_link_options(${TALF_TARGET} INTERFACE ${TACXXF_IF_CHECK_FAILED}) + endif() + if(DEFINED TALF_VAR) + string(STRIP "${${TALF_VAR}} ${TACXXF_IF_CHECK_FAILED}" ${TALF_VAR}) + endif() + endif() + + if(DEFINED TALF_VAR) + set(${TALF_VAR} "${${TALF_VAR}}" PARENT_SCOPE) + endif() + + if(DEFINED TALF_RESULT_VAR) + set(${TALF_RESULT_VAR} "${${result}}" PARENT_SCOPE) + endif() +endfunction() + +if(MSVC) + try_append_linker_flag("/WX" VAR working_linker_werror_flag) +elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + try_append_linker_flag("-Wl,-fatal_warnings" VAR working_linker_werror_flag) +else() + try_append_linker_flag("-Wl,--fatal-warnings" VAR working_linker_werror_flag) +endif() From 8f3a6454144b3b7aa70b38d99e79d7391bc9ec05 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sat, 2 Sep 2023 17:54:39 +0100 Subject: [PATCH 37/47] cmake: Add platform-specific linker flags --- CMakeLists.txt | 12 ++++++++++++ depends/toolchain.cmake.in | 4 ---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ec255e27c5da1..a6f2fd7592b4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,6 +86,8 @@ unset(check_pie_output) # It is intended to be a usage requirement for all other targets. add_library(core INTERFACE) +include(TryAppendLinkerFlag) + if(WIN32) #[=[ This build system supports two ways to build binaries for Windows. @@ -141,6 +143,10 @@ if(WIN32) _WINDOWS _MT ) + try_append_linker_flag("-static" TARGET core) + # We require Windows 7 (NT 6.1) or later. + try_append_linker_flag("-Wl,--major-subsystem-version,6" TARGET core) + try_append_linker_flag("-Wl,--minor-subsystem-version,1" TARGET core) endif() endif() @@ -156,6 +162,12 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") target_compile_definitions(core INTERFACE MAC_OSX ) + # These flags are specific to ld64, and may cause issues with other linkers. + # For example: GNU ld will interpret -dead_strip as -de and then try and use + # "ad_strip" as the symbol for the entry point. + try_append_linker_flag("-Wl,-dead_strip" TARGET core) + try_append_linker_flag("-Wl,-dead_strip_dylibs" TARGET core) + try_append_linker_flag("-Wl,-headerpad_max_install_names" TARGET core) endif() if(CMAKE_CROSSCOMPILING) diff --git a/depends/toolchain.cmake.in b/depends/toolchain.cmake.in index e13b5541060bd..35aeef819b760 100644 --- a/depends/toolchain.cmake.in +++ b/depends/toolchain.cmake.in @@ -75,10 +75,6 @@ endif() set(DEPENDS_COMPILE_DEFINITIONS @CPPFLAGS@) -if(CMAKE_SYSTEM_NAME STREQUAL "Windows") - set(CMAKE_EXE_LINKER_FLAGS_INIT "-static") -endif() - set(CMAKE_AR "@AR@") set(CMAKE_RANLIB "@RANLIB@") set(CMAKE_STRIP "@STRIP@") From dc830c69812b894b01911e131862f9d554e6c8b4 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sat, 2 Sep 2023 17:45:09 +0100 Subject: [PATCH 38/47] cmake: Redefine configuration flags --- CMakeLists.txt | 80 ++++++------ cmake/module/ProcessConfigurations.cmake | 155 +++++++++++++++++++++++ 2 files changed, 198 insertions(+), 37 deletions(-) create mode 100644 cmake/module/ProcessConfigurations.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index a6f2fd7592b4f..63bed09602aa3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,6 +86,7 @@ unset(check_pie_output) # It is intended to be a usage requirement for all other targets. add_library(core INTERFACE) +include(TryAppendCXXFlags) include(TryAppendLinkerFlag) if(WIN32) @@ -197,6 +198,41 @@ include(cmake/leveldb.cmake) include(cmake/minisketch.cmake) include(cmake/secp256k1.cmake) +include(ProcessConfigurations) +set_default_config(RelWithDebInfo) + +# Redefine configuration flags. +target_compile_definitions(core INTERFACE + $<$:DEBUG> + $<$:DEBUG_LOCKORDER> + $<$:DEBUG_LOCKCONTENTION> + $<$:RPC_DOC_CHECK> + $<$:ABORT_ON_FAILED_ASSUME> +) +# We leave assertions on. +if(MSVC) + remove_c_flag_from_all_configs(/DNDEBUG) + remove_cxx_flag_from_all_configs(/DNDEBUG) +else() + remove_c_flag_from_all_configs(-DNDEBUG) + remove_cxx_flag_from_all_configs(-DNDEBUG) + + # Prefer -O2 optimization level. (-O3 is CMake's default for Release for many compilers.) + replace_c_flag_in_config(Release -O3 -O2) + replace_cxx_flag_in_config(Release -O3 -O2) + + set(debug_flags) + try_append_cxx_flags("-O0" VAR debug_flags) + try_append_cxx_flags("-g3" VAR debug_flags RESULT_VAR compiler_supports_g3) + if(NOT compiler_supports_g3) + try_append_cxx_flags("-g" VAR debug_flags) + endif() + set(CMAKE_C_FLAGS_DEBUG "${debug_flags}") + try_append_cxx_flags("-ftrapv" VAR debug_flags) + set(CMAKE_CXX_FLAGS_DEBUG "${debug_flags}") + unset(debug_flags) +endif() + include(cmake/optional.cmake) find_package(Python3 3.9 COMPONENTS Interpreter) @@ -207,6 +243,9 @@ add_subdirectory(test) include(cmake/tests.cmake) +get_target_property(definitions core INTERFACE_COMPILE_DEFINITIONS) +separate_by_configs(definitions) + message("\n") message("Configure summary") message("=================") @@ -234,9 +273,7 @@ else() set(cross_status "FALSE") endif() message("Cross compiling ....................... ${cross_status}") -get_directory_property(definitions COMPILE_DEFINITIONS) -string(REPLACE ";" " " definitions "${definitions}") -message("Preprocessor defined macros ........... ${definitions}") +message("Preprocessor defined macros ........... ${definitions_ALL}") message("C compiler ............................ ${CMAKE_C_COMPILER}") list(JOIN DEPENDS_C_COMPILER_FLAGS " " depends_c_flags) string(STRIP "${CMAKE_C_FLAGS} ${depends_c_flags}" combined_c_flags) @@ -245,44 +282,13 @@ message("C++ compiler .......................... ${CMAKE_CXX_COMPILER}") list(JOIN DEPENDS_CXX_COMPILER_FLAGS " " depends_cxx_flags) string(STRIP "${CMAKE_CXX_FLAGS} ${depends_cxx_flags}" combined_cxx_flags) message("CXXFLAGS .............................. ${combined_cxx_flags}") -get_target_property(common_compile_options core INTERFACE_COMPILE_OPTIONS) -if(common_compile_options) - list(JOIN common_compile_options " " common_compile_options) -else() - set(common_compile_options) -endif() -string(GENEX_STRIP "${common_compile_options}" common_compile_options) +get_target_interface(common_compile_options core COMPILE_OPTIONS) message("Common compile options ................ ${common_compile_options}") -get_target_property(common_link_options core INTERFACE_LINK_OPTIONS) -if(common_link_options) - list(JOIN common_link_options " " common_link_options) -else() - set(common_link_options) -endif() +get_target_interface(common_link_options core LINK_OPTIONS) message("Common link options ................... ${common_link_options}") message("Linker flags for executables .......... ${CMAKE_EXE_LINKER_FLAGS}") message("Linker flags for shared libraries ..... ${CMAKE_SHARED_LINKER_FLAGS}") -if(DEFINED CMAKE_BUILD_TYPE) - message("Build type:") - message(" - CMAKE_BUILD_TYPE ................... ${CMAKE_BUILD_TYPE}") - string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type) - message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_${build_type}}") - message(" - CXXFLAGS ........................... ${CMAKE_CXX_FLAGS_${build_type}}") - message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_${build_type}}") - message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_${build_type}}") -else() - message("Available configurations .............. ${CMAKE_CONFIGURATION_TYPES}") - message("Debug configuration:") - message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_DEBUG}") - message(" - CXXFLAGS ........................... ${CMAKE_CXX_FLAGS_DEBUG}") - message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_DEBUG}") - message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}") - message("Release configuration:") - message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_RELEASE}") - message(" - CXXFLAGS ........................... ${CMAKE_CXX_FLAGS_RELEASE}") - message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_RELEASE}") - message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") -endif() +print_config_flags() message("Use assembly routines ................. ${ASM}") message("Use ccache for compiling .............. ${CCACHE}") message("\n") diff --git a/cmake/module/ProcessConfigurations.cmake b/cmake/module/ProcessConfigurations.cmake new file mode 100644 index 0000000000000..7d0702d8fa081 --- /dev/null +++ b/cmake/module/ProcessConfigurations.cmake @@ -0,0 +1,155 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +function(get_all_configs output) + get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + if(is_multi_config) + set(all_configs ${CMAKE_CONFIGURATION_TYPES}) + else() + get_property(all_configs CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS) + if(NOT all_configs) + # See https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#default-and-custom-configurations + set(all_configs Debug Release RelWithDebInfo MinSizeRel) + endif() + endif() + set(${output} "${all_configs}" PARENT_SCOPE) +endfunction() + + +#[=[ +Set the default build configuration. + +See: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations. + +On single-configuration generators, this function sets the CMAKE_BUILD_TYPE variable to +the default build configuration, which can be overridden by the user at configure time if needed. + +On multi-configuration generators, this function rearranges the CMAKE_CONFIGURATION_TYPES list, +ensuring that the default build configuration appears first while maintaining the order of the +remaining configurations. The user can choose a build configuration at build time. +]=] +function(set_default_config config) + get_all_configs(all_configs) + if(NOT ${config} IN_LIST all_configs) + message(FATAL_ERROR "The default config is \"${config}\", but must be one of ${all_configs}.") + endif() + + list(REMOVE_ITEM all_configs ${config}) + list(PREPEND all_configs ${config}) + + get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + if(is_multi_config) + get_property(help_string CACHE CMAKE_CONFIGURATION_TYPES PROPERTY HELPSTRING) + set(CMAKE_CONFIGURATION_TYPES "${all_configs}" CACHE STRING "${help_string}" FORCE) + else() + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY + STRINGS "${all_configs}" + ) + if(NOT CMAKE_BUILD_TYPE) + message(STATUS "Setting build type to \"${config}\" as none was specified") + get_property(help_string CACHE CMAKE_BUILD_TYPE PROPERTY HELPSTRING) + set(CMAKE_BUILD_TYPE "${config}" CACHE STRING "${help_string}" FORCE) + endif() + endif() +endfunction() + +function(remove_c_flag_from_all_configs flag) + get_all_configs(all_configs) + foreach(config IN LISTS all_configs) + string(TOUPPER "${config}" config_uppercase) + set(flags "${CMAKE_C_FLAGS_${config_uppercase}}") + separate_arguments(flags) + list(FILTER flags EXCLUDE REGEX "${flag}") + list(JOIN flags " " new_flags) + set(CMAKE_C_FLAGS_${config_uppercase} "${new_flags}" PARENT_SCOPE) + endforeach() +endfunction() + +function(remove_cxx_flag_from_all_configs flag) + get_all_configs(all_configs) + foreach(config IN LISTS all_configs) + string(TOUPPER "${config}" config_uppercase) + set(flags "${CMAKE_CXX_FLAGS_${config_uppercase}}") + separate_arguments(flags) + list(FILTER flags EXCLUDE REGEX "${flag}") + list(JOIN flags " " new_flags) + set(CMAKE_CXX_FLAGS_${config_uppercase} "${new_flags}" PARENT_SCOPE) + endforeach() +endfunction() + +function(replace_c_flag_in_config config old_flag new_flag) + string(TOUPPER "${config}" config_uppercase) + string(REGEX REPLACE "(^| )${old_flag}( |$)" "\\1${new_flag}\\2" new_flags "${CMAKE_C_FLAGS_${config_uppercase}}") + set(CMAKE_C_FLAGS_${config_uppercase} "${new_flags}" PARENT_SCOPE) +endfunction() + +function(replace_cxx_flag_in_config config old_flag new_flag) + string(TOUPPER "${config}" config_uppercase) + string(REGEX REPLACE "(^| )${old_flag}( |$)" "\\1${new_flag}\\2" new_flags "${CMAKE_CXX_FLAGS_${config_uppercase}}") + set(CMAKE_CXX_FLAGS_${config_uppercase} "${new_flags}" PARENT_SCOPE) +endfunction() + +function(separate_by_configs options) + list(JOIN ${options} " " ${options}_ALL) + string(GENEX_STRIP "${${options}_ALL}" ${options}_ALL) + string(STRIP "${${options}_ALL}" ${options}_ALL) + set(${options}_ALL "${${options}_ALL}" PARENT_SCOPE) + + get_all_configs(all_configs) + foreach(config IN LISTS all_configs) + string(REGEX MATCHALL "\\$<\\$:[^<>\n]*>" match "${${options}}") + list(JOIN match " " match) + string(REPLACE "\$<\$:" "" match "${match}") + string(REPLACE ">" "" match "${match}") + string(TOUPPER "${config}" conf_upper) + set(${options}_${conf_upper} "${match}" PARENT_SCOPE) + endforeach() +endfunction() + +function(get_target_interface var target property) + get_target_property(result ${target} INTERFACE_${property}) + if(result) + string(GENEX_STRIP "${result}" result) + list(JOIN result " " result) + else() + set(result) + endif() + + get_target_property(dependencies ${target} INTERFACE_LINK_LIBRARIES) + if(dependencies) + foreach(dependency IN LISTS dependencies) + if(TARGET ${dependency}) + get_target_interface(dep_result ${dependency} ${property}) + string(STRIP "${result} ${dep_result}" result) + endif() + endforeach() + endif() + + set(${var} "${result}" PARENT_SCOPE) +endfunction() + +function(print_config_flags) + macro(print_flags config) + string(TOUPPER "${config}" config_uppercase) + message(" - Preprocessor defined macros ........ ${definitions_${config_uppercase}}") + message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_${config_uppercase}}") + message(" - CXXFLAGS ........................... ${CMAKE_CXX_FLAGS_${config_uppercase}}") + message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_${config_uppercase}}") + message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_${config_uppercase}}") + endmacro() + + get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + if(is_multi_config) + list(JOIN CMAKE_CONFIGURATION_TYPES " " configs) + message("Available build types (configurations) ${configs}") + foreach(config IN LISTS CMAKE_CONFIGURATION_TYPES) + message("'${config}' build type (configuration):") + print_flags(${config}) + endforeach() + else() + message("Build type (configuration):") + message(" - CMAKE_BUILD_TYPE ................... ${CMAKE_BUILD_TYPE}") + print_flags(${CMAKE_BUILD_TYPE}) + endif() +endfunction() From aadacfa0c78da23c1fe65c98422f04e385258d50 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sat, 21 Oct 2023 23:01:18 +0100 Subject: [PATCH 39/47] cmake: Add general compile options --- CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 63bed09602aa3..7aa434b4c3148 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -235,6 +235,15 @@ endif() include(cmake/optional.cmake) +# Don't allow extended (non-ASCII) symbols in identifiers. This is easier for code review. +try_append_cxx_flags("-fno-extended-identifiers" TARGET core) + +# Currently all versions of gcc are subject to a class of bugs, see the +# gccbug_90348 test case (only reproduces on GCC 11 and earlier) and +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111843. To work around that, set +# -fstack-reuse=none for all gcc builds. (Only gcc understands this flag). +try_append_cxx_flags("-fstack-reuse=none" TARGET core) + find_package(Python3 3.9 COMPONENTS Interpreter) set(PYTHON_COMMAND ${Python3_EXECUTABLE}) From 3075828a45712423a2adcc8b5e0d9506b169730a Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Thu, 26 Oct 2023 14:21:39 +0100 Subject: [PATCH 40/47] cmake: Add `HARDENING` option --- CMakeLists.txt | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7aa434b4c3148..23dfa8234b371 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,6 +56,7 @@ include(CMakeDependentOption) cmake_dependent_option(BUILD_WALLET_TOOL "Build bitcoin-wallet tool." ON "ENABLE_WALLET" OFF) option(THREADLOCAL "Enable features that depend on the C++ thread_local keyword (currently just thread names in debug logs)." ON) +option(HARDENING "Attempt to harden the resulting executables." ON) tristate_option(CCACHE "Use ccache for compiling." "if ccache is found." AUTO) tristate_option(WITH_NATPMP "Enable NAT-PMP." "if libnatpmp is found." AUTO) @@ -244,6 +245,48 @@ try_append_cxx_flags("-fno-extended-identifiers" TARGET core) # -fstack-reuse=none for all gcc builds. (Only gcc understands this flag). try_append_cxx_flags("-fstack-reuse=none" TARGET core) +if(HARDENING) + add_library(hardening INTERFACE) + if(MSVC) + try_append_linker_flag("/DYNAMICBASE" TARGET hardening) + try_append_linker_flag("/HIGHENTROPYVA" TARGET hardening) + try_append_linker_flag("/NXCOMPAT" TARGET hardening) + else() + target_compile_options(hardening INTERFACE + $<$>:-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3> + ) + + try_append_cxx_flags("-Wstack-protector" TARGET hardening) + try_append_cxx_flags("-fstack-protector-all" TARGET hardening) + try_append_cxx_flags("-fcf-protection=full" TARGET hardening) + + if(MINGW) + # stack-clash-protection doesn't compile with GCC 10 and earlier. + # In any case, it is a no-op for Windows. + # See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90458 for more details. + else() + try_append_cxx_flags("-fstack-clash-protection" TARGET hardening) + endif() + + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") + try_append_cxx_flags("-mbranch-protection=bti" TARGET hardening) + endif() + + try_append_linker_flag("-Wl,--enable-reloc-section" TARGET hardening) + try_append_linker_flag("-Wl,--dynamicbase" TARGET hardening) + try_append_linker_flag("-Wl,--nxcompat" TARGET hardening) + try_append_linker_flag("-Wl,--high-entropy-va" TARGET hardening) + try_append_linker_flag("-Wl,-z,relro" TARGET hardening) + try_append_linker_flag("-Wl,-z,now" TARGET hardening) + try_append_linker_flag("-Wl,-z,separate-code" TARGET hardening) + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + try_append_linker_flag("-Wl,-bind_at_load" TARGET hardening) + try_append_linker_flag("-Wl,-fixup_chains" TARGET hardening) + endif() + endif() + target_link_libraries(core INTERFACE hardening) +endif() + find_package(Python3 3.9 COMPONENTS Interpreter) set(PYTHON_COMMAND ${Python3_EXECUTABLE}) @@ -299,6 +342,7 @@ message("Linker flags for executables .......... ${CMAKE_EXE_LINKER_FLAGS}") message("Linker flags for shared libraries ..... ${CMAKE_SHARED_LINKER_FLAGS}") print_config_flags() message("Use assembly routines ................. ${ASM}") +message("Attempt to harden executables ......... ${HARDENING}") message("Use ccache for compiling .............. ${CCACHE}") message("\n") if(configure_warnings) From 7f3d40d36b6a847fd30af89c0ff304842c814d7a Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sat, 21 Oct 2023 22:58:57 +0100 Subject: [PATCH 41/47] cmake: Add `REDUCE_EXPORTS` option --- CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 23dfa8234b371..b1a529b40ec3e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,6 +57,7 @@ cmake_dependent_option(BUILD_WALLET_TOOL "Build bitcoin-wallet tool." ON "ENABLE option(THREADLOCAL "Enable features that depend on the C++ thread_local keyword (currently just thread names in debug logs)." ON) option(HARDENING "Attempt to harden the resulting executables." ON) +option(REDUCE_EXPORTS "Attempt to reduce exported symbols in the resulting executables." OFF) tristate_option(CCACHE "Use ccache for compiling." "if ccache is found." AUTO) tristate_option(WITH_NATPMP "Enable NAT-PMP." "if libnatpmp is found." AUTO) @@ -287,6 +288,12 @@ if(HARDENING) target_link_libraries(core INTERFACE hardening) endif() +if(REDUCE_EXPORTS) + set(CMAKE_CXX_VISIBILITY_PRESET hidden) + set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) + try_append_linker_flag("-Wl,--exclude-libs,ALL" TARGET core) +endif() + find_package(Python3 3.9 COMPONENTS Interpreter) set(PYTHON_COMMAND ${Python3_EXECUTABLE}) From a8952fb4da093b113b22712388e6a0396fc2002b Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sat, 21 Oct 2023 22:49:04 +0100 Subject: [PATCH 42/47] cmake: Add `WERROR` option --- CMakeLists.txt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index b1a529b40ec3e..b07b3a71cf2e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,6 +58,7 @@ cmake_dependent_option(BUILD_WALLET_TOOL "Build bitcoin-wallet tool." ON "ENABLE option(THREADLOCAL "Enable features that depend on the C++ thread_local keyword (currently just thread names in debug logs)." ON) option(HARDENING "Attempt to harden the resulting executables." ON) option(REDUCE_EXPORTS "Attempt to reduce exported symbols in the resulting executables." OFF) +option(WERROR "Treat compiler warnings as errors." OFF) tristate_option(CCACHE "Use ccache for compiling." "if ccache is found." AUTO) tristate_option(WITH_NATPMP "Enable NAT-PMP." "if libnatpmp is found." AUTO) @@ -294,6 +295,19 @@ if(REDUCE_EXPORTS) try_append_linker_flag("-Wl,--exclude-libs,ALL" TARGET core) endif() +if(WERROR) + if(MSVC) + set(werror_flag "/WX") + else() + set(werror_flag "-Werror") + endif() + try_append_cxx_flags(${werror_flag} TARGET core RESULT_VAR compiler_supports_werror) + if(NOT compiler_supports_werror) + message(FATAL_ERROR "WERROR set but ${werror_flag} is not usable.") + endif() + unset(werror_flag) +endif() + find_package(Python3 3.9 COMPONENTS Interpreter) set(PYTHON_COMMAND ${Python3_EXECUTABLE}) @@ -350,6 +364,7 @@ message("Linker flags for shared libraries ..... ${CMAKE_SHARED_LINKER_FLAGS}") print_config_flags() message("Use assembly routines ................. ${ASM}") message("Attempt to harden executables ......... ${HARDENING}") +message("Treat compiler warnings as errors ..... ${WERROR}") message("Use ccache for compiling .............. ${CCACHE}") message("\n") if(configure_warnings) From 968a021f817c22b293ec263841e9d03d44d6324e Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sun, 2 Apr 2023 20:36:56 +0100 Subject: [PATCH 43/47] cmake: Implement `make install` --- CMakeLists.txt | 1 + src/CMakeLists.txt | 22 ++++++++++++++++++++++ src/bench/CMakeLists.txt | 4 ++++ src/test/CMakeLists.txt | 4 ++++ 4 files changed, 31 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index b07b3a71cf2e3..8755dc0fc12cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,6 +72,7 @@ tristate_option(WITH_USDT option(BUILD_TESTS "Build test_bitcoin executable." ON) option(BUILD_BENCH "Build bench_bitcoin executable." ON) +option(INSTALL_MAN "Install man pages." ON) set(configure_warnings) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index aa49eb77c60d8..3caa2c2d25e1a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,6 +2,8 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. +include(GNUInstallDirs) + configure_file(${CMAKE_SOURCE_DIR}/cmake/bitcoin-config.h.in config/bitcoin-config.h @ONLY) add_compile_definitions(HAVE_CONFIG_H) include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) @@ -101,6 +103,7 @@ target_link_libraries(bitcoin_common ) +set(installable_targets) if(ENABLE_WALLET) add_subdirectory(wallet) @@ -117,6 +120,7 @@ if(ENABLE_WALLET) bitcoin_util Boost::headers ) + list(APPEND installable_targets bitcoin-wallet) endif() endif() @@ -244,6 +248,7 @@ if(BUILD_DAEMON) bitcoin_node $ ) + list(APPEND installable_targets bitcoind) endif() @@ -268,6 +273,7 @@ if(BUILD_CLI) bitcoin_util libevent::libevent ) + list(APPEND installable_targets bitcoin-cli) endif() @@ -279,6 +285,7 @@ if(BUILD_TX) bitcoin_util univalue ) + list(APPEND installable_targets bitcoin-tx) endif() @@ -289,6 +296,7 @@ if(BUILD_UTIL) bitcoin_common bitcoin_util ) + list(APPEND installable_targets bitcoin-util) endif() @@ -300,3 +308,17 @@ endif() if(BUILD_TESTS) add_subdirectory(test) endif() + + +install(TARGETS ${installable_targets} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) +unset(installable_targets) + +if(INSTALL_MAN) + # TODO: these stubs are no longer needed. man pages should be generated at install time. + install(DIRECTORY ../doc/man/ + DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 + FILES_MATCHING PATTERN *.1 + ) +endif() diff --git a/src/bench/CMakeLists.txt b/src/bench/CMakeLists.txt index 8ba583e131523..f9ca545aa798b 100644 --- a/src/bench/CMakeLists.txt +++ b/src/bench/CMakeLists.txt @@ -67,3 +67,7 @@ if(ENABLE_WALLET) ) target_link_libraries(bench_bitcoin bitcoin_wallet) endif() + +install(TARGETS bench_bitcoin + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 4c5f3ca5cf277..e22008c9e017f 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -172,3 +172,7 @@ if(ENABLE_WALLET) target_sources(test_bitcoin PRIVATE ../wallet/test/db_tests.cpp) endif() endif() + +install(TARGETS test_bitcoin + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) From e17fffe6734b41748affe8243eb6572127abc5f7 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sun, 12 Nov 2023 20:03:04 +0000 Subject: [PATCH 44/47] cmake: Generate `obj/build.h` header --- src/CMakeLists.txt | 19 +++++++++++++++++++ src/util/CMakeLists.txt | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3caa2c2d25e1a..2ce9c81257020 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,6 +8,25 @@ configure_file(${CMAKE_SOURCE_DIR}/cmake/bitcoin-config.h.in config/bitcoin-conf add_compile_definitions(HAVE_CONFIG_H) include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) +# After the transition from Autotools to CMake, the obj/ subdirectory +# could be dropped as its only purpose was to separate a generated header +# from source files. +add_custom_target(generate_build_info + BYPRODUCTS ${PROJECT_BINARY_DIR}/src/obj/build.h + COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/src/obj + COMMAND ${PROJECT_SOURCE_DIR}/share/genbuild.sh ${PROJECT_BINARY_DIR}/src/obj/build.h ${PROJECT_SOURCE_DIR} + COMMENT "Generating obj/build.h" + VERBATIM +) +add_library(bitcoin_clientversion OBJECT EXCLUDE_FROM_ALL + clientversion.cpp +) +target_compile_definitions(bitcoin_clientversion + PRIVATE + HAVE_BUILD_INFO +) +add_dependencies(bitcoin_clientversion generate_build_info) + add_subdirectory(crypto) add_subdirectory(univalue) add_subdirectory(util) diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index dc7eec69a6f43..ed1cac7044b1e 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -33,7 +33,6 @@ add_library(bitcoin_util STATIC EXCLUDE_FROM_ALL time.cpp tokenpipe.cpp ../chainparamsbase.cpp - ../clientversion.cpp ../logging.cpp ../random.cpp ../randomenv.cpp @@ -52,6 +51,7 @@ target_compile_definitions(bitcoin_util target_link_libraries(bitcoin_util PRIVATE core + bitcoin_clientversion bitcoin_crypto Threads::Threads $<$:ws2_32> From 4cf9921557d654f3daad679f750000b52fafb694 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Wed, 22 Nov 2023 22:36:55 +0000 Subject: [PATCH 45/47] cmake: Add `GenerateBuildInfo.cmake` script --- cmake/script/GenerateBuildInfo.cmake | 115 +++++++++++++++++++++++++++ src/CMakeLists.txt | 2 +- 2 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 cmake/script/GenerateBuildInfo.cmake diff --git a/cmake/script/GenerateBuildInfo.cmake b/cmake/script/GenerateBuildInfo.cmake new file mode 100644 index 0000000000000..74221c789e600 --- /dev/null +++ b/cmake/script/GenerateBuildInfo.cmake @@ -0,0 +1,115 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +# This script is a multiplatform port of the share/genbuild.sh shell script. + +macro(fatal_error) + message(FATAL_ERROR "\n" + "Usage:\n" + " cmake -D BUILD_INFO_HEADER_PATH= [-D SOURCE_DIR=] -P ${CMAKE_CURRENT_LIST_FILE}\n" + "All specified paths must be absolute ones.\n" + ) +endmacro() + +if(DEFINED BUILD_INFO_HEADER_PATH AND IS_ABSOLUTE "${BUILD_INFO_HEADER_PATH}") + if(EXISTS "${BUILD_INFO_HEADER_PATH}") + file(STRINGS ${BUILD_INFO_HEADER_PATH} INFO LIMIT_COUNT 1) + endif() +else() + fatal_error() +endif() + +if(DEFINED SOURCE_DIR) + if(IS_ABSOLUTE "${SOURCE_DIR}" AND IS_DIRECTORY "${SOURCE_DIR}") + set(WORKING_DIR ${SOURCE_DIR}) + else() + fatal_error() + endif() +else() + set(WORKING_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +endif() + +set(GIT_TAG) +set(GIT_COMMIT) +if(NOT "$ENV{BITCOIN_GENBUILD_NO_GIT}" STREQUAL "1") + find_package(Git QUIET) + if(Git_FOUND) + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --is-inside-work-tree + WORKING_DIRECTORY ${WORKING_DIR} + OUTPUT_VARIABLE IS_INSIDE_WORK_TREE + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + if(IS_INSIDE_WORK_TREE) + # Clean 'dirty' status of touched files that haven't been modified. + execute_process( + COMMAND ${GIT_EXECUTABLE} diff + WORKING_DIRECTORY ${WORKING_DIR} + OUTPUT_QUIET + ERROR_QUIET + ) + + execute_process( + COMMAND ${GIT_EXECUTABLE} describe --abbrev=0 + WORKING_DIRECTORY ${WORKING_DIR} + OUTPUT_VARIABLE MOST_RECENT_TAG + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-list -1 ${MOST_RECENT_TAG} + WORKING_DIRECTORY ${WORKING_DIR} + OUTPUT_VARIABLE MOST_RECENT_TAG_COMMIT + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse HEAD + WORKING_DIRECTORY ${WORKING_DIR} + OUTPUT_VARIABLE HEAD_COMMIT + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + + execute_process( + COMMAND ${GIT_EXECUTABLE} diff-index --quiet HEAD -- + WORKING_DIRECTORY ${WORKING_DIR} + RESULT_VARIABLE IS_DIRTY + ) + + if(HEAD_COMMIT STREQUAL MOST_RECENT_TAG_COMMIT AND NOT IS_DIRTY) + # If latest commit is tagged and not dirty, then use the tag name. + set(GIT_TAG ${MOST_RECENT_TAG}) + else() + # Otherwise, generate suffix from git, i.e. string like "0e0a5173fae3-dirty". + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --short=12 HEAD + WORKING_DIRECTORY ${WORKING_DIR} + OUTPUT_VARIABLE GIT_COMMIT + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + if(IS_DIRTY) + string(APPEND GIT_COMMIT "-dirty") + endif() + endif() + endif() + endif() +endif() + +if(GIT_TAG) + set(NEWINFO "#define BUILD_GIT_TAG \"${GIT_TAG}\"\n") +elseif(GIT_COMMIT) + set(NEWINFO "#define BUILD_GIT_COMMIT \"${GIT_COMMIT}\"\n") +else() + set(NEWINFO "// No build information available\n") +endif() + +# Only update the header if necessary. +if(NOT "${INFO}" STREQUAL "${NEWINFO}") + file(WRITE ${BUILD_INFO_HEADER_PATH} ${NEWINFO}) +endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2ce9c81257020..f1b601871fb29 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -14,7 +14,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) add_custom_target(generate_build_info BYPRODUCTS ${PROJECT_BINARY_DIR}/src/obj/build.h COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/src/obj - COMMAND ${PROJECT_SOURCE_DIR}/share/genbuild.sh ${PROJECT_BINARY_DIR}/src/obj/build.h ${PROJECT_SOURCE_DIR} + COMMAND ${CMAKE_COMMAND} -DBUILD_INFO_HEADER_PATH=${PROJECT_BINARY_DIR}/src/obj/build.h -DSOURCE_DIR=${PROJECT_SOURCE_DIR} -P ${CMAKE_SOURCE_DIR}/cmake/script/GenerateBuildInfo.cmake COMMENT "Generating obj/build.h" VERBATIM ) From bb7cb2362f5fb3e4bf96d1e3a7e931f9918fb289 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Mon, 4 Dec 2023 16:40:37 +0000 Subject: [PATCH 46/47] cmake: Add vcpkg manifest file --- vcpkg.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 vcpkg.json diff --git a/vcpkg.json b/vcpkg.json new file mode 100644 index 0000000000000..bc2f10faad0fb --- /dev/null +++ b/vcpkg.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json", + "builtin-baseline": "9edb1b8e590cc086563301d735cae4b6e732d2d2", + "dependencies": [ + "berkeleydb", + "boost-date-time", + "boost-multi-index", + "boost-process", + "boost-signals2", + "boost-test", + "libevent", + "miniupnpc", + "sqlite3", + "zeromq" + ] +} From 2af94fb3dffac433138a36b7387e582568e72167 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sun, 12 Nov 2023 16:40:10 +0000 Subject: [PATCH 47/47] ci: Test CMake edge cases Keep this commit at the top when rebasing. --- .github/workflows/ci.yml | 291 ------------------------------------ .github/workflows/cmake.yml | 219 +++++++++++++++++++++++++++ 2 files changed, 219 insertions(+), 291 deletions(-) delete mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/cmake.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 1b43eca672319..0000000000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,291 +0,0 @@ -# Copyright (c) 2023 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -name: CI -on: - # See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request. - pull_request: - # See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#push. - push: - branches: - - '**' - tags-ignore: - - '**' - -concurrency: - group: ${{ github.event_name != 'pull_request' && github.run_id || github.ref }} - cancel-in-progress: true - -env: - DANGER_RUN_CI_ON_HOST: 1 - CI_FAILFAST_TEST_LEAVE_DANGLING: 1 # GHA does not care about dangling processes and setting this variable avoids killing the CI script itself on error - MAKEJOBS: '-j10' - -jobs: - test-each-commit: - name: 'test each commit' - runs-on: ubuntu-22.04 - if: github.event_name == 'pull_request' && github.event.pull_request.commits != 1 - timeout-minutes: 360 # Use maximum time, see https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idtimeout-minutes. Assuming a worst case time of 1 hour per commit, this leads to a --max-count=6 below. - env: - MAX_COUNT: 6 - steps: - - name: Determine fetch depth - run: echo "FETCH_DEPTH=$((${{ github.event.pull_request.commits }} + 2))" >> "$GITHUB_ENV" - - uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.sha }} - fetch-depth: ${{ env.FETCH_DEPTH }} - - name: Determine commit range - run: | - # Checkout HEAD~ and find the test base commit - # Checkout HEAD~ because it would be wasteful to rerun tests on the PR - # head commit that are already run by other jobs. - git checkout HEAD~ - # Figure out test base commit by listing ancestors of HEAD, excluding - # ancestors of the most recent merge commit, limiting the list to the - # newest MAX_COUNT ancestors, ordering it from oldest to newest, and - # taking the first one. - # - # If the branch contains up to MAX_COUNT ancestor commits after the - # most recent merge commit, all of those commits will be tested. If it - # contains more, only the most recent MAX_COUNT commits will be - # tested. - # - # In the command below, the ^@ suffix is used to refer to all parents - # of the merge commit as described in: - # https://git-scm.com/docs/git-rev-parse#_other_rev_parent_shorthand_notations - # and the ^ prefix is used to exclude these parents and all their - # ancestors from the rev-list output as described in: - # https://git-scm.com/docs/git-rev-list - echo "TEST_BASE=$(git rev-list -n$((${{ env.MAX_COUNT }} + 1)) --reverse HEAD ^$(git rev-list -n1 --merges HEAD)^@ | head -1)" >> "$GITHUB_ENV" - - run: | - sudo apt-get update - sudo apt-get install clang-15 ccache build-essential libtool autotools-dev automake pkg-config bsdmainutils python3-zmq libevent-dev libboost-dev libsqlite3-dev libdb++-dev systemtap-sdt-dev libminiupnpc-dev libnatpmp-dev libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools qtwayland5 libqrencode-dev -y - - name: Compile and run tests - run: | - # Run tests on commits after the last merge commit and before the PR head commit - # Use clang++, because it is a bit faster and uses less memory than g++ - git rebase --exec "echo Running test-one-commit on \$( git log -1 ) && ./autogen.sh && CC=clang-15 CXX=clang++-15 ./configure && make clean && make -j $(nproc) check && ./test/functional/test_runner.py -j $(( $(nproc) * 2 ))" ${{ env.TEST_BASE }} - - macos-native-x86_64: - name: 'macOS 13 native, x86_64, no depends, sqlite only, gui' - # Use latest image, but hardcode version to avoid silent upgrades (and breaks). - # See: https://github.com/actions/runner-images#available-images. - runs-on: macos-13 - - # No need to run on the read-only mirror, unless it is a PR. - if: github.repository != 'bitcoin-core/gui' || github.event_name == 'pull_request' - - timeout-minutes: 120 - - env: - FILE_ENV: './ci/test/00_setup_env_mac_native.sh' - BASE_ROOT_DIR: ${{ github.workspace }} - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Clang version - run: clang --version - - - name: Install Homebrew packages - run: brew install automake libtool pkg-config gnu-getopt ccache boost libevent miniupnpc libnatpmp zeromq qt@5 qrencode - - - name: Set Ccache directory - run: echo "CCACHE_DIR=${RUNNER_TEMP}/ccache_dir" >> "$GITHUB_ENV" - - - name: Restore Ccache cache - id: ccache-cache - uses: actions/cache/restore@v3 - with: - path: ${{ env.CCACHE_DIR }} - key: ${{ github.job }}-ccache-${{ github.run_id }} - restore-keys: ${{ github.job }}-ccache- - - - name: CI script - run: ./ci/test_run_all.sh - - - name: Save Ccache cache - uses: actions/cache/save@v3 - if: github.event_name != 'pull_request' && steps.ccache-cache.outputs.cache-hit != 'true' - with: - path: ${{ env.CCACHE_DIR }} - # https://github.com/actions/cache/blob/main/tips-and-workarounds.md#update-a-cache - key: ${{ github.job }}-ccache-${{ github.run_id }} - - win64-native: - name: 'Win64 native, VS 2022' - # Use latest image, but hardcode version to avoid silent upgrades (and breaks). - # See: https://github.com/actions/runner-images#available-images. - runs-on: windows-2022 - - # No need to run on the read-only mirror, unless it is a PR. - if: github.repository != 'bitcoin-core/gui' || github.event_name == 'pull_request' - - env: - CCACHE_MAXSIZE: '200M' - CI_CCACHE_VERSION: '4.7.5' - CI_QT_CONF: '-release -silent -opensource -confirm-license -opengl desktop -static -static-runtime -mp -qt-zlib -qt-pcre -qt-libpng -nomake examples -nomake tests -nomake tools -no-angle -no-dbus -no-gif -no-gtk -no-ico -no-icu -no-libjpeg -no-libudev -no-sql-sqlite -no-sql-odbc -no-sqlite -no-vulkan -skip qt3d -skip qtactiveqt -skip qtandroidextras -skip qtcharts -skip qtconnectivity -skip qtdatavis3d -skip qtdeclarative -skip doc -skip qtdoc -skip qtgamepad -skip qtgraphicaleffects -skip qtimageformats -skip qtlocation -skip qtlottie -skip qtmacextras -skip qtmultimedia -skip qtnetworkauth -skip qtpurchasing -skip qtquick3d -skip qtquickcontrols -skip qtquickcontrols2 -skip qtquicktimeline -skip qtremoteobjects -skip qtscript -skip qtscxml -skip qtsensors -skip qtserialbus -skip qtserialport -skip qtspeech -skip qtsvg -skip qtvirtualkeyboard -skip qtwayland -skip qtwebchannel -skip qtwebengine -skip qtwebglplugin -skip qtwebsockets -skip qtwebview -skip qtx11extras -skip qtxmlpatterns -no-openssl -no-feature-bearermanagement -no-feature-printdialog -no-feature-printer -no-feature-printpreviewdialog -no-feature-printpreviewwidget -no-feature-sql -no-feature-sqlmodel -no-feature-textbrowser -no-feature-textmarkdownwriter -no-feature-textodfwriter -no-feature-xml' - CI_QT_DIR: 'qt-everywhere-src-5.15.11' - CI_QT_URL: 'https://download.qt.io/official_releases/qt/5.15/5.15.11/single/qt-everywhere-opensource-src-5.15.11.zip' - PYTHONUTF8: 1 - TEST_RUNNER_TIMEOUT_FACTOR: 40 - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Configure Developer Command Prompt for Microsoft Visual C++ - # Using microsoft/setup-msbuild is not enough. - uses: ilammy/msvc-dev-cmd@v1 - with: - arch: x64 - - - name: Check MSBuild and Qt - run: | - msbuild -version | Out-File -FilePath "$env:GITHUB_WORKSPACE\msbuild_version" - Get-Content -Path "$env:GITHUB_WORKSPACE\msbuild_version" - $env:VCToolsVersion | Out-File -FilePath "$env:GITHUB_WORKSPACE\toolset_version" - Get-Content -Path "$env:GITHUB_WORKSPACE\toolset_version" - $env:CI_QT_URL | Out-File -FilePath "$env:GITHUB_WORKSPACE\qt_url" - $env:CI_QT_CONF | Out-File -FilePath "$env:GITHUB_WORKSPACE\qt_conf" - - - name: Restore static Qt cache - id: static-qt-cache - uses: actions/cache/restore@v3 - with: - path: C:\Qt_static - key: ${{ github.job }}-static-qt-${{ hashFiles('msbuild_version', 'qt_url', 'qt_conf') }} - - - name: Build static Qt. Download - if: steps.static-qt-cache.outputs.cache-hit != 'true' - shell: cmd - run: | - curl --location --output C:\qt-src.zip %CI_QT_URL% - choco install --yes --no-progress jom - - - name: Build static Qt. Expand source archive - if: steps.static-qt-cache.outputs.cache-hit != 'true' - shell: cmd - run: tar -xf C:\qt-src.zip -C C:\ - - - name: Build static Qt. Create build directory - if: steps.static-qt-cache.outputs.cache-hit != 'true' - run: | - Rename-Item -Path "C:\$env:CI_QT_DIR" -NewName "C:\qt-src" - New-Item -ItemType Directory -Path "C:\qt-src\build" - - - name: Build static Qt. Configure - if: steps.static-qt-cache.outputs.cache-hit != 'true' - working-directory: C:\qt-src\build - shell: cmd - run: ..\configure %CI_QT_CONF% -prefix C:\Qt_static - - - name: Build static Qt. Build - if: steps.static-qt-cache.outputs.cache-hit != 'true' - working-directory: C:\qt-src\build - shell: cmd - run: jom - - - name: Build static Qt. Install - if: steps.static-qt-cache.outputs.cache-hit != 'true' - working-directory: C:\qt-src\build - shell: cmd - run: jom install - - - name: Save static Qt cache - if: steps.static-qt-cache.outputs.cache-hit != 'true' - uses: actions/cache/save@v3 - with: - path: C:\Qt_static - key: ${{ github.job }}-static-qt-${{ hashFiles('msbuild_version', 'qt_url', 'qt_conf') }} - - - name: Ccache installation cache - id: ccache-installation-cache - uses: actions/cache@v3 - with: - path: | - C:\ProgramData\chocolatey\lib\ccache - C:\ProgramData\chocolatey\bin\ccache.exe - C:\ccache\cl.exe - key: ${{ github.job }}-ccache-installation-${{ env.CI_CCACHE_VERSION }} - - - name: Install Ccache - if: steps.ccache-installation-cache.outputs.cache-hit != 'true' - run: | - choco install --yes --no-progress ccache --version=$env:CI_CCACHE_VERSION - New-Item -ItemType Directory -Path "C:\ccache" - Copy-Item -Path "$env:ChocolateyInstall\lib\ccache\tools\ccache-$env:CI_CCACHE_VERSION-windows-x86_64\ccache.exe" -Destination "C:\ccache\cl.exe" - - - name: Restore Ccache cache - id: ccache-cache - uses: actions/cache/restore@v3 - with: - path: ~/AppData/Local/ccache - key: ${{ github.job }}-ccache-${{ github.run_id }} - restore-keys: ${{ github.job }}-ccache- - - - name: Using vcpkg with MSBuild - run: | - Set-Location "$env:VCPKG_INSTALLATION_ROOT" - Add-Content -Path "triplets\x64-windows-static.cmake" -Value "set(VCPKG_BUILD_TYPE release)" - Add-Content -Path "triplets\x64-windows-static.cmake" -Value "set(VCPKG_PLATFORM_TOOLSET_VERSION $env:VCToolsVersion)" - .\vcpkg.exe --vcpkg-root "$env:VCPKG_INSTALLATION_ROOT" integrate install - git rev-parse HEAD | Out-File -FilePath "$env:GITHUB_WORKSPACE\vcpkg_commit" - Get-Content -Path "$env:GITHUB_WORKSPACE\vcpkg_commit" - - - name: vcpkg tools cache - uses: actions/cache@v3 - with: - path: C:/vcpkg/downloads/tools - key: ${{ github.job }}-vcpkg-tools - - - name: vcpkg binary cache - uses: actions/cache@v3 - with: - path: ~/AppData/Local/vcpkg/archives - key: ${{ github.job }}-vcpkg-binary-${{ hashFiles('vcpkg_commit', 'msbuild_version', 'toolset_version', 'build_msvc/vcpkg.json') }} - - - name: Generate project files - run: py -3 build_msvc\msvc-autogen.py - - - name: Build - shell: cmd - run: | - ccache --zero-stats - msbuild build_msvc\bitcoin.sln -property:CLToolPath=C:\ccache;CLToolExe=cl.exe;UseMultiToolTask=true;Configuration=Release -maxCpuCount -verbosity:minimal -noLogo - - - name: Ccache stats - run: ccache --show-stats - - - name: Save Ccache cache - uses: actions/cache/save@v3 - if: github.event_name != 'pull_request' && steps.ccache-cache.outputs.cache-hit != 'true' - with: - path: ~/AppData/Local/ccache - # https://github.com/actions/cache/blob/main/tips-and-workarounds.md#update-a-cache - key: ${{ github.job }}-ccache-${{ github.run_id }} - - - name: Run unit tests - run: src\test_bitcoin.exe -l test_suite - - - name: Run benchmarks - run: src\bench_bitcoin.exe -sanity-check - - - name: Run util tests - run: py -3 test\util\test_runner.py - - - name: Run rpcauth test - run: py -3 test\util\rpcauth-test.py - - - name: Run functional tests - # Don't run functional tests for pull requests. - # The test suit regularly fails to complete in windows native github - # actions as a child process stops making progress. The root cause has - # not yet been determined. - # Discussed in https://github.com/bitcoin/bitcoin/pull/28509 - if: github.event_name != 'pull_request' - run: py -3 test\functional\test_runner.py --jobs $env:NUMBER_OF_PROCESSORS --ci --quiet --tmpdirprefix=$env:RUNNER_TEMP --combinedlogslen=99999999 --timeout-factor=$env:TEST_RUNNER_TIMEOUT_FACTOR --extended diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml new file mode 100644 index 0000000000000..faac26b04e45c --- /dev/null +++ b/.github/workflows/cmake.yml @@ -0,0 +1,219 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +name: CMake +on: + # See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request. + pull_request: + # See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#push. + push: + branches: + - '**' + tags-ignore: + - '**' + +concurrency: + group: ${{ github.workflow }}${{ github.event_name != 'pull_request' && github.run_id || github.ref }} + cancel-in-progress: true + +jobs: + build-info: + name: 'Test obj/build.h generation' + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - run: cp cmake/script/GenerateBuildInfo.cmake ${{ runner.temp }} + + - name: Test at HEAD + run: | + rm -rf src/obj build/src/obj + mkdir -p src/obj build/src/obj + ./share/genbuild.sh ${PWD}/src/obj/build.h ${PWD} + cmake -DBUILD_INFO_HEADER_PATH=${PWD}/build/src/obj/build.h -DSOURCE_DIR=${PWD} -P ${{ runner.temp }}/GenerateBuildInfo.cmake + cat src/obj/build.h + diff -u src/obj/build.h build/src/obj/build.h + + - name: Test out of tree + run: | + rm -rf src/obj build/src/obj + mkdir -p src/obj build/src/obj + ./share/genbuild.sh ${PWD}/src/obj/build.h ${{ runner.temp }} + cmake -DBUILD_INFO_HEADER_PATH=${PWD}/build/src/obj/build.h -DSOURCE_DIR=${{ runner.temp }} -P ${{ runner.temp }}/GenerateBuildInfo.cmake + cat src/obj/build.h + diff -u src/obj/build.h build/src/obj/build.h + + - name: Test at tag + run: | + rm -rf src/obj build/src/obj + mkdir -p src/obj build/src/obj + git -c advice.detachedHead=false checkout v25.1 + ./share/genbuild.sh ${PWD}/src/obj/build.h ${PWD} + cmake -DBUILD_INFO_HEADER_PATH=${PWD}/build/src/obj/build.h -DSOURCE_DIR=${PWD} -P ${{ runner.temp }}/GenerateBuildInfo.cmake + cat src/obj/build.h + diff -u src/obj/build.h build/src/obj/build.h + + - name: Test dirty tree + run: | + rm -rf src/obj build/src/obj + mkdir -p src/obj build/src/obj + echo "test" >> README.md + ./share/genbuild.sh ${PWD}/src/obj/build.h ${PWD} + cmake -DBUILD_INFO_HEADER_PATH=${PWD}/build/src/obj/build.h -DSOURCE_DIR=${PWD} -P ${{ runner.temp }}/GenerateBuildInfo.cmake + cat src/obj/build.h + diff -u src/obj/build.h build/src/obj/build.h + + - name: Test BITCOIN_GENBUILD_NO_GIT + env: + BITCOIN_GENBUILD_NO_GIT: '1' + run: | + rm -rf src/obj build/src/obj + mkdir -p src/obj build/src/obj + ./share/genbuild.sh ${PWD}/src/obj/build.h ${PWD} + cmake -DBUILD_INFO_HEADER_PATH=${PWD}/build/src/obj/build.h -DSOURCE_DIR=${PWD} -P ${{ runner.temp }}/GenerateBuildInfo.cmake + cat src/obj/build.h + diff -u src/obj/build.h build/src/obj/build.h + + + cross-build: + name: ${{ matrix.host.name }} + runs-on: ubuntu-22.04 + + strategy: + fail-fast: false + matrix: + host: + - name: 'Linux 32-bit, Clang, link to libatomic' + packages: 'clang-14 g++-multilib' + triplet: 'i686-pc-linux-gnu' + c_compiler: 'clang-14 -m32' + cxx_compiler: 'clang++-14 -m32' + depends_options: 'NO_QT=1' + configure_options: '-DWERROR=ON' + + env: + CCACHE_MAXSIZE: '120M' + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install dependency packages + run: | + sudo apt-get update + sudo apt-get install --no-install-recommends ccache ${{ matrix.host.packages }} + echo "CCACHE_DIR=${{ runner.temp }}/ccache" >> "$GITHUB_ENV" + + - name: Depends fingerprint + id: depends_fingerprint + run: | + ${{ matrix.host.c_compiler }} -v 2>&1 | tee depends/c_compiler_version + ${{ matrix.host.cxx_compiler }} -v 2>&1 | tee depends/cxx_compiler_version + echo ${{ matrix.host.depends_options }} > depends/depends_options + echo "hash=${{ hashFiles('./depends/**') }}" >> "$GITHUB_OUTPUT" + + - name: Depends cache + id: depends_cache + uses: actions/cache@v3 + with: + path: | + depends/built + key: ${{ matrix.host.triplet }}-depends-${{ steps.depends_fingerprint.outputs.hash }} + + - name: Build depends + run: | + cd depends + make -j$(nproc) HOST=${{ matrix.host.triplet }} CC='${{ matrix.host.c_compiler }}' CXX='${{ matrix.host.cxx_compiler }}' ${{ matrix.host.depends_options }} LOG=1 + + - name: Restore Ccache cache + uses: actions/cache/restore@v3 + id: ccache-cache + with: + path: ${{ env.CCACHE_DIR }} + key: ${{ matrix.host.triplet }}-ccache-${{ github.run_id }} + restore-keys: ${{ matrix.host.triplet }}-ccache- + + - name: Generate build system + run: | + cmake -B build --toolchain depends/${{ matrix.host.triplet }}/share/toolchain.cmake ${{ matrix.host.configure_options }} + + - name: Build + run: | + ccache --zero-stats + cmake --build build -j $(nproc) + ccache --version | head -n 1 && ccache --show-stats + file build/src/bitcoind + + - name: Save Ccache cache + uses: actions/cache/save@v3 + if: github.event_name != 'pull_request' && steps.ccache-cache.outputs.cache-hit != 'true' + with: + path: ${{ env.CCACHE_DIR }} + key: ${{ matrix.host.triplet }}-ccache-${{ github.run_id }} + + - name: Check + run: | + ctest --test-dir build -j $(nproc) + + + win64-native-builtin-tools: + name: 'Win64 native, VS 2022, built-in tools' + runs-on: windows-2022 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Remove non-MSVC tool installations + run: | + Remove-Item -Path "$env:ProgramFiles/CMake" -Recurse -Force + Remove-Item -Path "$env:VCPKG_INSTALLATION_ROOT" -Recurse -Force + + - name: Configure Visual Studio Developer PowerShell + # Using microsoft/setup-msbuild is not enough as it does not add other Visual Studio tools to PATH. + uses: ilammy/msvc-dev-cmd@v1 + + - name: Check build tools + run: | + cmake --version | Out-File -FilePath "cmake_version" + Get-Content -Path "cmake_version" + Write-Output "---" + msbuild -version | Out-File -FilePath "msbuild_version" + Get-Content -Path "msbuild_version" + Write-Output "---" + $env:VCToolsVersion | Out-File -FilePath "toolset_version" + Get-Content -Path "toolset_version" + # GHA Windows images have different versions of MSVC toolsets being installed + # side-by-side. Therefore, the VCPKG_PLATFORM_TOOLSET_VERSION must be set explicitly + # to avoid linker errors when using vcpkg in the manifest mode. + # See: https://github.com/bitcoin/bitcoin/pull/28934 + Add-Content -Path "$env:VCPKG_ROOT\triplets\x64-windows-static.cmake" -Value "set(VCPKG_PLATFORM_TOOLSET_VERSION $env:VCToolsVersion)" + + - name: Restore vcpkg binary cache + uses: actions/cache/restore@v3 + with: + path: ~/AppData/Local/vcpkg/archives + key: ${{ runner.os }}-${{ runner.arch }}-vcpkg-binary-${{ hashFiles('cmake_version', 'msbuild_version', 'toolset_version', 'vcpkg.json') }} + + - name: Generate build system + run: | + cmake -B build -A x64 --toolchain $env:VCPKG_ROOT\scripts\buildsystems\vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static -DWITH_NATPMP=OFF + + - name: Save vcpkg binary cache + uses: actions/cache/save@v3 + with: + path: ~/AppData/Local/vcpkg/archives + key: ${{ runner.os }}-${{ runner.arch }}-vcpkg-binary-${{ hashFiles('cmake_version', 'msbuild_version', 'toolset_version', 'vcpkg.json') }} + + - name: Build Release configuration + run: | + cmake --build build -j $env:NUMBER_OF_PROCESSORS --config Release + + - name: Test Release configuration + run: | + ctest --test-dir build -j $env:NUMBER_OF_PROCESSORS -C Release