diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000000000..827ea7c24543c --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,233 @@ +# 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. +# +# Debian 10 Buster, https://wiki.debian.org/LTS, EOL 2024: +# - CMake 3.13.4, https://packages.debian.org/buster/cmake +# +# Ubuntu 22.04 Jammy, https://wiki.ubuntu.com/Releases, EOL 2032: +# - CMake 3.22.1, https://packages.ubuntu.com/jammy/cmake +# +# Visual Studio 17 2022, https://visualstudio.microsoft.com: +# - CMake 3.24 +# +# All policies known to the running version of CMake and introduced +# in the 3.24 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.13...3.24) + +project("Bitcoin Core" + VERSION 24.99.0 + DESCRIPTION "Bitcoin client software" + HOMEPAGE_URL "https://bitcoincore.org/" + LANGUAGES CXX ASM +) + +set(PACKAGE_NAME ${PROJECT_NAME}) +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") + +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. +include(CMakeDependentOption) +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(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) +cmake_dependent_option(BUILD_WALLET_TOOL "Build bitcoin-wallet tool." ON "ENABLE_WALLET" OFF) + +cmake_dependent_option(CXX20 "Enable compilation in C++20 mode." OFF "NOT MSVC" ON) +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) +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 +) + +option(BUILD_TESTS "Build test_bitcoin executable." ON) +option(BUILD_BENCH "Build bench_bitcoin executable." ON) + +if(CXX20) + set(CMAKE_CXX_STANDARD 20) +else() + set(CMAKE_CXX_STANDARD 17) +endif() +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +set(configure_warnings) + +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. + ]=] + + add_compile_definitions(_WIN32_WINNT=0x0601 _WIN32_IE=0x0501 WIN32_LEAN_AND_MEAN NOMINMAX) + + if(MSVC) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") + add_compile_options(/utf-8 /Zc:__cplusplus) + endif() + + if(MINGW) + add_compile_definitions(WIN32 _WINDOWS _MT) + # We require Windows 7 (NT 6.1) or later. + add_link_options(-Wl,--major-subsystem-version,6 -Wl,--minor-subsystem-version,1) + endif() +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + add_compile_definitions(MAC_OSX) +endif() + +if(CMAKE_CROSSCOMPILING AND DEPENDS_ALLOW_HOST_PACKAGES) + list(APPEND CMAKE_FIND_ROOT_PATH "${CMAKE_SYSTEM_PREFIX_PATH}") +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) +include(cmake/leveldb.cmake) +include(cmake/minisketch.cmake) +include(cmake/secp256k1.cmake) + +include(cmake/optional.cmake) + +if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.14) + include(CheckPIESupported) + check_pie_supported(OUTPUT_VARIABLE check_pie_output LANGUAGES CXX) + if(CMAKE_CXX_LINK_PIE_SUPPORTED) + set(CMAKE_POSITION_INDEPENDENT_CODE ON) + endif() +else() + check_cxx_source_links_with_flags(-fPIE "int main(){}" COMPILER_SUPPORTS_PIE) + if(COMPILER_SUPPORTS_PIE) + set(CMAKE_POSITION_INDEPENDENT_CODE ON) + endif() +endif() + +find_package(Python3 3.8 COMPONENTS Interpreter) +set(PYTHON_COMMAND ${Python3_EXECUTABLE}) + +add_subdirectory(src) +add_subdirectory(test) + +include(cmake/tests.cmake) + +message("\n") +message("Configure summary") +message("=================") +message("Executables:") +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}") +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) + 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}") +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}") +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("Use assembly routines ................. ${ASM}") +message("Use ccache for compiling .............. ${CCACHE}") +message("\n") +if(configure_warnings) + message(" ******\n") + foreach(warning IN LISTS configure_warnings) + message(WARNING "${warning}") + endforeach() + message(" ******\n") +endif() diff --git a/cmake/bitcoin-config.h.in b/cmake/bitcoin-config.h.in new file mode 100644 index 0000000000000..ebbb97562cdb0 --- /dev/null +++ b/cmake/bitcoin-config.h.in @@ -0,0 +1,218 @@ +// 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 + +/* Define this symbol if type char equals int8_t */ +#cmakedefine CHAR_EQUALS_INT8 1 + +/* 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 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 + +/* 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 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 + +/* 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 + +/* 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@" + +/* 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@" + +/* 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 + +/* 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/crc32c.cmake b/cmake/crc32c.cmake new file mode 100644 index 0000000000000..fa3e629dc1d0b --- /dev/null +++ b/cmake/crc32c.cmake @@ -0,0 +1,113 @@ +# 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) +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() diff --git a/cmake/introspection.cmake b/cmake/introspection.cmake new file mode 100644 index 0000000000000..0462ede322d6e --- /dev/null +++ b/cmake/introspection.cmake @@ -0,0 +1,269 @@ +# 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(CheckCXXSourceCompiles) +include(CheckCXXSymbolExists) +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) + +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) + # Illumos/SmartOS requires linking with -lsocket if + # using getifaddrs & freeifaddrs. + # See: https://github.com/bitcoin/bitcoin/pull/21486 + if(HAVE_DECL_GETIFADDRS AND HAVE_DECL_FREEIFADDRS) + set(check_socket_source " + #include + #include + + int main() { + struct ifaddrs* ifaddr; + getifaddrs(&ifaddr); + freeifaddrs(ifaddr); + } + ") + check_cxx_source_links("${check_socket_source}" IFADDR_LINKS_WITHOUT_LIBSOCKET) + if(NOT IFADDR_LINKS_WITHOUT_LIBSOCKET) + check_cxx_source_links_with_libs(socket "${check_socket_source}" IFADDR_NEEDS_LINK_TO_LIBSOCKET) + if(IFADDR_NEEDS_LINK_TO_LIBSOCKET) + link_libraries(socket) + else() + message(FATAL_ERROR "Cannot figure out how to use getifaddrs/freeifaddrs.") + endif() + endif() + endif() +endif() + +# 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 +) + +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 +) + +if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin") + find_program(BREW_COMMAND brew) +endif() diff --git a/cmake/leveldb.cmake b/cmake/leveldb.cmake new file mode 100644 index 0000000000000..e137ef461db02 --- /dev/null +++ b/cmake/leveldb.cmake @@ -0,0 +1,94 @@ +# 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(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/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 +) +if(WIN32) + target_sources(leveldb PRIVATE ${PROJECT_SOURCE_DIR}/src/leveldb/util/env_windows.cc) + set_property(SOURCE ${PROJECT_SOURCE_DIR}/src/leveldb/util/env_windows.cc + APPEND PROPERTY COMPILE_OPTIONS $<$,$>:/wd4722> + ) +else() + target_sources(leveldb PRIVATE ${PROJECT_SOURCE_DIR}/src/leveldb/util/env_posix.cc) +endif() + +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} +) + +if(WIN32) + target_compile_definitions(leveldb + PRIVATE + LEVELDB_PLATFORM_WINDOWS + _UNICODE + UNICODE + __USE_MINGW_ANSI_STDIO=1 + ) +else() + target_compile_definitions(leveldb PRIVATE LEVELDB_PLATFORM_POSIX) +endif() + +target_include_directories(leveldb + PRIVATE + $ + PUBLIC + $ +) + +#TODO: figure out how to filter out: +# -Wconditional-uninitialized -Werror=conditional-uninitialized -Wsuggest-override -Werror=suggest-override + +target_link_libraries(leveldb PRIVATE crc32c) diff --git a/cmake/minisketch.cmake b/cmake/minisketch.cmake new file mode 100644 index 0000000000000..4d8e4b8af74df --- /dev/null +++ b/cmake/minisketch.cmake @@ -0,0 +1,71 @@ +# 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 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_defs INTERFACE) +target_compile_definitions(minisketch_defs INTERFACE + DISABLE_DEFAULT_FIELDS + ENABLE_FIELD_32 + $<$,$>:HAVE_CLZ> +) + +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 minisketch_defs) +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 + minisketch_defs + $ +) diff --git a/cmake/module/AddBoostIfNeeded.cmake b/cmake/module/AddBoostIfNeeded.cmake new file mode 100644 index 0000000000000..a31ed10a9f58b --- /dev/null +++ b/cmake/module/AddBoostIfNeeded.cmake @@ -0,0 +1,31 @@ +# 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::boost PROPERTIES IMPORTED_GLOBAL TRUE) + target_compile_definitions(Boost::boost INTERFACE + $<$:BOOST_MULTI_INDEX_ENABLE_SAFE_MODE> + ) + if(CMAKE_VERSION VERSION_LESS 3.15) + add_library(Boost::headers ALIAS Boost::boost) + endif() + + 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..302d068fe916c --- /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() + + include(CrossPkgConfig) + cross_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) + cross_pkg_check_modules(libevent_pthreads + REQUIRED IMPORTED_TARGET GLOBAL + libevent_pthreads>=${libevent_minimum_version} + ) + endif() +endfunction() 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/cmake/module/CheckSourceCompilesAndLinks.cmake b/cmake/module/CheckSourceCompilesAndLinks.cmake new file mode 100644 index 0000000000000..2e5ab54e67e70 --- /dev/null +++ b/cmake/module/CheckSourceCompilesAndLinks.cmake @@ -0,0 +1,36 @@ +# 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(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) + string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${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) + string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${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/CrossPkgConfig.cmake b/cmake/module/CrossPkgConfig.cmake new file mode 100644 index 0000000000000..429fa5fdc2432 --- /dev/null +++ b/cmake/module/CrossPkgConfig.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_package(PkgConfig REQUIRED) + +function(remove_isystem_from_include_directories_internal target) + 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() + + # A workaround for https://gitlab.kitware.com/cmake/cmake/-/issues/20652. + if(CMAKE_VERSION VERSION_LESS 3.17.3 AND TARGET PkgConfig::${prefix}) + remove_isystem_from_include_directories_internal(PkgConfig::${prefix}) + endif() +endmacro() 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/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/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/module/GenerateHeaders.cmake b/cmake/module/GenerateHeaders.cmake new file mode 100644 index 0000000000000..13359522f2758 --- /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} + 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} + VERBATIM + ) +endfunction() 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() diff --git a/cmake/optional.cmake b/cmake/optional.cmake new file mode 100644 index 0000000000000..e018a47f73725 --- /dev/null +++ b/cmake/optional.cmake @@ -0,0 +1,150 @@ +# 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_EXECUTABLE ccache) + if(CCACHE_EXECUTABLE) + set(CCACHE ON) + if(MSVC) + # See https://github.com/ccache/ccache/wiki/MS-Visual-Studio + set(MSVC_CCACHE_WRAPPER_CONTENT "\"${CCACHE_EXECUTABLE}\" \"${CMAKE_CXX_COMPILER}\"") + set(MSVC_CCACHE_WRAPPER_FILENAME wrapped-cl.bat) + file(WRITE ${CMAKE_BINARY_DIR}/${MSVC_CCACHE_WRAPPER_FILENAME} "${MSVC_CCACHE_WRAPPER_CONTENT} %*") + set(CMAKE_VS_GLOBALS + "CLToolExe=${MSVC_CCACHE_WRAPPER_FILENAME}" + "CLToolPath=${CMAKE_BINARY_DIR}" + "TrackFileAccess=false" + "UseMultiToolTask=true" + "DebugInformationFormat=OldStyle" + ) + else() + list(APPEND CMAKE_C_COMPILER_LAUNCHER ${CCACHE_EXECUTABLE}) + list(APPEND CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_EXECUTABLE}) + endif() + elseif(CCACHE STREQUAL "AUTO") + set(CCACHE OFF) + else() + message(FATAL_ERROR "ccache requested, but not found.") + endif() + mark_as_advanced(CCACHE_EXECUTABLE) +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() + +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() + +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) + set_property(TARGET PkgConfig::libzmq APPEND PROPERTY + INTERFACE_COMPILE_DEFINITIONS $<$:ZMQ_STATIC> + ) + set_property(TARGET PkgConfig::libzmq APPEND PROPERTY + INTERFACE_LINK_LIBRARIES $<$: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() + +include(CheckCXXSourceCompiles) +if(WITH_USDT) + 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 + ) + if(HAVE_USDT_H) + 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() + +if(ENABLE_WALLET) + if(WITH_SQLITE) + include(CrossPkgConfig) + cross_pkg_check_modules(sqlite sqlite3>=3.7.17 IMPORTED_TARGET) + if(sqlite_FOUND) + 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/cmake/script/GenerateHeaderFromJson.cmake b/cmake/script/GenerateHeaderFromJson.cmake new file mode 100644 index 0000000000000..e02705dd895e2 --- /dev/null +++ b/cmake/script/GenerateHeaderFromJson.cmake @@ -0,0 +1,23 @@ +# 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} "namespace json_tests{\n") +get_filename_component(json_source_basename ${JSON_SOURCE_PATH} NAME_WE) +file(APPEND ${HEADER_PATH} "static unsigned const char ${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/cmake/secp256k1.cmake b/cmake/secp256k1.cmake new file mode 100644 index 0000000000000..38014b1cde4f5 --- /dev/null +++ b/cmake/secp256k1.cmake @@ -0,0 +1,52 @@ +# 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. + +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> +) + +target_include_directories(secp256k1 + PUBLIC + $ +) + +target_compile_options(secp256k1 + PRIVATE + $<$:/wd4146 /wd4334> +) 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() diff --git a/depends/Makefile b/depends/Makefile index 3169117633503..ab17e43631fa4 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..59c98d745209d --- /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) + set(DEPENDS_C_COMPILER_FLAGS ${CMAKE_C_COMPILER}) + list(REMOVE_AT DEPENDS_C_COMPILER_FLAGS 0) + string(REPLACE ";" " " DEPENDS_C_COMPILER_FLAGS "${DEPENDS_C_COMPILER_FLAGS}") + list(GET CMAKE_C_COMPILER 0 CMAKE_C_COMPILER) + endif() +endif() +set(CMAKE_C_FLAGS_INIT "${DEPENDS_C_COMPILER_FLAGS} @CPPFLAGS@ @CFLAGS@") + +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) + set(DEPENDS_CXX_COMPILER_FLAGS ${CMAKE_CXX_COMPILER}) + list(REMOVE_AT DEPENDS_CXX_COMPILER_FLAGS 0) + string(REPLACE ";" " " DEPENDS_CXX_COMPILER_FLAGS "${DEPENDS_CXX_COMPILER_FLAGS}") + list(GET CMAKE_CXX_COMPILER 0 CMAKE_CXX_COMPILER) + endif() +endif() +set(CMAKE_CXX_FLAGS_INIT "${DEPENDS_CXX_COMPILER_FLAGS} @CPPFLAGS@ @CXXFLAGS@") + +if(NOT CMAKE_OBJCXX_COMPILER) + set(DEPENDS_OBJCXX_COMPILER_WITH_LAUNCHER @CXX@) + split_compiler_launcher(DEPENDS_OBJCXX_COMPILER_WITH_LAUNCHER CMAKE_OBJCXX_COMPILER_LAUNCHER CMAKE_OBJCXX_COMPILER) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.21) + set(CMAKE_OBJCXX_LINKER_LAUNCHER ${CMAKE_OBJCXX_COMPILER_LAUNCHER}) + endif() + if(CMAKE_VERSION VERSION_LESS 3.19) + set(DEPENDS_OBJCXX_COMPILER_FLAGS ${CMAKE_OBJCXX_COMPILER}) + list(REMOVE_AT DEPENDS_OBJCXX_COMPILER_FLAGS 0) + string(REPLACE ";" " " DEPENDS_OBJCXX_COMPILER_FLAGS "${DEPENDS_OBJCXX_COMPILER_FLAGS}") + list(GET CMAKE_OBJCXX_COMPILER 0 CMAKE_OBJCXX_COMPILER) + endif() +endif() +set(CMAKE_OBJCXX_FLAGS_INIT "${DEPENDS_OBJCXX_COMPILER_FLAGS} @CPPFLAGS@ @CXXFLAGS@") + +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() + +if(DEFINED ENV{PYTHONPATH}) + set(PYTHONPATH "@depends_prefix@/native/lib/python3/dist-packages:$ENV{PYTHONPATH}") +else() + set(PYTHONPATH "@depends_prefix@/native/lib/python3/dist-packages") +endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000000000..4f95797409580 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,293 @@ +# 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}) + +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 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. +add_library(bitcoin_common STATIC EXCLUDE_FROM_ALL + 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/standard.cpp + warnings.cpp +) +target_compile_definitions(bitcoin_common + PRIVATE + ${THREAD_LOCAL_IF_AVAILABLE} +) +target_link_libraries(bitcoin_common + PRIVATE + bitcoin_consensus + bitcoin_util + univalue + secp256k1 + Boost::headers + $ +) + + +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 + 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 + addrman.cpp + banman.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/mempool_persist.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/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 +) +if(ENABLE_WALLET) + target_sources(bitcoin_node PRIVATE wallet/init.cpp) + target_link_libraries(bitcoin_node PRIVATE bitcoin_wallet) +else() + target_sources(bitcoin_node PRIVATE dummywallet.cpp) +endif() +target_link_libraries(bitcoin_node + PRIVATE + 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 + PRIVATE + bitcoin_node + ) + target_link_options(bitcoind + PRIVATE + $<$:-static> + ) +endif() + + +add_library(bitcoin_cli STATIC EXCLUDE_FROM_ALL + compat/stdin.cpp + rpc/client.cpp +) +target_link_libraries(bitcoin_cli + PUBLIC + univalue +) + + +# Bitcoin Core RPC client +if(BUILD_CLI) + add_executable(bitcoin-cli bitcoin-cli.cpp) + target_link_libraries(bitcoin-cli + bitcoin_cli + bitcoin_common + bitcoin_util + libevent::libevent + ) +endif() + + +if(BUILD_TX) + add_executable(bitcoin-tx bitcoin-tx.cpp) + target_link_libraries(bitcoin-tx + bitcoin_common + bitcoin_util + univalue + ) +endif() + + +if(BUILD_UTIL) + add_executable(bitcoin-util bitcoin-util.cpp) + target_link_libraries(bitcoin-util + bitcoin_common + bitcoin_util + ) +endif() + + +add_subdirectory(test/util) +if(BUILD_BENCH) + add_subdirectory(bench) +endif() + +if(BUILD_TESTS) + add_subdirectory(test) +endif() diff --git a/src/bench/CMakeLists.txt b/src/bench/CMakeLists.txt new file mode 100644 index 0000000000000..dce546744b1b9 --- /dev/null +++ b/src/bench/CMakeLists.txt @@ -0,0 +1,67 @@ +# 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(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 + chacha_poly_aead.cpp + checkblock.cpp + checkqueue.cpp + crypto_hash.cpp + descriptors.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 +) + +target_link_libraries(bench_bitcoin + test_util + leveldb + univalue + Boost::headers +) + +if(ENABLE_WALLET) + target_sources(bench_bitcoin + PRIVATE + coin_selection.cpp + wallet_balance.cpp + wallet_create_tx.cpp + wallet_loading.cpp + ) + target_link_libraries(bench_bitcoin bitcoin_wallet) +endif() diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt new file mode 100644 index 0000000000000..3f191159a1506 --- /dev/null +++ b/src/crypto/CMakeLists.txt @@ -0,0 +1,122 @@ +# 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 + chacha_poly_aead.cpp + chacha20.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() diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt new file mode 100644 index 0000000000000..f1e3e2938d226 --- /dev/null +++ b/src/test/CMakeLists.txt @@ -0,0 +1,174 @@ +# 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(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 + 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 + 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_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 + 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 + test_util + bitcoin_cli + bitcoin_node + bitcoin_common + bitcoin_util + minisketch + leveldb + univalue + Boost::headers + libevent::libevent +) + +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/util/CMakeLists.txt b/src/test/util/CMakeLists.txt new file mode 100644 index 0000000000000..69d7ad02de2d2 --- /dev/null +++ b/src/test/util/CMakeLists.txt @@ -0,0 +1,34 @@ +# 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(test_util STATIC EXCLUDE_FROM_ALL + blockfilter.cpp + coins.cpp + index.cpp + json.cpp + logging.cpp + mining.cpp + net.cpp + script.cpp + setup_common.cpp + str.cpp + transaction_utils.cpp + txmempool.cpp + validation.cpp +) +target_link_libraries(test_util + PRIVATE + bitcoin_common + bitcoin_node + leveldb + univalue + Boost::headers +) + +if(ENABLE_WALLET) + target_sources(test_util + PRIVATE + ../../wallet/test/util.cpp + ) +endif() diff --git a/src/univalue/CMakeLists.txt b/src/univalue/CMakeLists.txt new file mode 100644 index 0000000000000..de9c837da275d --- /dev/null +++ b/src/univalue/CMakeLists.txt @@ -0,0 +1,15 @@ +# 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 + $ +) diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt new file mode 100644 index 0000000000000..c567293088c4c --- /dev/null +++ b/src/util/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. + +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 + ../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 + bitcoin_crypto + univalue + Threads::Threads + $<$:ws2_32> +) diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt new file mode 100644 index 0000000000000..9ff55d505815c --- /dev/null +++ b/src/wallet/CMakeLists.txt @@ -0,0 +1,52 @@ +# 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 + 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 PkgConfig::sqlite) +endif() +if(USE_BDB) + target_sources(bitcoin_wallet PRIVATE bdb.cpp salvage.cpp) + target_link_libraries(bitcoin_wallet PUBLIC BerkeleyDB::BerkeleyDB) +endif() diff --git a/src/zmq/CMakeLists.txt b/src/zmq/CMakeLists.txt new file mode 100644 index 0000000000000..39cef32fceb42 --- /dev/null +++ b/src/zmq/CMakeLists.txt @@ -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. + +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 + leveldb + univalue + $ + $ +) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000000000..0a8c2d33f2013 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,51 @@ +# 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) + elseif(CMAKE_VERSION VERSION_GREATER_EQUAL 3.14) + file(CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/${script} ${CMAKE_CURRENT_BINARY_DIR}/${script} COPY_ON_ERROR SYMBOLIC) + else() + file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/${script}) + execute_process(COMMAND ln -s ${CMAKE_CURRENT_SOURCE_DIR}/${script} ${CMAKE_CURRENT_BINARY_DIR}/${script}) + 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()