diff --git a/.github/workflows/build-src-cmake.yml b/.github/workflows/build-src-cmake.yml new file mode 100644 index 000000000000..632d87cbd2c9 --- /dev/null +++ b/.github/workflows/build-src-cmake.yml @@ -0,0 +1,116 @@ +name: Build source (CMake) + +on: + workflow_call: + inputs: + build-target: + description: "Target name as defined by inputs.sh" + required: true + type: string + container-path: + description: "Path to built container at registry" + required: true + type: string + depends-key: + description: "Key needed to access cached depends" + required: true + type: string + depends-host: + description: "Host triplet from depends build" + required: true + type: string + depends-dep-opts: + description: "DEP_OPTS used to build depends" + required: false + type: string + default: "" + runs-on: + description: "Runner label to use (e.g., ubuntu-24.04 or ubuntu-24.04-arm)" + required: true + type: string + +# Builds the tree with CMake on top of the depends prefix produced for the +# Autotools jobs, which is what makes this a full-stack check: depends emits +# toolchain.cmake, CMake consumes it, and the unit tests run against the +# result, followed by a short functional smoke list. The full functional suite +# stays with the Autotools jobs, so this job does not bundle artifacts. +jobs: + build-src-cmake: + name: Build source (CMake) + runs-on: ${{ inputs.runs-on }} + container: + image: ${{ inputs.container-path }} + options: --user root + steps: + - name: Checkout code + uses: actions/checkout@v6 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 50 + + - name: Initial setup + run: | + git config --global --add safe.directory "$PWD" + shell: bash + + - name: Restore depends cache + uses: actions/cache/restore@v5 + with: + path: depends/built/${{ inputs.depends-host }} + key: ${{ inputs.depends-key }} + fail-on-cache-miss: true + + - name: Rebuild depends prefix + run: | + # Use the HOST and DEP_OPTS from the depends build, not this build-target + # This ensures the build_id matches the cached packages, and it is what + # writes depends/${HOST}/toolchain.cmake. + make -j$(nproc) -C depends HOST="${{ inputs.depends-host }}" ${{ inputs.depends-dep-opts }} + shell: bash + + - name: Restore ccache cache + uses: actions/cache/restore@v5 + with: + path: | + /cache/ccache + key: ccache-${{ hashFiles('contrib/containers/ci/ci.Dockerfile', 'depends/packages/*') }}-${{ inputs.build-target }}-${{ github.sha }} + restore-keys: | + ccache-${{ hashFiles('contrib/containers/ci/ci.Dockerfile', 'depends/packages/*') }}-${{ inputs.build-target }}- + + - name: Build source + run: | + CCACHE_MAXSIZE="600M" + CACHE_DIR="/cache" + mkdir /output + BASE_OUTDIR="/output" + BUILD_TARGET="${{ inputs.build-target }}" + source ./ci/dash/matrix.sh + ./ci/dash/build_src_cmake.sh + ccache -X 9 + ccache -c + du -hd0 "${BASE_OUTDIR}" + shell: bash + + - name: Save ccache cache + if: | + github.event_name == 'push' && + github.ref_name == github.event.repository.default_branch + uses: actions/cache/save@v5 + with: + path: | + /cache/ccache + key: ccache-${{ hashFiles('contrib/containers/ci/ci.Dockerfile', 'depends/packages/*') }}-${{ inputs.build-target }}-${{ github.sha }} + + - name: Run unit tests + run: | + BUILD_TARGET="${{ inputs.build-target }}" + source ./ci/dash/matrix.sh + ./ci/dash/test_unittests_cmake.sh + shell: bash + + - name: Run functional smoke tests + run: | + BUILD_TARGET="${{ inputs.build-target }}" + source ./ci/dash/matrix.sh + ./ci/dash/test_integrationtests_cmake.sh + shell: bash diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1f4b5128f93b..d39eaf4319f5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -129,6 +129,7 @@ jobs: needs: [check-skip, container, cache-sources] if: | vars.SKIP_LINUX64 == '' || + vars.SKIP_LINUX64_CMAKE == '' || vars.SKIP_LINUX64_FUZZ == '' || vars.SKIP_LINUX64_SQLITE == '' || vars.SKIP_LINUX64_UBSAN == '' @@ -217,6 +218,19 @@ jobs: depends-dep-opts: ${{ needs.depends-linux64.outputs.dep-opts }} runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }} + src-linux64_cmake: + name: linux64_cmake-build + uses: ./.github/workflows/build-src-cmake.yml + needs: [check-skip, container, depends-linux64] + if: ${{ vars.SKIP_LINUX64_CMAKE == '' }} + with: + build-target: linux64_cmake + container-path: ${{ needs.container.outputs.path }} + depends-key: ${{ needs.depends-linux64.outputs.key }} + depends-host: ${{ needs.depends-linux64.outputs.host }} + depends-dep-opts: ${{ needs.depends-linux64.outputs.dep-opts }} + runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }} + src-linux64_fuzz: name: linux64_fuzz-build uses: ./.github/workflows/build-src.yml diff --git a/.gitignore b/.gitignore index eab9f3f83ec1..9c23ce3939fb 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,11 @@ todo.txt reset-files.bash +# Build subdirectories. +/*build* +!/build-aux +!/build_msvc + *.tar.gz *.exe diff --git a/CMakeLists.txt b/CMakeLists.txt index 1af0d14fa95d..a4a8f1a0da0f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,122 +1,813 @@ -# This CMakeLists.txt is not meant to actually work! -# It only serves as a dummy project to make CLion work properly when it comes to symbol resolution and all the nice -# features dependent on that. Building must still be done on the command line using the automake build chain -# If you load this project in CLion and would like to run/debug executables, make sure to remove the "Build" entry from -# the run/debug configuration as otherwise CLion will try to build this project with cmake, failing horribly. -# You'll also have to manually change the executable in the configuration to the correct path of the already built executable +# 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/. -cmake_minimum_required(VERSION 3.7) -project(dash) +# Ubuntu 22.04 LTS Jammy Jellyfish, https://wiki.ubuntu.com/Releases, EOSS in June 2027: +# - CMake 3.22.1, https://packages.ubuntu.com/jammy/cmake +# +# Centos Stream 9, EOL in May 2027: +# - CMake 3.26.5, https://mirror.stream.centos.org/9-stream/AppStream/x86_64/os/Packages/ +cmake_minimum_required(VERSION 3.22) +if(POLICY CMP0141) + # MSVC debug information format flags are selected by an abstraction. + # We want to use the CMAKE_MSVC_DEBUG_INFORMATION_FORMAT variable + # to select the MSVC debug information format. + cmake_policy(SET CMP0141 NEW) +endif() + +if (${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) + message(FATAL_ERROR "In-source builds are not allowed.") +endif() + +#============================= +# Project / Package metadata +#============================= +set(PACKAGE_NAME "Dash Core") +# AC_INIT's tarname argument; used for the NSIS installer and URI class. +set(PACKAGE_TARNAME "dashcore") +set(CLIENT_VERSION_MAJOR 23) +set(CLIENT_VERSION_MINOR 1) +set(CLIENT_VERSION_BUILD 5) +set(CLIENT_VERSION_RC 0) +set(CLIENT_VERSION_IS_RELEASE "false") +set(COPYRIGHT_YEAR "2026") + +# During the enabling of the CXX and CXXOBJ languages, we modify +# CMake's compiler/linker invocation strings by appending the content +# of the user-defined `APPEND_*` variables, which allows overriding +# any flag. We also ensure that the APPEND_* flags are considered +# during CMake's tests, which use the `try_compile()` command. +# +# CMake's docs state that the `CMAKE_TRY_COMPILE_PLATFORM_VARIABLES` +# variable "is meant to be set by CMake's platform information modules +# for the current toolchain, or by a toolchain file." We do our best +# to set it before the `project()` command. +set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES + CMAKE_CXX_COMPILE_OBJECT + CMAKE_OBJCXX_COMPILE_OBJECT + CMAKE_CXX_LINK_EXECUTABLE +) + +project(BitcoinCore + VERSION ${CLIENT_VERSION_MAJOR}.${CLIENT_VERSION_MINOR}.${CLIENT_VERSION_BUILD} + DESCRIPTION "Dash client software" + HOMEPAGE_URL "https://dash.org/" + LANGUAGES NONE +) +set(PACKAGE_VERSION ${PROJECT_VERSION}) +if(CLIENT_VERSION_RC GREATER 0) + string(APPEND PACKAGE_VERSION "rc${CLIENT_VERSION_RC}") +endif() + +set(COPYRIGHT_HOLDERS "The %s developers") +set(COPYRIGHT_HOLDERS_FINAL "The ${PACKAGE_NAME} developers") +set(PACKAGE_BUGREPORT "https://github.com/dashpay/dash/issues") + +#============================= +# Language setup +#============================= +if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT CMAKE_HOST_APPLE) + # We do not use the install_name_tool when cross-compiling for macOS. + # So disable this tool check in further enable_language() commands. + set(CMAKE_PLATFORM_HAS_INSTALLNAME FALSE) +endif() +enable_language(CXX) +enable_language(C) 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) + +#============================= +# Configurable options +#============================= +include(CMakeDependentOption) +# When adding a new option, end the with a full stop for consistency. +option(BUILD_DAEMON "Build bitcoind executable." ON) +option(BUILD_GUI "Build bitcoin-qt executable." OFF) +option(BUILD_CLI "Build bitcoin-cli executable." ON) + +option(BUILD_TESTS "Build test_bitcoin executable." ON) +option(BUILD_TX "Build bitcoin-tx executable." ${BUILD_TESTS}) +option(BUILD_UTIL "Build bitcoin-util executable." ${BUILD_TESTS}) + +# NOTE: Dash has not backported libbitcoinkernel yet, so there is no +# BUILD_KERNEL_LIB option. bitcoin-chainstate links the regular +# libraries instead. +option(BUILD_UTIL_CHAINSTATE "Build experimental bitcoin-chainstate executable." OFF) + +option(ENABLE_WALLET "Enable wallet." ON) +option(WITH_SQLITE "Enable SQLite wallet support." ${ENABLE_WALLET}) +if(WITH_SQLITE) + if(VCPKG_TARGET_TRIPLET) + # Use of the `unofficial::` namespace is a vcpkg package manager convention. + find_package(unofficial-sqlite3 CONFIG REQUIRED) + else() + find_package(SQLite3 3.7.17 REQUIRED) + endif() + set(USE_SQLITE ON) + set(ENABLE_WALLET ON) +endif() +option(WITH_BDB "Enable Berkeley DB (BDB) wallet support." OFF) +cmake_dependent_option(WARN_INCOMPATIBLE_BDB "Warn when using a Berkeley DB (BDB) version other than 4.8." ON "WITH_BDB" OFF) +if(WITH_BDB) + find_package(BerkeleyDB 4.8 MODULE REQUIRED) + set(USE_BDB ON) + set(ENABLE_WALLET ON) + if(NOT BerkeleyDB_VERSION VERSION_EQUAL 4.8) + message(WARNING "Found Berkeley DB (BDB) other than 4.8.\n" + "BDB (legacy) wallets opened by this build will not be portable!" + ) + if(WARN_INCOMPATIBLE_BDB) + message(WARNING "If this is intended, pass \"-DWARN_INCOMPATIBLE_BDB=OFF\".\n" + "Passing \"-DWITH_BDB=OFF\" will suppress this warning." + ) + endif() + endif() +endif() +cmake_dependent_option(BUILD_WALLET_TOOL "Build bitcoin-wallet tool." ${BUILD_TESTS} "ENABLE_WALLET" OFF) + +option(ENABLE_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) +option(WITH_CCACHE "Attempt to use ccache for compiling." ON) + +option(ENABLE_MINER "Enable the in-wallet miner and its RPCs." ON) + +# Dash, unlike upstream, still provides the public libdashconsensus API +# (--with-libs under Autotools, enabled by default). +option(BUILD_CONSENSUS_LIB "Build the public dashconsensus shared library." ON) +if(BUILD_CONSENSUS_LIB) + set(HAVE_CONSENSUS_LIB ON) +endif() + +# Matches the Autotools `--enable-stacktraces=auto` default: enabled when +# libbacktrace and its prerequisites are found, otherwise disabled with a +# warning. See the detection block further down. +option(ENABLE_STACKTRACES "Gather and print exception stack traces. Requires libbacktrace." ON) +cmake_dependent_option(ENABLE_CRASH_HOOKS "Hook into exception/signal/assert handling to gather stack traces." OFF "ENABLE_STACKTRACES" OFF) + +option(WITH_NATPMP "Enable NAT-PMP." OFF) +if(WITH_NATPMP) + find_package(NATPMP MODULE REQUIRED) +endif() + +option(WITH_MINIUPNPC "Enable UPnP." OFF) +if(WITH_MINIUPNPC) + find_package(MiniUPnPc MODULE REQUIRED) +endif() + +option(WITH_ZMQ "Enable ZMQ notifications." OFF) +if(WITH_ZMQ) + if(VCPKG_TARGET_TRIPLET) + find_package(ZeroMQ CONFIG REQUIRED) + else() + # The ZeroMQ project has provided config files since v4.2.2. + # TODO: Switch to find_package(ZeroMQ) at some point in the future. + find_package(PkgConfig REQUIRED) + pkg_check_modules(libzmq REQUIRED IMPORTED_TARGET libzmq>=4) + # TODO: This command will be redundant once + # https://github.com/bitcoin/bitcoin/pull/30508 is merged. + target_link_libraries(PkgConfig::libzmq INTERFACE + $<$:iphlpapi;ws2_32> + ) + endif() +endif() -include_directories( - src - src/qt/forms - src/leveldb/include - src/univalue/include +option(WITH_USDT "Enable tracepoints for Userspace, Statically Defined Tracing." OFF) +if(WITH_USDT) + find_package(USDT MODULE REQUIRED) +endif() + +cmake_dependent_option(ENABLE_EXTERNAL_SIGNER "Enable external signer support." ON "NOT WIN32" OFF) + +cmake_dependent_option(WITH_QRENCODE "Enable QR code support." ON "BUILD_GUI" OFF) +if(WITH_QRENCODE) + find_package(PkgConfig REQUIRED) + pkg_check_modules(libqrencode REQUIRED IMPORTED_TARGET libqrencode) + set(USE_QRCODE TRUE) +endif() + +cmake_dependent_option(WITH_DBUS "Enable DBus support." ON "CMAKE_SYSTEM_NAME STREQUAL \"Linux\" AND BUILD_GUI" OFF) + +option(WITH_MULTIPROCESS "Build multiprocess bitcoin-node and bitcoin-gui executables in addition to monolithic bitcoind and bitcoin-qt executables. Requires libmultiprocess library. Experimental." OFF) +if(WITH_MULTIPROCESS) + find_package(Libmultiprocess COMPONENTS Lib) + find_package(LibmultiprocessNative COMPONENTS Bin + NAMES Libmultiprocess + ) +endif() + +cmake_dependent_option(BUILD_GUI_TESTS "Build test_bitcoin-qt executable." ON "BUILD_GUI;BUILD_TESTS" OFF) +if(BUILD_GUI) + set(qt_components Core Gui Widgets LinguistTools) + if(ENABLE_WALLET) + list(APPEND qt_components Network) + endif() + if(WITH_DBUS) + list(APPEND qt_components DBus) + set(USE_DBUS TRUE) + endif() + if(BUILD_GUI_TESTS) + list(APPEND qt_components Test) + endif() + find_package(Qt5 5.11.3 MODULE REQUIRED + COMPONENTS ${qt_components} + ) + unset(qt_components) +endif() + +option(BUILD_BENCH "Build bench_bitcoin executable." OFF) +option(BUILD_FUZZ_BINARY "Build fuzz binary." OFF) +cmake_dependent_option(BUILD_FOR_FUZZING "Build for fuzzing. Enabling this will disable all other targets and override BUILD_FUZZ_BINARY." OFF "NOT MSVC" OFF) + +option(INSTALL_MAN "Install man pages." ON) + +set(APPEND_CPPFLAGS "" CACHE STRING "Preprocessor flags that are appended to the command line after all other flags added by the build system. This variable is intended for debugging and special builds.") +set(APPEND_CFLAGS "" CACHE STRING "C compiler flags that are appended to the command line after all other flags added by the build system. This variable is intended for debugging and special builds.") +set(APPEND_CXXFLAGS "" CACHE STRING "(Objective) C++ compiler flags that are appended to the command line after all other flags added by the build system. This variable is intended for debugging and special builds.") +set(APPEND_LDFLAGS "" CACHE STRING "Linker flags that are appended to the command line after all other flags added by the build system. This variable is intended for debugging and special builds.") +# Appending to this low-level rule variables is the only way to +# guarantee that the flags appear at the end of the command line. +string(APPEND CMAKE_CXX_COMPILE_OBJECT " ${APPEND_CPPFLAGS} ${APPEND_CXXFLAGS}") +string(APPEND CMAKE_CXX_CREATE_SHARED_LIBRARY " ${APPEND_LDFLAGS}") +string(APPEND CMAKE_CXX_LINK_EXECUTABLE " ${APPEND_LDFLAGS}") + +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) +elseif(NOT WIN32) + # The warning is superfluous for Windows. + 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) + +# The core_interface library aims to encapsulate common build flags. +# It is a usage requirement for all targets except for secp256k1, which +# gets its flags by other means. +add_library(core_interface INTERFACE) +add_library(core_interface_relwithdebinfo INTERFACE) +add_library(core_interface_debug INTERFACE) +target_link_libraries(core_interface INTERFACE + $<$:core_interface_relwithdebinfo> + $<$:core_interface_debug> +) +target_compile_definitions(core_interface INTERFACE + HAVE_CONFIG_H + # gsl/pointers.h pulls in and defines stream operators unless this + # is set. Keep it in sync with CORE_CPPFLAGS in configure.ac. + GSL_NO_IOSTREAMS ) -if(UNIX AND NOT APPLE) - set(DEPENDS_PREFIX depends/x86_64-pc-linux-gnu) -elseif(APPLE) - EXECUTE_PROCESS( COMMAND uname -m COMMAND tr -d '\n' OUTPUT_VARIABLE ARCHITECTURE ) - EXECUTE_PROCESS( COMMAND system_profiler -detailLevel mini -json SPSoftwareDataType - COMMAND jq .SPSoftwareDataType - COMMAND jq .[] - COMMAND jq .kernel_version - COMMAND tr -d "Dawrin\" " - OUTPUT_VARIABLE DARWIN_KERNEL_VERSION) - if( ${ARCHITECTURE} STREQUAL "arm64" ) - set(DEPENDS_PREFIX depends/aarch64-apple-darwin${DARWIN_KERNEL_VERSION}) +if(BUILD_FOR_FUZZING) + message(WARNING "BUILD_FOR_FUZZING=ON will disable all other targets and force BUILD_FUZZ_BINARY=ON.") + set(BUILD_DAEMON OFF) + set(BUILD_CLI OFF) + set(BUILD_TX OFF) + set(BUILD_UTIL OFF) + set(BUILD_UTIL_CHAINSTATE OFF) + set(BUILD_WALLET_TOOL OFF) + set(BUILD_GUI OFF) + set(ENABLE_EXTERNAL_SIGNER OFF) + set(WITH_NATPMP OFF) + set(WITH_MINIUPNPC OFF) + set(WITH_ZMQ OFF) + set(BUILD_TESTS OFF) + set(BUILD_GUI_TESTS OFF) + set(BUILD_BENCH OFF) + set(BUILD_FUZZ_BINARY ON) + + target_compile_definitions(core_interface INTERFACE + ABORT_ON_FAILED_ASSUME + ) +endif() + +include(ProcessConfigurations) + +include(TryAppendCXXFlags) +include(TryAppendLinkerFlag) + +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 INTERFACE + _WIN32_WINNT=0x0601 + _WIN32_IE=0x0501 + WIN32_LEAN_AND_MEAN + NOMINMAX + ) + + if(MSVC) + if(VCPKG_TARGET_TRIPLET MATCHES "-static") + set(msvc_library_linkage "") else() - set(DEPENDS_PREFIX depends/x86_64-apple-darwin${DARWIN_KERNEL_VERSION}) + set(msvc_library_linkage "DLL") endif() -elseif(WIN32) - set(DEPENDS_PREFIX depends/x86_64-w64-mingw32) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>${msvc_library_linkage}") + unset(msvc_library_linkage) + + target_compile_definitions(core_interface INTERFACE + _UNICODE;UNICODE + ) + target_compile_options(core_interface INTERFACE + /utf-8 + /Zc:preprocessor + /Zc:__cplusplus + /sdl + ) + # Improve parallelism in MSBuild. + # See: https://devblogs.microsoft.com/cppblog/improved-parallelism-in-msbuild/. + list(APPEND CMAKE_VS_GLOBALS "UseMultiToolTask=true") + endif() + + if(MINGW) + target_compile_definitions(core_interface INTERFACE + WIN32 + _WINDOWS + _MT + ) + # Avoid the use of aligned vector instructions when building for Windows. + # See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54412. + try_append_cxx_flags("-Wa,-muse-unaligned-vector-move" TARGET core_interface SKIP_LINK) + try_append_linker_flag("-static" TARGET core_interface) + # We require Windows 7 (NT 6.1) or later. + try_append_linker_flag("-Wl,--major-subsystem-version,6" TARGET core_interface) + try_append_linker_flag("-Wl,--minor-subsystem-version,1" TARGET core_interface) + endif() endif() -message(STATUS "DEPENDS_PREFIX: ${DEPENDS_PREFIX}") +# 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 INTERFACE + _FILE_OFFSET_BITS=64 + ) +endif() -if(DEFINED DEPENDS_PREFIX) - include_directories(${DEPENDS_PREFIX}/include) - include_directories(${DEPENDS_PREFIX}/include/QtWidgets) +if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + target_compile_definitions(core_interface INTERFACE + MAC_OSX + OBJC_OLD_DISPATCH_PROTOTYPES=0 + ) + # 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_interface) + try_append_linker_flag("-Wl,-dead_strip_dylibs" TARGET core_interface) + if(CMAKE_HOST_APPLE) + try_append_linker_flag("-Wl,-headerpad_max_install_names" TARGET core_interface) + endif() endif() -add_definitions( - -DENABLE_CRASH_HOOKS=1 - -DENABLE_STACKTRACES=1 - -DENABLE_WALLET=1 +set(THREADS_PREFER_PTHREAD_FLAG ON) +find_package(Threads REQUIRED) +target_link_libraries(core_interface INTERFACE + Threads::Threads ) -# find src/ -name '*.h' -or -name '*.cpp' | sed -r 's/[^/]*.(h|cpp)$/*.\1/' | sort | uniq | grep -Ev "/(bench/data|obj)/" > list.txt - -file(GLOB SOURCE_FILES - src/*.cpp - src/*.h - src/bench/*.cpp - src/bench/*.h - src/bls/*.cpp - src/bls/*.h - src/coinjoin/*.cpp - src/coinjoin/*.h - src/compat/*.cpp - src/compat/*.h - src/consensus/*.cpp - src/consensus/*.h - src/crypto/*.c - src/crypto/*.cpp - src/crypto/*.h - src/evo/*.cpp - src/evo/*.h - src/governance/*.cpp - src/governance/*.h - src/index/*.cpp - src/index/*.h - src/interfaces/*.cpp - src/interfaces/*.h - src/leveldb/db/*.cc - src/leveldb/db/*.h - src/leveldb/include/*.h - src/llmq/*.cpp - src/llmq/*.h - src/logging/*.h - src/masternode/*.cpp - src/masternode/*.h - src/node/*.cpp - src/node/*.h - src/policy/*.cpp - src/policy/*.h - src/primitives/*.cpp - src/primitives/*.h - src/qt/*.cpp - src/qt/*.h - src/qt/test/*.cpp - src/qt/test/*.h - src/rpc/*.cpp - src/rpc/*.h - src/script/*.cpp - src/script/*.h - src/secp256k1/include/*.h - src/support/allocators/*.h - src/support/*.cpp - src/support/*.h - src/test/*.cpp - src/test/*.h - src/test/fuzz/*.cpp - src/test/fuzz/*.h - src/test/util/*.cpp - src/test/util/*.h - src/univalue/include/*.h - src/univalue/lib/*.cpp - src/univalue/lib/*.h - src/util/*.h - src/util/*.cpp - src/wallet/*.cpp - src/wallet/*.h - src/wallet/test/*.cpp - src/zmq/*.cpp - src/zmq/*.h +add_library(sanitize_interface INTERFACE) +target_link_libraries(core_interface INTERFACE sanitize_interface) +if(SANITIZERS) + # First check if the compiler accepts flags. If an incompatible pair like + # -fsanitize=address,thread is used here, this check will fail. This will also + # fail if a bad argument is passed, e.g. -fsanitize=undfeined + try_append_cxx_flags("-fsanitize=${SANITIZERS}" TARGET sanitize_interface + RESULT_VAR cxx_supports_sanitizers + SKIP_LINK + ) + if(NOT cxx_supports_sanitizers) + message(FATAL_ERROR "Compiler did not accept requested flags.") + endif() + + # Some compilers (e.g. GCC) require additional libraries like libasan, + # libtsan, libubsan, etc. Make sure linking still works with the sanitize + # flag. This is a separate check so we can give a better error message when + # the sanitize flags are supported by the compiler but the actual sanitizer + # libs are missing. + try_append_linker_flag("-fsanitize=${SANITIZERS}" VAR SANITIZER_LDFLAGS + SOURCE " + #include + #include + extern \"C\" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return 0; } + __attribute__((weak)) // allow for libFuzzer linking + int main() { return 0; } + " + RESULT_VAR linker_supports_sanitizers + ) + if(NOT linker_supports_sanitizers) + message(FATAL_ERROR "Linker did not accept requested flags, you are missing required libraries.") + endif() +endif() +target_link_options(sanitize_interface INTERFACE ${SANITIZER_LDFLAGS}) + +if(BUILD_FUZZ_BINARY) + include(CheckSourceCompilesAndLinks) + check_cxx_source_links_with_flags("${SANITIZER_LDFLAGS}" " + #include + #include + extern \"C\" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return 0; } + // No main() function. + " FUZZ_BINARY_LINKS_WITHOUT_MAIN_FUNCTION + ) +endif() + +include(AddBoostIfNeeded) +add_boost_if_needed() + +if(BUILD_DAEMON OR BUILD_GUI OR BUILD_CLI OR BUILD_TESTS OR BUILD_BENCH OR BUILD_FUZZ_BINARY) + find_package(Libevent 2.1.8 MODULE REQUIRED) +endif() + +include(cmake/introspection.cmake) + +include(cmake/ccache.cmake) + +add_library(warn_interface INTERFACE) +target_link_libraries(core_interface INTERFACE warn_interface) +if(MSVC) + try_append_cxx_flags("/W3" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("/wd4018" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("/wd4244" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("/wd4267" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("/wd4715" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("/wd4805" TARGET warn_interface SKIP_LINK) + target_compile_definitions(warn_interface INTERFACE + _CRT_SECURE_NO_WARNINGS + _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING + ) +else() + try_append_cxx_flags("-Wall" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("-Wextra" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("-Wgnu" TARGET warn_interface SKIP_LINK) + # Some compilers will ignore -Wformat-security without -Wformat, so just combine the two here. + try_append_cxx_flags("-Wformat -Wformat-security" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("-Wvla" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("-Wshadow-field" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("-Wthread-safety" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("-Wloop-analysis" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("-Wredundant-decls" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("-Wunused-member-function" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("-Wdate-time" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("-Wconditional-uninitialized" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("-Wduplicated-branches" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("-Wduplicated-cond" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("-Wlogical-op" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("-Woverloaded-virtual" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("-Wsuggest-override" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("-Wimplicit-fallthrough" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("-Wunreachable-code" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("-Wdocumentation" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("-Wself-assign" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("-Wundef" TARGET warn_interface SKIP_LINK) + + # Some compilers (gcc) ignore unknown -Wno-* options, but warn about all + # unknown options if any other warning is produced. Test the -Wfoo case, and + # set the -Wno-foo case if it works. + try_append_cxx_flags("-Wunused-parameter" TARGET warn_interface SKIP_LINK + IF_CHECK_PASSED "-Wno-unused-parameter" + ) + + # Warnings that are suppressed outright. Keep in sync with NOWARN_CXXFLAGS in + # configure.ac; without these a WERROR build fails on GCC or Clang. + # -Wundef is not part of the Autotools warning set. Keep the diagnostic, but + # do not let it fail the build: crypto/x11/sph_types.h tests SPH_* macros + # that are deliberately left undefined. + try_append_cxx_flags("-Wundef" TARGET warn_interface SKIP_LINK + IF_CHECK_PASSED "-Wno-error=undef" + ) + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + # -Wdeprecated-literal-operator causes problems with clang 20. + # TODO: remove it once we update hana. + try_append_cxx_flags("-Wdeprecated-literal-operator" TARGET warn_interface SKIP_LINK + IF_CHECK_PASSED "-Wno-error=deprecated-literal-operator" + ) + endif() + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + # -Warray-bounds is noisy and currently unhappy with the immer implementation. + try_append_cxx_flags("-Warray-bounds" TARGET warn_interface SKIP_LINK + IF_CHECK_PASSED "-Wno-array-bounds" + ) + # -Wstringop-overread and -Wstringop-overflow are broken in GCC. + try_append_cxx_flags("-Wstringop-overread" TARGET warn_interface SKIP_LINK + IF_CHECK_PASSED "-Wno-stringop-overread" + ) + try_append_cxx_flags("-Wstringop-overflow" TARGET warn_interface SKIP_LINK + IF_CHECK_PASSED "-Wno-stringop-overflow" + ) + # -Wattributes causes problems with GCC before 14. + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14) + try_append_cxx_flags("-Wattributes" TARGET warn_interface SKIP_LINK + IF_CHECK_PASSED "-Wno-error=attributes" + ) + endif() + # -Wcpp is triggered by _FORTIFY_SOURCE=3 on GCC before 12, where level 3 + # does not exist yet. + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12) + try_append_cxx_flags("-Wcpp" TARGET warn_interface SKIP_LINK + IF_CHECK_PASSED "-Wno-error=cpp" + ) + endif() + endif() +endif() + +configure_file(cmake/script/Coverage.cmake Coverage.cmake COPYONLY) +configure_file(cmake/script/CoverageFuzz.cmake CoverageFuzz.cmake COPYONLY) +configure_file(cmake/script/CoverageInclude.cmake.in CoverageInclude.cmake @ONLY) +configure_file(contrib/filter-lcov.py filter-lcov.py COPYONLY) + +# Don't allow extended (non-ASCII) symbols in identifiers. This is easier for code review. +try_append_cxx_flags("-fno-extended-identifiers" TARGET core_interface SKIP_LINK) + +# 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_interface) + +if(ENABLE_HARDENING) + add_library(hardening_interface INTERFACE) + target_link_libraries(core_interface INTERFACE hardening_interface) + if(MSVC) + try_append_linker_flag("/DYNAMICBASE" TARGET hardening_interface) + try_append_linker_flag("/HIGHENTROPYVA" TARGET hardening_interface) + try_append_linker_flag("/NXCOMPAT" TARGET hardening_interface) + else() + try_append_cxx_flags("-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3" + RESULT_VAR cxx_supports_fortify_source + ) + if(cxx_supports_fortify_source) + # When the build configuration is Debug, all optimizations are disabled. + # However, _FORTIFY_SOURCE requires that there is some level of optimization, + # otherwise it does nothing and just creates a compiler warning. + # Since _FORTIFY_SOURCE is a no-op without optimizations, do not enable it + # when the build configuration is Debug. + target_compile_options(hardening_interface INTERFACE + $<$>:-U_FORTIFY_SOURCE> + $<$>:-D_FORTIFY_SOURCE=3> + ) + endif() + unset(cxx_supports_fortify_source) + + try_append_cxx_flags("-Wstack-protector" TARGET hardening_interface SKIP_LINK) + try_append_cxx_flags("-fstack-protector-all" TARGET hardening_interface) + try_append_cxx_flags("-fcf-protection=full" TARGET hardening_interface) + + 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_interface) + endif() + + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") + try_append_cxx_flags("-mbranch-protection=bti" TARGET hardening_interface SKIP_LINK) + endif() + + try_append_linker_flag("-Wl,--enable-reloc-section" TARGET hardening_interface) + try_append_linker_flag("-Wl,--dynamicbase" TARGET hardening_interface) + try_append_linker_flag("-Wl,--nxcompat" TARGET hardening_interface) + try_append_linker_flag("-Wl,--high-entropy-va" TARGET hardening_interface) + try_append_linker_flag("-Wl,-z,relro" TARGET hardening_interface) + try_append_linker_flag("-Wl,-z,now" TARGET hardening_interface) + try_append_linker_flag("-Wl,-z,separate-code" TARGET hardening_interface) + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + try_append_linker_flag("-Wl,-fixup_chains" TARGET hardening_interface) + endif() + endif() +endif() + +if(REDUCE_EXPORTS) + set(CMAKE_CXX_VISIBILITY_PRESET hidden) + try_append_linker_flag("-Wl,--exclude-libs,ALL" TARGET core_interface) + try_append_linker_flag("-Wl,-no_exported_symbols" VAR CMAKE_EXE_LINKER_FLAGS) +endif() + +if(WERROR) + if(MSVC) + set(werror_flag "/WX") + else() + set(werror_flag "-Werror") + endif() + try_append_cxx_flags(${werror_flag} TARGET warn_interface SKIP_LINK 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() + +# Autotools puts the warning and -Werror flags in CXXFLAGS only; AM_CFLAGS +# carries neither. Restrict them to C++ here as well, so that the vendored +# sphlib C sources under crypto/x11 are held to the same standard as they are +# by the Autotools build. +get_target_property(warn_interface_flags warn_interface INTERFACE_COMPILE_OPTIONS) +if(warn_interface_flags) + set_target_properties(warn_interface PROPERTIES + INTERFACE_COMPILE_OPTIONS "$<$:${warn_interface_flags}>" + ) +endif() +unset(warn_interface_flags) + +if(ENABLE_STACKTRACES) + include(CheckIncludeFileCXX) + check_include_file_cxx(backtrace.h HAVE_BACKTRACE_H) + if(NOT WIN32) + check_include_file_cxx(execinfo.h HAVE_EXECINFO_H) + endif() + find_library(BACKTRACE_LIBRARY NAMES backtrace) + if(NOT HAVE_BACKTRACE_H OR NOT BACKTRACE_LIBRARY OR (NOT WIN32 AND NOT HAVE_EXECINFO_H)) + message(WARNING "libbacktrace was not found, stacktraces will be disabled.") + list(APPEND configure_warnings "Stack traces disabled: libbacktrace not found.") + set(ENABLE_STACKTRACES OFF) + set(ENABLE_CRASH_HOOKS OFF) + endif() +endif() + +if(ENABLE_STACKTRACES) + add_library(stacktraces_interface INTERFACE) + target_link_libraries(core_interface INTERFACE stacktraces_interface) + target_link_libraries(stacktraces_interface INTERFACE ${BACKTRACE_LIBRARY}) + if(WIN32) + target_link_libraries(stacktraces_interface INTERFACE dbghelp) + else() + if(CMAKE_SYSTEM_NAME MATCHES "BSD$") + find_library(EXECINFO_LIBRARY NAMES execinfo) + if(EXECINFO_LIBRARY) + target_link_libraries(stacktraces_interface INTERFACE ${EXECINFO_LIBRARY}) + endif() + endif() + # Symbol names are resolved at run time, so they must stay in the dynamic + # symbol table. + try_append_linker_flag("-Wl,-export-dynamic" TARGET stacktraces_interface + RESULT_VAR linker_supports_export_dynamic + ) + if(NOT linker_supports_export_dynamic) + try_append_linker_flag("-rdynamic" TARGET stacktraces_interface) + endif() + unset(linker_supports_export_dynamic) + # More modern compilers may emit DWARF 5 binaries by default, which + # libbacktrace cannot parse. + try_append_cxx_flags("-gdwarf-4" TARGET stacktraces_interface SKIP_LINK) + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + try_append_cxx_flags("-fno-standalone-debug" TARGET stacktraces_interface SKIP_LINK) + endif() + endif() + + if(ENABLE_CRASH_HOOKS) + # Wrap the internal C++ ABI so that stacktraces can be attached to + # exceptions. Compilers whose linker lacks --wrap (e.g. ld64) fall back to + # the dlsym-based path in stacktraces.cpp. + try_append_linker_flag("-Wl,-wrap,__cxa_allocate_exception" VAR wrap_exceptions_flags + RESULT_VAR CRASH_HOOKS_WRAPPED_CXX_ABI + ) + if(CRASH_HOOKS_WRAPPED_CXX_ABI) + target_link_options(stacktraces_interface INTERFACE + "-Wl,-wrap,__cxa_allocate_exception" + "-Wl,-wrap,__cxa_free_exception" + ) + if(WIN32) + target_link_options(stacktraces_interface INTERFACE + "-Wl,-wrap,_assert" + "-Wl,-wrap,_wassert" + ) + else() + target_link_options(stacktraces_interface INTERFACE + "-Wl,-wrap,__assert_fail" ) + endif() + endif() + unset(wrap_exceptions_flags) + endif() +endif() + +find_package(Python3 3.9 COMPONENTS Interpreter) +if(Python3_EXECUTABLE) + set(PYTHON_COMMAND ${Python3_EXECUTABLE}) +else() + list(APPEND configure_warnings + "Minimum required Python not found. Utils and rpcauth tests are disabled." + ) +endif() + +target_compile_definitions(core_interface INTERFACE ${DEPENDS_COMPILE_DEFINITIONS}) +target_compile_definitions(core_interface_relwithdebinfo INTERFACE ${DEPENDS_COMPILE_DEFINITIONS_RELWITHDEBINFO}) +target_compile_definitions(core_interface_debug INTERFACE ${DEPENDS_COMPILE_DEFINITIONS_DEBUG}) + +# If the {CXX,LD}FLAGS environment variables are defined during building depends +# and configuring this build system, their content might be duplicated. +if(DEFINED ENV{CXXFLAGS}) + deduplicate_flags(CMAKE_CXX_FLAGS) +endif() +if(DEFINED ENV{LDFLAGS}) + deduplicate_flags(CMAKE_EXE_LINKER_FLAGS) +endif() + +if(BUILD_TESTS) + enable_testing() +endif() +# TODO: The `CMAKE_SKIP_BUILD_RPATH` variable setting can be deleted +# in the future after reordering Guix script commands to +# perform binary checks after the installation step. +# Relevant discussions: +# - https://github.com/hebasto/bitcoin/pull/236#issuecomment-2183120953 +# - https://github.com/bitcoin/bitcoin/pull/30312#issuecomment-2191235833 +set(CMAKE_SKIP_BUILD_RPATH TRUE) +set(CMAKE_SKIP_INSTALL_RPATH TRUE) +add_subdirectory(test) +add_subdirectory(doc) + +include(cmake/crc32c.cmake) +include(cmake/leveldb.cmake) +include(cmake/minisketch.cmake) +add_subdirectory(src) + +include(cmake/tests.cmake) + +include(Maintenance) +setup_split_debug_script() +add_maintenance_targets() +add_windows_deploy_target() +add_macos_deploy_target() + +message("\n") +message("Configure summary") +message("=================") +message("Executables:") +message(" bitcoind ............................ ${BUILD_DAEMON}") +message(" bitcoin-node (multiprocess) ......... ${WITH_MULTIPROCESS}") +message(" bitcoin-qt (GUI) .................... ${BUILD_GUI}") +if(BUILD_GUI AND WITH_MULTIPROCESS) + set(bitcoin_gui_status ON) +else() + set(bitcoin_gui_status OFF) +endif() +message(" bitcoin-gui (GUI, multiprocess) ..... ${bitcoin_gui_status}") +message(" bitcoin-cli ......................... ${BUILD_CLI}") +message(" bitcoin-tx .......................... ${BUILD_TX}") +message(" bitcoin-util ........................ ${BUILD_UTIL}") +message(" bitcoin-wallet ...................... ${BUILD_WALLET_TOOL}") +message(" bitcoin-chainstate (experimental) ... ${BUILD_UTIL_CHAINSTATE}") +message(" libdashconsensus .................... ${BUILD_CONSENSUS_LIB}") +message("Optional features:") +message(" wallet support ...................... ${ENABLE_WALLET}") +if(ENABLE_WALLET) + message(" - descriptor wallets (SQLite) ...... ${WITH_SQLITE}") + message(" - legacy wallets (Berkeley DB) ..... ${WITH_BDB}") +endif() +message(" external signer ..................... ${ENABLE_EXTERNAL_SIGNER}") +message(" port mapping:") +message(" - using NAT-PMP .................... ${WITH_NATPMP}") +message(" - using UPnP ....................... ${WITH_MINIUPNPC}") +message(" ZeroMQ .............................. ${WITH_ZMQ}") +message(" USDT tracing ........................ ${WITH_USDT}") +message(" QR code (GUI) ....................... ${WITH_QRENCODE}") +message(" DBus (GUI, Linux only) .............. ${WITH_DBUS}") +message("Tests:") +message(" test_bitcoin ........................ ${BUILD_TESTS}") +message(" test_bitcoin-qt ..................... ${BUILD_GUI_TESTS}") +message(" bench_bitcoin ....................... ${BUILD_BENCH}") +message(" fuzz binary ......................... ${BUILD_FUZZ_BINARY}") +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}") +message("C++ compiler .......................... ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}, ${CMAKE_CXX_COMPILER}") +include(FlagsSummary) +flags_summary() +message("Attempt to harden executables ......... ${ENABLE_HARDENING}") +message("Treat compiler warnings as errors ..... ${WERROR}") +message("Use ccache for compiling .............. ${WITH_CCACHE}") +message("\n") +if(configure_warnings) + message(" ******\n") + foreach(warning IN LISTS configure_warnings) + message(WARNING "${warning}") + endforeach() + message(" ******\n") +endif() -add_executable(dash ${SOURCE_FILES}) +# We want all build properties to be encapsulated properly. +include(WarnAboutGlobalProperties) diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 000000000000..a5f2ce79191f --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,42 @@ +{ + "version": 3, + "cmakeMinimumRequired": {"major": 3, "minor": 21, "patch": 0}, + "configurePresets": [ + { + "name": "vs2022", + "displayName": "Build using 'Visual Studio 17 2022' generator and 'x64-windows' triplet", + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + }, + "generator": "Visual Studio 17 2022", + "architecture": "x64", + "toolchainFile": "$env{VCPKG_ROOT}\\scripts\\buildsystems\\vcpkg.cmake", + "cacheVariables": { + "VCPKG_TARGET_TRIPLET": "x64-windows", + "BUILD_GUI": "ON", + "WITH_QRENCODE": "OFF", + "WITH_NATPMP": "OFF" + } + }, + { + "name": "vs2022-static", + "displayName": "Build using 'Visual Studio 17 2022' generator and 'x64-windows-static' triplet", + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + }, + "generator": "Visual Studio 17 2022", + "architecture": "x64", + "toolchainFile": "$env{VCPKG_ROOT}\\scripts\\buildsystems\\vcpkg.cmake", + "cacheVariables": { + "VCPKG_TARGET_TRIPLET": "x64-windows-static", + "BUILD_GUI": "ON", + "WITH_QRENCODE": "OFF", + "WITH_NATPMP": "OFF" + } + } + ] +} diff --git a/README.md b/README.md index edb28d9739c8..c99a0f27fe3d 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,8 @@ lots of money. Developers are strongly encouraged to write [unit tests](src/test/README.md) for new code, and to submit new unit tests for old code. Unit tests can be compiled and run -(assuming they weren't disabled in configure) with: `make check`. Further details on running +(assuming they weren't disabled during the generation of the build system) with `ctest --test-dir ` +for CMake builds, or `make check` for Autotools builds. Further details on running and extending unit tests can be found in [/src/test/README.md](/src/test/README.md). There are also [regression and integration tests](/test), written diff --git a/ci/dash/build_src_cmake.sh b/ci/dash/build_src_cmake.sh new file mode 100755 index 000000000000..f3ef63fd292c --- /dev/null +++ b/ci/dash/build_src_cmake.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# Copyright (c) 2026 The Dash Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# +# This script is executed inside the builder image +# +# Counterpart to build_src.sh for the CMake build system. It consumes the same +# depends prefix, by way of the toolchain file that `make -C depends` generates. + +export LC_ALL=C.UTF-8 + +set -e + +source ./ci/dash/matrix.sh + +unset CC CXX DISPLAY; + +ccache --zero-stats + +CMAKE_BUILD_DIR="${BASE_ROOT_DIR}/build-cmake" +TOOLCHAIN_FILE="${DEPENDS_DIR}/${HOST}/toolchain.cmake" + +if [ ! -f "${TOOLCHAIN_FILE}" ]; then + echo "No toolchain file at ${TOOLCHAIN_FILE}; run 'make -C depends' first." >&2 + exit 1 +fi + +BITCOIN_CONFIG_ALL="-DENABLE_EXTERNAL_SIGNER=ON -DCMAKE_INSTALL_PREFIX=${BASE_OUTDIR}" +if [ -z "$NO_WERROR" ]; then + BITCOIN_CONFIG_ALL="${BITCOIN_CONFIG_ALL} -DWERROR=ON" +fi + +rm -rf "${CMAKE_BUILD_DIR}" + +bash -c "cmake -B ${CMAKE_BUILD_DIR} -S ${BASE_ROOT_DIR} \ + --toolchain ${TOOLCHAIN_FILE} \ + ${BITCOIN_CONFIG_ALL} ${BITCOIN_CONFIG}" + +bash -c "cmake --build ${CMAKE_BUILD_DIR} ${MAKEJOBS}" || \ + ( echo "Build failure. Verbose build follows." && \ + cmake --build "${CMAKE_BUILD_DIR}" --verbose ; false ) + +if [ "${GOAL}" = "install" ]; then + cmake --install "${CMAKE_BUILD_DIR}" +fi + +ccache --version | head -n 1 && ccache --show-stats diff --git a/ci/dash/matrix.sh b/ci/dash/matrix.sh index de01eaf6d6c7..4d3ee0ea2c75 100755 --- a/ci/dash/matrix.sh +++ b/ci/dash/matrix.sh @@ -20,6 +20,8 @@ if [ "$BUILD_TARGET" = "aarch64-linux" ]; then source ./ci/test/00_setup_env_aarch64.sh elif [ "$BUILD_TARGET" = "linux64" ]; then source ./ci/test/00_setup_env_native_qt5.sh +elif [ "$BUILD_TARGET" = "linux64_cmake" ]; then + source ./ci/test/00_setup_env_native_cmake.sh elif [ "$BUILD_TARGET" = "linux64_asan" ]; then source ./ci/test/00_setup_env_native_asan.sh elif [ "$BUILD_TARGET" = "linux64_fuzz" ]; then diff --git a/ci/dash/test_integrationtests_cmake.sh b/ci/dash/test_integrationtests_cmake.sh new file mode 100755 index 000000000000..b67eb04b8115 --- /dev/null +++ b/ci/dash/test_integrationtests_cmake.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# Copyright (c) 2026 The Dash Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# +# This script is executed inside the builder image +# +# A functional smoke test for the CMake build. The Autotools jobs remain +# responsible for the full functional suite; this only proves that the binaries +# CMake produced actually start, mine and talk RPC. The mining tests matter in +# particular, because a missing ENABLE_MINER definition turns every mining RPC +# into a stub that unit tests would never notice. + +export LC_ALL=C.UTF-8 + +set -e + +source ./ci/dash/matrix.sh + +if [ "$RUN_FUNCTIONAL_TESTS" != "true" ]; then + echo "Skipping integration tests" + exit 0 +fi + +SMOKE_TESTS=( + mining_basic.py + rpc_blockchain.py + wallet_basic.py +) + +export LD_LIBRARY_PATH="$DEPENDS_DIR/$HOST/lib" + +cd "${BASE_ROOT_DIR}/build-cmake" + +# --combinedlogslen dumps the failing node's logs into the job output, which is +# what stands in for the log bundle the Autotools jobs upload. +./test/functional/test_runner.py \ + --ci --ansi --combinedlogslen=4000 --failfast --attempts=3 \ + --timeout-factor="${TEST_RUNNER_TIMEOUT_FACTOR}" \ + --tmpdir="$(pwd)/testdatadirs" \ + "${SMOKE_TESTS[@]}" diff --git a/ci/dash/test_unittests_cmake.sh b/ci/dash/test_unittests_cmake.sh new file mode 100755 index 000000000000..402411307315 --- /dev/null +++ b/ci/dash/test_unittests_cmake.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# Copyright (c) 2026 The Dash Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# +# This script is executed inside the builder image + +export LC_ALL=C.UTF-8 + +set -e + +source ./ci/dash/matrix.sh + +if [ "$RUN_UNIT_TESTS" != "true" ]; then + echo "Skipping unit tests" + exit 0 +fi + +export BOOST_TEST_RANDOM="${BOOST_TEST_RANDOM:-1}" +export LD_LIBRARY_PATH="$DEPENDS_DIR/$HOST/lib" +export BOOST_TEST_LOG_LEVEL=test_suite +# The Qt tests need a display; the offscreen platform stands in for one. +export QT_QPA_PLATFORM=minimal + +ctest --test-dir "${BASE_ROOT_DIR}/build-cmake" "${MAKEJOBS}" --output-on-failure diff --git a/ci/test/00_setup_env_native_cmake.sh b/ci/test/00_setup_env_native_cmake.sh new file mode 100755 index 000000000000..2a601261e7ba --- /dev/null +++ b/ci/test/00_setup_env_native_cmake.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2026 The Dash Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +export LC_ALL=C.UTF-8 + +# Builds the tree with CMake instead of Autotools, on top of the very same +# depends prefix the linux64 job uses. HOST and DEP_OPTS must therefore stay in +# sync with 00_setup_env_native_qt5.sh, otherwise the depends cache cannot be +# shared and this job would have to build depends from scratch. +export CONTAINER_NAME=ci_native_cmake +export HOST=x86_64-pc-linux-gnu +export PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools libdbus-1-dev libharfbuzz-dev" +export DEP_OPTS="" +export RUN_UNIT_TESTS="true" +# Only the smoke list in ci/dash/test_integrationtests_cmake.sh; the Autotools +# jobs still run the full functional suite. +export RUN_FUNCTIONAL_TESTS="true" +export GOAL="install" +# The remaining feature flags (GUI, wallet, ZMQ, ...) come from +# depends/toolchain.cmake, which reflects what was actually built in depends. +export BITCOIN_CONFIG="-DBUILD_BENCH=ON" diff --git a/cmake/bitcoin-config.h.in b/cmake/bitcoin-config.h.in new file mode 100644 index 000000000000..4ec3c7e19ff4 --- /dev/null +++ b/cmake/bitcoin-config.h.in @@ -0,0 +1,188 @@ +// 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/. + +#ifndef BITCOIN_CONFIG_H +#define BITCOIN_CONFIG_H + +/* Version Build */ +#define CLIENT_VERSION_BUILD @CLIENT_VERSION_BUILD@ + +/* Version is release */ +#define CLIENT_VERSION_IS_RELEASE @CLIENT_VERSION_IS_RELEASE@ + +/* Major version */ +#define CLIENT_VERSION_MAJOR @CLIENT_VERSION_MAJOR@ + +/* Minor version */ +#define CLIENT_VERSION_MINOR @CLIENT_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 "@PACKAGE_NAME@" + +/* Copyright year */ +#define COPYRIGHT_YEAR @COPYRIGHT_YEAR@ + +/* Define this symbol to build code that uses ARMv8 AES intrinsics */ +#cmakedefine ENABLE_ARM_AES 1 + +/* Define this symbol to build code that uses ARM NEON intrinsics */ +#cmakedefine ENABLE_ARM_NEON 1 + +/* Define this symbol to build code that uses ARMv8 SHA-NI intrinsics */ +#cmakedefine ENABLE_ARM_SHANI 1 + +/* Define this symbol to build code that uses AVX2 intrinsics */ +#cmakedefine ENABLE_AVX2 1 + +/* Define this symbol to hook into exception/signal/assert handling to gather + stack traces */ +#cmakedefine ENABLE_CRASH_HOOKS 1 + +/* Define this symbol if the __cxa_throw wrapper used by the crash hooks is + available */ +#cmakedefine CRASH_HOOKS_WRAPPED_CXX_ABI 1 + +/* Define if external signer support is enabled */ +#cmakedefine ENABLE_EXTERNAL_SIGNER 1 + +/* Define this symbol if in-wallet miner should be enabled */ +#cmakedefine ENABLE_MINER 1 + +/* Define this symbol to build code that uses SSE4.1 intrinsics */ +#cmakedefine ENABLE_SSE41 1 + +/* Define this symbol to build code that uses SSSE3 intrinsics */ +#cmakedefine ENABLE_SSSE3 1 + +/* Define this symbol to gather and print exception stack traces */ +#cmakedefine ENABLE_STACKTRACES 1 + +/* Define to 1 to enable tracepoints for Userspace, Statically Defined Tracing + */ +#cmakedefine ENABLE_TRACING 1 + +/* Define to 1 to enable wallet functions. */ +#cmakedefine ENABLE_WALLET 1 + +/* Define this symbol to build code that uses x86 AES-NI intrinsics */ +#cmakedefine ENABLE_X86_AESNI 1 + +/* Define this symbol to build code that uses x86 SHA-NI intrinsics */ +#cmakedefine ENABLE_X86_SHANI 1 + +/* Define this symbol if the consensus lib has been built */ +#cmakedefine HAVE_CONSENSUS_LIB 1 + +/* 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 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 `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 this symbol if evhttp_connection_get_peer expects const char** */ +#cmakedefine HAVE_EVHTTP_CONNECTION_GET_PEER_CONST_CHAR 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 the Linux getrandom system call is available */ +#cmakedefine HAVE_SYS_GETRANDOM 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 if platform supports unix domain sockets */ +#cmakedefine HAVE_SOCKADDR_UN 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_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 "@PACKAGE_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 "@PACKAGE_VERSION@" + +/* Define to 1 if strerror_r returns char *. */ +#cmakedefine STRERROR_R_CHAR_P 1 + +/* Define if BDB support should be compiled in */ +#cmakedefine USE_BDB 1 + +/* Define if dbus support should be compiled in */ +#cmakedefine USE_DBUS 1 + +/* Define if QR support should be compiled in */ +#cmakedefine USE_QRCODE 1 + +/* Define if sqlite support should be compiled in */ +#cmakedefine USE_SQLITE 1 + +#endif //BITCOIN_CONFIG_H diff --git a/cmake/ccache.cmake b/cmake/ccache.cmake new file mode 100644 index 000000000000..099aa66411fb --- /dev/null +++ b/cmake/ccache.cmake @@ -0,0 +1,36 @@ +# 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/. + +if(NOT MSVC) + find_program(CCACHE_EXECUTABLE ccache) + if(CCACHE_EXECUTABLE) + execute_process( + COMMAND readlink -f ${CMAKE_CXX_COMPILER} + OUTPUT_VARIABLE compiler_resolved_link + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(CCACHE_EXECUTABLE STREQUAL compiler_resolved_link AND NOT WITH_CCACHE) + list(APPEND configure_warnings + "Disabling ccache was attempted using -DWITH_CCACHE=${WITH_CCACHE}, but ccache masquerades as the compiler." + ) + set(WITH_CCACHE ON) + elseif(WITH_CCACHE) + list(APPEND CMAKE_C_COMPILER_LAUNCHER ${CCACHE_EXECUTABLE}) + list(APPEND CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_EXECUTABLE}) + endif() + else() + set(WITH_CCACHE OFF) + endif() + if(WITH_CCACHE) + try_append_cxx_flags("-fdebug-prefix-map=A=B" TARGET core_interface SKIP_LINK + IF_CHECK_PASSED "-fdebug-prefix-map=${PROJECT_SOURCE_DIR}=." + ) + try_append_cxx_flags("-fmacro-prefix-map=A=B" TARGET core_interface SKIP_LINK + IF_CHECK_PASSED "-fmacro-prefix-map=${PROJECT_SOURCE_DIR}=." + ) + endif() +endif() + +mark_as_advanced(CCACHE_EXECUTABLE) diff --git a/cmake/cov_tool_wrapper.sh.in b/cmake/cov_tool_wrapper.sh.in new file mode 100644 index 000000000000..f6b7ff3419ff --- /dev/null +++ b/cmake/cov_tool_wrapper.sh.in @@ -0,0 +1,5 @@ +# Copyright (c) 2024-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +exec @COV_TOOL@ "$@" diff --git a/cmake/crc32c.cmake b/cmake/crc32c.cmake new file mode 100644 index 000000000000..16fde7f95dab --- /dev/null +++ b/cmake/crc32c.cmake @@ -0,0 +1,123 @@ +# 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(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(ARM64_CRC_CXXFLAGS -march=armv8-a+crc+crypto) +check_cxx_source_compiles_with_flags("${ARM64_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_common INTERFACE) +target_compile_definitions(crc32c_common INTERFACE + HAVE_BUILTIN_PREFETCH=$ + HAVE_MM_PREFETCH=$ + HAVE_STRONG_GETAUXVAL=$ + BYTE_ORDER_BIG_ENDIAN=$ + HAVE_SSE42=$ + HAVE_ARM64_CRC32C=$ +) +target_link_libraries(crc32c_common INTERFACE + core_interface +) + +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_include_directories(crc32c + PUBLIC + $ +) +target_link_libraries(crc32c PRIVATE crc32c_common) +set_target_properties(crc32c PROPERTIES EXPORT_COMPILE_COMMANDS OFF) + +if(HAVE_SSE42) + add_library(crc32c_sse42 STATIC EXCLUDE_FROM_ALL + ${PROJECT_SOURCE_DIR}/src/crc32c/src/crc32c_sse42.cc + ) + target_compile_options(crc32c_sse42 PRIVATE ${SSE42_CXXFLAGS}) + target_link_libraries(crc32c_sse42 PRIVATE crc32c_common) + set_target_properties(crc32c_sse42 PROPERTIES EXPORT_COMPILE_COMMANDS OFF) + target_link_libraries(crc32c PRIVATE crc32c_sse42) +endif() + +if(HAVE_ARM64_CRC32C) + add_library(crc32c_arm64 STATIC EXCLUDE_FROM_ALL + ${PROJECT_SOURCE_DIR}/src/crc32c/src/crc32c_arm64.cc + ) + target_compile_options(crc32c_arm64 PRIVATE ${ARM64_CRC_CXXFLAGS}) + target_link_libraries(crc32c_arm64 PRIVATE crc32c_common) + set_target_properties(crc32c_arm64 PROPERTIES EXPORT_COMPILE_COMMANDS OFF) + target_link_libraries(crc32c PRIVATE crc32c_arm64) +endif() diff --git a/cmake/introspection.cmake b/cmake/introspection.cmake new file mode 100644 index 000000000000..8b6290f92768 --- /dev/null +++ b/cmake/introspection.cmake @@ -0,0 +1,316 @@ +# 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(CheckCXXSymbolExists) +include(CheckIncludeFileCXX) + +# The following HAVE_{HEADER}_H variables go to the bitcoin-config.h header. +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_symbol_exists(O_CLOEXEC "fcntl.h" HAVE_O_CLOEXEC) +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) + +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) + include(TestAppendRequiredLibraries) + test_append_socket_library(core_interface) +endif() + +include(TestAppendRequiredLibraries) +test_append_atomic_library(core_interface) + +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_cxx_source_compiles(" + #include + + int main() + { + char buf[100]; + char* p{strerror_r(0, buf, sizeof buf)}; + (void)p; + } + " STRERROR_R_CHAR_P +) + +# 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 UNIX sockets. +check_cxx_source_compiles(" + #include + #include + + int main() + { + struct sockaddr_un addr; + addr.sun_family = AF_UNIX; + } + " HAVE_SOCKADDR_UN +) + +# Check for different ways of gathering OS randomness: +# - Linux getrandom syscall +# NOTE: random.cpp issues the syscall directly rather than calling the libc +# wrapper, so probe for the syscall and keep the Autotools macro name. +check_cxx_source_compiles(" + #include + #include + #include + + int main() + { + syscall(SYS_getrandom, nullptr, 32, 0); + } + " HAVE_SYS_GETRANDOM +) + +# - BSD getentropy() +check_cxx_source_compiles(" + #include + + int main() + { + getentropy(nullptr, 32); + } + " 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 +) + +# Needed by script/bitcoinconsensus.h to export the public API symbols. +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(NOT MSVC) + include(CheckSourceCompilesAndLinks) + + # Check for SSSE3 intrinsics, used by the X11 hashing backends. + set(SSSE3_CXXFLAGS -mssse3) + check_cxx_source_compiles_with_flags("${SSSE3_CXXFLAGS}" " + #include + + int main() + { + __m64 x = _mm_abs_pi32(_m_from_int(0)); + return 0; + } + " HAVE_SSSE3 + ) + set(ENABLE_SSSE3 ${HAVE_SSSE3}) + + # Check for SSE4.1 intrinsics. + set(SSE41_CXXFLAGS -msse4.1) + check_cxx_source_compiles_with_flags("${SSE41_CXXFLAGS}" " + #include + + int main() + { + __m128i a = _mm_set1_epi32(0); + __m128i b = _mm_set1_epi32(1); + __m128i r = _mm_blend_epi16(a, b, 0xFF); + return _mm_extract_epi32(r, 3); + } + " HAVE_SSE41 + ) + set(ENABLE_SSE41 ${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 + ) + set(ENABLE_AVX2 ${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 + ) + set(ENABLE_X86_SHANI ${HAVE_X86_SHANI}) + + # Check for x86 AES-NI intrinsics, used by the X11 hashing backends. + set(X86_AESNI_CXXFLAGS -msse4.1 -maes) + check_cxx_source_compiles_with_flags("${X86_AESNI_CXXFLAGS}" " + #include + #include + #include + + int main() + { + __m128i x = _mm_setzero_si128(); + x = _mm_aesenc_si128(x, _mm_setzero_si128()); + return _mm_extract_epi32(x, 0); + } + " HAVE_X86_AESNI + ) + set(ENABLE_X86_AESNI ${HAVE_X86_AESNI}) + + # Check for ARMv8 AES intrinsics, used by the X11 hashing backends. + set(ARM_AES_CXXFLAGS -march=armv8-a+crypto) + check_cxx_source_compiles_with_flags("${ARM_AES_CXXFLAGS}" " + #include + + int main() + { + uint8x16_t a, b; + vaesmcq_u8(vaeseq_u8(a, b)); + return 0; + } + " HAVE_ARM_AES + ) + set(ENABLE_ARM_AES ${HAVE_ARM_AES}) + + # Check for ARM NEON intrinsics, used by the X11 hashing backends. + # Unlike the checks above, the required flag differs between ARMv8 and ARMv7. + # Each attempt needs its own result variable because check_cxx_source_compiles() + # is a no-op once the result variable is cached, including when cached as false. + set(neon_source " + #include + + int main() + { + float32x4_t f = vdupq_n_f32(0.0); + return 0; + } + ") + check_cxx_source_compiles_with_flags("-march=armv8-a" "${neon_source}" HAVE_ARM_NEON_ARMV8) + if(HAVE_ARM_NEON_ARMV8) + set(ARM_NEON_CXXFLAGS -march=armv8-a) + set(HAVE_ARM_NEON TRUE) + else() + check_cxx_source_compiles_with_flags("-march=armv7-a;-mfpu=neon" "${neon_source}" HAVE_ARM_NEON_ARMV7) + if(HAVE_ARM_NEON_ARMV7) + set(ARM_NEON_CXXFLAGS -march=armv7-a -mfpu=neon) + set(HAVE_ARM_NEON TRUE) + endif() + endif() + unset(neon_source) + set(ENABLE_ARM_NEON ${HAVE_ARM_NEON}) + + # 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 + ) + set(ENABLE_ARM_SHANI ${HAVE_ARM_SHANI}) +endif() diff --git a/cmake/leveldb.cmake b/cmake/leveldb.cmake new file mode 100644 index 000000000000..823a5d8e3dae --- /dev/null +++ b/cmake/leveldb.cmake @@ -0,0 +1,105 @@ +# 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=$ + $<$>:LEVELDB_PLATFORM_POSIX> + $<$:LEVELDB_PLATFORM_WINDOWS> + $<$:_UNICODE;UNICODE> +) +if(MINGW) + target_compile_definitions(leveldb + PRIVATE + __USE_MINGW_ANSI_STDIO=1 + ) +endif() + +target_include_directories(leveldb + PRIVATE + $ + PUBLIC + $ +) + +add_library(nowarn_leveldb_interface INTERFACE) +if(MSVC) + target_compile_options(nowarn_leveldb_interface INTERFACE + /wd4722 + ) + target_compile_definitions(nowarn_leveldb_interface INTERFACE + _CRT_NONSTDC_NO_WARNINGS + ) +else() + target_compile_options(nowarn_leveldb_interface INTERFACE + -Wno-conditional-uninitialized + -Wno-suggest-override + ) +endif() + +target_link_libraries(leveldb PRIVATE + core_interface + nowarn_leveldb_interface + crc32c +) + +set_target_properties(leveldb PROPERTIES + EXPORT_COMPILE_COMMANDS OFF +) diff --git a/cmake/minisketch.cmake b/cmake/minisketch.cmake new file mode 100644 index 000000000000..bb93c8046725 --- /dev/null +++ b/cmake/minisketch.cmake @@ -0,0 +1,91 @@ +# 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 +) +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_interface + minisketch_common + ) + set_target_properties(minisketch_clmul PROPERTIES + EXPORT_COMPILE_COMMANDS OFF + ) +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_interface + minisketch_common + $ +) + +set_target_properties(minisketch PROPERTIES + EXPORT_COMPILE_COMMANDS OFF +) diff --git a/cmake/module/AddBoostIfNeeded.cmake b/cmake/module/AddBoostIfNeeded.cmake new file mode 100644 index 000000000000..89603ecd6155 --- /dev/null +++ b/cmake/module/AddBoostIfNeeded.cmake @@ -0,0 +1,78 @@ +# 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(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. + ]=] + + # We cannot rely on find_package(Boost ...) to work properly without + # Boost_NO_BOOST_CMAKE set until we require a more recent Boost because + # upstream did not ship proper CMake files until 1.82.0. + # Until then, we rely on CMake's FindBoost module. + # See: https://cmake.org/cmake/help/latest/policy/CMP0167.html + if(POLICY CMP0167) + cmake_policy(SET CMP0167 OLD) + endif() + set(Boost_NO_BOOST_CMAKE ON) + find_package(Boost 1.73.0 REQUIRED) + mark_as_advanced(Boost_INCLUDE_DIR) + 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 + ) + if(DEFINED VCPKG_TARGET_TRIPLET) + # Workaround for https://github.com/microsoft/vcpkg/issues/36955. + target_compile_definitions(Boost::headers INTERFACE + BOOST_NO_USER_CONFIG + ) + endif() + + # Prevent use of std::unary_function, which was removed in C++17, + # and will generate warnings with newer compilers for Boost + # older than 1.80. + # See: https://github.com/boostorg/config/pull/430. + set(CMAKE_REQUIRED_DEFINITIONS -DBOOST_NO_CXX98_FUNCTION_BASE) + set(CMAKE_REQUIRED_INCLUDES ${Boost_INCLUDE_DIR}) + include(CMakePushCheckState) + cmake_push_check_state() + include(TryAppendCXXFlags) + set(CMAKE_REQUIRED_FLAGS ${working_compiler_werror_flag}) + set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + check_cxx_source_compiles(" + #include + " NO_DIAGNOSTICS_BOOST_NO_CXX98_FUNCTION_BASE + ) + cmake_pop_check_state() + if(NO_DIAGNOSTICS_BOOST_NO_CXX98_FUNCTION_BASE) + target_compile_definitions(Boost::headers INTERFACE + BOOST_NO_CXX98_FUNCTION_BASE + ) + else() + set(CMAKE_REQUIRED_DEFINITIONS) + endif() + + if(BUILD_TESTS) + # Some package managers, such as vcpkg, vendor Boost.Test separately + # from the rest of the headers, so we have to check for it individually. + list(APPEND CMAKE_REQUIRED_DEFINITIONS -DBOOST_TEST_NO_MAIN) + include(CheckIncludeFileCXX) + check_include_file_cxx(boost/test/included/unit_test.hpp 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() + endif() + +endfunction() diff --git a/cmake/module/AddWindowsResources.cmake b/cmake/module/AddWindowsResources.cmake new file mode 100644 index 000000000000..a9b4f51f73d9 --- /dev/null +++ b/cmake/module/AddWindowsResources.cmake @@ -0,0 +1,14 @@ +# Copyright (c) 2024-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) + +macro(add_windows_resources target rc_file) + if(WIN32) + target_sources(${target} PRIVATE ${rc_file}) + set_property(SOURCE ${rc_file} + APPEND PROPERTY COMPILE_DEFINITIONS WINDRES_PREPROC + ) + endif() +endmacro() diff --git a/cmake/module/CheckSourceCompilesAndLinks.cmake b/cmake/module/CheckSourceCompilesAndLinks.cmake new file mode 100644 index 000000000000..88c897d52433 --- /dev/null +++ b/cmake/module/CheckSourceCompilesAndLinks.cmake @@ -0,0 +1,39 @@ +# 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) +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/FindBerkeleyDB.cmake b/cmake/module/FindBerkeleyDB.cmake new file mode 100644 index 000000000000..03a3cce10c53 --- /dev/null +++ b/cmake/module/FindBerkeleyDB.cmake @@ -0,0 +1,133 @@ +# 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/. + +#[=======================================================================[ +FindBerkeleyDB +-------------- + +Finds the Berkeley DB headers and library. + +Imported Targets +^^^^^^^^^^^^^^^^ + +This module provides imported target ``BerkeleyDB::BerkeleyDB``, if +Berkeley DB has been found. + +Result Variables +^^^^^^^^^^^^^^^^ + +This module defines the following variables: + +``BerkeleyDB_FOUND`` + "True" if Berkeley DB found. + +``BerkeleyDB_VERSION`` + The MAJOR.MINOR version of Berkeley DB found. + +#]=======================================================================] + +set(_BerkeleyDB_homebrew_prefix) +if(CMAKE_HOST_APPLE) + find_program(HOMEBREW_EXECUTABLE brew) + if(HOMEBREW_EXECUTABLE) + # The Homebrew package manager installs the berkeley-db* packages as + # "keg-only", which means they are not symlinked into the default prefix. + # To find such a package, the find_path() and find_library() commands + # need additional path hints that are computed by Homebrew itself. + execute_process( + COMMAND ${HOMEBREW_EXECUTABLE} --prefix berkeley-db@4 + OUTPUT_VARIABLE _BerkeleyDB_homebrew_prefix + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + endif() +endif() + +find_path(BerkeleyDB_INCLUDE_DIR + NAMES db_cxx.h + HINTS ${_BerkeleyDB_homebrew_prefix}/include + PATH_SUFFIXES 4.8 48 db4.8 4 db4 5.3 db5.3 5 db5 +) +mark_as_advanced(BerkeleyDB_INCLUDE_DIR) +unset(_BerkeleyDB_homebrew_prefix) + +if(NOT BerkeleyDB_LIBRARY) + if(VCPKG_TARGET_TRIPLET) + # The vcpkg package manager installs the berkeleydb package with the same name + # of release and debug libraries. Therefore, the default search paths set by + # vcpkg's toolchain file cannot be used to search libraries as the debug one + # will always be found. + set(CMAKE_FIND_USE_CMAKE_PATH FALSE) + endif() + + get_filename_component(_BerkeleyDB_lib_hint "${BerkeleyDB_INCLUDE_DIR}" DIRECTORY) + + find_library(BerkeleyDB_LIBRARY_RELEASE + NAMES db_cxx-4.8 db4_cxx db48 db_cxx-5.3 db_cxx-5 db_cxx libdb48 + NAMES_PER_DIR + HINTS ${_BerkeleyDB_lib_hint} + PATH_SUFFIXES lib + ) + mark_as_advanced(BerkeleyDB_LIBRARY_RELEASE) + + find_library(BerkeleyDB_LIBRARY_DEBUG + NAMES db_cxx-4.8 db4_cxx db48 db_cxx-5.3 db_cxx-5 db_cxx libdb48 + NAMES_PER_DIR + HINTS ${_BerkeleyDB_lib_hint} + PATH_SUFFIXES debug/lib + ) + mark_as_advanced(BerkeleyDB_LIBRARY_DEBUG) + + unset(_BerkeleyDB_lib_hint) + unset(CMAKE_FIND_USE_CMAKE_PATH) + + include(SelectLibraryConfigurations) + select_library_configurations(BerkeleyDB) + # The select_library_configurations() command sets BerkeleyDB_FOUND, but we + # want the one from the find_package_handle_standard_args() command below. + unset(BerkeleyDB_FOUND) +endif() + +if(BerkeleyDB_INCLUDE_DIR) + file(STRINGS "${BerkeleyDB_INCLUDE_DIR}/db.h" _BerkeleyDB_version_strings REGEX "^#define[\t ]+DB_VERSION_(MAJOR|MINOR|PATCH)[ \t]+[0-9]+.*") + string(REGEX REPLACE ".*#define[\t ]+DB_VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" _BerkeleyDB_version_major "${_BerkeleyDB_version_strings}") + string(REGEX REPLACE ".*#define[\t ]+DB_VERSION_MINOR[ \t]+([0-9]+).*" "\\1" _BerkeleyDB_version_minor "${_BerkeleyDB_version_strings}") + string(REGEX REPLACE ".*#define[\t ]+DB_VERSION_PATCH[ \t]+([0-9]+).*" "\\1" _BerkeleyDB_version_patch "${_BerkeleyDB_version_strings}") + unset(_BerkeleyDB_version_strings) + # The MAJOR.MINOR.PATCH version will be logged in the following find_package_handle_standard_args() command. + set(_BerkeleyDB_full_version ${_BerkeleyDB_version_major}.${_BerkeleyDB_version_minor}.${_BerkeleyDB_version_patch}) + set(BerkeleyDB_VERSION ${_BerkeleyDB_version_major}.${_BerkeleyDB_version_minor}) + unset(_BerkeleyDB_version_major) + unset(_BerkeleyDB_version_minor) + unset(_BerkeleyDB_version_patch) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(BerkeleyDB + REQUIRED_VARS BerkeleyDB_LIBRARY BerkeleyDB_INCLUDE_DIR + VERSION_VAR _BerkeleyDB_full_version +) +unset(_BerkeleyDB_full_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(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() + 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() +endif() diff --git a/cmake/module/FindLibevent.cmake b/cmake/module/FindLibevent.cmake new file mode 100644 index 000000000000..901a4f3bd41e --- /dev/null +++ b/cmake/module/FindLibevent.cmake @@ -0,0 +1,80 @@ +# Copyright (c) 2024-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +#[=======================================================================[ +FindLibevent +------------ + +Finds the Libevent headers and libraries. + +This is a wrapper around find_package()/pkg_check_modules() commands that: + - facilitates searching in various build environments + - prints a standard log message + +#]=======================================================================] + +# Check whether evhttp_connection_get_peer expects const char**. +# See https://github.com/libevent/libevent/commit/a18301a2bb160ff7c3ffaf5b7653c39ffe27b385 +function(check_evhttp_connection_get_peer target) + include(CMakePushCheckState) + cmake_push_check_state(RESET) + set(CMAKE_REQUIRED_LIBRARIES ${target}) + include(CheckCXXSourceCompiles) + 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() + set(HAVE_EVHTTP_CONNECTION_GET_PEER_CONST_CHAR ${HAVE_EVHTTP_CONNECTION_GET_PEER_CONST_CHAR} PARENT_SCOPE) +endfunction() + + +include(FindPackageHandleStandardArgs) +if(VCPKG_TARGET_TRIPLET) + find_package(Libevent ${Libevent_FIND_VERSION} NO_MODULE QUIET + COMPONENTS extra + ) + find_package_handle_standard_args(Libevent + REQUIRED_VARS Libevent_DIR + VERSION_VAR Libevent_VERSION + ) + check_evhttp_connection_get_peer(libevent::extra) + add_library(libevent::libevent ALIAS libevent::extra) + mark_as_advanced(Libevent_DIR) + mark_as_advanced(_event_h) + mark_as_advanced(_event_lib) +else() + find_package(PkgConfig REQUIRED) + pkg_check_modules(libevent QUIET + IMPORTED_TARGET + libevent>=${Libevent_FIND_VERSION} + ) + set(_libevent_required_vars libevent_LIBRARY_DIRS libevent_FOUND) + if(NOT WIN32) + pkg_check_modules(libevent_pthreads QUIET + IMPORTED_TARGET + libevent_pthreads>=${Libevent_FIND_VERSION} + ) + list(APPEND _libevent_required_vars libevent_pthreads_FOUND) + endif() + find_package_handle_standard_args(Libevent + REQUIRED_VARS ${_libevent_required_vars} + VERSION_VAR libevent_VERSION + ) + unset(_libevent_required_vars) + check_evhttp_connection_get_peer(PkgConfig::libevent) + add_library(libevent::libevent ALIAS PkgConfig::libevent) + if(NOT WIN32) + add_library(libevent::pthreads ALIAS PkgConfig::libevent_pthreads) + endif() +endif() diff --git a/cmake/module/FindMiniUPnPc.cmake b/cmake/module/FindMiniUPnPc.cmake new file mode 100644 index 000000000000..34b94f05f16e --- /dev/null +++ b/cmake/module/FindMiniUPnPc.cmake @@ -0,0 +1,84 @@ +# 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/. + +if(NOT MSVC) + find_package(PkgConfig REQUIRED) + 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 000000000000..930555232bd8 --- /dev/null +++ b/cmake/module/FindNATPMP.cmake @@ -0,0 +1,32 @@ +# 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/. + +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/FindQt5.cmake b/cmake/module/FindQt5.cmake new file mode 100644 index 000000000000..f39ee53d5b5c --- /dev/null +++ b/cmake/module/FindQt5.cmake @@ -0,0 +1,66 @@ +# Copyright (c) 2024-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +#[=======================================================================[ +FindQt5 +------- + +Finds the Qt 5 headers and libraries. + +This is a wrapper around find_package() command that: + - facilitates searching in various build environments + - prints a standard log message + +#]=======================================================================] + +set(_qt_homebrew_prefix) +if(CMAKE_HOST_APPLE) + find_program(HOMEBREW_EXECUTABLE brew) + if(HOMEBREW_EXECUTABLE) + execute_process( + COMMAND ${HOMEBREW_EXECUTABLE} --prefix qt@5 + OUTPUT_VARIABLE _qt_homebrew_prefix + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + endif() +endif() + +# Save CMAKE_FIND_ROOT_PATH_MODE_LIBRARY state. +unset(_qt_find_root_path_mode_library_saved) +if(DEFINED CMAKE_FIND_ROOT_PATH_MODE_LIBRARY) + set(_qt_find_root_path_mode_library_saved ${CMAKE_FIND_ROOT_PATH_MODE_LIBRARY}) +endif() + +# The Qt config files internally use find_library() calls for all +# dependencies to ensure their availability. In turn, the find_library() +# inspects the well-known locations on the file system; therefore, it must +# be able to find platform-specific system libraries, for example: +# /usr/x86_64-w64-mingw32/lib/libm.a or /usr/arm-linux-gnueabihf/lib/libm.a. +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH) + +find_package(Qt5 ${Qt5_FIND_VERSION} + COMPONENTS ${Qt5_FIND_COMPONENTS} + HINTS ${_qt_homebrew_prefix} + PATH_SUFFIXES Qt5 # Required on OpenBSD systems. +) +unset(_qt_homebrew_prefix) + +# Restore CMAKE_FIND_ROOT_PATH_MODE_LIBRARY state. +if(DEFINED _qt_find_root_path_mode_library_saved) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ${_qt_find_root_path_mode_library_saved}) + unset(_qt_find_root_path_mode_library_saved) +else() + unset(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Qt5 + REQUIRED_VARS Qt5_DIR + VERSION_VAR Qt5_VERSION +) + +foreach(component IN LISTS Qt5_FIND_COMPONENTS ITEMS "") + mark_as_advanced(Qt5${component}_DIR) +endforeach() diff --git a/cmake/module/FindUSDT.cmake b/cmake/module/FindUSDT.cmake new file mode 100644 index 000000000000..0ba9a58fc10a --- /dev/null +++ b/cmake/module/FindUSDT.cmake @@ -0,0 +1,64 @@ +# Copyright (c) 2024-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +#[=======================================================================[ +FindUSDT +-------- + +Finds the Userspace, Statically Defined Tracing header(s). + +Imported Targets +^^^^^^^^^^^^^^^^ + +This module provides imported target ``USDT::headers``, if +USDT has been found. + +Result Variables +^^^^^^^^^^^^^^^^ + +This module defines the following variables: + +``USDT_FOUND`` + "True" if USDT found. + +#]=======================================================================] + +find_path(USDT_INCLUDE_DIR + NAMES sys/sdt.h +) +mark_as_advanced(USDT_INCLUDE_DIR) + +if(USDT_INCLUDE_DIR) + include(CMakePushCheckState) + cmake_push_check_state(RESET) + + include(CheckCXXSourceCompiles) + set(CMAKE_REQUIRED_INCLUDES ${USDT_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() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(USDT + REQUIRED_VARS USDT_INCLUDE_DIR HAVE_USDT_H +) + +if(USDT_FOUND AND NOT TARGET USDT::headers) + add_library(USDT::headers INTERFACE IMPORTED) + set_target_properties(USDT::headers PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${USDT_INCLUDE_DIR}" + ) + set(ENABLE_TRACING TRUE) +endif() diff --git a/cmake/module/FlagsSummary.cmake b/cmake/module/FlagsSummary.cmake new file mode 100644 index 000000000000..9a408f715d91 --- /dev/null +++ b/cmake/module/FlagsSummary.cmake @@ -0,0 +1,73 @@ +# Copyright (c) 2024-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) + +function(indent_message header content indent_num) + if(indent_num GREATER 0) + string(REPEAT " " ${indent_num} indentation) + string(REPEAT "." ${indent_num} tail) + string(REGEX REPLACE "${tail}$" "" header "${header}") + endif() + message("${indentation}${header} ${content}") +endfunction() + +# Print tools' flags on best-effort. Include the abstracted +# CMake flags that we touch ourselves. +function(print_flags_per_config config indent_num) + string(TOUPPER "${config}" config_uppercase) + + include(GetTargetInterface) + get_target_interface(definitions "${config}" core_interface COMPILE_DEFINITIONS) + indent_message("Preprocessor defined macros ..........." "${definitions}" ${indent_num}) + + string(STRIP "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${config_uppercase}}" combined_cxx_flags) + string(STRIP "${combined_cxx_flags} ${CMAKE_CXX${CMAKE_CXX_STANDARD}_STANDARD_COMPILE_OPTION}" combined_cxx_flags) + if(CMAKE_POSITION_INDEPENDENT_CODE) + string(JOIN " " combined_cxx_flags ${combined_cxx_flags} ${CMAKE_CXX_COMPILE_OPTIONS_PIC}) + endif() + get_target_interface(core_cxx_flags "${config}" core_interface COMPILE_OPTIONS) + string(STRIP "${combined_cxx_flags} ${core_cxx_flags}" combined_cxx_flags) + string(STRIP "${combined_cxx_flags} ${APPEND_CPPFLAGS}" combined_cxx_flags) + string(STRIP "${combined_cxx_flags} ${APPEND_CXXFLAGS}" combined_cxx_flags) + indent_message("C++ compiler flags ...................." "${combined_cxx_flags}" ${indent_num}) + + string(STRIP "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${config_uppercase}}" combined_linker_flags) + string(STRIP "${combined_linker_flags} ${CMAKE_EXE_LINKER_FLAGS}" combined_linker_flags) + get_target_interface(common_link_options "${config}" core_interface LINK_OPTIONS) + string(STRIP "${combined_linker_flags} ${common_link_options}" combined_linker_flags) + if(CMAKE_CXX_LINK_PIE_SUPPORTED) + string(JOIN " " combined_linker_flags ${combined_linker_flags} ${CMAKE_CXX_LINK_OPTIONS_PIE}) + endif() + string(STRIP "${combined_linker_flags} ${APPEND_LDFLAGS}" combined_linker_flags) + indent_message("Linker flags .........................." "${combined_linker_flags}" ${indent_num}) +endfunction() + +function(flags_summary) + get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + if(is_multi_config) + list(JOIN CMAKE_CONFIGURATION_TYPES ", " configs) + message("Available build configurations ........ ${configs}") + if(CMAKE_GENERATOR MATCHES "Visual Studio") + set(default_config "Debug") + else() + list(GET CMAKE_CONFIGURATION_TYPES 0 default_config) + endif() + message("Default build configuration ........... ${default_config}") + foreach(config IN LISTS CMAKE_CONFIGURATION_TYPES) + message("") + message("'${config}' build configuration:") + print_flags_per_config("${config}" 2) + endforeach() + else() + message("CMAKE_BUILD_TYPE ...................... ${CMAKE_BUILD_TYPE}") + print_flags_per_config("${CMAKE_BUILD_TYPE}" 0) + endif() + message("") + message([=[ +NOTE: The summary above may not exactly match the final applied build flags + if any additional CMAKE_* or environment variables have been modified. + To see the exact flags applied, build with the --verbose option. +]=]) +endfunction() diff --git a/cmake/module/GenerateHeaders.cmake b/cmake/module/GenerateHeaders.cmake new file mode 100644 index 000000000000..35dc54eebb5d --- /dev/null +++ b/cmake/module/GenerateHeaders.cmake @@ -0,0 +1,21 @@ +# 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(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 ${PROJECT_SOURCE_DIR}/cmake/script/GenerateHeaderFromJson.cmake + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${json_source_relpath} ${PROJECT_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 ${PROJECT_SOURCE_DIR}/cmake/script/GenerateHeaderFromRaw.cmake + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${raw_source_relpath} ${PROJECT_SOURCE_DIR}/cmake/script/GenerateHeaderFromRaw.cmake + VERBATIM + ) +endfunction() diff --git a/cmake/module/GenerateSetupNsi.cmake b/cmake/module/GenerateSetupNsi.cmake new file mode 100644 index 000000000000..dfdad654476d --- /dev/null +++ b/cmake/module/GenerateSetupNsi.cmake @@ -0,0 +1,28 @@ +# 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(generate_setup_nsi) + set(abs_top_srcdir ${PROJECT_SOURCE_DIR}) + set(abs_top_builddir ${PROJECT_BINARY_DIR}) + set(PACKAGE_URL ${PROJECT_HOMEPAGE_URL}) + # These have to match the executables' OUTPUT_NAMEs, since the deploy target + # stages the files under those names. Keep them in sync with configure.ac. + # PACKAGE_TARNAME comes from the top-level CMakeLists.txt, which is also where + # add_windows_deploy_target() reads it from. + set(BITCOIN_GUI_NAME "dash-qt") + set(BITCOIN_DAEMON_NAME "dashd") + set(BITCOIN_CLI_NAME "dash-cli") + set(BITCOIN_TX_NAME "dash-tx") + set(BITCOIN_WALLET_TOOL_NAME "dash-wallet") + set(BITCOIN_TEST_NAME "test_dash") + set(EXEEXT ${CMAKE_EXECUTABLE_SUFFIX}) + set(nsi_file ${PROJECT_BINARY_DIR}/${PACKAGE_TARNAME}-win64-setup.nsi) + configure_file(${PROJECT_SOURCE_DIR}/share/setup.nsi.in ${nsi_file} @ONLY) + # share/setup.nsi.in carries no OutFile directive; the Autotools recipe pipes + # one in ahead of the script when invoking makensis. Do the same here. + file(READ ${nsi_file} nsi_content) + file(WRITE ${nsi_file} + "OutFile \"${PROJECT_BINARY_DIR}/${PACKAGE_TARNAME}-${PACKAGE_VERSION}-win64-setup${EXEEXT}\"\n${nsi_content}" + ) +endfunction() diff --git a/cmake/module/GetTargetInterface.cmake b/cmake/module/GetTargetInterface.cmake new file mode 100644 index 000000000000..1e455d456b41 --- /dev/null +++ b/cmake/module/GetTargetInterface.cmake @@ -0,0 +1,53 @@ +# 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) + +# Evaluates config-specific generator expressions in a list. +# Recognizable patterns are: +# - $<$:[value]> +# - $<$>:[value]> +function(evaluate_generator_expressions list config) + set(input ${${list}}) + set(result) + foreach(token IN LISTS input) + if(token MATCHES "\\$<\\$]+)>:([^>]+)>") + if(CMAKE_MATCH_1 STREQUAL config) + list(APPEND result ${CMAKE_MATCH_2}) + endif() + elseif(token MATCHES "\\$<\\$]+)>>:([^>]+)>") + if(NOT CMAKE_MATCH_1 STREQUAL config) + list(APPEND result ${CMAKE_MATCH_2}) + endif() + else() + list(APPEND result ${token}) + endif() + endforeach() + set(${list} ${result} PARENT_SCOPE) +endfunction() + + +# Gets target's interface properties recursively. +function(get_target_interface var config target property) + get_target_property(result ${target} INTERFACE_${property}) + if(result) + evaluate_generator_expressions(result "${config}") + list(JOIN result " " result) + else() + set(result) + endif() + + get_target_property(dependencies ${target} INTERFACE_LINK_LIBRARIES) + if(dependencies) + evaluate_generator_expressions(dependencies "${config}") + foreach(dependency IN LISTS dependencies) + if(TARGET ${dependency}) + get_target_interface(dep_result "${config}" ${dependency} ${property}) + string(STRIP "${result} ${dep_result}" result) + endif() + endforeach() + endif() + + set(${var} "${result}" PARENT_SCOPE) +endfunction() diff --git a/cmake/module/Maintenance.cmake b/cmake/module/Maintenance.cmake new file mode 100644 index 000000000000..6183ab8bdac6 --- /dev/null +++ b/cmake/module/Maintenance.cmake @@ -0,0 +1,151 @@ +# 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) + +function(setup_split_debug_script) + if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") + set(OBJCOPY ${CMAKE_OBJCOPY}) + set(STRIP ${CMAKE_STRIP}) + configure_file( + contrib/devtools/split-debug.sh.in split-debug.sh + FILE_PERMISSIONS OWNER_READ OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE + WORLD_READ + @ONLY + ) + endif() +endfunction() + +function(add_maintenance_targets) + if(NOT PYTHON_COMMAND) + return() + endif() + + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + set(exe_format MACHO) + elseif(WIN32) + set(exe_format PE) + else() + set(exe_format ELF) + endif() + + # In CMake, the components of the compiler invocation are separated into distinct variables: + # - CMAKE_CXX_COMPILER: the full path to the compiler binary itself (e.g., /usr/bin/clang++). + # - CMAKE_CXX_COMPILER_ARG1: a string containing initial compiler options (e.g., --target=x86_64-apple-darwin -nostdlibinc). + # By concatenating these variables, we form the complete command line to be passed to a Python script via the CXX environment variable. + string(STRIP "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}" cxx_compiler_command) + add_custom_target(test-security-check + COMMAND ${CMAKE_COMMAND} -E env CXX=${cxx_compiler_command} CXXFLAGS=${CMAKE_CXX_FLAGS} LDFLAGS=${CMAKE_EXE_LINKER_FLAGS} ${PYTHON_COMMAND} ${PROJECT_SOURCE_DIR}/contrib/devtools/test-security-check.py TestSecurityChecks.test_${exe_format} + COMMAND ${CMAKE_COMMAND} -E env CXX=${cxx_compiler_command} CXXFLAGS=${CMAKE_CXX_FLAGS} LDFLAGS=${CMAKE_EXE_LINKER_FLAGS} ${PYTHON_COMMAND} ${PROJECT_SOURCE_DIR}/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_${exe_format} + VERBATIM + ) + + foreach(target IN ITEMS bitcoind bitcoin-qt bitcoin-cli bitcoin-tx bitcoin-util bitcoin-wallet test_bitcoin bench_bitcoin) + if(TARGET ${target}) + list(APPEND executables $) + endif() + endforeach() + + add_custom_target(check-symbols + COMMAND ${CMAKE_COMMAND} -E echo "Running symbol and dynamic library checks..." + COMMAND ${PYTHON_COMMAND} ${PROJECT_SOURCE_DIR}/contrib/devtools/symbol-check.py ${executables} + VERBATIM + ) + + if(ENABLE_HARDENING) + add_custom_target(check-security + COMMAND ${CMAKE_COMMAND} -E echo "Checking binary security..." + COMMAND ${PYTHON_COMMAND} ${PROJECT_SOURCE_DIR}/contrib/devtools/security-check.py ${executables} + VERBATIM + ) + else() + add_custom_target(check-security) + endif() +endfunction() + +function(add_windows_deploy_target) + if(MINGW AND TARGET bitcoin-qt AND TARGET bitcoind AND TARGET bitcoin-cli AND TARGET bitcoin-tx AND TARGET bitcoin-wallet AND TARGET bitcoin-util AND TARGET test_bitcoin) + # TODO: Consider replacing this code with the CPack NSIS Generator. + # See https://cmake.org/cmake/help/latest/cpack_gen/nsis.html + include(GenerateSetupNsi) + generate_setup_nsi() + add_custom_command( + OUTPUT ${PROJECT_BINARY_DIR}/${PACKAGE_TARNAME}-${PACKAGE_VERSION}-win64-setup.exe + COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/release + COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ + COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ + COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ + COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ + COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ + COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ + COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ + COMMAND makensis -V2 ${PROJECT_BINARY_DIR}/${PACKAGE_TARNAME}-win64-setup.nsi + VERBATIM + ) + add_custom_target(deploy DEPENDS ${PROJECT_BINARY_DIR}/${PACKAGE_TARNAME}-${PACKAGE_VERSION}-win64-setup.exe) + endif() +endfunction() + +function(add_macos_deploy_target) + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND TARGET bitcoin-qt) + set(macos_app "Dash-Qt.app") + # Populate Contents subdirectory. + configure_file(${PROJECT_SOURCE_DIR}/share/qt/Info.plist.in ${macos_app}/Contents/Info.plist) + file(CONFIGURE OUTPUT ${macos_app}/Contents/PkgInfo CONTENT "APPL????") + # Populate Contents/Resources subdirectory. + file(CONFIGURE OUTPUT ${macos_app}/Contents/Resources/empty.lproj CONTENT "") + configure_file(${PROJECT_SOURCE_DIR}/src/qt/res/icons/dash.icns ${macos_app}/Contents/Resources/dash.icns COPYONLY) + file(CONFIGURE OUTPUT ${macos_app}/Contents/Resources/Base.lproj/InfoPlist.strings + CONTENT "{ CFBundleDisplayName = \"@PACKAGE_NAME@\"; CFBundleName = \"@PACKAGE_NAME@\"; }" + ) + + add_custom_command( + OUTPUT ${PROJECT_BINARY_DIR}/${macos_app}/Contents/MacOS/Dash-Qt + COMMAND ${CMAKE_COMMAND} --install ${PROJECT_BINARY_DIR} --config $ --component GUI --prefix ${macos_app}/Contents/MacOS --strip + COMMAND ${CMAKE_COMMAND} -E rename ${macos_app}/Contents/MacOS/bin/$ ${macos_app}/Contents/MacOS/Dash-Qt + COMMAND ${CMAKE_COMMAND} -E rm -rf ${macos_app}/Contents/MacOS/bin + VERBATIM + ) + + string(REPLACE " " "-" osx_volname ${PACKAGE_NAME}) + if(CMAKE_HOST_APPLE) + add_custom_command( + OUTPUT ${PROJECT_BINARY_DIR}/${osx_volname}.zip + COMMAND ${PYTHON_COMMAND} ${PROJECT_SOURCE_DIR}/contrib/macdeploy/macdeployqtplus ${macos_app} ${osx_volname} -translations-dir=${QT_TRANSLATIONS_DIR} -zip + DEPENDS ${PROJECT_BINARY_DIR}/${macos_app}/Contents/MacOS/Dash-Qt + VERBATIM + ) + add_custom_target(deploydir + DEPENDS ${PROJECT_BINARY_DIR}/${osx_volname}.zip + ) + add_custom_target(deploy + DEPENDS ${PROJECT_BINARY_DIR}/${osx_volname}.zip + ) + else() + add_custom_command( + OUTPUT ${PROJECT_BINARY_DIR}/dist/${macos_app}/Contents/MacOS/Dash-Qt + COMMAND OBJDUMP=${CMAKE_OBJDUMP} ${PYTHON_COMMAND} ${PROJECT_SOURCE_DIR}/contrib/macdeploy/macdeployqtplus ${macos_app} ${osx_volname} -translations-dir=${QT_TRANSLATIONS_DIR} + DEPENDS ${PROJECT_BINARY_DIR}/${macos_app}/Contents/MacOS/Dash-Qt + VERBATIM + ) + add_custom_target(deploydir + DEPENDS ${PROJECT_BINARY_DIR}/dist/${macos_app}/Contents/MacOS/Dash-Qt + ) + + find_program(ZIP_COMMAND zip REQUIRED) + add_custom_command( + OUTPUT ${PROJECT_BINARY_DIR}/dist/${osx_volname}.zip + WORKING_DIRECTORY dist + COMMAND ${PROJECT_SOURCE_DIR}/cmake/script/macos_zip.sh ${ZIP_COMMAND} ${osx_volname}.zip + VERBATIM + ) + add_custom_target(deploy + DEPENDS ${PROJECT_BINARY_DIR}/dist/${osx_volname}.zip + ) + endif() + add_dependencies(deploydir bitcoin-qt) + add_dependencies(deploy deploydir) + endif() +endfunction() diff --git a/cmake/module/ProcessConfigurations.cmake b/cmake/module/ProcessConfigurations.cmake new file mode 100644 index 000000000000..5286d10267be --- /dev/null +++ b/cmake/module/ProcessConfigurations.cmake @@ -0,0 +1,175 @@ +# 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(TryAppendCXXFlags) + +macro(normalize_string string) + string(REGEX REPLACE " +" " " ${string} "${${string}}") + string(STRIP "${${string}}" ${string}) +endmacro() + +function(are_flags_overridden flags_var result_var) + normalize_string(${flags_var}) + normalize_string(${flags_var}_INIT) + if(${flags_var} STREQUAL ${flags_var}_INIT) + set(${result_var} FALSE PARENT_SCOPE) + else() + set(${result_var} TRUE PARENT_SCOPE) + endif() +endfunction() + + +# Removes duplicated flags. The relative order of flags is preserved. +# If duplicates are encountered, only the last instance is preserved. +function(deduplicate_flags flags) + separate_arguments(${flags}) + list(REVERSE ${flags}) + list(REMOVE_DUPLICATES ${flags}) + list(REVERSE ${flags}) + list(JOIN ${flags} " " result) + set(${flags} "${result}" PARENT_SCOPE) +endfunction() + + +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) + # Also see https://gitlab.kitware.com/cmake/cmake/-/issues/19512. + set(CMAKE_TRY_COMPILE_CONFIGURATION "${config}" PARENT_SCOPE) + 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() + set(CMAKE_TRY_COMPILE_CONFIGURATION "${CMAKE_BUILD_TYPE}" PARENT_SCOPE) + endif() +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) + set(CMAKE_CXX_FLAGS_${config_uppercase} "${new_flags}" + CACHE STRING + "Flags used by the CXX compiler during ${config_uppercase} builds." + FORCE + ) + endforeach() +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) + set(CMAKE_CXX_FLAGS_${config_uppercase} "${new_flags}" + CACHE STRING + "Flags used by the CXX compiler during ${config_uppercase} builds." + FORCE + ) +endfunction() + +set_default_config(RelWithDebInfo) + +# Redefine/adjust per-configuration flags. +target_compile_definitions(core_interface_debug INTERFACE + DEBUG + DEBUG_LOCKORDER + DEBUG_LOCKCONTENTION + RPC_DOC_CHECK + ABORT_ON_FAILED_ASSUME +) +# We leave assertions on. +if(MSVC) + remove_cxx_flag_from_all_configs(/DNDEBUG) +else() + remove_cxx_flag_from_all_configs(-DNDEBUG) + + # Adjust flags used by the CXX compiler during RELEASE builds. + # Prefer -O2 optimization level. (-O3 is CMake's default for Release for many compilers.) + replace_cxx_flag_in_config(Release -O3 -O2) + + are_flags_overridden(CMAKE_CXX_FLAGS_DEBUG cxx_flags_debug_overridden) + if(NOT cxx_flags_debug_overridden) + # Redefine flags used by the CXX compiler during DEBUG builds. + try_append_cxx_flags("-g3" RESULT_VAR compiler_supports_g3) + if(compiler_supports_g3) + replace_cxx_flag_in_config(Debug -g -g3) + endif() + unset(compiler_supports_g3) + + try_append_cxx_flags("-ftrapv" RESULT_VAR compiler_supports_ftrapv) + if(compiler_supports_ftrapv) + string(PREPEND CMAKE_CXX_FLAGS_DEBUG "-ftrapv ") + endif() + unset(compiler_supports_ftrapv) + + string(PREPEND CMAKE_CXX_FLAGS_DEBUG "-O0 ") + + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}" + CACHE STRING + "Flags used by the CXX compiler during DEBUG builds." + FORCE + ) + endif() + unset(cxx_flags_debug_overridden) +endif() + +set(CMAKE_CXX_FLAGS_COVERAGE "-Og --coverage") +set(CMAKE_OBJCXX_FLAGS_COVERAGE "-Og --coverage") +set(CMAKE_EXE_LINKER_FLAGS_COVERAGE "--coverage") +set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE "--coverage") +get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(is_multi_config) + if(NOT "Coverage" IN_LIST CMAKE_CONFIGURATION_TYPES) + list(APPEND CMAKE_CONFIGURATION_TYPES Coverage) + endif() +endif() diff --git a/cmake/module/TestAppendRequiredLibraries.cmake b/cmake/module/TestAppendRequiredLibraries.cmake new file mode 100644 index 000000000000..5352102c7a48 --- /dev/null +++ b/cmake/module/TestAppendRequiredLibraries.cmake @@ -0,0 +1,92 @@ +# 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 +# - https://smartos.org/man/3socket/getifaddrs +function(test_append_socket_library target) + if (NOT TARGET ${target}) + message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}() called with non-existent target \"${target}\".") + endif() + + 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(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) + target_link_libraries(${target} INTERFACE socket) + else() + message(FATAL_ERROR "Cannot figure out how to use getifaddrs/freeifaddrs.") + endif() + endif() + set(HAVE_DECL_GETIFADDRS TRUE PARENT_SCOPE) + set(HAVE_DECL_FREEIFADDRS TRUE PARENT_SCOPE) +endfunction() + +# Clang, when building for 32-bit, +# and linking against libstdc++, requires linking with +# -latomic if using the C++ atomic library. +# Can be tested with: clang++ -std=c++20 test.cpp -m32 +# +# Sourced from http://bugs.debian.org/797228 +function(test_append_atomic_library target) + if (NOT TARGET ${target}) + message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}() called with non-existent target \"${target}\".") + endif() + + 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); + auto t1 = t.load(); + t.compare_exchange_strong(t1, 3s); + + std::atomic d{}; + d.store(3.14); + auto d1 = d.load(); + + 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() diff --git a/cmake/module/TryAppendCXXFlags.cmake b/cmake/module/TryAppendCXXFlags.cmake new file mode 100644 index 000000000000..0f6e014d437a --- /dev/null +++ b/cmake/module/TryAppendCXXFlags.cmake @@ -0,0 +1,138 @@ +# 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) + +#[=[ +Add language-wide flags, which will be passed to all invocations of the compiler. +This includes invocations that drive compiling and those that drive linking. + +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_interface + 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_interface + IF_CHECK_PASSED "-Wno-unused-parameter" + ) + + + try_append_cxx_flags("-Werror=return-type" TARGET core_interface + 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 + "SKIP_LINK" # options + "TARGET;VAR;SOURCE;RESULT_VAR" # one_value_keywords + "IF_CHECK_PASSED;IF_CHECK_FAILED" # multi_value_keywords + ) + + set(flags_as_string "${flags}") + separate_arguments(flags) + + string(MAKE_C_IDENTIFIER "${flags_as_string}" id_string) + string(TOUPPER "${id_string}" id_string) + + 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 id_string _${source_hash_head}) + endif() + + # This avoids running a linker. + set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + set(CMAKE_REQUIRED_FLAGS "${flags_as_string} ${working_compiler_werror_flag}") + set(compiler_result CXX_SUPPORTS_${id_string}) + check_cxx_source_compiles("${source}" ${compiler_result}) + + if(${compiler_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_as_string}" ${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} "${${compiler_result}}" PARENT_SCOPE) + endif() + + if(NOT ${compiler_result} OR TACXXF_SKIP_LINK) + return() + endif() + + # This forces running a linker. + set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE) + set(CMAKE_REQUIRED_FLAGS "${flags_as_string}") + set(CMAKE_REQUIRED_LINK_OPTIONS ${working_linker_werror_flag}) + set(linker_result LINKER_SUPPORTS_${id_string}) + check_cxx_source_compiles("${source}" ${linker_result}) + + if(${linker_result}) + if(DEFINED TACXXF_IF_CHECK_PASSED) + if(DEFINED TACXXF_TARGET) + target_link_options(${TACXXF_TARGET} INTERFACE ${TACXXF_IF_CHECK_PASSED}) + endif() + else() + if(DEFINED TACXXF_TARGET) + target_link_options(${TACXXF_TARGET} INTERFACE ${flags}) + endif() + endif() + else() + message(WARNING "'${flags_as_string}' fail(s) to link.") + endif() +endfunction() + +if(MSVC) + try_append_cxx_flags("/WX /options:strict" VAR working_compiler_werror_flag SKIP_LINK) +else() + try_append_cxx_flags("-Werror" VAR working_compiler_werror_flag SKIP_LINK) +endif() diff --git a/cmake/module/TryAppendLinkerFlag.cmake b/cmake/module/TryAppendLinkerFlag.cmake new file mode 100644 index 000000000000..57220fbb913c --- /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_interface) + + +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 ${TALF_IF_CHECK_FAILED}) + endif() + if(DEFINED TALF_VAR) + string(STRIP "${${TALF_VAR}} ${TALF_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() diff --git a/cmake/module/WarnAboutGlobalProperties.cmake b/cmake/module/WarnAboutGlobalProperties.cmake new file mode 100644 index 000000000000..faa56a2a7f19 --- /dev/null +++ b/cmake/module/WarnAboutGlobalProperties.cmake @@ -0,0 +1,36 @@ +# 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) +set_target_properties(check_loose_linked_libraries PROPERTIES EXPORT_COMPILE_COMMANDS OFF) +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() diff --git a/cmake/script/Coverage.cmake b/cmake/script/Coverage.cmake new file mode 100644 index 000000000000..0df2e0b734d8 --- /dev/null +++ b/cmake/script/Coverage.cmake @@ -0,0 +1,77 @@ +# Copyright (c) 2024-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +include(${CMAKE_CURRENT_LIST_DIR}/CoverageInclude.cmake) + +set(functional_test_runner test/functional/test_runner.py) +if(EXTENDED_FUNCTIONAL_TESTS) + list(APPEND functional_test_runner --extended) +endif() +if(DEFINED JOBS) + list(APPEND CMAKE_CTEST_COMMAND -j ${JOBS}) + list(APPEND functional_test_runner -j ${JOBS}) +endif() + +execute_process( + COMMAND ${CMAKE_CTEST_COMMAND} --build-config Coverage + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + COMMAND_ERROR_IS_FATAL ANY +) +execute_process( + COMMAND ${LCOV_COMMAND} --capture --directory src --test-name test_bitcoin --output-file test_bitcoin.info + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} +) +execute_process( + COMMAND ${LCOV_COMMAND} --zerocounters --directory src + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} +) +execute_process( + COMMAND ${LCOV_FILTER_COMMAND} test_bitcoin.info test_bitcoin_filtered.info + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} +) +execute_process( + COMMAND ${LCOV_COMMAND} --add-tracefile test_bitcoin_filtered.info --output-file test_bitcoin_filtered.info + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} +) +execute_process( + COMMAND ${LCOV_COMMAND} --add-tracefile baseline_filtered.info --add-tracefile test_bitcoin_filtered.info --output-file test_bitcoin_coverage.info + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} +) +execute_process( + COMMAND ${GENHTML_COMMAND} test_bitcoin_coverage.info --output-directory test_bitcoin.coverage + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} +) + +execute_process( + COMMAND ${functional_test_runner} + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + COMMAND_ERROR_IS_FATAL ANY +) +execute_process( + COMMAND ${LCOV_COMMAND} --capture --directory src --test-name functional-tests --output-file functional_test.info + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} +) +execute_process( + COMMAND ${LCOV_COMMAND} --zerocounters --directory src + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} +) +execute_process( + COMMAND ${LCOV_FILTER_COMMAND} functional_test.info functional_test_filtered.info + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} +) +execute_process( + COMMAND ${LCOV_COMMAND} --add-tracefile functional_test_filtered.info --output-file functional_test_filtered.info + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} +) +execute_process( + COMMAND ${LCOV_COMMAND} --add-tracefile baseline_filtered.info --add-tracefile test_bitcoin_filtered.info --add-tracefile functional_test_filtered.info --output-file total_coverage.info + COMMAND ${GREP_EXECUTABLE} "%" + COMMAND ${AWK_EXECUTABLE} "{ print substr($3,2,50) \"/\" $5 }" + OUTPUT_FILE coverage_percent.txt + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} +) +execute_process( + COMMAND ${GENHTML_COMMAND} total_coverage.info --output-directory total.coverage + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} +) diff --git a/cmake/script/CoverageFuzz.cmake b/cmake/script/CoverageFuzz.cmake new file mode 100644 index 000000000000..2626ea0cb5de --- /dev/null +++ b/cmake/script/CoverageFuzz.cmake @@ -0,0 +1,42 @@ +# Copyright (c) 2024-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +include(${CMAKE_CURRENT_LIST_DIR}/CoverageInclude.cmake) + +if(NOT DEFINED FUZZ_SEED_CORPUS_DIR) + set(FUZZ_SEED_CORPUS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/qa-assets/fuzz_seed_corpus) +endif() + +execute_process( + COMMAND test/fuzz/test_runner.py ${FUZZ_SEED_CORPUS_DIR} --loglevel DEBUG + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + COMMAND_ERROR_IS_FATAL ANY +) +execute_process( + COMMAND ${LCOV_COMMAND} --capture --directory src --test-name fuzz-tests --output-file fuzz.info + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} +) +execute_process( + COMMAND ${LCOV_COMMAND} --zerocounters --directory src + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} +) +execute_process( + COMMAND ${LCOV_FILTER_COMMAND} fuzz.info fuzz_filtered.info + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} +) +execute_process( + COMMAND ${LCOV_COMMAND} --add-tracefile fuzz_filtered.info --output-file fuzz_filtered.info + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} +) +execute_process( + COMMAND ${LCOV_COMMAND} --add-tracefile baseline_filtered.info --add-tracefile fuzz_filtered.info --output-file fuzz_coverage.info + COMMAND ${GREP_EXECUTABLE} "%" + COMMAND ${AWK_EXECUTABLE} "{ print substr($3,2,50) \"/\" $5 }" + OUTPUT_FILE coverage_percent.txt + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} +) +execute_process( + COMMAND ${GENHTML_COMMAND} fuzz_coverage.info --output-directory fuzz.coverage + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} +) diff --git a/cmake/script/CoverageInclude.cmake.in b/cmake/script/CoverageInclude.cmake.in new file mode 100644 index 000000000000..7a8bf2f0af2d --- /dev/null +++ b/cmake/script/CoverageInclude.cmake.in @@ -0,0 +1,56 @@ +# Copyright (c) 2024-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +if("@CMAKE_CXX_COMPILER_ID@" STREQUAL "Clang") + find_program(LLVM_COV_EXECUTABLE llvm-cov REQUIRED) + set(COV_TOOL "${LLVM_COV_EXECUTABLE} gcov") +else() + find_program(GCOV_EXECUTABLE gcov REQUIRED) + set(COV_TOOL "${GCOV_EXECUTABLE}") +endif() + +# COV_TOOL is used to replace a placeholder. +configure_file( + cmake/cov_tool_wrapper.sh.in ${CMAKE_CURRENT_LIST_DIR}/cov_tool_wrapper.sh + FILE_PERMISSIONS OWNER_READ OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE + WORLD_READ + @ONLY +) + +find_program(LCOV_EXECUTABLE lcov REQUIRED) +separate_arguments(LCOV_OPTS) +set(LCOV_COMMAND ${LCOV_EXECUTABLE} --gcov-tool ${CMAKE_CURRENT_LIST_DIR}/cov_tool_wrapper.sh ${LCOV_OPTS}) + +find_program(GENHTML_EXECUTABLE genhtml REQUIRED) +set(GENHTML_COMMAND ${GENHTML_EXECUTABLE} --show-details ${LCOV_OPTS}) + +find_program(GREP_EXECUTABLE grep REQUIRED) +find_program(AWK_EXECUTABLE awk REQUIRED) + +set(LCOV_FILTER_COMMAND ./filter-lcov.py) +list(APPEND LCOV_FILTER_COMMAND -p "/usr/local/") +list(APPEND LCOV_FILTER_COMMAND -p "/usr/include/") +list(APPEND LCOV_FILTER_COMMAND -p "/usr/lib/") +list(APPEND LCOV_FILTER_COMMAND -p "/usr/lib64/") +list(APPEND LCOV_FILTER_COMMAND -p "src/leveldb/") +list(APPEND LCOV_FILTER_COMMAND -p "src/crc32c/") +list(APPEND LCOV_FILTER_COMMAND -p "src/bench/") +list(APPEND LCOV_FILTER_COMMAND -p "src/crypto/ctaes") +list(APPEND LCOV_FILTER_COMMAND -p "src/minisketch") +list(APPEND LCOV_FILTER_COMMAND -p "src/secp256k1") +list(APPEND LCOV_FILTER_COMMAND -p "depends") + +execute_process( + COMMAND ${LCOV_COMMAND} --capture --initial --directory src --output-file baseline.info + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} +) +execute_process( + COMMAND ${LCOV_FILTER_COMMAND} baseline.info baseline_filtered.info + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} +) +execute_process( + COMMAND ${LCOV_COMMAND} --add-tracefile baseline_filtered.info --output-file baseline_filtered.info + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} +) diff --git a/cmake/script/GenerateBuildInfo.cmake b/cmake/script/GenerateBuildInfo.cmake new file mode 100644 index 000000000000..486ce750e1d2 --- /dev/null +++ b/cmake/script/GenerateBuildInfo.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/. + +# 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() + +# NOTE: Unlike upstream, clientversion.cpp only knows about +# BUILD_GIT_DESCRIPTION, so this emits the same `git describe` string +# that share/genbuild.sh produces. Otherwise every non-release build +# reports its version as "vX.Y.Z-unk". +set(GIT_DESCRIPTION) +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=12 --dirty + WORKING_DIRECTORY ${WORKING_DIR} + OUTPUT_VARIABLE GIT_DESCRIPTION + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + endif() + endif() +endif() + +if(GIT_DESCRIPTION) + set(NEWINFO "#define BUILD_GIT_DESCRIPTION \"${GIT_DESCRIPTION}\"") +else() + set(NEWINFO "// No build information available") +endif() + +# Only update the header if necessary. +if(NOT "${INFO}" STREQUAL "${NEWINFO}") + file(WRITE ${BUILD_INFO_HEADER_PATH} "${NEWINFO}\n") +endif() diff --git a/cmake/script/GenerateHeaderFromJson.cmake b/cmake/script/GenerateHeaderFromJson.cmake new file mode 100644 index 000000000000..0c2f2f39cb4b --- /dev/null +++ b/cmake/script/GenerateHeaderFromJson.cmake @@ -0,0 +1,23 @@ +# 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/. + +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 const unsigned 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 000000000000..18c5b4bef25d --- /dev/null +++ b/cmake/script/GenerateHeaderFromRaw.cmake @@ -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/. + +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/script/macos_zip.sh b/cmake/script/macos_zip.sh new file mode 100755 index 000000000000..cc51699dc938 --- /dev/null +++ b/cmake/script/macos_zip.sh @@ -0,0 +1,12 @@ +#!/bin/sh +# Copyright (c) 2024-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +export LC_ALL=C + +if [ -n "$SOURCE_DATE_EPOCH" ]; then + find . -exec touch -d "@$SOURCE_DATE_EPOCH" {} + +fi + +find . | sort | "$1" -X@ "$2" diff --git a/cmake/tests.cmake b/cmake/tests.cmake new file mode 100644 index 000000000000..279132980017 --- /dev/null +++ b/cmake/tests.cmake @@ -0,0 +1,15 @@ +# 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/. + +if(TARGET bitcoin-util AND TARGET bitcoin-tx AND PYTHON_COMMAND) + add_test(NAME util_test_runner + COMMAND ${CMAKE_COMMAND} -E env BITCOINUTIL=$ BITCOINTX=$ ${PYTHON_COMMAND} ${PROJECT_BINARY_DIR}/test/util/test_runner.py + ) +endif() + +if(PYTHON_COMMAND) + add_test(NAME util_rpcauth_test + COMMAND ${PYTHON_COMMAND} ${PROJECT_BINARY_DIR}/test/util/rpcauth-test.py + ) +endif() diff --git a/contrib/guix/README.md b/contrib/guix/README.md index cb7eb134a2e6..a16446ac3f54 100644 --- a/contrib/guix/README.md +++ b/contrib/guix/README.md @@ -261,6 +261,7 @@ details. - `guix` build commands as in `guix shell --cores="$JOBS"` - `make` as in `make --jobs="$JOBS"` + - `cmake` as in `cmake --build build -j "$JOBS"` - `xargs` as in `xargs -P"$JOBS"` See [here](#controlling-the-number-of-threads-used-by-guix-build-commands) for diff --git a/depends/Makefile b/depends/Makefile index c8510f4cc010..b7fe0fbd7dbd 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -196,6 +196,7 @@ meta_depends = Makefile config.guess config.sub funcs.mk builders/default.mk hos 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) @@ -263,6 +264,52 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_ $< > $@ touch $@ +ifeq ($(host),$(build)) + crosscompiling=FALSE +else + crosscompiling=TRUE +endif + +$(host_prefix)/toolchain.cmake : toolchain.cmake.in $(host_prefix)/.stamp_$(final_build_id) + @mkdir -p $(@D) + sed -e 's|@depends_crosscompiling@|$(crosscompiling)|' \ + -e 's|@host_system_name@|$($(host_os)_cmake_system_name)|' \ + -e 's|@host_system_version@|$($(host_os)_cmake_system_version)|' \ + -e 's|@host_arch@|$(host_arch)|' \ + -e 's|@CC@|$(host_CC)|' \ + -e 's|@CXX@|$(host_CXX)|' \ + -e 's|@OSX_SDK@|$(OSX_SDK)|' \ + -e 's|@AR@|$(host_AR)|' \ + -e 's|@RANLIB@|$(host_RANLIB)|' \ + -e 's|@STRIP@|$(host_STRIP)|' \ + -e 's|@OBJCOPY@|$(host_OBJCOPY)|' \ + -e 's|@OBJDUMP@|$(host_OBJDUMP)|' \ + -e 's|@depends_prefix@|$(host_prefix)|' \ + -e 's|@CFLAGS@|$(strip $(host_CFLAGS))|' \ + -e 's|@CFLAGS_RELEASE@|$(strip $(host_release_CFLAGS))|' \ + -e 's|@CFLAGS_DEBUG@|$(strip $(host_debug_CFLAGS))|' \ + -e 's|@CXXFLAGS@|$(strip $(host_CXXFLAGS))|' \ + -e 's|@CXXFLAGS_RELEASE@|$(strip $(host_release_CXXFLAGS))|' \ + -e 's|@CXXFLAGS_DEBUG@|$(strip $(host_debug_CXXFLAGS))|' \ + -e 's|@CPPFLAGS@|$(strip $(host_CPPFLAGS))|' \ + -e 's|@CPPFLAGS_RELEASE@|$(strip $(host_release_CPPFLAGS))|' \ + -e 's|@CPPFLAGS_DEBUG@|$(strip $(host_debug_CPPFLAGS))|' \ + -e 's|@LDFLAGS@|$(strip $(host_LDFLAGS))|' \ + -e 's|@LDFLAGS_RELEASE@|$(strip $(host_release_LDFLAGS))|' \ + -e 's|@LDFLAGS_DEBUG@|$(strip $(host_debug_LDFLAGS))|' \ + -e 's|@qt_packages@|$(qt_packages_)|' \ + -e 's|@qrencode_packages@|$(qrencode_packages_)|' \ + -e 's|@zmq_packages@|$(zmq_packages_)|' \ + -e 's|@wallet_packages@|$(wallet_packages_)|' \ + -e 's|@bdb_packages@|$(bdb_packages_)|' \ + -e 's|@sqlite_packages@|$(sqlite_packages_)|' \ + -e 's|@upnp_packages@|$(upnp_packages_)|' \ + -e 's|@natpmp_packages@|$(natpmp_packages_)|' \ + -e 's|@usdt_packages@|$(usdt_packages_)|' \ + -e 's|@no_harden@|$(NO_HARDEN)|' \ + -e 's|@multiprocess@|$(MULTIPROCESS)|' \ + $< > $@ + touch $@ define check_or_remove_cached mkdir -p $(BASE_CACHE)/$(host)/$(package) && cd $(BASE_CACHE)/$(host)/$(package); \ @@ -284,6 +331,7 @@ check-sources: @$(foreach package,$(all_packages),$(call check_or_remove_sources,$(package));) $(host_prefix)/share/config.site: check-packages +$(host_prefix)/toolchain.cmake: check-packages check-packages: check-sources @@ -293,7 +341,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)/toolchain.cmake download-one: check-sources $(all_sources) diff --git a/depends/funcs.mk b/depends/funcs.mk index 566f83a9868e..8da899f173e9 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -172,7 +172,7 @@ $(1)_autoconf += LDFLAGS="$$($(1)_ldflags)" endif # We hardcode the library install path to "lib" to match the PKG_CONFIG_PATH -# setting in depends/config.site.in, which also hardcodes "lib". +# setting in depends/toolchain.cmake.in, which also hardcodes "lib". # Without this setting, CMake by default would use the OS library # directory, which might be "lib64" or something else, not "lib", on multiarch systems. $(1)_cmake=env CC="$$($(1)_cc)" \ diff --git a/depends/hosts/default.mk b/depends/hosts/default.mk index 54c12c818024..b0f907f13db0 100644 --- a/depends/hosts/default.mk +++ b/depends/hosts/default.mk @@ -28,8 +28,8 @@ endef define add_host_flags_func ifeq ($(filter $(origin $1),undefined default),) -$(host_arch)_$(host_os)_$1 = -$(host_arch)_$(host_os)_$(release_type)_$1 = $($1) +$(host_arch)_$(host_os)_$1 = $($1) +$(host_arch)_$(host_os)_$(release_type)_$1 = else $(host_arch)_$(host_os)_$1 += $($(host_os)_$1) $(host_arch)_$(host_os)_$(release_type)_$1 += $($(host_os)_$(release_type)_$1) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 18aedcf7afcf..ca6ddc0803c8 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -286,13 +286,14 @@ define $(package)_build_cmds $(MAKE) endef +# TODO: Investigate whether specific targets can be used here to minimize the amount of files/components installed. define $(package)_stage_cmds - $(MAKE) -C qtbase/src INSTALL_ROOT=$($(package)_staging_dir) $(addsuffix -install_subtargets,$(addprefix sub-,$($(package)_qt_libs))) && \ - $(MAKE) -C qttools/src/linguist INSTALL_ROOT=$($(package)_staging_dir) $(addsuffix -install_subtargets,$(addprefix sub-,$($(package)_linguist_tools))) && \ + $(MAKE) -C qtbase INSTALL_ROOT=$($(package)_staging_dir) install && \ + $(MAKE) -C qttools INSTALL_ROOT=$($(package)_staging_dir) install && \ $(MAKE) -C qttranslations INSTALL_ROOT=$($(package)_staging_dir) install_subtargets endef define $(package)_postprocess_cmds - rm -rf native/mkspecs/ native/lib/ lib/cmake/ && \ + rm -rf doc/ native/lib/ && \ rm -f lib/lib*.la endef diff --git a/depends/patches/qt/qt.pro b/depends/patches/qt/qt.pro index 8f2e900a840f..6d8b7fdb6a2c 100644 --- a/depends/patches/qt/qt.pro +++ b/depends/patches/qt/qt.pro @@ -3,10 +3,6 @@ cache(, super) !QTDIR_build: cache(CONFIG, add, $$list(QTDIR_build)) -prl = no_install_prl -CONFIG += $$prl -cache(CONFIG, add stash, prl) - TEMPLATE = subdirs SUBDIRS = qtbase qttools qttranslations diff --git a/depends/toolchain.cmake.in b/depends/toolchain.cmake.in new file mode 100644 index 000000000000..c733c81edf77 --- /dev/null +++ b/depends/toolchain.cmake.in @@ -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/. + +# This file is expected to be highly volatile and may still change substantially. + +# If CMAKE_SYSTEM_NAME is set within a toolchain file, CMake will also +# set CMAKE_CROSSCOMPILING to TRUE, even if CMAKE_SYSTEM_NAME matches +# CMAKE_HOST_SYSTEM_NAME. To avoid potential misconfiguration of CMake, +# it is best not to touch CMAKE_SYSTEM_NAME unless cross-compiling is +# intended. +if(@depends_crosscompiling@) + set(CMAKE_SYSTEM_NAME @host_system_name@) + set(CMAKE_SYSTEM_VERSION @host_system_version@) + set(CMAKE_SYSTEM_PROCESSOR @host_arch@) +endif() + +if(NOT DEFINED CMAKE_C_FLAGS_INIT) + set(CMAKE_C_FLAGS_INIT "@CFLAGS@") +endif() +if(NOT DEFINED CMAKE_C_FLAGS_RELWITHDEBINFO_INIT) + set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "@CFLAGS_RELEASE@") +endif() +if(NOT DEFINED CMAKE_C_FLAGS_DEBUG_INIT) + set(CMAKE_C_FLAGS_DEBUG_INIT "@CFLAGS_DEBUG@") +endif() + +if(NOT DEFINED CMAKE_C_COMPILER) + set(CMAKE_C_COMPILER @CC@) +endif() + +if(NOT DEFINED CMAKE_CXX_FLAGS_INIT) + set(CMAKE_CXX_FLAGS_INIT "@CXXFLAGS@") + set(CMAKE_OBJCXX_FLAGS_INIT "@CXXFLAGS@") +endif() +if(NOT DEFINED CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT) + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "@CXXFLAGS_RELEASE@") + set(CMAKE_OBJCXX_FLAGS_RELWITHDEBINFO_INIT "@CXXFLAGS_RELEASE@") +endif() +if(NOT DEFINED CMAKE_CXX_FLAGS_DEBUG_INIT) + set(CMAKE_CXX_FLAGS_DEBUG_INIT "@CXXFLAGS_DEBUG@") + set(CMAKE_OBJCXX_FLAGS_DEBUG_INIT "@CXXFLAGS_DEBUG@") +endif() + +if(NOT DEFINED CMAKE_CXX_COMPILER) + set(CMAKE_CXX_COMPILER @CXX@) + set(CMAKE_OBJCXX_COMPILER ${CMAKE_CXX_COMPILER}) +endif() + +# The DEPENDS_COMPILE_DEFINITIONS* variables are to be treated as lists. +set(DEPENDS_COMPILE_DEFINITIONS @CPPFLAGS@) +set(DEPENDS_COMPILE_DEFINITIONS_RELWITHDEBINFO @CPPFLAGS_RELEASE@) +set(DEPENDS_COMPILE_DEFINITIONS_DEBUG @CPPFLAGS_DEBUG@) + +if(NOT DEFINED CMAKE_EXE_LINKER_FLAGS_INIT) + set(CMAKE_EXE_LINKER_FLAGS_INIT "@LDFLAGS@") +endif() +if(NOT DEFINED CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT) + set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT "@LDFLAGS_RELEASE@") +endif() +if(NOT DEFINED CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT) + set(CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT "@LDFLAGS_DEBUG@") +endif() + +set(CMAKE_AR "@AR@") +set(CMAKE_RANLIB "@RANLIB@") +set(CMAKE_STRIP "@STRIP@") +set(CMAKE_OBJCOPY "@OBJCOPY@") +set(CMAKE_OBJDUMP "@OBJDUMP@") + +# Using our own built dependencies should not be +# affected by a potentially random environment. +set(CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH OFF) + +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(QT_TRANSLATIONS_DIR "@depends_prefix@/translations") + +if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT CMAKE_HOST_APPLE) + # The find_package(Qt ...) function internally uses find_library() + # calls for all dependencies to ensure their availability. + # In turn, the find_library() inspects the well-known locations + # on the file system; therefore, a hint is required. + set(CMAKE_FRAMEWORK_PATH "@OSX_SDK@/System/Library/Frameworks") +endif() + + +# Customize pkg-config behaviour. +cmake_path(APPEND CMAKE_FIND_ROOT_PATH "lib" "pkgconfig" OUTPUT_VARIABLE pkg_config_path) +set(ENV{PKG_CONFIG_PATH} ${pkg_config_path}) +set(ENV{PKG_CONFIG_LIBDIR} ${pkg_config_path}) +unset(pkg_config_path) +set(PKG_CONFIG_ARGN --static) + + +# Set configuration options for the main build system. +set(qt_packages @qt_packages@) +if("${qt_packages}" STREQUAL "") + set(BUILD_GUI OFF CACHE BOOL "") +else() + set(BUILD_GUI ON CACHE BOOL "") +endif() + +set(qrencode_packages @qrencode_packages@) +if("${qrencode_packages}" STREQUAL "") + set(WITH_QRENCODE OFF CACHE BOOL "") +else() + set(WITH_QRENCODE ON CACHE BOOL "") +endif() + +set(zmq_packages @zmq_packages@) +if("${zmq_packages}" STREQUAL "") + set(WITH_ZMQ OFF CACHE BOOL "") +else() + set(WITH_ZMQ ON CACHE BOOL "") +endif() + +set(wallet_packages @wallet_packages@) +if("${wallet_packages}" STREQUAL "") + set(ENABLE_WALLET OFF CACHE BOOL "") +else() + set(ENABLE_WALLET ON CACHE BOOL "") +endif() + +set(bdb_packages @bdb_packages@) +if("${wallet_packages}" STREQUAL "" OR "${bdb_packages}" STREQUAL "") + set(WITH_BDB OFF CACHE BOOL "") +else() + set(WITH_BDB ON CACHE BOOL "") +endif() + +set(sqlite_packages @sqlite_packages@) +if("${wallet_packages}" STREQUAL "" OR "${sqlite_packages}" STREQUAL "") + set(WITH_SQLITE OFF CACHE BOOL "") +else() + set(WITH_SQLITE ON CACHE BOOL "") +endif() + +set(upnp_packages @upnp_packages@) +if("${upnp_packages}" STREQUAL "") + set(WITH_MINIUPNPC OFF CACHE BOOL "") +else() + set(WITH_MINIUPNPC ON CACHE BOOL "") +endif() + +set(natpmp_packages @natpmp_packages@) +if("${natpmp_packages}" STREQUAL "") + set(WITH_NATPMP OFF CACHE BOOL "") +else() + set(WITH_NATPMP ON CACHE BOOL "") +endif() + +set(usdt_packages @usdt_packages@) +if("${usdt_packages}" STREQUAL "") + set(WITH_USDT OFF CACHE BOOL "") +else() + set(WITH_USDT ON CACHE BOOL "") +endif() + +if("@no_harden@") + set(ENABLE_HARDENING OFF CACHE BOOL "") +else() + set(ENABLE_HARDENING ON CACHE BOOL "") +endif() + +if("@multiprocess@" STREQUAL "1") + set(WITH_MULTIPROCESS ON CACHE BOOL "") + set(LibmultiprocessNative_DIR "${CMAKE_FIND_ROOT_PATH}/native/lib/cmake/Libmultiprocess" CACHE PATH "") +else() + set(WITH_MULTIPROCESS OFF CACHE BOOL "") +endif() diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt new file mode 100644 index 000000000000..61a7653e4aa5 --- /dev/null +++ b/doc/CMakeLists.txt @@ -0,0 +1,25 @@ +# Copyright (c) 2024-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +find_package(Doxygen COMPONENTS dot) + +if(DOXYGEN_FOUND) + set(doxyfile ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) + configure_file(Doxyfile.in ${doxyfile}) + + # In CMake 3.27, The FindDoxygen module's doxygen_add_docs() + # command gained a CONFIG_FILE option to specify a custom doxygen + # configuration file. + # TODO: Consider using it. + add_custom_target(docs + COMMAND Doxygen::doxygen ${doxyfile} + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + COMMENT "Generating developer documentation" + VERBATIM USES_TERMINAL + ) +else() + add_custom_target(docs + COMMAND ${CMAKE_COMMAND} -E echo "Error: Doxygen not found" + ) +endif() diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index 611e4941a07e..654c61f91fbf 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -61,7 +61,7 @@ PROJECT_LOGO = doc/bitcoin_logo_doxygen.png # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. -OUTPUT_DIRECTORY = doc/doxygen +OUTPUT_DIRECTORY = @PROJECT_BINARY_DIR@/doc/doxygen # If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and diff --git a/doc/build-windows-msvc.md b/doc/build-windows-msvc.md new file mode 100644 index 000000000000..cbe6df3f49aa --- /dev/null +++ b/doc/build-windows-msvc.md @@ -0,0 +1,91 @@ +# Windows / MSVC Build Guide + +This guide describes how to build dashd, command-line utilities, and GUI on Windows using Microsoft Visual Studio. + +For cross-compiling options, please see [`build-windows.md`](./build-windows.md). + +## Preparation + +### 1. Visual Studio + +This guide relies on using CMake and vcpkg package manager provided with the Visual Studio installation. +Here are requirements for the Visual Studio installation: +1. Minimum required version: Visual Studio 2022 version 17.6. +2. Installed components: +- The "Desktop development with C++" workload. + +The commands in this guide should be executed in "Developer PowerShell for VS 2022" or "Developer Command Prompt for VS 2022". +The former is assumed hereinafter. + +### 2. Git + +Download and install [Git for Windows](https://git-scm.com/download/win). Once installed, Git is available from PowerShell or the Command Prompt. + +### 3. Clone Dash Repository + +Clone the Dash Core repository to a directory. All build scripts and commands will run from this directory. +``` +git clone https://github.com/dashpay/dash.git +cd dash +``` + + +### 4. vcpkg + +The presets below reference `$env{VCPKG_ROOT}`. Set it to the vcpkg instance +shipped with Visual Studio, or to your own clone, before configuring: +``` +$env:VCPKG_ROOT = "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\vcpkg" +``` + +## Triplets and Presets + +The Dash Core project supports the following vcpkg triplets: +- `x64-windows` (both CRT and library linkage is dynamic) +- `x64-windows-static` (both CRT and library linkage is static) + +To facilitate build process, the Dash Core project provides presets, which are used in this guide. + +Available presets can be listed as follows: +``` +cmake --list-presets +``` + +## Building + +CMake will put the resulting object files, libraries, and executables into a dedicated build directory. + +In the following instructions, the "Debug" configuration can be specified instead of the "Release" one. + +### 5. Building with Dynamic Linking with GUI + +``` +cmake -B build --preset vs2022 -DBUILD_GUI=ON # It might take a while if the vcpkg binary cache is unpopulated or invalidated. +cmake --build build --config Release # Use "-j N" for N parallel jobs. +ctest --test-dir build --build-config Release # Use "-j N" for N parallel tests. Some tests are disabled if Python 3 is not available. +``` + +### 6. Building with Static Linking without GUI + +``` +cmake -B build --preset vs2022-static # It might take a while if the vcpkg binary cache is unpopulated or invalidated. +cmake --build build --config Release # Use "-j N" for N parallel jobs. +ctest --test-dir build --build-config Release # Use "-j N" for N parallel tests. Some tests are disabled if Python 3 is not available. +cmake --install build --config Release # Optional. +``` + +## Performance Notes + +### 7. vcpkg Manifest Default Features + +One can skip vcpkg manifest default features to speedup the configuration step. +For example, the following invocation will skip all features except for "wallet" and "tests" and their dependencies: +``` +cmake -B build --preset vs2022 -DVCPKG_MANIFEST_NO_DEFAULT_FEATURES=ON -DVCPKG_MANIFEST_FEATURES="wallet;tests" -DBUILD_GUI=OFF +``` + +Available features are listed in the [`vcpkg.json`](/vcpkg.json) file. + +### 8. Antivirus Software + +To improve the build process performance, one might add the Dash repository directory to the Microsoft Defender Antivirus exclusions. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 000000000000..ff865088148b --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,576 @@ +# 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(GNUInstallDirs) +include(AddWindowsResources) + +configure_file(${PROJECT_SOURCE_DIR}/cmake/bitcoin-config.h.in config/bitcoin-config.h @ONLY) +include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/immer) + +# TODO: 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 ${CMAKE_COMMAND} -DBUILD_INFO_HEADER_PATH=${PROJECT_BINARY_DIR}/src/obj/build.h -DSOURCE_DIR=${PROJECT_SOURCE_DIR} -P ${PROJECT_SOURCE_DIR}/cmake/script/GenerateBuildInfo.cmake + 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 +) +target_link_libraries(bitcoin_clientversion + PRIVATE + core_interface +) +add_dependencies(bitcoin_clientversion generate_build_info) + +add_subdirectory(crypto) +add_subdirectory(univalue) +add_subdirectory(util) +if(WITH_MULTIPROCESS) + add_subdirectory(ipc) +endif() + +#============================= +# secp256k1 subtree +#============================= +message("") +message("Configuring secp256k1 subtree...") +set(SECP256K1_DISABLE_SHARED ON CACHE BOOL "" FORCE) +set(SECP256K1_ENABLE_MODULE_ECDH OFF CACHE BOOL "" FORCE) +set(SECP256K1_ENABLE_MODULE_RECOVERY ON CACHE BOOL "" FORCE) +set(SECP256K1_BUILD_BENCHMARK OFF CACHE BOOL "" FORCE) +set(SECP256K1_BUILD_TESTS ${BUILD_TESTS} CACHE BOOL "" FORCE) +set(SECP256K1_BUILD_EXHAUSTIVE_TESTS ${BUILD_TESTS} CACHE BOOL "" FORCE) +set(SECP256K1_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) +include(GetTargetInterface) +# -fsanitize and related flags apply to both C++ and C, +# so we can pass them down to libsecp256k1 as CFLAGS. +get_target_interface(core_sanitizer_cxx_flags "" sanitize_interface COMPILE_OPTIONS) +set(SECP256K1_LATE_CFLAGS ${core_sanitizer_cxx_flags} CACHE STRING "" FORCE) +unset(core_sanitizer_cxx_flags) +# We want to build libsecp256k1 with the most tested RelWithDebInfo configuration. +enable_language(C) +foreach(config IN LISTS CMAKE_BUILD_TYPE CMAKE_CONFIGURATION_TYPES) + if(config STREQUAL "") + continue() + endif() + string(TOUPPER "${config}" config) + set(CMAKE_C_FLAGS_${config} "${CMAKE_C_FLAGS_RELWITHDEBINFO}") +endforeach() +# If the CFLAGS environment variable is defined during building depends +# and configuring this build system, its content might be duplicated. +if(DEFINED ENV{CFLAGS}) + deduplicate_flags(CMAKE_C_FLAGS) +endif() +set(CMAKE_EXPORT_COMPILE_COMMANDS OFF) +add_subdirectory(secp256k1) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +string(APPEND CMAKE_C_COMPILE_OBJECT " ${APPEND_CPPFLAGS} ${APPEND_CFLAGS}") + +set(BUILD_BLS_JS_BINDINGS OFF CACHE STRING "" FORCE) +set(BUILD_BLS_PYTHON_BINDINGS OFF CACHE STRING "" FORCE) +set(BUILD_BLS_TESTS OFF CACHE STRING "" FORCE) +set(BUILD_BLS_BENCHMARKS OFF CACHE STRING "" FORCE) +add_subdirectory(dashbls EXCLUDE_FROM_ALL) +# The dashbls and relic headers are noisy (mostly -Wdocumentation). Autotools +# pulls them in with -isystem; do the same here so that they do not drown out +# our own warnings, or fail the build outright when WERROR is set. +get_target_property(dashbls_include_dirs dashbls INTERFACE_INCLUDE_DIRECTORIES) +set_target_properties(dashbls PROPERTIES + INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${dashbls_include_dirs}" +) +unset(dashbls_include_dirs) + +# Stable, backwards-compatible consensus functionality. +set(consensus_sources + arith_uint256.cpp + bls/bls.cpp + consensus/merkle.cpp + consensus/tx_check.cpp + hash.cpp + primitives/block.cpp + primitives/transaction.cpp + pubkey.cpp + script/bitcoinconsensus.cpp + script/interpreter.cpp + script/script.cpp + script/script_error.cpp + uint256.cpp + util/strencodings.cpp + util/string.cpp +) +# Internal-only; the installable library below is the public dashconsensus. +add_library(bitcoin_consensus STATIC EXCLUDE_FROM_ALL ${consensus_sources}) +target_link_libraries(bitcoin_consensus + PRIVATE + core_interface + bitcoin_crypto + Boost::headers + dashbls + secp256k1 +) + +# Dash still ships the public consensus library that upstream dropped in +# bitcoin#29648, so build and install it here too. It gets its own compilation +# of the consensus and crypto sources because the public library is built +# without the optimised SHA-256 backends; see libdashconsensus_la in +# src/Makefile.am. This has to stay below add_subdirectory(crypto), which is +# what sets crypto_base_sources and crypto_sph_sources in this scope. +if(BUILD_CONSENSUS_LIB) + add_library(dashconsensus SHARED + ${consensus_sources} + ${crypto_base_sources} + ${crypto_sph_sources} + ) + target_compile_definitions(dashconsensus + PRIVATE + BUILD_BITCOIN_INTERNAL + DISABLE_OPTIMIZED_SHA256 + SPH_SMALL_FOOTPRINT_CUBEHASH=1 + SPH_SMALL_FOOTPRINT_JH=1 + ) + target_link_libraries(dashconsensus + PRIVATE + core_interface + Boost::headers + dashbls + secp256k1 + ) + install(TARGETS dashconsensus + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) + install(FILES script/bitcoinconsensus.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/script + ) + set(prefix ${CMAKE_INSTALL_PREFIX}) + set(exec_prefix "\${prefix}") + set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}") + set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") + configure_file(${PROJECT_SOURCE_DIR}/libdashconsensus.pc.in + ${PROJECT_BINARY_DIR}/libdashconsensus.pc @ONLY + ) + install(FILES ${PROJECT_BINARY_DIR}/libdashconsensus.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig + ) +endif() + +if(WITH_ZMQ) + add_subdirectory(zmq) +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 + chainparamsbase.cpp + coins.cpp + common/bloom.cpp + common/run_command.cpp + common/url.cpp + compressor.cpp + core_read.cpp + core_write.cpp + deploymentinfo.cpp + evo/core_write.cpp + evo/netinfo.cpp + evo/providertx_util.cpp + external_signer.cpp + governance/common.cpp + governance/core_write.cpp + init/common.cpp + key.cpp + key_io.cpp + llmq/core_write.cpp + merkleblock.cpp + net_permissions.cpp + net_types.cpp + netaddress.cpp + netbase.cpp + outputtype.cpp + policy/feerate.cpp + policy/policy.cpp + protocol.cpp + psbt.cpp + rpc/external_signer.cpp + rpc/rawtransaction_util.cpp + rpc/request.cpp + rpc/util.cpp + saltedhasher.cpp + scheduler.cpp + script/descriptor.cpp + script/miniscript.cpp + script/sign.cpp + script/signingprovider.cpp + script/standard.cpp + warnings.cpp +) +target_link_libraries(bitcoin_common + PRIVATE + core_interface + bitcoin_consensus + bitcoin_util + leveldb + univalue + dashbls + secp256k1 + Boost::headers + $ + $ + $<$:ws2_32> +) + + +set(installable_targets) +if(ENABLE_WALLET) + add_subdirectory(wallet) + + if(BUILD_WALLET_TOOL) + add_executable(bitcoin-wallet + bitcoin-wallet.cpp + init/bitcoin-wallet.cpp + wallet/wallettool.cpp + ) + add_windows_resources(bitcoin-wallet dash-wallet-res.rc) + target_link_libraries(bitcoin-wallet + core_interface + bitcoin_wallet + bitcoin_common + bitcoin_util + univalue + Boost::headers + ) + set_target_properties(bitcoin-wallet PROPERTIES OUTPUT_NAME dash-wallet) + list(APPEND installable_targets bitcoin-wallet) + endif() +endif() + + +# P2P and RPC server functionality used by `bitcoind` and `bitcoin-qt` executables. +add_library(bitcoin_node STATIC EXCLUDE_FROM_ALL + active/context.cpp + active/dkgsession.cpp + active/dkgsessionhandler.cpp + active/masternode.cpp + addrdb.cpp + addrman.cpp + banman.cpp + batchedlogger.cpp + bip324.cpp + blockencodings.cpp + blockfilter.cpp + chainlock/chainlock.cpp + chainlock/clsig.cpp + chainlock/handler.cpp + chainlock/signing.cpp + coinjoin/coinjoin.cpp + coinjoin/server.cpp + coinjoin/walletman.cpp + chain.cpp + consensus/tx_verify.cpp + dbwrapper.cpp + deploymentstatus.cpp + dsnotificationinterface.cpp + evo/assetlocktx.cpp + evo/cbtx.cpp + evo/creditpool.cpp + evo/chainhelper.cpp + evo/deterministicmns.cpp + evo/dmnstate.cpp + evo/evodb.cpp + evo/mnauth.cpp + evo/mnhftx.cpp + evo/providertx.cpp + evo/simplifiedmns.cpp + evo/smldiff.cpp + evo/specialtx.cpp + evo/specialtx_filter.cpp + evo/specialtxman.cpp + flatfile.cpp + governance/governance.cpp + governance/net_governance.cpp + governance/object.cpp + governance/signing.cpp + governance/superblock.cpp + governance/vote.cpp + governance/votedb.cpp + gsl/assert.cpp + httprpc.cpp + httpserver.cpp + i2p.cpp + index/addressindex.cpp + index/addressindex_util.cpp + index/base.cpp + index/blockfilterindex.cpp + index/coinstatsindex.cpp + index/spentindex.cpp + index/timestampindex.cpp + index/txindex.cpp + init.cpp + kernel/coinstats.cpp + instantsend/db.cpp + instantsend/instantsend.cpp + instantsend/lock.cpp + instantsend/net_instantsend.cpp + instantsend/signing.cpp + llmq/blockprocessor.cpp + llmq/commitment.cpp + llmq/context.cpp + llmq/debug.cpp + llmq/dkgsession.cpp + llmq/dkgsessionhandler.cpp + llmq/dkgsessionmgr.cpp + llmq/ehf_signals.cpp + llmq/net_dkg.cpp + llmq/net_quorum.cpp + llmq/net_signing.cpp + llmq/observer.cpp + llmq/options.cpp + llmq/quorums.cpp + llmq/quorumsman.cpp + llmq/signhash.cpp + llmq/signing.cpp + llmq/signing_shares.cpp + llmq/snapshot.cpp + llmq/utils.cpp + mapport.cpp + masternode/meta.cpp + masternode/payments.cpp + masternode/sync.cpp + masternode/utils.cpp + net.cpp + netfulfilledman.cpp + net_processing.cpp + netgroup.cpp + node/blockstorage.cpp + node/caches.cpp + node/chainstate.cpp + node/coin.cpp + node/connection_types.cpp + node/context.cpp + node/eviction.cpp + node/interface_ui.cpp + node/interfaces.cpp + node/miner.cpp + node/minisketchwrapper.cpp + node/psbt.cpp + node/sync_manager.cpp + node/transaction.cpp + node/txreconciliation.cpp + noui.cpp + policy/fees.cpp + policy/packages.cpp + policy/settings.cpp + pow.cpp + rest.cpp + rpc/blockchain.cpp + rpc/coinjoin.cpp + rpc/evo.cpp + rpc/evo_util.cpp + rpc/fees.cpp + rpc/governance.cpp + rpc/masternode.cpp + rpc/mempool.cpp + rpc/mining.cpp + rpc/net.cpp + rpc/node.cpp + rpc/output_script.cpp + rpc/quorums.cpp + rpc/rawtransaction.cpp + rpc/server.cpp + rpc/server_util.cpp + rpc/signmessage.cpp + rpc/txoutproof.cpp + script/sigcache.cpp + shutdown.cpp + spork.cpp + stats/client.cpp + stats/rawsender.cpp + timedata.cpp + torcontrol.cpp + txdb.cpp + txmempool.cpp + txorphanage.cpp + validation.cpp + validationinterface.cpp + versionbits.cpp + $<$:wallet/init.cpp> + $<$>:dummywallet.cpp> +) +target_link_libraries(bitcoin_node + PRIVATE + core_interface + bitcoin_common + bitcoin_util + dashbls + leveldb + minisketch + univalue + Boost::headers + $ + $ + $ + $ + $ + $ +) + + +# Bitcoin Core bitcoind. +if(BUILD_DAEMON) + add_executable(bitcoind + bitcoind.cpp + init/bitcoind.cpp + ) + add_windows_resources(bitcoind dashd-res.rc) + target_link_libraries(bitcoind + core_interface + bitcoin_node + $ + ) + set_target_properties(bitcoind PROPERTIES OUTPUT_NAME dashd) + list(APPEND installable_targets bitcoind) +endif() +if(WITH_MULTIPROCESS) + add_executable(bitcoin-node + bitcoind.cpp + init/bitcoin-node.cpp + ) + target_link_libraries(bitcoin-node + core_interface + bitcoin_node + bitcoin_ipc + $ + ) + set_target_properties(bitcoin-node PROPERTIES OUTPUT_NAME dash-node) + list(APPEND installable_targets bitcoin-node) +endif() + + +add_library(bitcoin_cli STATIC EXCLUDE_FROM_ALL + compat/stdin.cpp + rpc/client.cpp +) +target_link_libraries(bitcoin_cli + PUBLIC + core_interface + univalue +) + + +# Bitcoin Core RPC client +if(BUILD_CLI) + add_executable(bitcoin-cli bitcoin-cli.cpp) + add_windows_resources(bitcoin-cli dash-cli-res.rc) + target_link_libraries(bitcoin-cli + core_interface + bitcoin_cli + bitcoin_common + bitcoin_util + $ + ) + set_target_properties(bitcoin-cli PROPERTIES OUTPUT_NAME dash-cli) + list(APPEND installable_targets bitcoin-cli) +endif() + + +if(BUILD_TX) + add_executable(bitcoin-tx bitcoin-tx.cpp) + add_windows_resources(bitcoin-tx dash-tx-res.rc) + target_link_libraries(bitcoin-tx + core_interface + bitcoin_common + bitcoin_util + univalue + ) + set_target_properties(bitcoin-tx PROPERTIES OUTPUT_NAME dash-tx) + list(APPEND installable_targets bitcoin-tx) +endif() + + +if(BUILD_UTIL) + add_executable(bitcoin-util bitcoin-util.cpp) + add_windows_resources(bitcoin-util bitcoin-util-res.rc) + target_link_libraries(bitcoin-util + core_interface + bitcoin_common + bitcoin_util + ) + set_target_properties(bitcoin-util PROPERTIES OUTPUT_NAME dash-util) + list(APPEND installable_targets bitcoin-util) +endif() + + +if(BUILD_GUI) + add_subdirectory(qt) +endif() + + +if(BUILD_UTIL_CHAINSTATE) + add_executable(bitcoin-chainstate + bitcoin-chainstate.cpp + ) + # TODO: The `SKIP_BUILD_RPATH` property setting can be deleted + # in the future after reordering Guix script commands to + # perform binary checks after the installation step. + # Relevant discussions: + # - https://github.com/hebasto/bitcoin/pull/236#issuecomment-2183120953 + # - https://github.com/bitcoin/bitcoin/pull/30312#issuecomment-2191235833 + set_target_properties(bitcoin-chainstate PROPERTIES + SKIP_BUILD_RPATH OFF + ) + target_link_libraries(bitcoin-chainstate + PRIVATE + core_interface + bitcoin_common + bitcoin_node + bitcoin_util + Boost::headers + dashbls + leveldb + univalue + $ + ) + set_target_properties(bitcoin-chainstate PROPERTIES OUTPUT_NAME dash-chainstate) + list(APPEND installable_targets bitcoin-chainstate) +endif() + + +add_subdirectory(test/util) +if(BUILD_BENCH) + add_subdirectory(bench) +endif() + +if(BUILD_TESTS) + add_subdirectory(test) +endif() + +if(BUILD_FUZZ_BINARY) + add_subdirectory(test/fuzz) +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/Makefile.qt.include b/src/Makefile.qt.include index 16296207eca1..67320fcd8edb 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -424,7 +424,7 @@ BITCOIN_QT_RC = qt/res/dash-qt-res.rc BITCOIN_QT_INCLUDES = -DQT_NO_KEYWORDS -DQT_USE_QSTRINGBUILDER qt_libbitcoinqt_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \ - $(QT_INCLUDES) $(QT_DBUS_INCLUDES) $(QR_CFLAGS) $(BOOST_CPPFLAGS) + $(QT_INCLUDES) $(QT_DBUS_INCLUDES) $(QR_CFLAGS) $(BOOST_CPPFLAGS) $(BDB_CPPFLAGS) qt_libbitcoinqt_a_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS) qt_libbitcoinqt_a_OBJCXXFLAGS = $(AM_OBJCXXFLAGS) $(QT_PIE_FLAGS) diff --git a/src/bench/CMakeLists.txt b/src/bench/CMakeLists.txt new file mode 100644 index 000000000000..fb8154e11671 --- /dev/null +++ b/src/bench/CMakeLists.txt @@ -0,0 +1,81 @@ +# 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/block813851.raw) + +add_executable(bench_bitcoin + bench_bitcoin.cpp + bench.cpp + data.cpp + nanobench.cpp + ${CMAKE_CURRENT_BINARY_DIR}/data/block813851.raw.h +# Benchmarks: + addrman.cpp + base58.cpp + bech32.cpp + bip324_ecdh.cpp + bls.cpp + bls_dkg.cpp + bls_pubkey_agg.cpp + block_assemble.cpp + ccoins_caching.cpp + chacha20.cpp + checkblock.cpp + checkqueue.cpp + crypto_hash.cpp + duplicate_inputs.cpp + ecdsa.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 + pow_hash.cpp + prevector.cpp + rollingbloom.cpp + rpc_blockchain.cpp + rpc_mempool.cpp + strencodings.cpp + string_cast.cpp + util_time.cpp + verify_script.cpp +) +set_target_properties(bench_bitcoin PROPERTIES OUTPUT_NAME bench_dash) + +target_link_libraries(bench_bitcoin + core_interface + test_util + bitcoin_node + Boost::headers + dashbls + leveldb +) + +if(ENABLE_WALLET) + target_sources(bench_bitcoin + PRIVATE + coin_selection.cpp + wallet_balance.cpp + wallet_create.cpp + wallet_loading.cpp + ) + target_link_libraries(bench_bitcoin bitcoin_wallet) +endif() + +add_test(NAME bench_sanity_check_high_priority + COMMAND bench_bitcoin -sanity-check -priority-level=high +) + +install(TARGETS bench_bitcoin + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt new file mode 100644 index 000000000000..471553daed1b --- /dev/null +++ b/src/crypto/CMakeLists.txt @@ -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/. + +set(crypto_base_sources + aes.cpp + chacha20.cpp + chacha20poly1305.cpp + hkdf_sha256_32.cpp + hmac_sha256.cpp + hmac_sha512.cpp + muhash.cpp + pkcs5_pbkdf2_hmac_sha512.cpp + poly1305.cpp + ripemd160.cpp + sha1.cpp + sha256.cpp + sha256_sse4.cpp + sha3.cpp + sha512.cpp + siphash.cpp + ../support/cleanse.cpp +) +add_library(bitcoin_crypto STATIC EXCLUDE_FROM_ALL ${crypto_base_sources}) + +target_link_libraries(bitcoin_crypto + PRIVATE + core_interface +) + +if(HAVE_SSE41) + add_library(bitcoin_crypto_sse41 STATIC EXCLUDE_FROM_ALL + sha256_sse41.cpp + ) + target_compile_definitions(bitcoin_crypto_sse41 PUBLIC ENABLE_SSE41) + target_compile_options(bitcoin_crypto_sse41 PRIVATE ${SSE41_CXXFLAGS}) + target_link_libraries(bitcoin_crypto_sse41 PRIVATE core_interface) + target_link_libraries(bitcoin_crypto PRIVATE bitcoin_crypto_sse41) +endif() + +if(HAVE_AVX2) + add_library(bitcoin_crypto_avx2 STATIC EXCLUDE_FROM_ALL + sha256_avx2.cpp + ) + target_compile_definitions(bitcoin_crypto_avx2 PUBLIC ENABLE_AVX2) + target_compile_options(bitcoin_crypto_avx2 PRIVATE ${AVX2_CXXFLAGS}) + target_link_libraries(bitcoin_crypto_avx2 PRIVATE core_interface) + target_link_libraries(bitcoin_crypto PRIVATE bitcoin_crypto_avx2) +endif() + +if(HAVE_SSE41 AND HAVE_X86_SHANI) + add_library(bitcoin_crypto_x86_shani STATIC EXCLUDE_FROM_ALL + sha256_x86_shani.cpp + ) + target_compile_definitions(bitcoin_crypto_x86_shani PUBLIC ENABLE_SSE41 ENABLE_X86_SHANI) + target_compile_options(bitcoin_crypto_x86_shani PRIVATE ${X86_SHANI_CXXFLAGS}) + target_link_libraries(bitcoin_crypto_x86_shani PRIVATE core_interface) + target_link_libraries(bitcoin_crypto PRIVATE bitcoin_crypto_x86_shani) +endif() + +if(HAVE_ARM_SHANI) + add_library(bitcoin_crypto_arm_shani STATIC EXCLUDE_FROM_ALL + sha256_arm_shani.cpp + ) + target_compile_definitions(bitcoin_crypto_arm_shani PUBLIC ENABLE_ARM_SHANI) + target_compile_options(bitcoin_crypto_arm_shani PRIVATE ${ARM_SHANI_CXXFLAGS}) + target_link_libraries(bitcoin_crypto_arm_shani PRIVATE core_interface) + target_link_libraries(bitcoin_crypto PRIVATE bitcoin_crypto_arm_shani) +endif() + +# The sphlib sources sit on the X11 proof-of-work path, so Autotools builds +# them as their own library with -O3 (SPHLIB_FLAGS in configure.ac). Mirror +# that here instead of letting them inherit the default optimisation level. +set(crypto_sph_sources + x11/aes.cpp + x11/blake.c + x11/bmw.c + x11/cubehash.c + x11/dispatch.cpp + x11/echo.cpp + x11/groestl.c + x11/jh.c + x11/keccak.c + x11/luffa.c + x11/shavite.cpp + x11/simd.c + x11/skein.c +) +add_library(bitcoin_crypto_sph STATIC EXCLUDE_FROM_ALL ${crypto_sph_sources}) +target_compile_definitions(bitcoin_crypto_sph + PRIVATE + SPH_SMALL_FOOTPRINT_CUBEHASH=1 + SPH_SMALL_FOOTPRINT_JH=1 +) +if(NOT MSVC) + target_compile_options(bitcoin_crypto_sph PRIVATE $<$>:-O3>) +endif() +target_link_libraries(bitcoin_crypto_sph PRIVATE core_interface) +target_link_libraries(bitcoin_crypto PRIVATE bitcoin_crypto_sph) + +# X11 hashing backends. The generic implementations in bitcoin_crypto_sph are +# always built; these libraries provide the SIMD variants that x11/dispatch.cpp +# selects at run time. Keep the definitions in sync with cmake/bitcoin-config.h.in, +# which is what dispatch.cpp checks when deciding whether a backend exists. +# They link into bitcoin_crypto_sph rather than bitcoin_crypto because that is +# where dispatch.cpp lives, and a static archive has to follow the objects that +# reference it on the linker command line. +if(HAVE_SSSE3) + add_library(bitcoin_crypto_x11_ssse3 STATIC EXCLUDE_FROM_ALL + x11/ssse3/echo.cpp + ) + target_compile_definitions(bitcoin_crypto_x11_ssse3 PUBLIC ENABLE_SSSE3) + target_compile_options(bitcoin_crypto_x11_ssse3 PRIVATE ${SSSE3_CXXFLAGS}) + target_link_libraries(bitcoin_crypto_x11_ssse3 PRIVATE core_interface) + target_link_libraries(bitcoin_crypto_sph PRIVATE bitcoin_crypto_x11_ssse3) +endif() + +if(HAVE_X86_AESNI) + add_library(bitcoin_crypto_x11_x86_aesni STATIC EXCLUDE_FROM_ALL + x11/x86_aesni/echo.cpp + x11/x86_aesni/shavite.cpp + ) + target_compile_definitions(bitcoin_crypto_x11_x86_aesni PUBLIC ENABLE_SSE41 ENABLE_X86_AESNI) + target_compile_options(bitcoin_crypto_x11_x86_aesni PRIVATE ${X86_AESNI_CXXFLAGS}) + target_link_libraries(bitcoin_crypto_x11_x86_aesni PRIVATE core_interface) + target_link_libraries(bitcoin_crypto_sph PRIVATE bitcoin_crypto_x11_x86_aesni) +endif() + +if(HAVE_ARM_AES) + add_library(bitcoin_crypto_x11_arm_aes STATIC EXCLUDE_FROM_ALL + x11/arm_crypto/echo.cpp + x11/arm_crypto/shavite.cpp + ) + target_compile_definitions(bitcoin_crypto_x11_arm_aes PUBLIC ENABLE_ARM_AES) + target_compile_options(bitcoin_crypto_x11_arm_aes PRIVATE ${ARM_AES_CXXFLAGS}) + target_link_libraries(bitcoin_crypto_x11_arm_aes PRIVATE core_interface) + target_link_libraries(bitcoin_crypto_sph PRIVATE bitcoin_crypto_x11_arm_aes) +endif() + +if(HAVE_ARM_NEON) + add_library(bitcoin_crypto_x11_arm_neon STATIC EXCLUDE_FROM_ALL + x11/arm_neon/echo.cpp + ) + target_compile_definitions(bitcoin_crypto_x11_arm_neon PUBLIC ENABLE_ARM_NEON) + target_compile_options(bitcoin_crypto_x11_arm_neon PRIVATE ${ARM_NEON_CXXFLAGS}) + target_link_libraries(bitcoin_crypto_x11_arm_neon PRIVATE core_interface) + target_link_libraries(bitcoin_crypto_sph PRIVATE bitcoin_crypto_x11_arm_neon) +endif() + +# The public dashconsensus library compiles these again with its own +# definitions, so hand the lists up with absolute paths. +list(TRANSFORM crypto_base_sources PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/") +list(TRANSFORM crypto_sph_sources PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/") +set(crypto_base_sources ${crypto_base_sources} PARENT_SCOPE) +set(crypto_sph_sources ${crypto_sph_sources} PARENT_SCOPE) diff --git a/src/dashbls/CMakeLists.txt b/src/dashbls/CMakeLists.txt index f413f97cc7a9..199a411a432c 100644 --- a/src/dashbls/CMakeLists.txt +++ b/src/dashbls/CMakeLists.txt @@ -123,18 +123,18 @@ add_subdirectory(src) # Write include paths for rust binding if(EMSCRIPTEN) - file(APPEND "${CMAKE_CURRENT_LIST_DIR}/build/include_paths.txt" "${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}/c++/v1/;") + file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/include_paths.txt" "${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}/c++/v1/;") endif() -file(APPEND "${CMAKE_CURRENT_LIST_DIR}/build/include_paths.txt" "${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES};") +file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/include_paths.txt" "${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES};") if(GMP_INCLUDES) - file(APPEND "${CMAKE_CURRENT_LIST_DIR}/build/include_paths.txt" "${GMP_INCLUDES};") + file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/include_paths.txt" "${GMP_INCLUDES};") endif() # Write gmp library path for rust binding if(GMP_LIBRARIES) - file(APPEND "${CMAKE_CURRENT_LIST_DIR}/build/gmp_libraries.txt" "${GMP_LIBRARIES}") + file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/gmp_libraries.txt" "${GMP_LIBRARIES}") endif() if(EMSCRIPTEN) diff --git a/src/dashbls/depends/relic/CMakeLists.txt b/src/dashbls/depends/relic/CMakeLists.txt index db36c9bb7d46..c974da672d4a 100644 --- a/src/dashbls/depends/relic/CMakeLists.txt +++ b/src/dashbls/depends/relic/CMakeLists.txt @@ -299,9 +299,9 @@ message(STATUS "Compiler flags: ${CMAKE_C_FLAGS}") message(STATUS "Linker flags: ${CMAKE_EXE_LINKER_FLAGS}") string(TOUPPER ${ARITH} ARITH) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/relic_conf.h.in +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/relic_conf.h.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/include/relic_conf.h @ONLY) -message(STATUS "Configured ${CMAKE_CURRENT_SOURCE_DIR}/include/relic_conf.h.in") +message(STATUS "Configured ${CMAKE_CURRENT_SOURCE_DIR}/include/relic_conf.h.cmake.in") string(TOLOWER ${ARITH} ARITH) if (LABEL) diff --git a/src/dashbls/depends/relic/include/relic_conf.h.cmake.in b/src/dashbls/depends/relic/include/relic_conf.h.cmake.in new file mode 100644 index 000000000000..7db6f5b509c4 --- /dev/null +++ b/src/dashbls/depends/relic/include/relic_conf.h.cmake.in @@ -0,0 +1,717 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2009 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Project configuration. + * + * @version $Id: relic_conf.h.in 45 2009-07-04 23:45:48Z dfaranha $ + * @ingroup relic + */ + +#ifndef RLC_CONF_H +#define RLC_CONF_H + +/** Project version. */ +#define RLC_VERSION "@VERSION@" + +/** Debugging support. */ +#cmakedefine DEBUG +/** Profiling support. */ +#cmakedefine PROFL +/** Error handling support. */ +#cmakedefine CHECK +/** Verbose error messages. */ +#cmakedefine VERBS +/** Build with overhead estimation. */ +#cmakedefine OVERH +/** Build documentation. */ +#cmakedefine DOCUM +/** Build only the selected algorithms. */ +#cmakedefine STRIP +/** Build with printing disabled. */ +#cmakedefine QUIET +/** Build with colored output. */ +#cmakedefine COLOR +/** Build with big-endian support. */ +#cmakedefine BIGED +/** Build shared library. */ +#cmakedefine SHLIB +/** Build static library. */ +#cmakedefine STLIB + +/** Number of times each test is ran. */ +#define TESTS @TESTS@ +/** Number of times each benchmark is ran. */ +#define BENCH @BENCH@ +/** Number of available cores. */ +#define CORES @CORES@ + +/** Atmel AVR ATMega128 8-bit architecture. */ +#define AVR 1 +/** MSP430 16-bit architecture. */ +#define MSP 2 +/** ARM 32-bit architecture. */ +#define ARM 3 +/** Intel x86-compatible 32-bit architecture. */ +#define X86 4 +/** AMD64-compatible 64-bit architecture. */ +#define X64 5 +/** Architecture. */ +#cmakedefine ARCH @ARCH@ + +/** Size of word in this architecture. */ +#define WSIZE @WSIZE@ + +/** Byte boundary to align digit vectors. */ +#define ALIGN @ALIGN@ + +/** Build multiple precision integer module. */ +#cmakedefine WITH_BN +/** Build prime field module. */ +#cmakedefine WITH_FP +/** Build prime field extension module. */ +#cmakedefine WITH_FPX +/** Build binary field module. */ +#cmakedefine WITH_FB +/** Build prime elliptic curve module. */ +#cmakedefine WITH_EP +/** Build prime field extension elliptic curve module. */ +#cmakedefine WITH_EPX +/** Build binary elliptic curve module. */ +#cmakedefine WITH_EB +/** Build elliptic Edwards curve module. */ +#cmakedefine WITH_ED +/** Build elliptic curve cryptography module. */ +#cmakedefine WITH_EC +/** Build pairings over prime curves module. */ +#cmakedefine WITH_PP +/** Build pairing-based cryptography module. */ +#cmakedefine WITH_PC +/** Build block ciphers. */ +#cmakedefine WITH_BC +/** Build hash functions. */ +#cmakedefine WITH_MD +/** Build cryptographic protocols. */ +#cmakedefine WITH_CP +/** Build Multi-party computation primitives. */ +#cmakedefine WITH_MPC + +/** Easy C-only backend. */ +#define EASY 1 +/** GMP backend. */ +#define GMP 2 +/** GMP constant-time backend. */ +#define GMP_SEC 3 +/** Arithmetic backend. */ +#define ARITH @ARITH@ + +/** Required precision in bits. */ +#define BN_PRECI @BN_PRECI@ +/** A multiple precision integer can store w words. */ +#define SINGLE 0 +/** A multiple precision integer can store the result of an addition. */ +#define CARRY 1 +/** A multiple precision integer can store the result of a multiplication. */ +#define DOUBLE 2 +/** Effective size of a multiple precision integer. */ +#define BN_MAGNI @BN_MAGNI@ +/** Number of Karatsuba steps. */ +#define BN_KARAT @BN_KARAT@ + +/** Schoolbook multiplication. */ +#define BASIC 1 +/** Comba multiplication. */ +#define COMBA 2 +/** Chosen multiple precision multiplication method. */ +#define BN_MUL @BN_MUL@ + +/** Schoolbook squaring. */ +#define BASIC 1 +/** Comba squaring. */ +#define COMBA 2 +/** Reuse multiplication for squaring. */ +#define MULTP 4 +/** Chosen multiple precision multiplication method. */ +#define BN_SQR @BN_SQR@ + +/** Division modular reduction. */ +#define BASIC 1 +/** Barrett modular reduction. */ +#define BARRT 2 +/** Montgomery modular reduction. */ +#define MONTY 3 +/** Pseudo-Mersenne modular reduction. */ +#define PMERS 4 +/** Chosen multiple precision modular reduction method. */ +#define BN_MOD @BN_MOD@ + +/** Binary modular exponentiation. */ +#define BASIC 1 +/** Sliding window modular exponentiation. */ +#define SLIDE 2 +/** Montgomery powering ladder. */ +#define MONTY 3 +/** Chosen multiple precision modular exponentiation method. */ +#define BN_MXP @BN_MXP@ + +/** Basic Euclidean GCD Algorithm. */ +#define BASIC 1 +/** Lehmer's fast GCD Algorithm. */ +#define LEHME 2 +/** Stein's binary GCD Algorithm. */ +#define STEIN 3 +/** Chosen multiple precision greatest common divisor method. */ +#define BN_GCD @BN_GCD@ + +/** Basic prime generation. */ +#define BASIC 1 +/** Safe prime generation. */ +#define SAFEP 2 +/** Strong prime generation. */ +#define STRON 3 +/** Chosen prime generation algorithm. */ +#define BN_GEN @BN_GEN@ + +/** Multiple precision arithmetic method */ +#define BN_METHD "@BN_METHD@" + +/** Prime field size in bits. */ +#define FP_PRIME @FP_PRIME@ +/** Number of Karatsuba steps. */ +#define FP_KARAT @FP_KARAT@ +/** Prefer Pseudo-Mersenne primes over random primes. */ +#cmakedefine FP_PMERS +/** Use -1 as quadratic non-residue. */ +#cmakedefine FP_QNRES +/** Width of window processing for exponentiation methods. */ +#define FP_WIDTH @FP_WIDTH@ + +/** Schoolbook addition. */ +#define BASIC 1 +/** Integrated modular addtion. */ +#define INTEG 3 +/** Chosen prime field multiplication method. */ +#define FP_ADD @FP_ADD@ + +/** Schoolbook multiplication. */ +#define BASIC 1 +/** Comba multiplication. */ +#define COMBA 2 +/** Integrated modular multiplication. */ +#define INTEG 3 +/** Chosen prime field multiplication method. */ +#define FP_MUL @FP_MUL@ + +/** Schoolbook squaring. */ +#define BASIC 1 +/** Comba squaring. */ +#define COMBA 2 +/** Integrated modular squaring. */ +#define INTEG 3 +/** Reuse multiplication for squaring. */ +#define MULTP 4 +/** Chosen prime field multiplication method. */ +#define FP_SQR @FP_SQR@ + +/** Division-based reduction. */ +#define BASIC 1 +/** Fast reduction modulo special form prime. */ +#define QUICK 2 +/** Montgomery modular reduction. */ +#define MONTY 3 +/** Chosen prime field reduction method. */ +#define FP_RDC @FP_RDC@ + +/** Inversion by Fermat's Little Theorem. */ +#define BASIC 1 +/** Binary inversion. */ +#define BINAR 2 +/** Integrated modular multiplication. */ +#define MONTY 3 +/** Extended Euclidean algorithm. */ +#define EXGCD 4 +/** Constant-time inversion by Bernstein-Yang division steps. */ +#define DIVST 5 +/** Use implementation provided by the lower layer. */ +#define LOWER 8 +/** Chosen prime field inversion method. */ +#define FP_INV @FP_INV@ + +/** Binary modular exponentiation. */ +#define BASIC 1 +/** Sliding window modular exponentiation. */ +#define SLIDE 2 +/** Constant-time Montgomery powering ladder. */ +#define MONTY 3 +/** Chosen multiple precision modular exponentiation method. */ +#define FP_EXP @FP_EXP@ + +/** Prime field arithmetic method */ +#define FP_METHD "@FP_METHD@" + +/** Basic quadratic extension field arithmetic. */ +#define BASIC 1 +/** Integrated extension field arithmetic. */ +#define INTEG 3 +/* Chosen extension field arithmetic method. */ +#define FPX_QDR @FPX_QDR@ + +/** Basic cubic extension field arithmetic. */ +#define BASIC 1 +/** Integrated extension field arithmetic. */ +#define INTEG 3 +/* Chosen extension field arithmetic method. */ +#define FPX_CBC @FPX_CBC@ + +/** Basic quadratic extension field arithmetic. */ +#define BASIC 1 +/** Lazy-reduced extension field arithmetic. */ +#define LAZYR 2 +/* Chosen extension field arithmetic method. */ +#define FPX_RDC @FPX_RDC@ + +/** Prime extension field arithmetic method */ +#define FPX_METHD "@FPX_METHD@" + +/** Irreducible polynomial size in bits. */ +#define FB_POLYN @FB_POLYN@ +/** Number of Karatsuba steps. */ +#define FB_KARAT @FB_KARAT@ +/** Prefer trinomials over pentanomials. */ +#cmakedefine FB_TRINO +/** Prefer square-root friendly polynomials. */ +#cmakedefine FB_SQRTF +/** Precompute multiplication table for sqrt(z). */ +#cmakedefine FB_PRECO +/** Width of window processing for exponentiation methods. */ +#define FB_WIDTH @FB_WIDTH@ + +/** Shift-and-add multiplication. */ +#define BASIC 1 +/** Lopez-Dahab multiplication. */ +#define LODAH 2 +/** Integrated modular multiplication. */ +#define INTEG 3 +/** Chosen binary field multiplication method. */ +#define FB_MUL @FB_MUL@ + +/** Basic squaring. */ +#define BASIC 1 +/** Table-based squaring. */ +#define QUICK 2 +/** Integrated modular squaring. */ +#define INTEG 3 +/** Chosen binary field squaring method. */ +#define FB_SQR @FB_SQR@ + +/** Shift-and-add modular reduction. */ +#define BASIC 1 +/** Fast reduction modulo a trinomial or pentanomial. */ +#define QUICK 2 +/** Chosen binary field modular reduction method. */ +#define FB_RDC @FB_RDC@ + +/** Square root by repeated squaring. */ +#define BASIC 1 +/** Fast square root extraction. */ +#define QUICK 2 +/** Chosen binary field modular reduction method. */ +#define FB_SRT @FB_SRT@ + +/** Trace by repeated squaring. */ +#define BASIC 1 +/** Fast trace computation. */ +#define QUICK 2 +/** Chosen trace computation method. */ +#define FB_TRC @FB_TRC@ + +/** Solve by half-trace computation. */ +#define BASIC 1 +/** Solve with precomputed half-traces. */ +#define QUICK 2 +/** Chosen method to solve a quadratic equation. */ +#define FB_SLV @FB_SLV@ + +/** Inversion by Fermat's Little Theorem. */ +#define BASIC 1 +/** Binary inversion. */ +#define BINAR 2 +/** Almost inverse algorithm. */ +#define ALMOS 3 +/** Extended Euclidean algorithm. */ +#define EXGCD 4 +/** Itoh-Tsuji inversion. */ +#define ITOHT 5 +/** Hardware-friendly inversion by Brunner-Curiger-Hofstetter.*/ +#define BRUCH 6 +/** Constant-time version of almost inverse. */ +#define CTAIA 7 +/** Use implementation provided by the lower layer. */ +#define LOWER 8 +/** Chosen binary field inversion method. */ +#define FB_INV @FB_INV@ + +/** Binary modular exponentiation. */ +#define BASIC 1 +/** Sliding window modular exponentiation. */ +#define SLIDE 2 +/** Constant-time Montgomery powering ladder. */ +#define MONTY 3 +/** Chosen multiple precision modular exponentiation method. */ +#define FB_EXP @FB_EXP@ + +/** Iterated squaring/square-root by consecutive squaring/square-root. */ +#define BASIC 1 +/** Iterated squaring/square-root by table-based method. */ +#define QUICK 2 +/** Chosen method to solve a quadratic equation. */ +#define FB_ITR @FB_ITR@ + +/** Binary field arithmetic method */ +#define FB_METHD "@FB_METHD@" + +/** Support for ordinary curves. */ +#cmakedefine EP_PLAIN +/** Support for supersingular curves. */ +#cmakedefine EP_SUPER +/** Support for prime curves with efficient endormorphisms. */ +#cmakedefine EP_ENDOM +/** Use mixed coordinates. */ +#cmakedefine EP_MIXED +/** Build precomputation table for generator. */ +#cmakedefine EP_PRECO +/** Enable isogeny map for SSWU map-to-curve. */ +#cmakedefine EP_CTMAP +/** Width of precomputation table for fixed point methods. */ +#define EP_DEPTH @EP_DEPTH@ +/** Width of window processing for unknown point methods. */ +#define EP_WIDTH @EP_WIDTH@ + +/** Affine coordinates. */ +#define BASIC 1 +/** Projective coordinates. */ +#define PROJC 2 +/** Jacobian coordinates. */ +#define JACOB 3 +/** Chosen prime elliptic curve coordinate method. */ +#define EP_ADD @EP_ADD@ + +/** Binary point multiplication. */ +#define BASIC 1 +/** Sliding window. */ +#define SLIDE 2 +/** Montgomery powering ladder. */ +#define MONTY 3 +/** Left-to-right Width-w NAF. */ +#define LWNAF 4 +/** Left-to-right Width-w NAF. */ +#define LWREG 5 +/** Chosen prime elliptic curve point multiplication method. */ +#define EP_MUL @EP_MUL@ + +/** Binary point multiplication. */ +#define BASIC 1 +/** Single-table comb method. */ +#define COMBS 2 +/** Double-table comb method. */ +#define COMBD 3 +/** Left-to-right Width-w NAF. */ +#define LWNAF 4 +/** Chosen prime elliptic curve point multiplication method. */ +#define EP_FIX @EP_FIX@ + +/** Basic simultaneouns point multiplication. */ +#define BASIC 1 +/** Shamir's trick. */ +#define TRICK 2 +/** Interleaving of w-(T)NAFs. */ +#define INTER 3 +/** Joint sparse form. */ +#define JOINT 4 +/** Chosen prime elliptic curve simulteanous point multiplication method. */ +#define EP_SIM @EP_SIM@ + +/** Prime elliptic curve arithmetic method. */ +#define EP_METHD "@EP_METHD@" + +/** Support for ordinary curves without endormorphisms. */ +#cmakedefine EB_PLAIN +/** Support for Koblitz anomalous binary curves. */ +#cmakedefine EB_KBLTZ +/** Use mixed coordinates. */ +#cmakedefine EB_MIXED +/** Build precomputation table for generator. */ +#cmakedefine EB_PRECO +/** Width of precomputation table for fixed point methods. */ +#define EB_DEPTH @EB_DEPTH@ +/** Width of window processing for unknown point methods. */ +#define EB_WIDTH @EB_WIDTH@ + +/** Binary elliptic curve arithmetic method. */ +#define EB_METHD "@EB_METHD@" + +/** Affine coordinates. */ +#define BASIC 1 +/** López-Dahab Projective coordinates. */ +#define PROJC 2 +/** Chosen binary elliptic curve coordinate method. */ +#define EB_ADD @EB_ADD@ + +/** Binary point multiplication. */ +#define BASIC 1 +/** L�pez-Dahab point multiplication. */ +#define LODAH 2 +/** Halving. */ +#define HALVE 3 +/** Left-to-right width-w (T)NAF. */ +#define LWNAF 4 +/** Right-to-left width-w (T)NAF. */ +#define RWNAF 5 +/** Chosen binary elliptic curve point multiplication method. */ +#define EB_MUL @EB_MUL@ + +/** Binary point multiplication. */ +#define BASIC 1 +/** Single-table comb method. */ +#define COMBS 2 +/** Double-table comb method. */ +#define COMBD 3 +/** Left-to-right Width-w NAF. */ +#define LWNAF 4 +/** Chosen binary elliptic curve point multiplication method. */ +#define EB_FIX @EB_FIX@ + +/** Basic simultaneouns point multiplication. */ +#define BASIC 1 +/** Shamir's trick. */ +#define TRICK 2 +/** Interleaving of w-(T)NAFs. */ +#define INTER 3 +/** Joint sparse form. */ +#define JOINT 4 +/** Chosen binary elliptic curve simulteanous point multiplication method. */ +#define EB_SIM @EB_SIM@ + +/** Build precomputation table for generator. */ +#cmakedefine ED_PRECO +/** Width of precomputation table for fixed point methods. */ +#define ED_DEPTH @ED_DEPTH@ +/** Width of window processing for unknown point methods. */ +#define ED_WIDTH @ED_WIDTH@ + +/** Edwards elliptic curve arithmetic method. */ +#define ED_METHD "@ED_METHD@" + +/** Affine coordinates. */ +#define BASIC 1 +/** Simple projective twisted Edwards coordinates */ +#define PROJC 2 +/** Extended projective twisted Edwards coordinates */ +#define EXTND 3 +/** Chosen binary elliptic curve coordinate method. */ +#define ED_ADD @ED_ADD@ + +/** Binary point multiplication. */ +#define BASIC 1 +/** Sliding window. */ +#define SLIDE 2 +/** Montgomery powering ladder. */ +#define MONTY 3 +/** Left-to-right Width-w NAF. */ +#define LWNAF 4 +/** Left-to-right Width-w NAF. */ +#define LWREG 5 +/** Chosen prime elliptic twisted Edwards curve point multiplication method. */ +#define ED_MUL @ED_MUL@ + +/** Binary point multiplication. */ +#define BASIC 1 +/** Single-table comb method. */ +#define COMBS 2 +/** Double-table comb method. */ +#define COMBD 3 +/** Left-to-right Width-w NAF. */ +#define LWNAF 4 +/** Chosen prime elliptic twisted Edwards curve point multiplication method. */ +#define ED_FIX @ED_FIX@ + +/** Basic simultaneouns point multiplication. */ +#define BASIC 1 +/** Shamir's trick. */ +#define TRICK 2 +/** Interleaving of w-(T)NAFs. */ +#define INTER 3 +/** Joint sparse form. */ +#define JOINT 4 +/** Chosen prime elliptic curve simulteanous point multiplication method. */ +#define ED_SIM @ED_SIM@ + +/** Prime curves. */ +#define PRIME 1 +/** Binary curves. */ +#define CHAR2 2 +/** Edwards curves */ +#define EDDIE 3 +/** Chosen elliptic curve type. */ +#define EC_CUR @EC_CUR@ + +/** Chosen elliptic curve cryptography method. */ +#define EC_METHD "@EC_METHD@" +/** Prefer curves with efficient endomorphisms. */ +#cmakedefine EC_ENDOM + +/** Basic quadratic extension field arithmetic. */ +#define BASIC 1 +/** Lazy-reduced extension field arithmetic. */ +#define LAZYR 2 +/* Chosen extension field arithmetic method. */ +#define PP_EXT @PP_EXT@ + +/** Bilinear pairing method. */ +#define PP_METHD "@PP_METHD@" + +/** Tate pairing. */ +#define TATEP 1 +/** Weil pairing. */ +#define WEILP 2 +/** Optimal ate pairing. */ +#define OATEP 3 +/** Chosen pairing method over prime elliptic curves. */ +#define PP_MAP @PP_MAP@ + +/** SHA-224 hash function. */ +#define SH224 2 +/** SHA-256 hash function. */ +#define SH256 3 +/** SHA-384 hash function. */ +#define SH384 4 +/** SHA-512 hash function. */ +#define SH512 5 +/** BLAKE2s-160 hash function. */ +#define B2S160 6 +/** BLAKE2s-256 hash function. */ +#define B2S256 7 +/** Chosen hash function. */ +#define MD_MAP @MD_MAP@ + +/** Choice of hash function. */ +#define MD_METHD "@MD_METHD@" + +/** Chosen RSA method. */ +#cmakedefine CP_CRT +/** RSA without padding. */ +#define BASIC 1 +/** RSA PKCS#1 v1.5 padding. */ +#define PKCS1 2 +/** RSA PKCS#1 v2.1 padding. */ +#define PKCS2 3 +/** Chosen RSA padding method. */ +#define CP_RSAPD @CP_RSAPD@ + +/** Automatic memory allocation. */ +#define AUTO 1 +/** Dynamic memory allocation. */ +#define DYNAMIC 2 +/** Chosen memory allocation policy. */ +#define ALLOC @ALLOC@ + +/** NIST HASH-DRBG generator. */ +#define HASHD 1 +/** Intel RdRand instruction. */ +#define RDRND 2 +/** Operating system underlying generator. */ +#define UDEV 3 +/** Override library generator with the callback. */ +#define CALL 4 +/** Chosen random generator. */ +#define RAND @RAND@ + +/** Standard C library generator. */ +#define LIBC 1 +/** Intel RdRand instruction. */ +#define RDRND 2 +/** Device node generator. */ +#define UDEV 3 +/** Use Windows' CryptGenRandom. */ +#define WCGR 4 +/** Chosen random generator seeder. */ +#cmakedefine SEED @SEED@ + +/** GNU/Linux operating system. */ +#define LINUX 1 +/** FreeBSD operating system. */ +#define FREEBSD 2 +/** Windows operating system. */ +#define MACOSX 3 +/** Windows operating system. */ +#define WINDOWS 4 +/** Android operating system. */ +#define DROID 5 +/** Arduino platform. */ +#define DUINO 6 +/** OpenBSD operating system. */ +#define OPENBSD 7 +/** Detected operation system. */ +#cmakedefine OPSYS @OPSYS@ + +/** OpenMP multithreading support. */ +#define OPENMP 1 +/** POSIX multithreading support. */ +#define PTHREAD 2 +/** Chosen multithreading API. */ +#cmakedefine MULTI @MULTI@ + +/** Per-process high-resolution timer. */ +#define HREAL 1 +/** Per-process high-resolution timer. */ +#define HPROC 2 +/** Per-thread high-resolution timer. */ +#define HTHRD 3 +/** POSIX-compatible timer. */ +#define POSIX 4 +/** ANSI-compatible timer. */ +#define ANSI 5 +/** Cycle-counting timer. */ +#define CYCLE 6 +/** Performance monitoring framework. */ +#define PERF 7 +/** Chosen timer. */ +#cmakedefine TIMER @TIMER@ + +/** Prefix to identity this build of the library. */ +#cmakedefine LABEL @LABEL@ + +#ifndef ASM + +#include "relic_label.h" + +/** + * Prints the project options selected at build time. + */ +void conf_print(void); + +#endif /* ASM */ + +#endif /* !RLC_CONF_H */ diff --git a/src/dashbls/src/CMakeLists.txt b/src/dashbls/src/CMakeLists.txt index 5802843a61ed..7b101f546c93 100644 --- a/src/dashbls/src/CMakeLists.txt +++ b/src/dashbls/src/CMakeLists.txt @@ -1,7 +1,7 @@ file(GLOB HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../include/dashbls/*.hpp) source_group("SrcHeaders" FILES ${HEADERS}) -add_library(dashbls +add_library(dashbls STATIC ${HEADERS} ${CMAKE_CURRENT_SOURCE_DIR}/privatekey.cpp ${CMAKE_CURRENT_SOURCE_DIR}/bls.cpp @@ -17,6 +17,7 @@ target_include_directories(dashbls PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} $<$:${GMP_INCLUDES}> + ${CMAKE_CURRENT_SOURCE_DIR}/../include ${CMAKE_CURRENT_SOURCE_DIR}/../include/dashbls ${CMAKE_CURRENT_SOURCE_DIR}/../depends/mimalloc/include ${CMAKE_CURRENT_SOURCE_DIR}/../depends/relic/include diff --git a/src/ipc/CMakeLists.txt b/src/ipc/CMakeLists.txt new file mode 100644 index 000000000000..94b1ceb54e4d --- /dev/null +++ b/src/ipc/CMakeLists.txt @@ -0,0 +1,18 @@ +# 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_ipc STATIC EXCLUDE_FROM_ALL + capnp/protocol.cpp + interfaces.cpp + process.cpp +) + +target_capnp_sources(bitcoin_ipc ${PROJECT_SOURCE_DIR} + capnp/echo.capnp capnp/init.capnp +) + +target_link_libraries(bitcoin_ipc + PRIVATE + core_interface +) diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt new file mode 100644 index 000000000000..6495ff59382c --- /dev/null +++ b/src/qt/CMakeLists.txt @@ -0,0 +1,369 @@ +# 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/. + +if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + enable_language(OBJCXX) + set(CMAKE_OBJCXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + set(CMAKE_OBJCXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") + set(CMAKE_OBJCXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") + set(CMAKE_OBJCXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}") + string(APPEND CMAKE_OBJCXX_COMPILE_OBJECT " ${APPEND_CPPFLAGS} ${APPEND_CXXFLAGS}") +endif() + +get_target_property(qt_lib_type Qt5::Core TYPE) + +# TODO: After the transition from Autotools to CMake, +# all `Q_IMPORT_PLUGIN` macros can be deleted from the +# qt/bitcoin.cpp and qt/test/test_main.cpp source files. +function(import_plugins target) + if(qt_lib_type STREQUAL "STATIC_LIBRARY") + set(plugins Qt5::QMinimalIntegrationPlugin) + if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + list(APPEND plugins Qt5::QXcbIntegrationPlugin) + elseif(WIN32) + list(APPEND plugins Qt5::QWindowsIntegrationPlugin Qt5::QWindowsVistaStylePlugin) + elseif(APPLE) + list(APPEND plugins Qt5::QCocoaIntegrationPlugin Qt5::QMacStylePlugin) + endif() + qt5_import_plugins(${target} + INCLUDE ${plugins} + EXCLUDE_BY_TYPE imageformats iconengines + ) + endif() +endfunction() + +# For Qt-specific commands and variables, please consult: +# - https://cmake.org/cmake/help/latest/manual/cmake-qt.7.html +# - https://doc.qt.io/qt-5/cmake-manual.html + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOUIC_SEARCH_PATHS forms) + +# TODO: The file(GLOB ...) command should be replaced with an explicit +# file list. Such a change must be synced with the corresponding change +# to https://github.com/bitcoin-core/bitcoin-maintainer-tools/blob/main/update-translations.py +file(GLOB ts_files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} locale/*.ts) +set_source_files_properties(${ts_files} PROPERTIES OUTPUT_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/locale) +qt5_add_translation(qm_files ${ts_files}) + +configure_file(dash_locale.qrc dash_locale.qrc COPYONLY) + +# The bitcoinqt sources have to include headers in +# order to parse them to collect translatable strings. +add_library(bitcoinqt STATIC EXCLUDE_FROM_ALL + appearancewidget.cpp + appearancewidget.h + bantablemodel.cpp + bantablemodel.h + bitcoin.cpp + bitcoin.h + bitcoinaddressvalidator.cpp + bitcoinaddressvalidator.h + bitcoinamountfield.cpp + bitcoinamountfield.h + bitcoingui.cpp + bitcoingui.h + bitcoinunits.cpp + bitcoinunits.h + clientfeeds.cpp + clientfeeds.h + clientmodel.cpp + clientmodel.h + csvmodelwriter.cpp + csvmodelwriter.h + donutchart.cpp + donutchart.h + guiutil.cpp + guiutil.h + guiutil_font.cpp + informationwidget.cpp + informationwidget.h + initexecutor.cpp + initexecutor.h + intro.cpp + intro.h + $<$:macdockiconhandler.h> + $<$:macdockiconhandler.mm> + $<$:macnotificationhandler.h> + $<$:macnotificationhandler.mm> + $<$:macos_appnap.h> + $<$:macos_appnap.mm> + masternodemodel.cpp + masternodemodel.h + modaloverlay.cpp + modaloverlay.h + networkstyle.cpp + networkstyle.h + networkwidget.cpp + networkwidget.h + notificator.cpp + notificator.h + optionsdialog.cpp + optionsdialog.h + optionsmodel.cpp + optionsmodel.h + peertablemodel.cpp + peertablemodel.h + peertablesortproxy.cpp + peertablesortproxy.h + proposalinfo.cpp + proposalinfo.h + proposalmodel.cpp + proposalmodel.h + qvalidatedlineedit.cpp + qvalidatedlineedit.h + qvaluecombobox.cpp + qvaluecombobox.h + rpcconsole.cpp + rpcconsole.h + splashscreen.cpp + splashscreen.h + trafficgraphdata.cpp + trafficgraphdata.h + trafficgraphwidget.cpp + trafficgraphwidget.h + utilitydialog.cpp + utilitydialog.h + $<$:winshutdownmonitor.cpp> + $<$:winshutdownmonitor.h> + dash.qrc + ${CMAKE_CURRENT_BINARY_DIR}/dash_locale.qrc +) +target_compile_definitions(bitcoinqt + PUBLIC + QT_NO_KEYWORDS + QT_USE_QSTRINGBUILDER +) +target_include_directories(bitcoinqt + PUBLIC + $ +) +set_property(SOURCE macnotificationhandler.mm + # Ignore warnings "'NSUserNotificationCenter' is deprecated: first deprecated in macOS 11.0". + APPEND PROPERTY COMPILE_OPTIONS -Wno-deprecated-declarations +) +target_link_libraries(bitcoinqt + PUBLIC + Qt5::Widgets + PRIVATE + core_interface + bitcoin_cli + bitcoin_common + bitcoin_util + dashbls + leveldb + univalue + Boost::headers + $ + $ + $ + $<$:-framework\ AppKit> + $<$:shlwapi> +) + +if(ENABLE_WALLET) + target_sources(bitcoinqt + PRIVATE + addressbookpage.cpp + addressbookpage.h + addresstablemodel.cpp + addresstablemodel.h + askpassphrasedialog.cpp + askpassphrasedialog.h + coincontroldialog.cpp + coincontroldialog.h + coincontroltreewidget.cpp + coincontroltreewidget.h + createwalletdialog.cpp + createwalletdialog.h + descriptiondialog.cpp + descriptiondialog.h + editaddressdialog.cpp + editaddressdialog.h + masternodelist.cpp + masternodelist.h + mnemonicverificationdialog.cpp + mnemonicverificationdialog.h + openuridialog.cpp + openuridialog.h + overviewpage.cpp + overviewpage.h + paymentserver.cpp + paymentserver.h + proposalcreate.cpp + proposalcreate.h + proposallist.cpp + proposallist.h + proposalresume.cpp + proposalresume.h + psbtoperationsdialog.cpp + psbtoperationsdialog.h + qrdialog.cpp + qrdialog.h + qrimagewidget.cpp + qrimagewidget.h + receivecoinsdialog.cpp + receivecoinsdialog.h + receiverequestdialog.cpp + receiverequestdialog.h + recentrequeststablemodel.cpp + recentrequeststablemodel.h + sendcoinsdialog.cpp + sendcoinsdialog.h + sendcoinsentry.cpp + sendcoinsentry.h + signverifymessagedialog.cpp + signverifymessagedialog.h + transactiondesc.cpp + transactiondesc.h + transactionfilterproxy.cpp + transactionfilterproxy.h + transactionoverviewwidget.cpp + transactionoverviewwidget.h + transactionrecord.cpp + transactionrecord.h + transactiontablemodel.cpp + transactiontablemodel.h + transactionview.cpp + transactionview.h + walletcontroller.cpp + walletcontroller.h + walletframe.cpp + walletframe.h + walletmodel.cpp + walletmodel.h + walletmodeltransaction.cpp + walletmodeltransaction.h + walletview.cpp + walletview.h + ) + target_link_libraries(bitcoinqt + PRIVATE + bitcoin_wallet + Qt5::Network + ) +endif() + +if(WITH_DBUS) + target_link_libraries(bitcoinqt PRIVATE Qt5::DBus) +endif() + +if(qt_lib_type STREQUAL "STATIC_LIBRARY") + # We want to define static plugins to link ourselves, thus preventing + # automatic linking against a "sane" set of default static plugins. + qt5_import_plugins(bitcoinqt + EXCLUDE_BY_TYPE bearer iconengines imageformats platforms styles + ) +endif() + +add_executable(bitcoin-qt + main.cpp + ../init/bitcoin-qt.cpp +) +set_target_properties(bitcoin-qt PROPERTIES OUTPUT_NAME dash-qt) + +add_windows_resources(bitcoin-qt res/dash-qt-res.rc) + +target_link_libraries(bitcoin-qt + core_interface + bitcoinqt + bitcoin_node +) + +import_plugins(bitcoin-qt) +set(installable_targets bitcoin-qt) +if(WIN32) + set_target_properties(bitcoin-qt PROPERTIES WIN32_EXECUTABLE TRUE) +endif() + +if(WITH_MULTIPROCESS) + add_executable(bitcoin-gui + main.cpp + ../init/bitcoin-gui.cpp + ) + target_link_libraries(bitcoin-gui + core_interface + bitcoinqt + bitcoin_node + bitcoin_ipc + ) + set_target_properties(bitcoin-gui PROPERTIES OUTPUT_NAME dash-gui) + import_plugins(bitcoin-gui) + list(APPEND installable_targets bitcoin-gui) + if(WIN32) + set_target_properties(bitcoin-gui PROPERTIES WIN32_EXECUTABLE TRUE) + endif() +endif() + +install(TARGETS ${installable_targets} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + COMPONENT GUI +) + +if(BUILD_GUI_TESTS) + add_subdirectory(test) +endif() + + +# Gets sources to be parsed to gather translatable strings. +function(get_translatable_sources var) + set(result) + set(targets) + foreach(dir IN ITEMS ${ARGN}) + get_directory_property(dir_targets DIRECTORY ${PROJECT_SOURCE_DIR}/${dir} BUILDSYSTEM_TARGETS) + list(APPEND targets ${dir_targets}) + endforeach() + foreach(target IN LISTS targets) + get_target_property(target_sources ${target} SOURCES) + if(target_sources) + foreach(source IN LISTS target_sources) + # Get an expression from the generator expression, if any. + if(source MATCHES ":([^>]+)>$") + set(source ${CMAKE_MATCH_1}) + endif() + cmake_path(GET source EXTENSION LAST_ONLY ext) + if(ext STREQUAL ".qrc") + continue() + endif() + if(NOT IS_ABSOLUTE source) + get_target_property(target_source_dir ${target} SOURCE_DIR) + cmake_path(APPEND target_source_dir ${source} OUTPUT_VARIABLE source) + endif() + list(APPEND result ${source}) + endforeach() + endif() + endforeach() + set(${var} ${result} PARENT_SCOPE) +endfunction() + +find_program(XGETTEXT_EXECUTABLE xgettext) +find_program(SED_EXECUTABLE sed) +if(NOT XGETTEXT_EXECUTABLE) + add_custom_target(translate + COMMAND ${CMAKE_COMMAND} -E echo "Error: GNU gettext-tools not found" + ) +elseif(NOT SED_EXECUTABLE) + add_custom_target(translate + COMMAND ${CMAKE_COMMAND} -E echo "Error: GNU sed not found" + ) +else() + set(translatable_sources_directories src src/qt src/util) + if(ENABLE_WALLET) + list(APPEND translatable_sources_directories src/wallet) + endif() + get_translatable_sources(translatable_sources ${translatable_sources_directories}) + get_translatable_sources(qt_translatable_sources src/qt) + file(GLOB ui_files ${CMAKE_CURRENT_SOURCE_DIR}/forms/*.ui) + add_custom_target(translate + COMMAND ${CMAKE_COMMAND} -E env XGETTEXT=${XGETTEXT_EXECUTABLE} COPYRIGHT_HOLDERS=${COPYRIGHT_HOLDERS} ${Python3_EXECUTABLE} ${PROJECT_SOURCE_DIR}/share/qt/extract_strings_qt.py ${translatable_sources} + COMMAND Qt5::lupdate -no-obsolete -I ${PROJECT_SOURCE_DIR}/src -locations relative ${CMAKE_CURRENT_SOURCE_DIR}/dashstrings.cpp ${ui_files} ${qt_translatable_sources} -ts ${CMAKE_CURRENT_SOURCE_DIR}/locale/dash_en.ts + COMMAND Qt5::lconvert -drop-translations -o ${CMAKE_CURRENT_SOURCE_DIR}/locale/dash_en.xlf -i ${CMAKE_CURRENT_SOURCE_DIR}/locale/dash_en.ts + COMMAND ${SED_EXECUTABLE} -i.old -e "s|source-language=\"en\" target-language=\"en\"|source-language=\"en\"|" -e "/<\\/target>/d" ${CMAKE_CURRENT_SOURCE_DIR}/locale/dash_en.xlf + COMMAND ${CMAKE_COMMAND} -E rm ${CMAKE_CURRENT_SOURCE_DIR}/locale/dash_en.xlf.old + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src + VERBATIM + ) +endif() diff --git a/src/qt/test/CMakeLists.txt b/src/qt/test/CMakeLists.txt new file mode 100644 index 000000000000..32cd3a3f2c5c --- /dev/null +++ b/src/qt/test/CMakeLists.txt @@ -0,0 +1,63 @@ +# Copyright (c) 2024-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +add_executable(test_bitcoin-qt + apptests.cpp + optiontests.cpp + rpcnestedtests.cpp + test_main.cpp + trafficgraphdatatests.cpp + uritests.cpp + util.cpp + ../../init/bitcoin-qt.cpp +) + +set_target_properties(test_bitcoin-qt PROPERTIES OUTPUT_NAME test_dash-qt) + +target_link_libraries(test_bitcoin-qt + core_interface + bitcoinqt + test_util + bitcoin_node + # The Dash-specific headers reachable from these tests include dbwrapper.h, + # so the LevelDB headers have to be on the include path. + leveldb + dashbls + Boost::headers + Qt5::Test +) + +import_plugins(test_bitcoin-qt) + +if(ENABLE_WALLET) + target_sources(test_bitcoin-qt + PRIVATE + addressbooktests.cpp + wallettests.cpp + ../../wallet/test/wallet_test_fixture.cpp + ) +endif() + +if(NOT QT_IS_STATIC) + add_custom_command( + TARGET test_bitcoin-qt POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different $>> $/plugins/platforms + VERBATIM + ) +endif() + +add_test(NAME test_bitcoin-qt + COMMAND test_bitcoin-qt +) +if(WIN32 AND VCPKG_TARGET_TRIPLET) + # On Windows, vcpkg configures Qt with `-opengl dynamic`, which makes + # the "minimal" platform plugin unusable due to internal Qt bugs. + set_tests_properties(test_bitcoin-qt PROPERTIES + ENVIRONMENT "QT_QPA_PLATFORM=windows" + ) +endif() + +install(TARGETS test_bitcoin-qt + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt new file mode 100644 index 000000000000..a693b6c9e1a4 --- /dev/null +++ b/src/test/CMakeLists.txt @@ -0,0 +1,236 @@ +# 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/bip39_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/proposals_invalid.json) +generate_header_from_json(data/proposals_valid.json) +generate_header_from_json(data/script_tests.json) +generate_header_from_json(data/sighash.json) +generate_header_from_json(data/trivially_invalid.json) +generate_header_from_json(data/trivially_valid.json) +generate_header_from_json(data/tx_invalid.json) +generate_header_from_json(data/tx_valid.json) +generate_header_from_raw(data/asmap.raw) + +# Do not use generator expressions in test sources because the +# SOURCES property is processed to gather test suite macros. +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/bip39_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/proposals_invalid.json.h + ${CMAKE_CURRENT_BINARY_DIR}/data/proposals_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/trivially_invalid.json.h + ${CMAKE_CURRENT_BINARY_DIR}/data/trivially_valid.json.h + ${CMAKE_CURRENT_BINARY_DIR}/data/tx_invalid.json.h + ${CMAKE_CURRENT_BINARY_DIR}/data/tx_valid.json.h + 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 + block_reward_reallocation_tests.cpp + blockchain_tests.cpp + blockencodings_tests.cpp + blockfilter_index_tests.cpp + blockfilter_tests.cpp + blockmanager_tests.cpp + bloom_tests.cpp + bls_tests.cpp + bswap_tests.cpp + cachemap_tests.cpp + cachemultimap_tests.cpp + checkdatasig_tests.cpp + checkqueue_tests.cpp + coinjoin_dstxmanager_tests.cpp + coinjoin_inouts_tests.cpp + coinjoin_queue_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 + dip0020opcodes_tests.cpp + dynamic_activation_thresholds_tests.cpp + evo_assetlocks_tests.cpp + evo_cbtx_tests.cpp + evo_deterministicmns_tests.cpp + evo_islock_tests.cpp + evo_mnhf_tests.cpp + evo_netinfo_tests.cpp + evo_simplifiedmns_tests.cpp + evo_trivialvalidation.cpp + evo_utils_tests.cpp + flatfile_tests.cpp + fs_tests.cpp + getarg_tests.cpp + governance_superblock_tests.cpp + governance_validators_tests.cpp + hash_tests.cpp + httpserver_tests.cpp + i2p_tests.cpp + interfaces_tests.cpp + key_io_tests.cpp + key_tests.cpp + limitedmap_tests.cpp + llmq_chainlock_tests.cpp + llmq_commitment_tests.cpp + llmq_dkg_tests.cpp + llmq_hash_tests.cpp + llmq_params_tests.cpp + llmq_snapshot_tests.cpp + llmq_utils_tests.cpp + logging_tests.cpp + mempool_tests.cpp + merkle_tests.cpp + merkleblock_tests.cpp + miner_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 + policyestimator_tests.cpp + pool_tests.cpp + pow_tests.cpp + prevector_tests.cpp + raii_event_tests.cpp + random_tests.cpp + ratecheck_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_p2pk_tests.cpp + script_p2pkh_tests.cpp + script_parse_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 + subsidy_tests.cpp + sync_tests.cpp + system_tests.cpp + timedata_tests.cpp + torcontrol_tests.cpp + transaction_tests.cpp + txindex_tests.cpp + txpackage_tests.cpp + txreconciliation_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 +) +set_target_properties(test_bitcoin PROPERTIES OUTPUT_NAME test_dash) + +target_link_libraries(test_bitcoin + core_interface + test_util + bitcoin_cli + bitcoin_node + dashbls + leveldb + minisketch + secp256k1 + Boost::headers + $ +) + +if(ENABLE_WALLET) + add_subdirectory(${PROJECT_SOURCE_DIR}/src/wallet/test wallet) +endif() + +# NOTE: Upstream also builds an IPC test library here from ipc_test.cpp, +# ipc_test.capnp and ipc_tests.cpp. Dash has not backported those sources +# (bitcoin#28921), and referencing them makes -DWITH_MULTIPROCESS=ON fail +# during generation. Restore this block along with the test sources. + +function(add_boost_test source_file) + if(NOT EXISTS ${source_file}) + return() + endif() + + file(READ "${source_file}" 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} + COMMAND test_bitcoin --run_test=${test_suite_name} --catch_system_error=no + ) + set_property(TEST ${test_suite_name} PROPERTY + SKIP_REGULAR_EXPRESSION "no test cases matching filter" "Skipping" + ) + 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}) + cmake_path(IS_RELATIVE test_source result) + if(result) + cmake_path(APPEND test_source_dir ${test_source} OUTPUT_VARIABLE test_source) + endif() + add_boost_test(${test_source}) + endforeach() +endfunction() + +add_all_test_targets() + +install(TARGETS test_bitcoin + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/src/test/fuzz/CMakeLists.txt b/src/test/fuzz/CMakeLists.txt new file mode 100644 index 000000000000..1aaf9de0b978 --- /dev/null +++ b/src/test/fuzz/CMakeLists.txt @@ -0,0 +1,133 @@ +# 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_subdirectory(util) + +add_executable(fuzz + addition_overflow.cpp + addrman.cpp + asmap.cpp + asmap_direct.cpp + autofile.cpp + banman.cpp + base_encode_decode.cpp + bech32.cpp + bip324.cpp + block.cpp + block_header.cpp + blockfilter.cpp + bloom_filter.cpp + buffered_file.cpp + chain.cpp + checkqueue.cpp + coins_view.cpp + coinscache_sim.cpp + connman.cpp + crypto.cpp + crypto_aes256.cpp + crypto_aes256cbc.cpp + crypto_chacha20.cpp + crypto_common.cpp + crypto_diff_fuzz_chacha20.cpp + crypto_hkdf_hmac_sha256_l32.cpp + crypto_poly1305.cpp + cuckoocache.cpp + decode_tx.cpp + descriptor_parse.cpp + deserialize.cpp + eval_script.cpp + fee_rate.cpp + fees.cpp + flatfile.cpp + float.cpp + golomb_rice.cpp + hex.cpp + http_request.cpp + integer.cpp + key.cpp + key_io.cpp + kitchen_sink.cpp + load_external_block_file.cpp + locale.cpp + merkleblock.cpp + message.cpp + miniscript.cpp + minisketch.cpp + muhash.cpp + multiplication_overflow.cpp + net.cpp + net_permissions.cpp + netaddress.cpp + netbase_dns_lookup.cpp + node_eviction.cpp + p2p_transport_serialization.cpp + parse_hd_keypath.cpp + parse_numbers.cpp + parse_script.cpp + parse_univalue.cpp + policy_estimator.cpp + policy_estimator_io.cpp + poolresource.cpp + pow.cpp + prevector.cpp + primitives_transaction.cpp + process_message.cpp + process_messages.cpp + protocol.cpp + psbt.cpp + random.cpp + rolling_bloom_filter.cpp + rpc.cpp + script.cpp + script_bitcoin_consensus.cpp + script_descriptor_cache.cpp + script_flags.cpp + script_format.cpp + script_interpreter.cpp + script_ops.cpp + script_sigcache.cpp + script_sign.cpp + scriptnum_ops.cpp + secp256k1_ec_seckey_import_export_der.cpp + secp256k1_ecdsa_signature_parse_der_lax.cpp + signature_checker.cpp + socks5.cpp + span.cpp + spanparsing.cpp + string.cpp + strprintf.cpp + system.cpp + timedata.cpp + torcontrol.cpp + transaction.cpp + tx_in.cpp + tx_out.cpp + tx_pool.cpp + txorphan.cpp + utxo_snapshot.cpp + utxo_total_supply.cpp + validation_load_mempool.cpp + versionbits.cpp +) +target_link_libraries(fuzz + core_interface + test_fuzz + bitcoin_cli + bitcoin_common + minisketch + leveldb + univalue + secp256k1 + Boost::headers + $ +) + +# When the fuzzing engine does not supply main(), fuzz.cpp has to. +if(NOT FUZZ_BINARY_LINKS_WITHOUT_MAIN_FUNCTION) + target_compile_definitions(fuzz PRIVATE PROVIDE_FUZZ_MAIN_FUNCTION) +endif() + +if(ENABLE_WALLET) + add_subdirectory(${PROJECT_SOURCE_DIR}/src/wallet/test/fuzz wallet) +endif() diff --git a/src/test/fuzz/util/CMakeLists.txt b/src/test/fuzz/util/CMakeLists.txt new file mode 100644 index 000000000000..c45acba82e9a --- /dev/null +++ b/src/test/fuzz/util/CMakeLists.txt @@ -0,0 +1,24 @@ +# 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_fuzz STATIC EXCLUDE_FROM_ALL + net.cpp + ../fuzz.cpp + ../util.cpp + ../../util/mining.cpp +) + +target_link_libraries(test_fuzz + PRIVATE + core_interface + test_util + bitcoin_node + Boost::headers + dashbls + leveldb +) + +if(NOT FUZZ_BINARY_LINKS_WITHOUT_MAIN_FUNCTION) + target_compile_definitions(test_fuzz PRIVATE PROVIDE_FUZZ_MAIN_FUNCTION) +endif() diff --git a/src/test/util/CMakeLists.txt b/src/test/util/CMakeLists.txt new file mode 100644 index 000000000000..86b76f8a50e2 --- /dev/null +++ b/src/test/util/CMakeLists.txt @@ -0,0 +1,31 @@ +# 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 + script.cpp + setup_common.cpp + str.cpp + transaction_utils.cpp + txmempool.cpp + validation.cpp + $<$:wallet.cpp> + $<$:${PROJECT_SOURCE_DIR}/src/wallet/test/util.cpp> +) + +target_link_libraries(test_util + PRIVATE + core_interface + Boost::headers + dashbls + leveldb + PUBLIC + univalue +) diff --git a/src/univalue/CMakeLists.txt b/src/univalue/CMakeLists.txt new file mode 100644 index 000000000000..96733fe07725 --- /dev/null +++ b/src/univalue/CMakeLists.txt @@ -0,0 +1,41 @@ +# 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(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_interface) + +if(BUILD_TESTS) + add_executable(unitester test/unitester.cpp) + target_compile_definitions(unitester + PRIVATE + JSON_TEST_SRC=\"${CMAKE_CURRENT_SOURCE_DIR}/test\" + ) + target_link_libraries(unitester + PRIVATE + core_interface + univalue + ) + add_test(NAME univalue_test + COMMAND unitester + ) + + add_executable(object test/object.cpp) + target_link_libraries(object + PRIVATE + core_interface + univalue + ) + add_test(NAME univalue_object_test + COMMAND object + ) +endif() diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt new file mode 100644 index 000000000000..783e6a7a6c74 --- /dev/null +++ b/src/util/CMakeLists.txt @@ -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/. + +add_library(bitcoin_util STATIC EXCLUDE_FROM_ALL + asmap.cpp + bip32.cpp + bytevectorhash.cpp + check.cpp + edge.cpp + error.cpp + fees.cpp + getuniquepath.cpp + hasher.cpp + message.cpp + moneystr.cpp + readwritefile.cpp + ranges_set.cpp + serfloat.cpp + settings.cpp + sock.cpp + spanparsing.cpp + strencodings.cpp + string.cpp + system.cpp + syserror.cpp + thread.cpp + threadinterrupt.cpp + threadnames.cpp + time.cpp + tokenpipe.cpp + wpipe.cpp + ../bls/bls_ies.cpp + ../bls/bls_worker.cpp + ../coinjoin/common.cpp + ../coinjoin/options.cpp + ../fs.cpp + ../interfaces/echo.cpp + ../interfaces/handler.cpp + ../interfaces/init.cpp + ../logging.cpp + ../messagesigner.cpp + ../random.cpp + ../randomenv.cpp + ../stacktraces.cpp + ../support/cleanse.cpp + ../support/lockedpool.cpp + ../sync.cpp +) + +target_link_libraries(bitcoin_util + PRIVATE + core_interface + bitcoin_clientversion + bitcoin_crypto + Boost::headers + dashbls + univalue + $<$:ws2_32> +) diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt new file mode 100644 index 000000000000..a6f2a2596989 --- /dev/null +++ b/src/wallet/CMakeLists.txt @@ -0,0 +1,65 @@ +# 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/. + +# Wallet functionality used by bitcoind and bitcoin-wallet executables. +add_library(bitcoin_wallet STATIC EXCLUDE_FROM_ALL + ../coinjoin/client.cpp + ../coinjoin/interfaces.cpp + ../coinjoin/util.cpp + bip39.cpp + coinjoin.cpp + coincontrol.cpp + coinselection.cpp + context.cpp + crypter.cpp + db.cpp + dump.cpp + external_signer_scriptpubkeyman.cpp + fees.cpp + hdchain.cpp + interfaces.cpp + load.cpp + receive.cpp + rpc/addresses.cpp + rpc/backup.cpp + rpc/coins.cpp + rpc/encrypt.cpp + rpc/signmessage.cpp + rpc/spend.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_interface + bitcoin_common + leveldb + dashbls + 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() diff --git a/src/wallet/test/CMakeLists.txt b/src/wallet/test/CMakeLists.txt new file mode 100644 index 000000000000..3b4bcbc1316e --- /dev/null +++ b/src/wallet/test/CMakeLists.txt @@ -0,0 +1,32 @@ +# 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/. + +# Do not use generator expressions in test sources because the +# SOURCES property is processed to gather test suite macros. +target_sources(test_bitcoin + PRIVATE + init_test_fixture.cpp + wallet_test_fixture.cpp + availablecoins_tests.cpp + bip39_tests.cpp + coinjoin_tests.cpp + coinselector_tests.cpp + init_tests.cpp + ismine_tests.cpp + psbt_wallet_tests.cpp + rpc_util_tests.cpp + scriptpubkeyman_tests.cpp + spend_tests.cpp + wallet_crypto_tests.cpp + wallet_tests.cpp + wallet_transaction_tests.cpp + walletdb_tests.cpp +) +if(USE_BDB) + target_sources(test_bitcoin + PRIVATE + db_tests.cpp + ) +endif() +target_link_libraries(test_bitcoin bitcoin_wallet) diff --git a/src/wallet/test/fuzz/CMakeLists.txt b/src/wallet/test/fuzz/CMakeLists.txt new file mode 100644 index 000000000000..48edf6302301 --- /dev/null +++ b/src/wallet/test/fuzz/CMakeLists.txt @@ -0,0 +1,12 @@ +# 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/. + +target_sources(fuzz + PRIVATE + coincontrol.cpp + coinselection.cpp + $<$:${CMAKE_CURRENT_LIST_DIR}/notifications.cpp> + parse_iso8601.cpp +) +target_link_libraries(fuzz bitcoin_wallet) diff --git a/src/zmq/CMakeLists.txt b/src/zmq/CMakeLists.txt new file mode 100644 index 000000000000..e7e7658dddd3 --- /dev/null +++ b/src/zmq/CMakeLists.txt @@ -0,0 +1,28 @@ +# 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 EXCLUDE_FROM_ALL + zmqabstractnotifier.cpp + zmqnotificationinterface.cpp + zmqpublishnotifier.cpp + zmqrpc.cpp + zmqutil.cpp +) +target_compile_definitions(bitcoin_zmq + INTERFACE + ENABLE_ZMQ=1 + PRIVATE + $<$,$>:ZMQ_STATIC> +) +target_link_libraries(bitcoin_zmq + PRIVATE + core_interface + univalue + # zmqpublishnotifier.cpp reaches dbwrapper.h through node/blockstorage.h + # and bls.h through chainlock/chainlock.h. + leveldb + dashbls + $ + $ +) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 000000000000..04ed75c78ad1 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,53 @@ +# 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(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) + # config.ini.in still uses the Autotools name; without this the placeholder + # expands to nothing and ENABLE_FUZZ is reported as true unconditionally. + # Autotools drives that entry from --enable-fuzz (BUILD_FOR_FUZZING here), + # but test/fuzz/test_runner.py only uses it to decide whether fuzz targets + # were built, so BUILD_FUZZ_BINARY is the more accurate source. + set_configure_variable(BUILD_FUZZ_BINARY ENABLE_FUZZ) + set_configure_variable(WITH_ZMQ ENABLE_ZMQ) + set_configure_variable(ENABLE_EXTERNAL_SIGNER ENABLE_EXTERNAL_SIGNER) + set_configure_variable(WITH_USDT 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) + +file(GLOB_RECURSE functional_tests RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} functional/*) +foreach(script ${functional_tests} fuzz/test_runner.py util/rpcauth-test.py util/test_runner.py) + if(CMAKE_HOST_WIN32) + set(symlink) + else() + set(symlink SYMBOLIC) + endif() + file(CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/${script} ${CMAKE_CURRENT_BINARY_DIR}/${script} COPY_ON_ERROR ${symlink}) +endforeach() +unset(functional_tests) diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index f97e9261a223..d2972187004a 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -585,9 +585,11 @@ def run_tests(*, test_list, src_dir, build_dir, tmpdir, jobs=1, attempts=1, enab print("%sWARNING!%s There is a cache directory here: %s. If tests fail unexpectedly, try deleting the cache directory." % (BOLD[1], BOLD[0], cache_dir)) + # Upstream reads the tests out of the build directory, which relies on the + # build system linking or copying them there. CMake does that (see + # test/CMakeLists.txt), but Autotools does not, so keep using the source + # directory while both build systems are supported. tests_dir = src_dir + '/test/functional/' - # This allows `test_runner.py` to work from an out-of-source build directory using a symlink, - # a hard link or a copy on any platform. See https://github.com/bitcoin/bitcoin/pull/27561. sys.path.append(tests_dir) if not skipunit: diff --git a/vcpkg.json b/vcpkg.json new file mode 100644 index 000000000000..ecbccb072c23 --- /dev/null +++ b/vcpkg.json @@ -0,0 +1,51 @@ +{ + "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json", + "builtin-baseline": "9edb1b8e590cc086563301d735cae4b6e732d2d2", + "overrides":[ + {"name": "libevent", "version": "2.1.12#7"}, + {"name": "liblzma", "version": "5.4.1#1"} + ], + "dependencies": [ + "boost-date-time", + "boost-multi-index", + "boost-signals2", + "libevent" + ], + "default-features": [ + "wallet", + "miniupnpc", + "zeromq", + "tests", + "qt5" + ], + "features": { + "wallet": { + "description": "Enable wallet", + "dependencies": [ "berkeleydb", "sqlite3" ] + }, + "sqlite": { + "description": "Enable SQLite wallet support", + "dependencies": [ "sqlite3" ] + }, + "berkeleydb": { + "description": "Enable Berkeley DB wallet support", + "dependencies": [ "berkeleydb" ] + }, + "miniupnpc": { + "description": "Enable UPnP", + "dependencies": [ "miniupnpc" ] + }, + "zeromq": { + "description": "Enable ZMQ notifications", + "dependencies": [ "zeromq" ] + }, + "tests": { + "description": "Build test_bitcoin.exe executable", + "dependencies": [ "boost-test" ] + }, + "qt5": { + "description": "Build GUI, Qt 5", + "dependencies": [ "qt5-base", "qt5-tools" ] + } + } +}