diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7961c3c9005db..6d3854cb6706a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,12 +67,12 @@ jobs: echo "TEST_BASE=$(git rev-list -n$((${{ env.MAX_COUNT }} + 1)) --reverse HEAD $EXCLUDE_MERGE_BASE_ANCESTORS | head -1)" >> "$GITHUB_ENV" - run: | sudo apt-get update - sudo apt-get install clang ccache build-essential libtool autotools-dev automake pkg-config bsdmainutils python3-zmq libevent-dev libboost-dev libsqlite3-dev libdb++-dev systemtap-sdt-dev libminiupnpc-dev libnatpmp-dev qtbase5-dev qttools5-dev qttools5-dev-tools qtwayland5 libqrencode-dev -y + sudo apt-get install clang ccache build-essential cmake pkg-config bsdmainutils python3-zmq libevent-dev libboost-dev libsqlite3-dev libdb++-dev systemtap-sdt-dev libminiupnpc-dev libnatpmp-dev qtbase5-dev qttools5-dev qttools5-dev-tools qtwayland5 libqrencode-dev -y - name: Compile and run tests run: | # Run tests on commits after the last merge commit and before the PR head commit # Use clang++, because it is a bit faster and uses less memory than g++ - git rebase --exec "echo Running test-one-commit on \$( git log -1 ) && ./autogen.sh && CC=clang CXX=clang++ ./configure --with-incompatible-bdb && make clean && make -j $(nproc) check && ./test/functional/test_runner.py -j $(( $(nproc) * 2 ))" ${{ env.TEST_BASE }} + git rebase --exec "echo Running test-one-commit on \$( git log -1 ) && CC=clang CXX=clang++ cmake -B build -DBUILD_GUI=ON -DBUILD_BENCH=ON -DBUILD_FUZZ_BINARY=ON -DWITH_BDB=ON -DWITH_NATPMP=ON -DWITH_MINIUPNPC=ON -DWITH_USDT=ON && cmake --build build -j $(nproc) && ctest --test-dir build -j $(nproc) && ./build/test/functional/test_runner.py -j $(( $(nproc) * 2 ))" ${{ env.TEST_BASE }} macos-native-x86_64: name: 'macOS 13 native, x86_64, no depends, sqlite only, gui' @@ -139,11 +139,6 @@ jobs: if: github.repository != 'bitcoin-core/gui' || github.event_name == 'pull_request' env: - CCACHE_MAXSIZE: '200M' - CI_CCACHE_VERSION: '4.7.5' - CI_QT_CONF: '-release -silent -opensource -confirm-license -opengl desktop -static -static-runtime -mp -qt-zlib -qt-pcre -qt-libpng -nomake examples -nomake tests -nomake tools -no-angle -no-dbus -no-gif -no-gtk -no-ico -no-icu -no-libjpeg -no-libudev -no-sql-sqlite -no-sql-odbc -no-sqlite -no-vulkan -skip qt3d -skip qtactiveqt -skip qtandroidextras -skip qtcharts -skip qtconnectivity -skip qtdatavis3d -skip qtdeclarative -skip doc -skip qtdoc -skip qtgamepad -skip qtgraphicaleffects -skip qtimageformats -skip qtlocation -skip qtlottie -skip qtmacextras -skip qtmultimedia -skip qtnetworkauth -skip qtpurchasing -skip qtquick3d -skip qtquickcontrols -skip qtquickcontrols2 -skip qtquicktimeline -skip qtremoteobjects -skip qtscript -skip qtscxml -skip qtsensors -skip qtserialbus -skip qtserialport -skip qtspeech -skip qtsvg -skip qtvirtualkeyboard -skip qtwayland -skip qtwebchannel -skip qtwebengine -skip qtwebglplugin -skip qtwebsockets -skip qtwebview -skip qtx11extras -skip qtxmlpatterns -no-openssl -no-feature-bearermanagement -no-feature-printdialog -no-feature-printer -no-feature-printpreviewdialog -no-feature-printpreviewwidget -no-feature-sql -no-feature-sqlmodel -no-feature-textbrowser -no-feature-textmarkdownwriter -no-feature-textodfwriter -no-feature-xml' - CI_QT_DIR: 'qt-everywhere-src-5.15.11' - CI_QT_URL: 'https://download.qt.io/official_releases/qt/5.15/5.15.11/single/qt-everywhere-opensource-src-5.15.11.zip' PYTHONUTF8: 1 TEST_RUNNER_TIMEOUT_FACTOR: 40 @@ -151,6 +146,10 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Remove non-MSVC tool installations + run: | + Remove-Item -Path "$env:ProgramFiles/CMake" -Recurse -Force + - name: Configure Developer Command Prompt for Microsoft Visual C++ # Using microsoft/setup-msbuild is not enough. uses: ilammy/msvc-dev-cmd@v1 @@ -159,94 +158,18 @@ jobs: - name: Get tool information run: | + cmake -version | Tee-Object -FilePath "cmake_version" + Write-Output "---" msbuild -version | Tee-Object -FilePath "msbuild_version" $env:VCToolsVersion | Tee-Object -FilePath "toolset_version" - $env:CI_QT_URL | Out-File -FilePath "qt_url" - $env:CI_QT_CONF | Out-File -FilePath "qt_conf" py -3 --version Write-Host "PowerShell version $($PSVersionTable.PSVersion.ToString())" - - name: Restore static Qt cache - id: static-qt-cache - uses: actions/cache/restore@v4 - with: - path: C:\Qt_static - key: ${{ github.job }}-static-qt-${{ hashFiles('msbuild_version', 'qt_url', 'qt_conf') }} - - - name: Build static Qt. Download - if: steps.static-qt-cache.outputs.cache-hit != 'true' - shell: cmd - run: | - curl --location --output C:\qt-src.zip %CI_QT_URL% - choco install --yes --no-progress jom - - - name: Build static Qt. Expand source archive - if: steps.static-qt-cache.outputs.cache-hit != 'true' - shell: cmd - run: tar -xf C:\qt-src.zip -C C:\ - - - name: Build static Qt. Create build directory - if: steps.static-qt-cache.outputs.cache-hit != 'true' - run: | - Rename-Item -Path "C:\$env:CI_QT_DIR" -NewName "C:\qt-src" - New-Item -ItemType Directory -Path "C:\qt-src\build" - - - name: Build static Qt. Configure - if: steps.static-qt-cache.outputs.cache-hit != 'true' - working-directory: C:\qt-src\build - shell: cmd - run: ..\configure %CI_QT_CONF% -prefix C:\Qt_static - - - name: Build static Qt. Build - if: steps.static-qt-cache.outputs.cache-hit != 'true' - working-directory: C:\qt-src\build - shell: cmd - run: jom - - - name: Build static Qt. Install - if: steps.static-qt-cache.outputs.cache-hit != 'true' - working-directory: C:\qt-src\build - shell: cmd - run: jom install - - - name: Save static Qt cache - if: steps.static-qt-cache.outputs.cache-hit != 'true' - uses: actions/cache/save@v4 - with: - path: C:\Qt_static - key: ${{ github.job }}-static-qt-${{ hashFiles('msbuild_version', 'qt_url', 'qt_conf') }} - - - name: Ccache installation cache - id: ccache-installation-cache - uses: actions/cache@v4 - with: - path: | - C:\ProgramData\chocolatey\lib\ccache - C:\ProgramData\chocolatey\bin\ccache.exe - C:\ccache\cl.exe - key: ${{ github.job }}-ccache-installation-${{ env.CI_CCACHE_VERSION }} - - - name: Install Ccache - if: steps.ccache-installation-cache.outputs.cache-hit != 'true' - run: | - choco install --yes --no-progress ccache --version=$env:CI_CCACHE_VERSION - New-Item -ItemType Directory -Path "C:\ccache" - Copy-Item -Path "$env:ChocolateyInstall\lib\ccache\tools\ccache-$env:CI_CCACHE_VERSION-windows-x86_64\ccache.exe" -Destination "C:\ccache\cl.exe" - - - name: Restore Ccache cache - id: ccache-cache - uses: actions/cache/restore@v4 - with: - path: ~/AppData/Local/ccache - key: ${{ github.job }}-ccache-${{ github.run_id }} - restore-keys: ${{ github.job }}-ccache- - - name: Using vcpkg with MSBuild run: | Set-Location "$env:VCPKG_INSTALLATION_ROOT" + Add-Content -Path "triplets\x64-windows.cmake" -Value "set(VCPKG_BUILD_TYPE release)" Add-Content -Path "triplets\x64-windows-static.cmake" -Value "set(VCPKG_BUILD_TYPE release)" - .\vcpkg.exe --vcpkg-root "$env:VCPKG_INSTALLATION_ROOT" integrate install - git rev-parse HEAD | Tee-Object -FilePath "$env:GITHUB_WORKSPACE\vcpkg_commit" - name: vcpkg tools cache uses: actions/cache@v4 @@ -254,46 +177,41 @@ jobs: path: C:/vcpkg/downloads/tools key: ${{ github.job }}-vcpkg-tools - - name: vcpkg binary cache - uses: actions/cache@v4 + - name: Restore vcpkg binary cache + uses: actions/cache/restore@v4 + id: vcpkg-binary-cache with: path: ~/AppData/Local/vcpkg/archives - key: ${{ github.job }}-vcpkg-binary-${{ hashFiles('vcpkg_commit', 'msbuild_version', 'toolset_version', 'build_msvc/vcpkg.json') }} - - - name: Generate project files - run: py -3 build_msvc\msvc-autogen.py + key: ${{ github.job }}-vcpkg-binary-${{ hashFiles('cmake_version', 'msbuild_version', 'toolset_version', 'vcpkg.json') }} - - name: Build - shell: cmd + - name: Generate build system run: | - ccache --zero-stats - msbuild build_msvc\bitcoin.sln -property:CLToolPath=C:\ccache;CLToolExe=cl.exe;UseMultiToolTask=true;Configuration=Release -maxCpuCount -verbosity:minimal -noLogo - - - name: Ccache stats - run: ccache --show-stats + cmake -B build --preset vs2022-static -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT\scripts\buildsystems\vcpkg.cmake" -DBUILD_BENCH=ON -DBUILD_FUZZ_BINARY=ON -DWERROR=ON - - name: Save Ccache cache + - name: Save vcpkg binary cache uses: actions/cache/save@v4 - if: github.event_name != 'pull_request' && steps.ccache-cache.outputs.cache-hit != 'true' + if: github.event_name != 'pull_request' && steps.vcpkg-binary-cache.outputs.cache-hit != 'true' with: - path: ~/AppData/Local/ccache - # https://github.com/actions/cache/blob/main/tips-and-workarounds.md#update-a-cache - key: ${{ github.job }}-ccache-${{ github.run_id }} - - - name: Run unit tests - run: src\test_bitcoin.exe -l test_suite - - - name: Run benchmarks - run: src\bench_bitcoin.exe -sanity-check + path: ~/AppData/Local/vcpkg/archives + key: ${{ github.job }}-vcpkg-binary-${{ hashFiles('cmake_version', 'msbuild_version', 'toolset_version', 'vcpkg.json') }} - - name: Run util tests - run: py -3 test\util\test_runner.py + - name: Build + working-directory: build + run: | + cmake --build . -j $env:NUMBER_OF_PROCESSORS --config Release - - name: Run rpcauth test - run: py -3 test\util\rpcauth-test.py + - name: Run test suite + working-directory: build + run: | + ctest -j $env:NUMBER_OF_PROCESSORS -C Release - name: Run functional tests + working-directory: build env: + BITCOIND: '${{ github.workspace }}\build\src\Release\bitcoind.exe' + BITCOINCLI: '${{ github.workspace }}\build\src\Release\bitcoin-cli.exe' + BITCOINUTIL: '${{ github.workspace }}\build\src\Release\bitcoin-util.exe' + BITCOINWALLET: '${{ github.workspace }}\build\src\Release\bitcoin-wallet.exe' TEST_RUNNER_EXTRA: ${{ github.event_name != 'pull_request' && '--extended' || '' }} shell: cmd run: py -3 test\functional\test_runner.py --jobs %NUMBER_OF_PROCESSORS% --ci --quiet --tmpdirprefix=%RUNNER_TEMP% --combinedlogslen=99999999 --timeout-factor=%TEST_RUNNER_TIMEOUT_FACTOR% %TEST_RUNNER_EXTRA% @@ -306,8 +224,9 @@ jobs: git log -1 - name: Run fuzz binaries + working-directory: build env: - BITCOINFUZZ: "${{ github.workspace}}\\src\\fuzz.exe" + BITCOINFUZZ: '${{ github.workspace }}\build\src\test\fuzz\Release\fuzz.exe' shell: cmd run: py -3 test\fuzz\test_runner.py --par %NUMBER_OF_PROCESSORS% --loglevel DEBUG %RUNNER_TEMP%\qa-assets\fuzz_seed_corpus diff --git a/.gitignore b/.gitignore index f7bcbd145986d..a09c95d8fa60d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ +# Build subdirectories. +/*build* +!/build-aux +!/build_msvc + *.tar.gz *.exe diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000000000..32db4189d49a0 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,662 @@ +# 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/. + +# 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 "Bitcoin Core") +set(CLIENT_VERSION_MAJOR 27) +set(CLIENT_VERSION_MINOR 99) +set(CLIENT_VERSION_BUILD 0) +set(CLIENT_VERSION_RC 0) +set(CLIENT_VERSION_IS_RELEASE "false") +set(COPYRIGHT_YEAR "2024") + +# 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 "Bitcoin client software" + HOMEPAGE_URL "https://bitcoincore.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/bitcoin/bitcoin/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) +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}) + +option(BUILD_UTIL_CHAINSTATE "Build experimental bitcoin-chainstate executable." OFF) +option(BUILD_KERNEL_LIB "Build experimental bitcoinkernel library." ${BUILD_UTIL_CHAINSTATE}) + +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(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() + +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> +) + +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_KERNEL_LIB 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(msvc_library_linkage "DLL") + endif() + 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() + +# 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(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() + +set(THREADS_PREFER_PTHREAD_FLAG ON) +find_package(Threads REQUIRED) +target_link_libraries(core_interface INTERFACE + Threads::Threads +) + +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" + ) +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 core_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() + +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(" libbitcoinkernel (experimental) ..... ${BUILD_KERNEL_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() + +# We want all build properties to be encapsulated properly. +include(WarnAboutGlobalProperties) diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000000000..a5f2ce79191fe --- /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 2eab2315eb6ea..cf106ad687ac4 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ 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`. 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/test/00_setup_env.sh b/ci/test/00_setup_env.sh index b9e6818afbccd..98098c9e75c60 100755 --- a/ci/test/00_setup_env.sh +++ b/ci/test/00_setup_env.sh @@ -61,8 +61,6 @@ export CCACHE_COMPRESS=${CCACHE_COMPRESS:-1} export CCACHE_DIR=${CCACHE_DIR:-$BASE_SCRATCH_DIR/.ccache} # Folder where the build result is put (bin and lib). export BASE_OUTDIR=${BASE_OUTDIR:-$BASE_SCRATCH_DIR/out} -# Folder where the build is done (dist and out-of-tree build). -export BASE_BUILD_DIR=${BASE_BUILD_DIR:-$BASE_SCRATCH_DIR/build} # The folder for previous release binaries. # This folder exists only on the ci guest, and on the ci host as a volume. export PREVIOUS_RELEASES_DIR=${PREVIOUS_RELEASES_DIR:-$BASE_ROOT_DIR/prev_releases} diff --git a/ci/test/00_setup_env_arm.sh b/ci/test/00_setup_env_arm.sh index 396e7829593d8..749ae86cb2ba8 100755 --- a/ci/test/00_setup_env_arm.sh +++ b/ci/test/00_setup_env_arm.sh @@ -17,4 +17,4 @@ export RUN_FUNCTIONAL_TESTS=false export GOAL="install" # -Wno-psabi is to disable ABI warnings: "note: parameter passing for argument of type ... changed in GCC 7.1" # This could be removed once the ABI change warning does not show up by default -export BITCOIN_CONFIG="--enable-reduce-exports CXXFLAGS='-Wno-psabi -Wno-error=maybe-uninitialized'" +export BITCOIN_CONFIG="-DREDUCE_EXPORTS=ON -DCMAKE_CXX_FLAGS='-Wno-psabi -Wno-error=maybe-uninitialized'" diff --git a/ci/test/00_setup_env_i686_centos.sh b/ci/test/00_setup_env_i686_centos.sh index 5f8391c5dacfd..881f006732575 100755 --- a/ci/test/00_setup_env_i686_centos.sh +++ b/ci/test/00_setup_env_i686_centos.sh @@ -13,5 +13,5 @@ export CI_BASE_PACKAGES="gcc-c++ glibc-devel.x86_64 libstdc++-devel.x86_64 glibc export PIP_PACKAGES="pyzmq" export GOAL="install" export NO_WERROR=1 # Suppress error: #warning _FORTIFY_SOURCE > 2 is treated like 2 on this platform [-Werror=cpp] -export BITCOIN_CONFIG="--enable-zmq --with-gui=qt5 --enable-reduce-exports" +export BITCOIN_CONFIG="-DWITH_ZMQ=ON -DBUILD_GUI=ON -DREDUCE_EXPORTS=ON" export CONFIG_SHELL="/bin/dash" diff --git a/ci/test/00_setup_env_i686_multiprocess.sh b/ci/test/00_setup_env_i686_multiprocess.sh index f6463438d3959..5810ae8639fa8 100755 --- a/ci/test/00_setup_env_i686_multiprocess.sh +++ b/ci/test/00_setup_env_i686_multiprocess.sh @@ -13,6 +13,11 @@ export PACKAGES="llvm clang g++-multilib" export DEP_OPTS="DEBUG=1 MULTIPROCESS=1" export GOAL="install" export TEST_RUNNER_EXTRA="--v2transport" -export BITCOIN_CONFIG="--enable-debug CC='clang -m32' CXX='clang++ -m32' \ -CPPFLAGS='-DBOOST_MULTI_INDEX_ENABLE_SAFE_MODE' CXXFLAGS='-Wno-error=documentation'" +export BITCOIN_CONFIG="\ + -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_C_COMPILER='clang;-m32' \ + -DCMAKE_CXX_COMPILER='clang++;-m32' \ + -DCMAKE_CXX_FLAGS='-Wno-error=documentation' \ + -DAPPEND_CPPFLAGS='-DBOOST_MULTI_INDEX_ENABLE_SAFE_MODE' \ +" export BITCOIND=bitcoin-node # Used in functional tests diff --git a/ci/test/00_setup_env_mac_cross.sh b/ci/test/00_setup_env_mac_cross.sh index f607c93ae6016..6a1e116a547b7 100755 --- a/ci/test/00_setup_env_mac_cross.sh +++ b/ci/test/00_setup_env_mac_cross.sh @@ -17,4 +17,4 @@ export XCODE_BUILD_ID=15A240d export RUN_UNIT_TESTS=false export RUN_FUNCTIONAL_TESTS=false export GOAL="deploy" -export BITCOIN_CONFIG="--with-gui --enable-reduce-exports" +export BITCOIN_CONFIG="-DBUILD_GUI=ON -DREDUCE_EXPORTS=ON" diff --git a/ci/test/00_setup_env_mac_native.sh b/ci/test/00_setup_env_mac_native.sh index c47f13f96ed30..6076740887024 100755 --- a/ci/test/00_setup_env_mac_native.sh +++ b/ci/test/00_setup_env_mac_native.sh @@ -11,7 +11,7 @@ export HOST=x86_64-apple-darwin # Therefore, `--break-system-packages` is needed. export PIP_PACKAGES="--break-system-packages zmq" export GOAL="install" -export BITCOIN_CONFIG="--with-gui --with-miniupnpc --with-natpmp --enable-reduce-exports" +export BITCOIN_CONFIG="-DBUILD_GUI=ON -DWITH_MINIUPNPC=ON -DWITH_NATPMP=ON -DREDUCE_EXPORTS=ON" export CI_OS_NAME="macos" export NO_DEPENDS=1 export OSX_SDK="" diff --git a/ci/test/00_setup_env_native_asan.sh b/ci/test/00_setup_env_native_asan.sh index 9ab08fb4a3ff5..173b5b71c9552 100755 --- a/ci/test/00_setup_env_native_asan.sh +++ b/ci/test/00_setup_env_native_asan.sh @@ -22,8 +22,13 @@ export CONTAINER_NAME=ci_native_asan export PACKAGES="systemtap-sdt-dev clang-18 llvm-18 libclang-rt-18-dev python3-zmq qtbase5-dev qttools5-dev qttools5-dev-tools libevent-dev libboost-dev libdb5.3++-dev libminiupnpc-dev libnatpmp-dev libzmq3-dev libqrencode-dev libsqlite3-dev ${BPFCC_PACKAGE}" export NO_DEPENDS=1 export GOAL="install" -export BITCOIN_CONFIG="--enable-usdt --enable-zmq --with-incompatible-bdb --with-gui=qt5 \ -CPPFLAGS='-DARENA_DEBUG -DDEBUG_LOCKORDER' \ ---with-sanitizers=address,float-divide-by-zero,integer,undefined \ -CC='clang-18 -ftrivial-auto-var-init=pattern' CXX='clang++-18 -ftrivial-auto-var-init=pattern'" +export BITCOIN_CONFIG="\ + -DWITH_USDT=ON -DWITH_ZMQ=ON -DWARN_INCOMPATIBLE_BDB=OFF -DBUILD_GUI=ON \ + -DSANITIZERS=address,float-divide-by-zero,integer,undefined \ + -DCMAKE_C_COMPILER=clang-18 \ + -DCMAKE_CXX_COMPILER=clang++-18 \ + -DCMAKE_C_FLAGS='-ftrivial-auto-var-init=pattern' \ + -DCMAKE_CXX_FLAGS='-ftrivial-auto-var-init=pattern' \ + -DAPPEND_CPPFLAGS='-DARENA_DEBUG -DDEBUG_LOCKORDER' \ +" export CCACHE_MAXSIZE=300M diff --git a/ci/test/00_setup_env_native_fuzz.sh b/ci/test/00_setup_env_native_fuzz.sh index f50561f875078..e1a353056df8f 100755 --- a/ci/test/00_setup_env_native_fuzz.sh +++ b/ci/test/00_setup_env_native_fuzz.sh @@ -15,7 +15,13 @@ export RUN_FUNCTIONAL_TESTS=false export RUN_FUZZ_TESTS=true export GOAL="install" export CI_CONTAINER_CAP="--cap-add SYS_PTRACE" # If run with (ASan + LSan), the container needs access to ptrace (https://github.com/google/sanitizers/issues/764) -export BITCOIN_CONFIG="--enable-fuzz --with-sanitizers=fuzzer,address,undefined,float-divide-by-zero,integer \ -CC='clang-18 -ftrivial-auto-var-init=pattern' CXX='clang++-18 -ftrivial-auto-var-init=pattern'" +export BITCOIN_CONFIG="\ + -DBUILD_FOR_FUZZING=ON \ + -DSANITIZERS=fuzzer,address,undefined,float-divide-by-zero,integer \ + -DCMAKE_C_COMPILER=clang-18 \ + -DCMAKE_CXX_COMPILER=clang++-18 \ + -DCMAKE_C_FLAGS='-ftrivial-auto-var-init=pattern' \ + -DCMAKE_CXX_FLAGS='-ftrivial-auto-var-init=pattern' \ +" export CCACHE_MAXSIZE=200M export LLVM_SYMBOLIZER_PATH="/usr/bin/llvm-symbolizer-18" diff --git a/ci/test/00_setup_env_native_fuzz_with_msan.sh b/ci/test/00_setup_env_native_fuzz_with_msan.sh index f1c358082d5c1..85f02c01c522f 100755 --- a/ci/test/00_setup_env_native_fuzz_with_msan.sh +++ b/ci/test/00_setup_env_native_fuzz_with_msan.sh @@ -18,7 +18,11 @@ export PACKAGES="ninja-build" export DEP_OPTS="DEBUG=1 NO_BDB=1 NO_QT=1 CC=clang CXX=clang++ CFLAGS='${MSAN_FLAGS}' CXXFLAGS='${MSAN_AND_LIBCXX_FLAGS}'" export GOAL="install" # _FORTIFY_SOURCE is not compatible with MSAN. -export BITCOIN_CONFIG="--enable-fuzz --with-sanitizers=fuzzer,memory CPPFLAGS='-DBOOST_MULTI_INDEX_ENABLE_SAFE_MODE -U_FORTIFY_SOURCE'" +export BITCOIN_CONFIG="\ + -DBUILD_FOR_FUZZING=ON \ + -DSANITIZERS=fuzzer,memory \ + -DAPPEND_CPPFLAGS='-DBOOST_MULTI_INDEX_ENABLE_SAFE_MODE -U_FORTIFY_SOURCE' \ +" export USE_MEMORY_SANITIZER="true" export RUN_UNIT_TESTS="false" export RUN_FUNCTIONAL_TESTS="false" diff --git a/ci/test/00_setup_env_native_fuzz_with_valgrind.sh b/ci/test/00_setup_env_native_fuzz_with_valgrind.sh index bf4d1573e3ccf..02903b5199590 100755 --- a/ci/test/00_setup_env_native_fuzz_with_valgrind.sh +++ b/ci/test/00_setup_env_native_fuzz_with_valgrind.sh @@ -15,5 +15,10 @@ export RUN_FUNCTIONAL_TESTS=false export RUN_FUZZ_TESTS=true export FUZZ_TESTS_CONFIG="--valgrind" export GOAL="install" -export BITCOIN_CONFIG="--enable-fuzz --with-sanitizers=fuzzer CC=clang-16 CXX=clang++-16" +export BITCOIN_CONFIG="\ + -DBUILD_FOR_FUZZING=ON \ + -DSANITIZERS=fuzzer \ + -DCMAKE_C_COMPILER=clang-16 \ + -DCMAKE_CXX_COMPILER=clang++-16 \ +" export CCACHE_MAXSIZE=200M diff --git a/ci/test/00_setup_env_native_msan.sh b/ci/test/00_setup_env_native_msan.sh index dd465cac2e295..85a1d3bd48e0a 100755 --- a/ci/test/00_setup_env_native_msan.sh +++ b/ci/test/00_setup_env_native_msan.sh @@ -18,7 +18,7 @@ export PACKAGES="ninja-build" export DEP_OPTS="DEBUG=1 NO_BDB=1 NO_QT=1 CC=clang CXX=clang++ CFLAGS='${MSAN_FLAGS}' CXXFLAGS='${MSAN_AND_LIBCXX_FLAGS}'" export GOAL="install" # _FORTIFY_SOURCE is not compatible with MSAN. -export BITCOIN_CONFIG="--with-sanitizers=memory CPPFLAGS='-U_FORTIFY_SOURCE'" +export BITCOIN_CONFIG="-DSANITIZERS=memory -DAPPEND_CPPFLAGS='-U_FORTIFY_SOURCE'" export USE_MEMORY_SANITIZER="true" export RUN_FUNCTIONAL_TESTS="false" export CCACHE_MAXSIZE=250M diff --git a/ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh b/ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh index 49660aac0c147..479628d3e8e45 100755 --- a/ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh +++ b/ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh @@ -7,9 +7,9 @@ export LC_ALL=C.UTF-8 export CONTAINER_NAME=ci_native_nowallet_libbitcoinkernel -export CI_IMAGE_NAME_TAG="docker.io/debian:bullseye" -# Use minimum supported python3.9 and clang-16, see doc/dependencies.md +export CI_IMAGE_NAME_TAG="docker.io/debian:bookworm" +# Use minimum supported python3.9 (or best-effort 3.11) and clang-16, see doc/dependencies.md export PACKAGES="python3-zmq clang-16 llvm-16 libc++abi-16-dev libc++-16-dev" export DEP_OPTS="NO_WALLET=1 CC=clang-16 CXX='clang++-16 -stdlib=libc++'" export GOAL="install" -export BITCOIN_CONFIG="--enable-reduce-exports --enable-experimental-util-chainstate --with-experimental-kernel-lib --enable-shared" +export BITCOIN_CONFIG="-DREDUCE_EXPORTS=ON -DBUILD_UTIL_CHAINSTATE=ON -DBUILD_KERNEL_LIB=ON -DBUILD_SHARED_LIBS=ON" diff --git a/ci/test/00_setup_env_native_previous_releases.sh b/ci/test/00_setup_env_native_previous_releases.sh index 9da3b18999c24..2482e545e1354 100755 --- a/ci/test/00_setup_env_native_previous_releases.sh +++ b/ci/test/00_setup_env_native_previous_releases.sh @@ -16,5 +16,12 @@ export RUN_UNIT_TESTS_SEQUENTIAL="true" export RUN_UNIT_TESTS="false" export GOAL="install" export DOWNLOAD_PREVIOUS_RELEASES="true" -export BITCOIN_CONFIG="--enable-zmq --with-gui=qt5 --enable-reduce-exports --enable-debug \ -CFLAGS=\"-g0 -O2 -funsigned-char\" CPPFLAGS='-DBOOST_MULTI_INDEX_ENABLE_SAFE_MODE' CXXFLAGS=\"-g0 -O2 -funsigned-char\"" +export BITCOIN_CONFIG="\ + -DWITH_ZMQ=ON -DBUILD_GUI=ON -DREDUCE_EXPORTS=ON \ + -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_C_FLAGS='-funsigned-char' \ + -DCMAKE_C_FLAGS_DEBUG='-g0 -O2' \ + -DCMAKE_CXX_FLAGS='-funsigned-char' \ + -DCMAKE_CXX_FLAGS_DEBUG='-g0 -O2' \ + -DAPPEND_CPPFLAGS='-DBOOST_MULTI_INDEX_ENABLE_SAFE_MODE' \ +" diff --git a/ci/test/00_setup_env_native_tidy.sh b/ci/test/00_setup_env_native_tidy.sh index 5f422bbdb6e02..beebf180adc75 100755 --- a/ci/test/00_setup_env_native_tidy.sh +++ b/ci/test/00_setup_env_native_tidy.sh @@ -9,12 +9,18 @@ export LC_ALL=C.UTF-8 export CI_IMAGE_NAME_TAG="docker.io/ubuntu:24.04" export CONTAINER_NAME=ci_native_tidy export TIDY_LLVM_V="18" -export PACKAGES="clang-${TIDY_LLVM_V} libclang-${TIDY_LLVM_V}-dev llvm-${TIDY_LLVM_V}-dev libomp-${TIDY_LLVM_V}-dev clang-tidy-${TIDY_LLVM_V} jq bear libevent-dev libboost-dev libminiupnpc-dev libnatpmp-dev libzmq3-dev systemtap-sdt-dev qtbase5-dev qttools5-dev qttools5-dev-tools libqrencode-dev libsqlite3-dev libdb++-dev" +export PACKAGES="clang-${TIDY_LLVM_V} libclang-${TIDY_LLVM_V}-dev llvm-${TIDY_LLVM_V}-dev libomp-${TIDY_LLVM_V}-dev clang-tidy-${TIDY_LLVM_V} jq libevent-dev libboost-dev libminiupnpc-dev libnatpmp-dev libzmq3-dev systemtap-sdt-dev qtbase5-dev qttools5-dev qttools5-dev-tools libqrencode-dev libsqlite3-dev libdb++-dev" export NO_DEPENDS=1 export RUN_UNIT_TESTS=false export RUN_FUNCTIONAL_TESTS=false export RUN_FUZZ_TESTS=false export RUN_TIDY=true export GOAL="install" -export BITCOIN_CONFIG="CC=clang-${TIDY_LLVM_V} CXX=clang++-${TIDY_LLVM_V} --with-incompatible-bdb --disable-hardening CFLAGS='-O0 -g0' CXXFLAGS='-O0 -g0'" +export BITCOIN_CONFIG="\ + -DWARN_INCOMPATIBLE_BDB=OFF -DENABLE_HARDENING=OFF \ + -DCMAKE_C_COMPILER=clang-${TIDY_LLVM_V} \ + -DCMAKE_CXX_COMPILER=clang++-${TIDY_LLVM_V} \ + -DCMAKE_C_FLAGS_RELWITHDEBINFO='-O0 -g0' \ + -DCMAKE_CXX_FLAGS_RELWITHDEBINFO='-O0 -g0' \ +" export CCACHE_MAXSIZE=200M diff --git a/ci/test/00_setup_env_native_tsan.sh b/ci/test/00_setup_env_native_tsan.sh index 5bfbb4cbf1a55..9c2da778b484b 100755 --- a/ci/test/00_setup_env_native_tsan.sh +++ b/ci/test/00_setup_env_native_tsan.sh @@ -11,4 +11,5 @@ export CI_IMAGE_NAME_TAG="docker.io/ubuntu:24.04" export PACKAGES="clang-18 llvm-18 libclang-rt-18-dev libc++abi-18-dev libc++-18-dev python3-zmq" export DEP_OPTS="CC=clang-18 CXX='clang++-18 -stdlib=libc++'" export GOAL="install" -export BITCOIN_CONFIG="--enable-zmq CPPFLAGS='-DARENA_DEBUG -DDEBUG_LOCKORDER -DDEBUG_LOCKCONTENTION -D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES' --with-sanitizers=thread" +export BITCOIN_CONFIG="-DWITH_ZMQ=ON -DSANITIZERS=thread \ +-DAPPEND_CPPFLAGS='-DARENA_DEBUG -DDEBUG_LOCKORDER -DDEBUG_LOCKCONTENTION -D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES'" diff --git a/ci/test/00_setup_env_native_valgrind.sh b/ci/test/00_setup_env_native_valgrind.sh index ebef590c0a9e0..341f267d949ba 100755 --- a/ci/test/00_setup_env_native_valgrind.sh +++ b/ci/test/00_setup_env_native_valgrind.sh @@ -13,4 +13,9 @@ export USE_VALGRIND=1 export NO_DEPENDS=1 export TEST_RUNNER_EXTRA="--exclude feature_init,rpc_bind,feature_bind_extra" # feature_init excluded for now, see https://github.com/bitcoin/bitcoin/issues/30011 ; bind tests excluded for now, see https://github.com/bitcoin/bitcoin/issues/17765#issuecomment-602068547 export GOAL="install" -export BITCOIN_CONFIG="--enable-zmq --with-incompatible-bdb --with-gui=no CC=clang-16 CXX=clang++-16" # TODO enable GUI +# TODO enable GUI +export BITCOIN_CONFIG="\ + -DWITH_ZMQ=ON -DWARN_INCOMPATIBLE_BDB=OFF -DBUILD_GUI=OFF \ + -DCMAKE_C_COMPILER=clang-16 \ + -DCMAKE_CXX_COMPILER=clang++-16 \ +" diff --git a/ci/test/00_setup_env_s390x.sh b/ci/test/00_setup_env_s390x.sh index 2fd94e253cac7..eb12bc6fd179b 100755 --- a/ci/test/00_setup_env_s390x.sh +++ b/ci/test/00_setup_env_s390x.sh @@ -13,4 +13,4 @@ export CI_IMAGE_NAME_TAG="docker.io/s390x/ubuntu:24.04" export TEST_RUNNER_EXTRA="--exclude rpc_bind,feature_bind_extra" # Excluded for now, see https://github.com/bitcoin/bitcoin/issues/17765#issuecomment-602068547 export RUN_FUNCTIONAL_TESTS=true export GOAL="install" -export BITCOIN_CONFIG="--enable-reduce-exports" +export BITCOIN_CONFIG="-DREDUCE_EXPORTS=ON" diff --git a/ci/test/00_setup_env_win64.sh b/ci/test/00_setup_env_win64.sh index bf80d5d435f0e..15b9e407b6051 100755 --- a/ci/test/00_setup_env_win64.sh +++ b/ci/test/00_setup_env_win64.sh @@ -16,4 +16,5 @@ export GOAL="deploy" # Prior to 11.0.0, the mingw-w64 headers were missing noreturn attributes, causing warnings when # cross-compiling for Windows. https://sourceforge.net/p/mingw-w64/bugs/306/ # https://github.com/mingw-w64/mingw-w64/commit/1690994f515910a31b9fb7c7bd3a52d4ba987abe -export BITCOIN_CONFIG="--enable-reduce-exports --disable-gui-tests CXXFLAGS='-Wno-return-type -Wno-error=maybe-uninitialized -Wno-error=array-bounds'" +export BITCOIN_CONFIG="-DREDUCE_EXPORTS=ON -DBUILD_GUI_TESTS=OFF \ +-DCMAKE_CXX_FLAGS='-Wno-error=return-type -Wno-error=maybe-uninitialized -Wno-error=array-bounds'" diff --git a/ci/test/03_test_script.sh b/ci/test/03_test_script.sh index 1d7a9d76dbbfe..3088898c6a63b 100755 --- a/ci/test/03_test_script.sh +++ b/ci/test/03_test_script.sh @@ -99,51 +99,37 @@ if [ "$DOWNLOAD_PREVIOUS_RELEASES" = "true" ]; then test/get_previous_releases.py -b -t "$PREVIOUS_RELEASES_DIR" fi -BITCOIN_CONFIG_ALL="--disable-dependency-tracking" +BITCOIN_CONFIG_ALL="-DBUILD_BENCH=ON -DBUILD_FUZZ_BINARY=ON" if [ -z "$NO_DEPENDS" ]; then - BITCOIN_CONFIG_ALL="${BITCOIN_CONFIG_ALL} CONFIG_SITE=$DEPENDS_DIR/$HOST/share/config.site" + BITCOIN_CONFIG_ALL="${BITCOIN_CONFIG_ALL} -DCMAKE_TOOLCHAIN_FILE=$DEPENDS_DIR/$HOST/toolchain.cmake" fi if [ -z "$NO_WERROR" ]; then - BITCOIN_CONFIG_ALL="${BITCOIN_CONFIG_ALL} --enable-werror" + BITCOIN_CONFIG_ALL="${BITCOIN_CONFIG_ALL} -DWERROR=ON" fi ccache --zero-stats PRINT_CCACHE_STATISTICS="ccache --version | head -n 1 && ccache --show-stats" -BITCOIN_CONFIG_ALL="${BITCOIN_CONFIG_ALL} --enable-external-signer --prefix=$BASE_OUTDIR" - -if [ -n "$CONFIG_SHELL" ]; then - "$CONFIG_SHELL" -c "./autogen.sh" -else - ./autogen.sh -fi - +# Folder where the build is done. +BASE_BUILD_DIR=${BASE_BUILD_DIR:-$BASE_SCRATCH_DIR/build-$HOST} mkdir -p "${BASE_BUILD_DIR}" cd "${BASE_BUILD_DIR}" -bash -c "${BASE_ROOT_DIR}/configure --cache-file=config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG" || ( (cat config.log) && false) - -make distdir VERSION="$HOST" - -cd "${BASE_BUILD_DIR}/bitcoin-$HOST" - -bash -c "./configure --cache-file=../config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG" || ( (cat config.log) && false) +BITCOIN_CONFIG_ALL="$BITCOIN_CONFIG_ALL -DENABLE_EXTERNAL_SIGNER=ON -DCMAKE_INSTALL_PREFIX=$BASE_OUTDIR" if [[ "${RUN_TIDY}" == "true" ]]; then - MAYBE_BEAR="bear --config src/.bear-tidy-config" - MAYBE_TOKEN="--" + BITCOIN_CONFIG_ALL="$BITCOIN_CONFIG_ALL -DCMAKE_EXPORT_COMPILE_COMMANDS=ON" fi -bash -c "${MAYBE_BEAR} ${MAYBE_TOKEN} make $MAKEJOBS $GOAL" || ( echo "Build failure. Verbose build follows." && make "$GOAL" V=1 ; false ) +bash -c "cmake -S $BASE_ROOT_DIR $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( (cat CMakeFiles/CMakeOutput.log CMakeFiles/CMakeError.log) && false)" + +bash -c "make $MAKEJOBS all $GOAL" || ( echo "Build failure. Verbose build follows." && make all "$GOAL" V=1 ; false ) bash -c "${PRINT_CCACHE_STATISTICS}" du -sh "${DEPENDS_DIR}"/*/ du -sh "${PREVIOUS_RELEASES_DIR}" if [[ $HOST = *-mingw32 ]]; then - # Generate all binaries, so that they can be wrapped - make "$MAKEJOBS" -C src/secp256k1 VERBOSE=1 - make "$MAKEJOBS" -C src minisketch/test.exe VERBOSE=1 "${BASE_ROOT_DIR}/ci/test/wrap-wine.sh" fi @@ -152,7 +138,7 @@ if [ -n "$USE_VALGRIND" ]; then fi if [ "$RUN_UNIT_TESTS" = "true" ]; then - DIR_UNIT_TEST_DATA="${DIR_UNIT_TEST_DATA}" LD_LIBRARY_PATH="${DEPENDS_DIR}/${HOST}/lib" make "${MAKEJOBS}" check VERBOSE=1 + DIR_UNIT_TEST_DATA="${DIR_UNIT_TEST_DATA}" LD_LIBRARY_PATH="${DEPENDS_DIR}/${HOST}/lib" CTEST_OUTPUT_ON_FAILURE=ON ctest "${MAKEJOBS}" fi if [ "$RUN_UNIT_TESTS_SEQUENTIAL" = "true" ]; then @@ -170,7 +156,7 @@ if [ "${RUN_TIDY}" = "true" ]; then cmake --build /tidy-build --target bitcoin-tidy-tests "$MAKEJOBS" set -eo pipefail - cd "${BASE_BUILD_DIR}/bitcoin-$HOST/src/" + cd "${BASE_BUILD_DIR}/src/" if ! ( run-clang-tidy-"${TIDY_LLVM_V}" -quiet -load="/tidy-build/libbitcoin-tidy.so" "${MAKEJOBS}" | tee tmp.tidy-out.txt ); then grep -C5 "error: " tmp.tidy-out.txt echo "^^^ ⚠️ Failure generated from clang-tidy" @@ -180,12 +166,12 @@ if [ "${RUN_TIDY}" = "true" ]; then # accepted in src/.bear-tidy-config # Filter out: # * qt qrc and moc generated files - jq 'map(select(.file | test("src/qt/qrc_.*\\.cpp$|/moc_.*\\.cpp$") | not))' ../compile_commands.json > tmp.json - mv tmp.json ../compile_commands.json - cd "${BASE_BUILD_DIR}/bitcoin-$HOST/" + jq 'map(select(.file | test("src/qt/qrc_.*\\.cpp$|/moc_.*\\.cpp$") | not))' "${BASE_BUILD_DIR}/compile_commands.json" > tmp.json + mv tmp.json "${BASE_BUILD_DIR}/compile_commands.json" + cd "${BASE_ROOT_DIR}" python3 "/include-what-you-use/iwyu_tool.py" \ - -p . "${MAKEJOBS}" \ - -- -Xiwyu --cxx17ns -Xiwyu --mapping_file="${BASE_BUILD_DIR}/bitcoin-$HOST/contrib/devtools/iwyu/bitcoin.core.imp" \ + -p "${BASE_BUILD_DIR}" "${MAKEJOBS}" \ + -- -Xiwyu --cxx17ns -Xiwyu --mapping_file="${BASE_ROOT_DIR}/contrib/devtools/iwyu/bitcoin.core.imp" \ -Xiwyu --max_line_length=160 \ 2>&1 | tee /tmp/iwyu_ci.out cd "${BASE_ROOT_DIR}/src" diff --git a/ci/test/wrap-wine.sh b/ci/test/wrap-wine.sh index 90e53887bc4b8..a0d32a93a3f9c 100755 --- a/ci/test/wrap-wine.sh +++ b/ci/test/wrap-wine.sh @@ -6,7 +6,7 @@ export LC_ALL=C.UTF-8 -for b_name in {"${BASE_OUTDIR}/bin"/*,src/secp256k1/*tests,src/minisketch/test{,-verify},src/univalue/{test_json,unitester,object}}.exe; do +for b_name in {"${BASE_OUTDIR}/bin"/*,src/univalue/{test_json,unitester,object}}.exe; do # shellcheck disable=SC2044 for b in $(find "${BASE_ROOT_DIR}" -executable -type f -name "$(basename "$b_name")"); do if (file "$b" | grep "Windows"); then diff --git a/cmake/bitcoin-config.h.in b/cmake/bitcoin-config.h.in new file mode 100644 index 0000000000000..094eb8040a3bd --- /dev/null +++ b/cmake/bitcoin-config.h.in @@ -0,0 +1,153 @@ +// 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 SHA-NI intrinsics */ +#cmakedefine ENABLE_ARM_SHANI 1 + +/* Define this symbol to build code that uses AVX2 intrinsics */ +#cmakedefine ENABLE_AVX2 1 + +/* Define if external signer support is enabled */ +#cmakedefine ENABLE_EXTERNAL_SIGNER 1 + +/* Define this symbol to build code that uses SSE4.1 intrinsics */ +#cmakedefine ENABLE_SSE41 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 SHA-NI intrinsics */ +#cmakedefine ENABLE_X86_SHANI 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 function call is available */ +#cmakedefine HAVE_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 0000000000000..099aa66411fb6 --- /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 0000000000000..f6b7ff3419ffd --- /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 0000000000000..16fde7f95dab9 --- /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 0000000000000..5435a109d41cd --- /dev/null +++ b/cmake/introspection.cmake @@ -0,0 +1,227 @@ +# 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() +check_cxx_source_compiles(" + #include + + int main() + { + getrandom(nullptr, 32, 0); + } + " HAVE_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 +) + +if(NOT MSVC) + include(CheckSourceCompilesAndLinks) + + # 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 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 0000000000000..823a5d8e3daee --- /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 0000000000000..bb93c80467256 --- /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 0000000000000..89603ecd6155d --- /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 0000000000000..a9b4f51f73d96 --- /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 0000000000000..88c897d524330 --- /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 0000000000000..03a3cce10c53f --- /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 0000000000000..901a4f3bd41ec --- /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 0000000000000..34b94f05f16ef --- /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 0000000000000..930555232bd86 --- /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 0000000000000..f39ee53d5b5c5 --- /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 0000000000000..0ba9a58fc10ac --- /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 0000000000000..9a408f715d918 --- /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 0000000000000..35dc54eebb5d4 --- /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 0000000000000..b7ea423611f7f --- /dev/null +++ b/cmake/module/GenerateSetupNsi.cmake @@ -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/. + +function(generate_setup_nsi) + set(abs_top_srcdir ${PROJECT_SOURCE_DIR}) + set(abs_top_builddir ${PROJECT_BINARY_DIR}) + set(PACKAGE_URL ${PROJECT_HOMEPAGE_URL}) + set(PACKAGE_TARNAME "bitcoin") + set(BITCOIN_GUI_NAME "bitcoin-qt") + set(BITCOIN_DAEMON_NAME "bitcoind") + set(BITCOIN_CLI_NAME "bitcoin-cli") + set(BITCOIN_TX_NAME "bitcoin-tx") + set(BITCOIN_WALLET_TOOL_NAME "bitcoin-wallet") + set(BITCOIN_TEST_NAME "test_bitcoin") + set(EXEEXT ${CMAKE_EXECUTABLE_SUFFIX}) + configure_file(${PROJECT_SOURCE_DIR}/share/setup.nsi.in ${PROJECT_BINARY_DIR}/bitcoin-win64-setup.nsi @ONLY) +endfunction() diff --git a/cmake/module/GetTargetInterface.cmake b/cmake/module/GetTargetInterface.cmake new file mode 100644 index 0000000000000..1e455d456b419 --- /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 0000000000000..2c6cfc1863c28 --- /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}/bitcoin-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}/bitcoin-win64-setup.nsi + VERBATIM + ) + add_custom_target(deploy DEPENDS ${PROJECT_BINARY_DIR}/bitcoin-win64-setup.exe) + endif() +endfunction() + +function(add_macos_deploy_target) + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND TARGET bitcoin-qt) + set(macos_app "Bitcoin-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/bitcoin.icns ${macos_app}/Contents/Resources/bitcoin.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/Bitcoin-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/Bitcoin-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/Bitcoin-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/Bitcoin-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/Bitcoin-Qt + VERBATIM + ) + add_custom_target(deploydir + DEPENDS ${PROJECT_BINARY_DIR}/dist/${macos_app}/Contents/MacOS/Bitcoin-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 0000000000000..5286d10267bed --- /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 0000000000000..5352102c7a485 --- /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 0000000000000..0f6e014d437aa --- /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 0000000000000..749120d4458dd --- /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 ${TACXXF_IF_CHECK_FAILED}) + endif() + if(DEFINED TALF_VAR) + string(STRIP "${${TALF_VAR}} ${TACXXF_IF_CHECK_FAILED}" ${TALF_VAR}) + endif() + endif() + + if(DEFINED TALF_VAR) + set(${TALF_VAR} "${${TALF_VAR}}" PARENT_SCOPE) + endif() + + if(DEFINED TALF_RESULT_VAR) + set(${TALF_RESULT_VAR} "${${result}}" PARENT_SCOPE) + endif() +endfunction() + +if(MSVC) + try_append_linker_flag("/WX" VAR working_linker_werror_flag) +elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + try_append_linker_flag("-Wl,-fatal_warnings" VAR working_linker_werror_flag) +else() + try_append_linker_flag("-Wl,--fatal-warnings" VAR working_linker_werror_flag) +endif() diff --git a/cmake/module/WarnAboutGlobalProperties.cmake b/cmake/module/WarnAboutGlobalProperties.cmake new file mode 100644 index 0000000000000..faa56a2a7f191 --- /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 0000000000000..0df2e0b734d81 --- /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 0000000000000..2626ea0cb5dec --- /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 0000000000000..7a8bf2f0af2d3 --- /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 0000000000000..4a640b9636f25 --- /dev/null +++ b/cmake/script/GenerateBuildInfo.cmake @@ -0,0 +1,115 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +# This script is a multiplatform port of the share/genbuild.sh shell script. + +macro(fatal_error) + message(FATAL_ERROR "\n" + "Usage:\n" + " cmake -D BUILD_INFO_HEADER_PATH= [-D SOURCE_DIR=] -P ${CMAKE_CURRENT_LIST_FILE}\n" + "All specified paths must be absolute ones.\n" + ) +endmacro() + +if(DEFINED BUILD_INFO_HEADER_PATH AND IS_ABSOLUTE "${BUILD_INFO_HEADER_PATH}") + if(EXISTS "${BUILD_INFO_HEADER_PATH}") + file(STRINGS ${BUILD_INFO_HEADER_PATH} INFO LIMIT_COUNT 1) + endif() +else() + fatal_error() +endif() + +if(DEFINED SOURCE_DIR) + if(IS_ABSOLUTE "${SOURCE_DIR}" AND IS_DIRECTORY "${SOURCE_DIR}") + set(WORKING_DIR ${SOURCE_DIR}) + else() + fatal_error() + endif() +else() + set(WORKING_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +endif() + +set(GIT_TAG) +set(GIT_COMMIT) +if(NOT "$ENV{BITCOIN_GENBUILD_NO_GIT}" STREQUAL "1") + find_package(Git QUIET) + if(Git_FOUND) + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --is-inside-work-tree + WORKING_DIRECTORY ${WORKING_DIR} + OUTPUT_VARIABLE IS_INSIDE_WORK_TREE + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + if(IS_INSIDE_WORK_TREE) + # Clean 'dirty' status of touched files that haven't been modified. + execute_process( + COMMAND ${GIT_EXECUTABLE} diff + WORKING_DIRECTORY ${WORKING_DIR} + OUTPUT_QUIET + ERROR_QUIET + ) + + execute_process( + COMMAND ${GIT_EXECUTABLE} describe --abbrev=0 + WORKING_DIRECTORY ${WORKING_DIR} + OUTPUT_VARIABLE MOST_RECENT_TAG + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-list -1 ${MOST_RECENT_TAG} + WORKING_DIRECTORY ${WORKING_DIR} + OUTPUT_VARIABLE MOST_RECENT_TAG_COMMIT + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse HEAD + WORKING_DIRECTORY ${WORKING_DIR} + OUTPUT_VARIABLE HEAD_COMMIT + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + + execute_process( + COMMAND ${GIT_EXECUTABLE} diff-index --quiet HEAD -- + WORKING_DIRECTORY ${WORKING_DIR} + RESULT_VARIABLE IS_DIRTY + ) + + if(HEAD_COMMIT STREQUAL MOST_RECENT_TAG_COMMIT AND NOT IS_DIRTY) + # If latest commit is tagged and not dirty, then use the tag name. + set(GIT_TAG ${MOST_RECENT_TAG}) + else() + # Otherwise, generate suffix from git, i.e. string like "0e0a5173fae3-dirty". + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --short=12 HEAD + WORKING_DIRECTORY ${WORKING_DIR} + OUTPUT_VARIABLE GIT_COMMIT + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + if(IS_DIRTY) + string(APPEND GIT_COMMIT "-dirty") + endif() + endif() + endif() + endif() +endif() + +if(GIT_TAG) + set(NEWINFO "#define BUILD_GIT_TAG \"${GIT_TAG}\"") +elseif(GIT_COMMIT) + set(NEWINFO "#define BUILD_GIT_COMMIT \"${GIT_COMMIT}\"") +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 0000000000000..279ceedf04405 --- /dev/null +++ b/cmake/script/GenerateHeaderFromJson.cmake @@ -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/. + +file(READ ${JSON_SOURCE_PATH} hex_content HEX) +string(REGEX MATCHALL "([A-Za-z0-9][A-Za-z0-9])" bytes "${hex_content}") + +file(WRITE ${HEADER_PATH} "#include \n") +file(APPEND ${HEADER_PATH} "namespace json_tests{\n") +get_filename_component(json_source_basename ${JSON_SOURCE_PATH} NAME_WE) +file(APPEND ${HEADER_PATH} "static const std::string ${json_source_basename}{\n") + +set(i 0) +foreach(byte ${bytes}) + math(EXPR i "${i} + 1") + math(EXPR remainder "${i} % 8") + if(remainder EQUAL 0) + file(APPEND ${HEADER_PATH} "0x${byte},\n") + else() + file(APPEND ${HEADER_PATH} "0x${byte}, ") + endif() +endforeach() + +file(APPEND ${HEADER_PATH} "\n};};") diff --git a/cmake/script/GenerateHeaderFromRaw.cmake b/cmake/script/GenerateHeaderFromRaw.cmake new file mode 100644 index 0000000000000..18c5b4bef25d9 --- /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 0000000000000..cc51699dc938a --- /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 0000000000000..279132980017f --- /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 6fb647f8a9d13..5e05e1016e5ed 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/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh index fa6933b3328f2..1ffc22a76bce1 100755 --- a/contrib/guix/libexec/build.sh +++ b/contrib/guix/libexec/build.sh @@ -206,13 +206,13 @@ mkdir -p "$OUTDIR" ########################### # CONFIGFLAGS -CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests --disable-fuzz-binary" +CONFIGFLAGS="-DREDUCE_EXPORTS=ON -DBUILD_BENCH=OFF -DBUILD_GUI_TESTS=OFF -DBUILD_FUZZ_BINARY=OFF" # CFLAGS HOST_CFLAGS="-O2 -g" HOST_CFLAGS+=$(find /gnu/store -maxdepth 1 -mindepth 1 -type d -exec echo -n " -ffile-prefix-map={}=/usr" \;) case "$HOST" in - *linux*) HOST_CFLAGS+=" -ffile-prefix-map=${PWD}=." ;; + *linux*) HOST_CFLAGS+=" -ffile-prefix-map=${DISTSRC}/src=." ;; *mingw*) HOST_CFLAGS+=" -fno-ident" ;; *darwin*) unset HOST_CFLAGS ;; esac @@ -239,38 +239,31 @@ mkdir -p "$DISTSRC" # Extract the source tarball tar --strip-components=1 -xf "${GIT_ARCHIVE}" - ./autogen.sh - # Configure this DISTSRC for $HOST # shellcheck disable=SC2086 - env CONFIG_SITE="${BASEPREFIX}/${HOST}/share/config.site" \ - ./configure --prefix=/ \ - --disable-ccache \ - --disable-maintainer-mode \ - --disable-dependency-tracking \ - ${CONFIGFLAGS} \ - ${HOST_CFLAGS:+CFLAGS="${HOST_CFLAGS}"} \ - ${HOST_CXXFLAGS:+CXXFLAGS="${HOST_CXXFLAGS}"} \ - ${HOST_LDFLAGS:+LDFLAGS="${HOST_LDFLAGS}"} - - sed -i.old 's/-lstdc++ //g' config.status libtool + env CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}" \ + cmake -S . -B build \ + --toolchain "${BASEPREFIX}/${HOST}/toolchain.cmake" \ + -DWITH_CCACHE=OFF \ + ${CONFIGFLAGS} # Build Bitcoin Core - make --jobs="$JOBS" ${V:+V=1} + cmake --build build -j "$JOBS" ${V:+--verbose} # Check that symbol/security checks tools are sane. - make test-security-check ${V:+V=1} + cmake --build build --target test-security-check ${V:+--verbose} # Perform basic security checks on a series of executables. - make -C src --jobs=1 check-security ${V:+V=1} + cmake --build build -j 1 --target check-security ${V:+--verbose} # Check that executables only contain allowed version symbols. - make -C src --jobs=1 check-symbols ${V:+V=1} + cmake --build build -j 1 --target check-symbols ${V:+--verbose} mkdir -p "$OUTDIR" # Make the os-specific installers case "$HOST" in *mingw*) - make deploy ${V:+V=1} BITCOIN_WIN_INSTALLER="${OUTDIR}/${DISTNAME}-win64-setup-unsigned.exe" + cmake --build build -j "$JOBS" -t deploy ${V:+--verbose} + mv build/bitcoin-win64-setup.exe "${OUTDIR}/${DISTNAME}-win64-setup-unsigned.exe" ;; esac @@ -282,20 +275,25 @@ mkdir -p "$DISTSRC" # Install built Bitcoin Core to $INSTALLPATH case "$HOST" in *darwin*) - make install-strip DESTDIR="${INSTALLPATH}" ${V:+V=1} + # This workaround can be dropped for CMake >= 3.27. + # See the upstream commit 689616785f76acd844fd448c51c5b2a0711aafa2. + find build -name 'cmake_install.cmake' -exec sed -i 's| -u -r | |g' {} + + + cmake --install build --strip --prefix "${INSTALLPATH}" ${V:+--verbose} ;; *) - make install DESTDIR="${INSTALLPATH}" ${V:+V=1} + cmake --install build --prefix "${INSTALLPATH}" ${V:+--verbose} ;; esac case "$HOST" in *darwin*) - make deploydir ${V:+V=1} + cmake --build build --target deploy ${V:+--verbose} + mv build/dist/Bitcoin-Core.zip "${OUTDIR}/${DISTNAME}-${HOST}-unsigned.zip" mkdir -p "unsigned-app-${HOST}" cp --target-directory="unsigned-app-${HOST}" \ contrib/macdeploy/detached-sig-create.sh - mv --target-directory="unsigned-app-${HOST}" dist + mv --target-directory="unsigned-app-${HOST}" build/dist ( cd "unsigned-app-${HOST}" find . -print0 \ @@ -304,23 +302,18 @@ mkdir -p "$DISTSRC" | gzip -9n > "${OUTDIR}/${DISTNAME}-${HOST}-unsigned.tar.gz" \ || ( rm -f "${OUTDIR}/${DISTNAME}-${HOST}-unsigned.tar.gz" && exit 1 ) ) - make deploy ${V:+V=1} OSX_ZIP="${OUTDIR}/${DISTNAME}-${HOST}-unsigned.zip" ;; esac ( cd installed - # Prune libtool and object archives - find . -name "lib*.la" -delete - find . -name "lib*.a" -delete - case "$HOST" in *darwin*) ;; *) # Split binaries from their debug symbols { find "${DISTNAME}/bin" -type f -executable -print0 - } | xargs -0 -P"$JOBS" -I{} "${DISTSRC}/contrib/devtools/split-debug.sh" {} {} {}.dbg + } | xargs -0 -P"$JOBS" -I{} "${DISTSRC}/build/split-debug.sh" {} {} {}.dbg ;; esac diff --git a/depends/Makefile b/depends/Makefile index 52a9a14e56a15..306e7f93c97e2 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -184,6 +184,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) @@ -249,6 +250,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); \ @@ -270,6 +317,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 @@ -279,7 +327,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/README.md b/depends/README.md index adaeed468f633..19d704a50c837 100644 --- a/depends/README.md +++ b/depends/README.md @@ -12,17 +12,13 @@ For example: make HOST=x86_64-w64-mingw32 -j4 -**Bitcoin Core's `configure` script by default will ignore the depends output.** In +**When configuring Bitcoin Core, CMake by default will ignore the depends output.** In order for it to pick up libraries, tools, and settings from the depends build, -you must set the `CONFIG_SITE` environment variable to point to a `config.site` settings file. -Make sure that `CONFIG_SITE` is an absolute path. -In the above example, a file named `depends/x86_64-w64-mingw32/share/config.site` will be -created. To use it during compilation: +you must specify the toolchain file. +In the above example, a file named `depends/x86_64-w64-mingw32/toolchain.cmake` will be +created. To use it during configuring Bitcoin Core: - CONFIG_SITE=$PWD/depends/x86_64-w64-mingw32/share/config.site ./configure - -The default install prefix when using `config.site` is `--prefix=depends/`, -so depends build outputs will be installed in that location. + cmake -B build --toolchain depends/x86_64-w64-mingw32/toolchain.cmake Common `host-platform-triplet`s for cross compilation are: @@ -90,9 +86,13 @@ For linux S390X cross compilation: pkg install bash +### Install the required dependencies: NetBSD + + pkgin install bash gmake + ### Install the required dependencies: OpenBSD - pkg_add bash gtar + pkg_add bash gmake gtar ### Dependency Options @@ -125,8 +125,8 @@ The following can be set when running make: `make FOO=bar` - `LTO`: Enable options needed for LTO. Does not add `-flto` related options to *FLAGS. - `NO_HARDEN=1`: Don't use hardening options when building packages -If some packages are not built, for example `make NO_WALLET=1`, the appropriate -options will be passed to bitcoin's configure. In this case, `--disable-wallet`. +If some packages are not built, for example `make NO_WALLET=1`, the appropriate CMake cache +variables will be set when generating the Bitcoin Core buildsystem. In this case, `-DENABLE_WALLET=OFF`. ### Additional targets diff --git a/depends/funcs.mk b/depends/funcs.mk index 3c0dc7a7fcab5..a2f760bd0e726 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -171,7 +171,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)" \ @@ -191,7 +191,7 @@ ifeq ($($(1)_type),build) $(1)_cmake += -DCMAKE_INSTALL_RPATH:PATH="$$($($(1)_type)_prefix)/lib" else ifneq ($(host),$(build)) -$(1)_cmake += -DCMAKE_SYSTEM_NAME=$($(host_os)_cmake_system) +$(1)_cmake += -DCMAKE_SYSTEM_NAME=$($(host_os)_cmake_system_name) $(1)_cmake += -DCMAKE_C_COMPILER_TARGET=$(host) $(1)_cmake += -DCMAKE_CXX_COMPILER_TARGET=$(host) endif diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index a50e36110dc02..a27d8b323b694 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -75,4 +75,7 @@ darwin_release_CXXFLAGS=$(darwin_release_CFLAGS) darwin_debug_CFLAGS=-O1 -g darwin_debug_CXXFLAGS=$(darwin_debug_CFLAGS) -darwin_cmake_system=Darwin +darwin_cmake_system_name=Darwin +# Darwin version, which corresponds to OSX_MIN_VERSION. +# See https://en.wikipedia.org/wiki/Darwin_(operating_system) +darwin_cmake_system_version=20.1 diff --git a/depends/hosts/default.mk b/depends/hosts/default.mk index d82c33f29ce06..24689da45bc19 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/hosts/freebsd.mk b/depends/hosts/freebsd.mk index 055097b03ddc8..8cef32e231cff 100644 --- a/depends/hosts/freebsd.mk +++ b/depends/hosts/freebsd.mk @@ -28,4 +28,4 @@ x86_64_freebsd_CC=$(default_host_CC) -m64 x86_64_freebsd_CXX=$(default_host_CXX) -m64 endif -freebsd_cmake_system=FreeBSD +freebsd_cmake_system_name=FreeBSD diff --git a/depends/hosts/linux.mk b/depends/hosts/linux.mk index f5ce2bb0b8557..e2f34265d153e 100644 --- a/depends/hosts/linux.mk +++ b/depends/hosts/linux.mk @@ -39,4 +39,7 @@ i686_linux_CXX=$(default_host_CXX) -m32 x86_64_linux_CC=$(default_host_CC) -m64 x86_64_linux_CXX=$(default_host_CXX) -m64 endif -linux_cmake_system=Linux + +linux_cmake_system_name=Linux +# Refer to doc/dependencies.md for the minimum required kernel. +linux_cmake_system_version=3.17.0 diff --git a/depends/hosts/mingw32.mk b/depends/hosts/mingw32.mk index 4c657358f6a57..c09f7b1e3a8db 100644 --- a/depends/hosts/mingw32.mk +++ b/depends/hosts/mingw32.mk @@ -19,4 +19,6 @@ mingw32_debug_CXXFLAGS=$(mingw32_debug_CFLAGS) mingw32_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -mingw32_cmake_system=Windows +mingw32_cmake_system_name=Windows +# Windows 7 (NT 6.1). +mingw32_cmake_system_version=6.1 diff --git a/depends/hosts/netbsd.mk b/depends/hosts/netbsd.mk index f33b2d2889571..16dff92d428a3 100644 --- a/depends/hosts/netbsd.mk +++ b/depends/hosts/netbsd.mk @@ -36,4 +36,4 @@ x86_64_netbsd_CC=$(default_host_CC) -m64 x86_64_netbsd_CXX=$(default_host_CXX) -m64 endif -netbsd_cmake_system=NetBSD +netbsd_cmake_system_name=NetBSD diff --git a/depends/hosts/openbsd.mk b/depends/hosts/openbsd.mk index bdd36dc9b35de..63f6d73d55598 100644 --- a/depends/hosts/openbsd.mk +++ b/depends/hosts/openbsd.mk @@ -28,4 +28,4 @@ x86_64_openbsd_CC=$(default_host_CC) -m64 x86_64_openbsd_CXX=$(default_host_CXX) -m64 endif -openbsd_cmake_system=OpenBSD +openbsd_cmake_system_name=OpenBSD diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index b133539495982..917e17993228f 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -265,13 +265,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 8f2e900a840fb..6d8b7fdb6a2ca 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 0000000000000..c733c81edf777 --- /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 0000000000000..61a7653e4aa5e --- /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 d8fd46d1c7d0b..ccaf31170a175 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -58,7 +58,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/README.md b/doc/README.md index 74a85b04e62dc..7f5db1b5bf49b 100644 --- a/doc/README.md +++ b/doc/README.md @@ -41,7 +41,7 @@ The following are developer notes on how to build Bitcoin Core on your native pl - [Dependencies](dependencies.md) - [macOS Build Notes](build-osx.md) - [Unix Build Notes](build-unix.md) -- [Windows Build Notes](build-windows.md) +- [Windows Build Notes](build-windows-msvc.md) - [FreeBSD Build Notes](build-freebsd.md) - [OpenBSD Build Notes](build-openbsd.md) - [NetBSD Build Notes](build-netbsd.md) diff --git a/doc/benchmarking.md b/doc/benchmarking.md index 84d5f2c444ba3..c6dc75dc5cd87 100644 --- a/doc/benchmarking.md +++ b/doc/benchmarking.md @@ -8,16 +8,17 @@ thread queue, wallet balance. Running --------------------- -For benchmarking, you only need to compile `bitcoin_bench`. The bench runner -warns if you configure with `--enable-debug`, but consider if building without +For benchmarking, you only need to compile `bench_bitcoin`. The bench runner +warns if you configure with `-DCMAKE_BUILD_TYPE=Debug`, but consider if building without it will impact the benchmark(s) you are interested in by unlatching log printers and lock analysis. - make -C src bitcoin_bench + cmake -B build -DBUILD_BENCH=ON + cmake --build build -t bench_bitcoin After compiling bitcoin-core, the benchmarks can be run with: - src/bench/bench_bitcoin + build/src/bench/bench_bitcoin The output will look similar to: ``` @@ -39,7 +40,7 @@ The output will look similar to: Help --------------------- - src/bench/bench_bitcoin -? + build/src/bench/bench_bitcoin -? To print the various options, like listing the benchmarks without running them or using a regex filter to only run certain benchmarks. diff --git a/doc/build-freebsd.md b/doc/build-freebsd.md index bf86a0ee4b14b..fba5a17e9aada 100644 --- a/doc/build-freebsd.md +++ b/doc/build-freebsd.md @@ -10,15 +10,14 @@ This guide describes how to build bitcoind, command-line utilities, and GUI on F Run the following as root to install the base dependencies for building. ```bash -pkg install autoconf automake boost-libs git gmake libevent libtool pkgconf - +pkg install boost-libs cmake git libevent pkgconf ``` See [dependencies.md](dependencies.md) for a complete overview. ### 2. Clone Bitcoin Repo Now that `git` and all the required dependencies are installed, let's clone the Bitcoin Core repository to a directory. All build scripts and commands will run from this directory. -``` bash +```bash git clone https://github.com/bitcoin/bitcoin.git ``` @@ -31,7 +30,7 @@ It is not necessary to build wallet functionality to run either `bitcoind` or `b `sqlite3` is required to support [descriptor wallets](descriptors.md). Skip if you don't intend to use descriptor wallets. -``` bash +```bash pkg install sqlite3 ``` @@ -41,7 +40,8 @@ BerkeleyDB is only required if legacy wallet support is required. It is required to use Berkeley DB 4.8. You **cannot** use the BerkeleyDB library from ports. However, you can build DB 4.8 yourself [using depends](/depends). -``` +```bash +pkg install gmake gmake -C depends NO_BOOST=1 NO_LIBEVENT=1 NO_QT=1 NO_SQLITE=1 NO_NATPMP=1 NO_UPNP=1 NO_ZMQ=1 NO_USDT=1 ``` @@ -64,17 +64,23 @@ sh/bash: export BDB_PREFIX=[path displayed above] #### GUI Dependencies ###### Qt5 -Bitcoin Core includes a GUI built with the cross-platform Qt Framework. To compile the GUI, we need to install the necessary parts of Qt. Skip if you don't intend to use the GUI. +Bitcoin Core includes a GUI built with the cross-platform Qt Framework. To compile the GUI, we need to install +the necessary parts of Qt, the libqrencode and pass `-DBUILD_GUI=ON`. Skip if you don't intend to use the GUI. + ```bash pkg install qt5-buildtools qt5-core qt5-gui qt5-linguisttools qt5-testlib qt5-widgets ``` ###### libqrencode -The GUI can encode addresses in a QR Code. To build in QR support for the GUI, install `libqrencode`. Skip if not using the GUI or don't want QR code functionality. +The GUI will be able to encode addresses in QR codes unless this feature is explicitly disabled. To install libqrencode, run: + ```bash pkg install libqrencode ``` + +Otherwise, if you don't need QR encoding support, use the `-DWITH_QRENCODE=OFF` option to disable this feature in order to compile the GUI. + --- #### Notifications @@ -101,33 +107,28 @@ pkg install python3 databases/py-sqlite3 There are many ways to configure Bitcoin Core, here are a few common examples: ##### Descriptor Wallet and GUI: -This explicitly enables the GUI and disables legacy wallet support, assuming `sqlite` and `qt` are installed. +This disables legacy wallet support and enables the GUI, assuming `sqlite` and `qt` are installed. ```bash -./autogen.sh -./configure --without-bdb --with-gui=yes MAKE=gmake +cmake -B build -DWITH_BDB=OFF -DBUILD_GUI=ON ``` +Run `cmake -B build -LH` to see the full list of available options. + ##### Descriptor & Legacy Wallet. No GUI: -This enables support for both wallet types and disables the GUI, assuming +This enables support for both wallet types, assuming `sqlite3` and `db4` are both installed. ```bash -./autogen.sh -./configure --with-gui=no \ - BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" \ - BDB_CFLAGS="-I${BDB_PREFIX}/include" \ - MAKE=gmake +cmake -B build -DBerkeleyDB_INCLUDE_DIR:PATH="${BDB_PREFIX}/include" ``` ##### No Wallet or GUI -``` bash -./autogen.sh -./configure --without-wallet --with-gui=no MAKE=gmake +```bash +cmake -B build -DENABLE_WALLET=OFF ``` ### 2. Compile -**Important**: Use `gmake` (the non-GNU `make` will exit with an error). ```bash -gmake # use "-j N" for N parallel jobs -gmake check # Run tests if Python 3 is available +cmake --build build # Use "-j N" for N parallel jobs. +ctest --test-dir build # Use "-j N" for N parallel tests. Some tests are disabled if Python 3 is not available. ``` diff --git a/doc/build-netbsd.md b/doc/build-netbsd.md index 5f54fd6d9a2c5..63bfbd61dbbb4 100644 --- a/doc/build-netbsd.md +++ b/doc/build-netbsd.md @@ -12,8 +12,7 @@ Install the required dependencies the usual way you [install software on NetBSD] The example commands below use `pkgin`. ```bash -pkgin install autoconf automake libtool pkg-config git gmake boost-headers libevent - +pkgin install git cmake pkg-config boost-headers libevent ``` NetBSD currently ships with an older version of `gcc` than is needed to build. You should upgrade your `gcc` and then pass this new version to the configure script. @@ -25,10 +24,10 @@ pkgin install gcc12 Then, when configuring, pass the following: ```bash -./configure +cmake -B build ... - CC="/usr/pkg/gcc12/bin/gcc" \ - CXX="/usr/pkg/gcc12/bin/g++" \ + -DCMAKE_C_COMPILER="/usr/pkg/gcc12/bin/gcc" \ + -DCMAKE_CXX_COMPILER="/usr/pkg/gcc12/bin/g++" \ ... ``` @@ -65,19 +64,26 @@ pkgin install db4 ``` #### GUI Dependencies +###### Qt5 -Bitcoin Core includes a GUI built with the cross-platform Qt Framework. To compile the GUI, Qt 5 is required. +Bitcoin Core includes a GUI built with the cross-platform Qt Framework. To compile the GUI, we need to install +the necessary parts of Qt, the libqrencode and pass `-DBUILD_GUI=ON`. Skip if you don't intend to use the GUI. ```bash pkgin install qt5-qtbase qt5-qttools ``` -The GUI can encode addresses in a QR Code. To build in QR support for the GUI, install `qrencode`. +###### libqrencode + +The GUI will be able to encode addresses in QR codes unless this feature is explicitly disabled. To install libqrencode, run: ```bash pkgin install qrencode ``` +Otherwise, if you don't need QR encoding support, use the `-DWITH_QRENCODE=OFF` option to disable this feature in order to compile the GUI. + + #### Test Suite Dependencies There is an included test suite that is useful for testing code changes when developing. @@ -89,28 +95,22 @@ pkgin install python39 ### Building Bitcoin Core -**Note**: Use `gmake` (the non-GNU `make` will exit with an error). - - ### 1. Configuration There are many ways to configure Bitcoin Core. Here is an example that explicitly disables the wallet and GUI: ```bash -./autogen.sh -./configure --without-wallet --with-gui=no \ - CPPFLAGS="-I/usr/pkg/include" \ - MAKE=gmake +cmake -B build -DENABLE_WALLET=OFF -DBUILD_GUI=OFF ``` -For a full list of configuration options, see the output of `./configure --help` +Run `cmake -B build -LH` to see the full list of available options. ### 2. Compile Build and run the tests: ```bash -gmake # use "-j N" here for N parallel jobs -gmake check # Run tests if Python 3 is available +cmake --build build # Use "-j N" for N parallel jobs. +ctest --test-dir build # Use "-j N" for N parallel tests. Some tests are disabled if Python 3 is not available. ``` diff --git a/doc/build-openbsd.md b/doc/build-openbsd.md index 0fba281dc1a14..32129aadf3c3a 100644 --- a/doc/build-openbsd.md +++ b/doc/build-openbsd.md @@ -10,9 +10,7 @@ This guide describes how to build bitcoind, command-line utilities, and GUI on O Run the following as root to install the base dependencies for building. ```bash -pkg_add bash git gmake libevent libtool boost -# Select the newest version of the following packages: -pkg_add autoconf automake python +pkg_add git cmake boost libevent ``` See [dependencies.md](dependencies.md) for a complete overview. @@ -31,7 +29,7 @@ It is not necessary to build wallet functionality to run either `bitcoind` or `b ###### Descriptor Wallet Support -`sqlite3` is required to support [descriptor wallets](descriptors.md). +SQLite is required to support [descriptor wallets](descriptors.md). ``` bash pkg_add sqlite3 @@ -48,19 +46,20 @@ Refer to [depends/README.md](/depends/README.md) for detailed instructions. ```bash gmake -C depends NO_BOOST=1 NO_LIBEVENT=1 NO_QT=1 NO_SQLITE=1 NO_NATPMP=1 NO_UPNP=1 NO_ZMQ=1 NO_USDT=1 ... -to: /path/to/bitcoin/depends/x86_64-unknown-openbsd +to: /path/to/bitcoin/depends/*-unknown-openbsd* ``` Then set `BDB_PREFIX`: ```bash -export BDB_PREFIX="/path/to/bitcoin/depends/x86_64-unknown-openbsd" +export BDB_PREFIX="[path displayed above]" ``` #### GUI Dependencies ###### Qt5 -Bitcoin Core includes a GUI built with the cross-platform Qt Framework. To compile the GUI, Qt 5 is required. +Bitcoin Core includes a GUI built with the cross-platform Qt Framework. To compile the GUI, we need to install +the necessary parts of Qt, the libqrencode and pass `-DBUILD_GUI=ON`. Skip if you don't intend to use the GUI. ```bash pkg_add qtbase qttools @@ -68,10 +67,14 @@ pkg_add qtbase qttools ###### libqrencode -The GUI can encode addresses in a QR Code. To build in QR support for the GUI, install `libqrencode`. Skip if not using the GUI or don't want QR code functionality. +The GUI will be able to encode addresses in QR codes unless this feature is explicitly disabled. To install libqrencode, run: + ```bash pkg_add libqrencode ``` + +Otherwise, if you don't need QR encoding support, use the `-DWITH_QRENCODE=OFF` option to disable this feature in order to compile the GUI. + --- #### Notifications @@ -82,47 +85,41 @@ Bitcoin Core can provide notifications via ZeroMQ. If the package is installed, pkg_add zeromq ``` -## Building Bitcoin Core - -**Important**: Use `gmake` (the non-GNU `make` will exit with an error). +#### Test Suite Dependencies +There is an included test suite that is useful for testing code changes when developing. +To run the test suite (recommended), you will need to have Python 3 installed: -Preparation: ```bash - -# Adapt the following for the version you installed (major.minor only): -export AUTOCONF_VERSION=2.71 -export AUTOMAKE_VERSION=1.16 - -./autogen.sh +pkg_add install python # Select the newest version of the package. ``` +## Building Bitcoin Core + ### 1. Configuration There are many ways to configure Bitcoin Core, here are a few common examples: ##### Descriptor Wallet and GUI: -This enables the GUI and descriptor wallet support, assuming `sqlite` and `qt5` are installed. +This enables descriptor wallet support and the GUI, assuming SQLite and Qt 5 are installed. ```bash -./configure MAKE=gmake +cmake -B build -DWITH_SQLITE=ON -DBUILD_GUI=ON ``` +Run `cmake -B build -LH` to see the full list of available options. + ##### Descriptor & Legacy Wallet. No GUI: -This enables support for both wallet types and disables the GUI: +This enables support for both wallet types: ```bash -./configure --with-gui=no \ - BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" \ - BDB_CFLAGS="-I${BDB_PREFIX}/include" \ - MAKE=gmake +cmake -B build -DBerkeleyDB_INCLUDE_DIR:PATH="${BDB_PREFIX}/include" ``` ### 2. Compile -**Important**: Use `gmake` (the non-GNU `make` will exit with an error). ```bash -gmake # use "-j N" for N parallel jobs -gmake check # Run tests if Python 3 is available +cmake --build build # Use "-j N" for N parallel jobs. +ctest --test-dir build # Use "-j N" for N parallel tests. Some tests are disabled if Python 3 is not available. ``` ## Resource limits diff --git a/doc/build-osx.md b/doc/build-osx.md index 20c92ab7a42e8..161ba395b06cc 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -1,6 +1,6 @@ # macOS Build Guide -**Updated for MacOS [11.2](https://www.apple.com/macos/big-sur/)** +**Updated for MacOS [14.4](https://www.apple.com/macos/sonoma/)** This guide describes how to build bitcoind, command-line utilities, and GUI on macOS @@ -48,7 +48,7 @@ See [dependencies.md](dependencies.md) for a complete overview. To install, run the following from your terminal: ``` bash -brew install automake libtool boost pkg-config libevent +brew install cmake boost pkg-config libevent ``` For macOS 11 (Big Sur) and 12 (Monterey) you need to install a more recent version of llvm. @@ -102,9 +102,8 @@ brew install berkeley-db@4 ###### Qt -Bitcoin Core includes a GUI built with the cross-platform Qt Framework. -To compile the GUI, we need to install `qt@5`. -Skip if you don't intend to use the GUI. +Bitcoin Core includes a GUI built with the cross-platform Qt Framework. To compile the GUI, we need to install +the necessary parts of Qt, the libqrencode and pass `-DBUILD_GUI=ON`. Skip if you don't intend to use the GUI. ``` bash brew install qt@5 @@ -113,14 +112,16 @@ brew install qt@5 Note: Building with Qt binaries downloaded from the Qt website is not officially supported. See the notes in [#7714](https://github.com/bitcoin/bitcoin/issues/7714). -###### qrencode +###### libqrencode -The GUI can encode addresses in a QR Code. To build in QR support for the GUI, install `qrencode`. -Skip if not using the GUI or don't want QR code functionality. +The GUI will be able to encode addresses in QR codes unless this feature is explicitly disabled. To install libqrencode, run: ``` bash brew install qrencode ``` + +Otherwise, if you don't need QR encoding support, use the `-DWITH_QRENCODE=OFF` option to disable this feature in order to compile the GUI. + --- #### Port Mapping Dependencies @@ -177,7 +178,7 @@ brew install python #### Deploy Dependencies -You can deploy a `.zip` containing the Bitcoin Core application using `make deploy`. +You can [deploy](#3-deploy-optional) a `.zip` containing the Bitcoin Core application. It is required that you have `python` installed. ## Building Bitcoin Core @@ -188,32 +189,25 @@ There are many ways to configure Bitcoin Core, here are a few common examples: ##### Wallet (BDB + SQlite) Support, No GUI: -If `berkeley-db@4` is installed, then legacy wallet support will be built. -If `sqlite` is installed, then descriptor wallet support will also be built. -Additionally, this explicitly disables the GUI. +If `berkeley-db@4` or `sqlite` are not installed, this will throw an error. ``` bash -./autogen.sh -./configure --with-gui=no +cmake -B build -DWITH_BDB=ON ``` ##### Wallet (only SQlite) and GUI Support: -This explicitly enables the GUI and disables legacy wallet support. -If `qt` is not installed, this will throw an error. -If `sqlite` is installed then descriptor wallet functionality will be built. -If `sqlite` is not installed, then wallet functionality will be disabled. +This enables the GUI. +If `sqlite` or `qt` are not installed, this will throw an error. ``` bash -./autogen.sh -./configure --without-bdb --with-gui=yes +cmake -B build -DBUILD_GUI=ON ``` ##### No Wallet or GUI ``` bash -./autogen.sh -./configure --without-wallet --with-gui=no +cmake -B build -DENABLE_WALLET=OFF ``` ##### Further Configuration @@ -222,7 +216,7 @@ You may want to dig deeper into the configuration options to achieve your desire Examine the output of the following command for a full list of configuration options: ``` bash -./configure -help +cmake -B build -LH ``` ### 2. Compile @@ -231,8 +225,8 @@ After configuration, you are ready to compile. Run the following in your terminal to compile Bitcoin Core: ``` bash -make # use "-j N" here for N parallel jobs -make check # Run tests if Python 3 is available +cmake --build build # Use "-j N" here for N parallel jobs. +ctest --test-dir build # Use "-j N" for N parallel tests. Some tests are disabled if Python 3 is not available. ``` ### 3. Deploy (optional) @@ -240,7 +234,7 @@ make check # Run tests if Python 3 is available You can also create a `.zip` containing the `.app` bundle by running the following command: ``` bash -make deploy +cmake --build build --target deploy ``` ## Running Bitcoin Core @@ -276,8 +270,8 @@ tail -f $HOME/Library/Application\ Support/Bitcoin/debug.log ## Other commands: ```shell -./src/bitcoind -daemon # Starts the bitcoin daemon. -./src/bitcoin-cli --help # Outputs a list of command-line options. -./src/bitcoin-cli help # Outputs a list of RPC commands when the daemon is running. -./src/qt/bitcoin-qt -server # Starts the bitcoin-qt server mode, allows bitcoin-cli control +./build/src/bitcoind -daemon # Starts the bitcoin daemon. +./build/src/bitcoin-cli --help # Outputs a list of command-line options. +./build/src/bitcoin-cli help # Outputs a list of RPC commands when the daemon is running. +./build/src/qt/bitcoin-qt -server # Starts the bitcoin-qt server mode, allows bitcoin-cli control ``` diff --git a/doc/build-unix.md b/doc/build-unix.md index de54fb4eebd40..45433a32b3ca9 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -8,10 +8,9 @@ To Build --------------------- ```bash -./autogen.sh -./configure -make # use "-j N" for N parallel jobs -make install # optional +cmake -B build +cmake --build build # use "-j N" for N parallel jobs +cmake --install build # optional ``` See below for instructions on how to [install the dependencies on popular Linux @@ -22,19 +21,20 @@ distributions](#linux-distribution-specific-instructions), or the C++ compilers are memory-hungry. It is recommended to have at least 1.5 GB of memory available when compiling Bitcoin Core. On systems with less, gcc can be -tuned to conserve memory with additional CXXFLAGS: +tuned to conserve memory with additional `CMAKE_CXX_FLAGS`: - ./configure CXXFLAGS="--param ggc-min-expand=1 --param ggc-min-heapsize=32768" + cmake -B build -DCMAKE_CXX_FLAGS="--param ggc-min-expand=1 --param ggc-min-heapsize=32768" -Alternatively, or in addition, debugging information can be skipped for compilation. The default compile flags are -`-g -O2`, and can be changed with: +Alternatively, or in addition, debugging information can be skipped for compilation. +For the default build type `RelWithDebInfo`, the default compile flags are +`-O2 -g`, and can be changed with: - ./configure CXXFLAGS="-g0" + cmake -B build -DCMAKE_CXX_FLAGS_RELWITHDEBINFO="-O2 -g0" Finally, clang (often less resource hungry) can be used instead of gcc, which is used by default: - ./configure CXX=clang++ CC=clang + cmake -B build -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_CC_COMPILER=clang ## Linux Distribution Specific Instructions @@ -44,7 +44,7 @@ Finally, clang (often less resource hungry) can be used instead of gcc, which is Build requirements: - sudo apt-get install build-essential libtool autotools-dev automake pkg-config bsdmainutils python3 + sudo apt-get install build-essential cmake pkg-config bsdmainutils python3 Now, you can either build from self-compiled [depends](#dependencies) or install the required dependencies: @@ -56,12 +56,11 @@ SQLite is required for the descriptor wallet: Berkeley DB is only required for the legacy wallet. Ubuntu and Debian have their own `libdb-dev` and `libdb++-dev` packages, but these will install Berkeley DB 5.3 or later. This will break binary wallet compatibility with the distributed -executables, which are based on BerkeleyDB 4.8. If you do not care about wallet compatibility, pass -`--with-incompatible-bdb` to configure. Otherwise, you can build Berkeley DB [yourself](#berkeley-db). +executables, which are based on BerkeleyDB 4.8. Otherwise, you can build Berkeley DB [yourself](#berkeley-db). To build Bitcoin Core without wallet, see [*Disable-wallet mode*](#disable-wallet-mode) -Optional port mapping libraries (see: `--with-miniupnpc` and `--with-natpmp`): +Optional port mapping libraries (see: `-DWITH_MINIUPNPC=ON` and `-DWITH_NATPMP=ON`): sudo apt install libminiupnpc-dev libnatpmp-dev @@ -75,11 +74,8 @@ User-Space, Statically Defined Tracing (USDT) dependencies: GUI dependencies: -If you want to build bitcoin-qt, make sure that the required packages for Qt development -are installed. Qt 5 is necessary to build the GUI. -To build without GUI pass `--without-gui`. - -To build with Qt 5 you need the following: +Bitcoin Core includes a GUI built with the cross-platform Qt Framework. To compile the GUI, we need to install +the necessary parts of Qt, the libqrencode and pass `-DBUILD_GUI=ON`. Skip if you don't intend to use the GUI. sudo apt-get install qtbase5-dev qttools5-dev qttools5-dev-tools @@ -87,12 +83,11 @@ Additionally, to support Wayland protocol for modern desktop environments: sudo apt install qtwayland5 -libqrencode (optional) can be installed with: +The GUI will be able to encode addresses in QR codes unless this feature is explicitly disabled. To install libqrencode, run: sudo apt-get install libqrencode-dev -Once these are installed, they will be found by configure and a bitcoin-qt executable will be -built by default. +Otherwise, if you don't need QR encoding support, use the `-DWITH_QRENCODE=OFF` option to disable this feature in order to compile the GUI. ### Fedora @@ -118,7 +113,7 @@ pass `--with-incompatible-bdb` to configure. Otherwise, you can build Berkeley D To build Bitcoin Core without wallet, see [*Disable-wallet mode*](#disable-wallet-mode) -Optional port mapping libraries (see: `--with-miniupnpc` and `--with-natpmp`): +Optional port mapping libraries (see: `-DWITH_MINIUPNPC=ON` and `-DWITH_NATPMP=ON`): sudo dnf install miniupnpc-devel libnatpmp-devel @@ -132,11 +127,8 @@ User-Space, Statically Defined Tracing (USDT) dependencies: GUI dependencies: -If you want to build bitcoin-qt, make sure that the required packages for Qt development -are installed. Qt 5 is necessary to build the GUI. -To build without GUI pass `--without-gui`. - -To build with Qt 5 you need the following: +Bitcoin Core includes a GUI built with the cross-platform Qt Framework. To compile the GUI, we need to install +the necessary parts of Qt, the libqrencode and pass `-DBUILD_GUI=ON`. Skip if you don't intend to use the GUI. sudo dnf install qt5-qttools-devel qt5-qtbase-devel @@ -144,12 +136,11 @@ Additionally, to support Wayland protocol for modern desktop environments: sudo dnf install qt5-qtwayland -libqrencode (optional) can be installed with: +The GUI will be able to encode addresses in QR codes unless this feature is explicitly disabled. To install libqrencode, run: sudo dnf install qrencode-devel -Once these are installed, they will be found by configure and a bitcoin-qt executable will be -built by default. +Otherwise, if you don't need QR encoding support, use the `-DWITH_QRENCODE=OFF` option to disable this feature in order to compile the GUI. ## Dependencies @@ -171,9 +162,7 @@ and configure using the following: ```bash export BDB_PREFIX="/path/to/bitcoin/depends/x86_64-pc-linux-gnu" -./configure \ - BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" \ - BDB_CFLAGS="-I${BDB_PREFIX}/include" +cmake -B build -DBerkeleyDB_INCLUDE_DIR:PATH="${BDB_PREFIX}/include" ``` **Note**: Make sure that `BDB_PREFIX` is an absolute path. @@ -185,7 +174,7 @@ Disable-wallet mode When the intention is to only run a P2P node, without a wallet, Bitcoin Core can be compiled in disable-wallet mode with: - ./configure --disable-wallet + cmake -B build -DENABLE_WALLET=OFF In this case there is no dependency on SQLite or Berkeley DB. @@ -195,19 +184,19 @@ Additional Configure Flags -------------------------- A list of additional configure flags can be displayed with: - ./configure --help + cmake -B build -LH Setup and Build Example: Arch Linux ----------------------------------- This example lists the steps necessary to setup and build a command line only distribution of the latest changes on Arch Linux: - pacman --sync --needed autoconf automake boost gcc git libevent libtool make pkgconf python sqlite + pacman --sync --needed cmake boost gcc git libevent make pkgconf python sqlite git clone https://github.com/bitcoin/bitcoin.git cd bitcoin/ - ./autogen.sh - ./configure - make check - ./src/bitcoind + cmake -B build + cmake --build build + ctest --test-dir build + ./build/src/bitcoind If you intend to work with legacy Berkeley DB wallets, see [Berkeley DB](#berkeley-db) section. diff --git a/doc/build-windows-msvc.md b/doc/build-windows-msvc.md new file mode 100644 index 0000000000000..ec839724dd200 --- /dev/null +++ b/doc/build-windows-msvc.md @@ -0,0 +1,82 @@ +# Windows / MSVC Build Guide + +This guide describes how to build bitcoind, command-line utilities, and GUI on Windows using Micsrosoft 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 Bitcoin Repository + +Clone the Bitcoin Core repository to a directory. All build scripts and commands will run from this directory. +``` +git clone https://github.com/bitcoin/bitcoin.git +``` + + +## Triplets and Presets + +The Bitcoin 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 Bitcoin 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 following istructions, the "Debug" configuration can be specified instead of the "Release" one. + +### 4. 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. +``` + +### 5. 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 + +### 6. 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. + +### 7. Antivirus Software + +To improve the build process performance, one might add the Bitcoin repository directory to the Microsoft Defender Antivirus exclusions. diff --git a/doc/build-windows.md b/doc/build-windows.md index 1217f10c1bf64..2d47d120e3f5b 100644 --- a/doc/build-windows.md +++ b/doc/build-windows.md @@ -7,7 +7,7 @@ The options known to work for building Bitcoin Core on Windows are: * On Linux, using the [Mingw-w64](https://www.mingw-w64.org/) cross compiler tool chain. * On Windows, using [Windows Subsystem for Linux (WSL)](https://learn.microsoft.com/en-us/windows/wsl/about) and Mingw-w64. -* On Windows, using [Microsoft Visual Studio](https://visualstudio.microsoft.com). See [README.md](/build_msvc/README.md). +* On Windows, using [Microsoft Visual Studio](https://visualstudio.microsoft.com). See [`build-windows-msvc.md`](./build-windows-msvc.md). Other options which may work, but which have not been extensively tested are (please contribute instructions): @@ -32,14 +32,14 @@ First, install the general dependencies: sudo apt update sudo apt upgrade - sudo apt install build-essential libtool autotools-dev automake pkg-config bsdmainutils cmake curl git + sudo apt install cmake curl g++ git make pkg-config -A host toolchain (`build-essential`) is necessary because some dependency +A host toolchain (`g++`) is necessary because some dependency packages need to build host utilities that are used in the build process. See [dependencies.md](dependencies.md) for a complete overview. -If you want to build the windows installer with `make deploy` you need [NSIS](https://nsis.sourceforge.io/Main_Page): +If you want to build the Windows installer using the `deploy` build target, you will need [NSIS](https://nsis.sourceforge.io/Main_Page): sudo apt install nsis @@ -50,7 +50,7 @@ Acquire the source in the usual way: ## Building for 64-bit Windows -The first step is to install the mingw-w64 cross-compilation tool chain: +The first step is to install the mingw-w64 cross-compilation toolchain: ```sh sudo apt install g++-mingw-w64-x86-64-posix @@ -62,21 +62,12 @@ Note that for WSL the Bitcoin Core source path MUST be somewhere in the default example /usr/src/bitcoin, AND not under /mnt/d/. If this is not the case the dependency autoconf scripts will fail. This means you cannot use a directory that is located directly on the host Windows file system to perform the build. -Additional WSL Note: WSL support for [launching Win32 applications](https://learn.microsoft.com/en-us/archive/blogs/wsl/windows-and-ubuntu-interoperability#launching-win32-applications-from-within-wsl) -results in `Autoconf` configure scripts being able to execute Windows Portable Executable files. This can cause -unexpected behaviour during the build, such as Win32 error dialogs for missing libraries. The recommended approach -is to temporarily disable WSL support for Win32 applications. - Build using: - sudo bash -c "echo 0 > /proc/sys/fs/binfmt_misc/status" # Disable WSL support for Win32 applications. - cd depends - make HOST=x86_64-w64-mingw32 - cd .. - ./autogen.sh - CONFIG_SITE=$PWD/depends/x86_64-w64-mingw32/share/config.site ./configure --prefix=/ - make # use "-j N" for N parallel jobs - sudo bash -c "echo 1 > /proc/sys/fs/binfmt_misc/status" # Enable WSL support for Win32 applications. + gmake -C depends HOST=x86_64-w64-mingw32 # Use "-j N" for N parallel jobs. + cmake -B build --toolchain depends/x86_64-w64-mingw32/toolchain.cmake + cmake --build build # Use "-j N" for N parallel jobs. + ctest --test-dir build # Use "-j N" for N parallel tests. Some tests are disabled if Python 3 is not available. ## Depends system @@ -90,8 +81,8 @@ executables to a directory on the Windows drive in the same directory structure as they appear in the release `.zip` archive. This can be done in the following way. This will install to `c:\workspace\bitcoin`, for example: - make install DESTDIR=/mnt/c/workspace/bitcoin + cmake --install build --prefix /mnt/c/workspace/bitcoin You can also create an installer using: - make deploy + cmake --build build --target deploy diff --git a/doc/developer-notes.md b/doc/developer-notes.md index 0445921026587..3066aabe600a0 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -338,11 +338,11 @@ Recommendations: ### Generating Documentation -The documentation can be generated with `make docs` and cleaned up with `make -clean-docs`. The resulting files are located in `doc/doxygen/html`; open +The documentation can be generated with `cmake --build --target docs`. +The resulting files are located in `/doc/doxygen/html`; open `index.html` in that directory to view the homepage. -Before running `make docs`, you'll need to install these dependencies: +Before building the `docs` target, you'll need to install these dependencies: Linux: `sudo apt install doxygen graphviz` @@ -476,25 +476,34 @@ $ ./test/functional/test_runner.py --valgrind ### Compiling for test coverage -LCOV can be used to generate a test coverage report based upon `make check` +LCOV can be used to generate a test coverage report based upon `ctest` execution. LCOV must be installed on your system (e.g. the `lcov` package on Debian/Ubuntu). To enable LCOV report generation during test runs: ```shell -./configure --enable-lcov -make -make cov +cmake -B build -DCMAKE_BUILD_TYPE=Coverage +cmake --build build +cmake -P build/Coverage.cmake -# A coverage report will now be accessible at `./test_bitcoin.coverage/index.html`, -# which covers unit tests, and `./total.coverage/index.html`, which covers +# A coverage report will now be accessible at `./build/test_bitcoin.coverage/index.html`, +# which covers unit tests, and `./build/total.coverage/index.html`, which covers # unit and functional tests. ``` Additional LCOV options can be specified using `LCOV_OPTS`, but may be dependent on the version of LCOV. For example, when using LCOV `2.x`, branch coverage can be -enabled by setting `LCOV_OPTS="--rc branch_coverage=1"`, when configuring. +enabled by setting `LCOV_OPTS="--rc branch_coverage=1"`: + +``` +cmake -DLCOV_OPTS="--rc branch_coverage=1" -P build/Coverage.cmake +``` + +To enable test parallelism: +``` +cmake -DJOBS=$(nproc) -P build/Coverage.cmake +``` ### Performance profiling with perf diff --git a/doc/fuzzing.md b/doc/fuzzing.md index c9fb918c8f277..ffc6a0496490a 100644 --- a/doc/fuzzing.md +++ b/doc/fuzzing.md @@ -7,12 +7,15 @@ To quickly get started fuzzing Bitcoin Core using [libFuzzer](https://llvm.org/d ```sh $ git clone https://github.com/bitcoin/bitcoin $ cd bitcoin/ -$ ./autogen.sh -$ CC=clang CXX=clang++ ./configure --enable-fuzz --with-sanitizers=address,fuzzer,undefined +$ cmake -B build_fuzz \ + -DCMAKE_C_COMPILER="clang" \ + -DCMAKE_CXX_COMPILER="clang++" \ + -DBUILD_FOR_FUZZING=ON \ + -DSANITIZERS=undefined,address,fuzzer # macOS users: If you have problem with this step then make sure to read "macOS hints for # libFuzzer" on https://github.com/bitcoin/bitcoin/blob/master/doc/fuzzing.md#macos-hints-for-libfuzzer -$ make -$ FUZZ=process_message src/test/fuzz/fuzz +$ cmake --build build_fuzz +$ FUZZ=process_message build_fuzz/src/test/fuzz/fuzz # abort fuzzing using ctrl-c ``` @@ -33,7 +36,7 @@ If you specify a corpus directory then any new coverage increasing inputs will b ```sh $ mkdir -p process_message-seeded-from-thin-air/ -$ FUZZ=process_message src/test/fuzz/fuzz process_message-seeded-from-thin-air/ +$ FUZZ=process_message build_fuzz/src/test/fuzz/fuzz process_message-seeded-from-thin-air/ INFO: Seed: 840522292 INFO: Loaded 1 modules (424174 inline 8-bit counters): 424174 [0x55e121ef9ab8, 0x55e121f613a6), INFO: Loaded 1 PC tables (424174 PCs): 424174 [0x55e121f613a8,0x55e1225da288), @@ -77,7 +80,7 @@ of the test. Just make sure to use double-dash to distinguish them from the fuzzer's own arguments: ```sh -$ FUZZ=address_deserialize_v2 src/test/fuzz/fuzz -runs=1 fuzz_seed_corpus/address_deserialize_v2 --checkaddrman=5 --printtoconsole=1 +$ FUZZ=address_deserialize_v2 build_fuzz/src/test/fuzz/fuzz -runs=1 fuzz_seed_corpus/address_deserialize_v2 --checkaddrman=5 --printtoconsole=1 ``` ## Fuzzing corpora @@ -88,7 +91,7 @@ To fuzz `process_message` using the [`bitcoin-core/qa-assets`](https://github.co ```sh $ git clone https://github.com/bitcoin-core/qa-assets -$ FUZZ=process_message src/test/fuzz/fuzz qa-assets/fuzz_seed_corpus/process_message/ +$ FUZZ=process_message build_fuzz/src/test/fuzz/fuzz qa-assets/fuzz_seed_corpus/process_message/ INFO: Seed: 1346407872 INFO: Loaded 1 modules (424174 inline 8-bit counters): 424174 [0x55d8a9004ab8, 0x55d8a906c3a6), INFO: Loaded 1 PC tables (424174 PCs): 424174 [0x55d8a906c3a8,0x55d8a96e5288), @@ -101,7 +104,15 @@ INFO: seed corpus: files: 991 min: 1b max: 1858b total: 288291b rss: 150Mb ## Run without sanitizers for increased throughput -Fuzzing on a harness compiled with `--with-sanitizers=address,fuzzer,undefined` is good for finding bugs. However, the very slow execution even under libFuzzer will limit the ability to find new coverage. A good approach is to perform occasional long runs without the additional bug-detectors (configure `--with-sanitizers=fuzzer`) and then merge new inputs into a corpus as described in the qa-assets repo (https://github.com/bitcoin-core/qa-assets/blob/main/.github/PULL_REQUEST_TEMPLATE.md). Patience is useful; even with improved throughput, libFuzzer may need days and 10s of millions of executions to reach deep/hard targets. +Fuzzing on a harness compiled with `-DSANITIZERS=address,fuzzer,undefined` is +good for finding bugs. However, the very slow execution even under libFuzzer +will limit the ability to find new coverage. A good approach is to perform +occasional long runs without the additional bug-detectors (just +`-DSANITIZERS=fuzzer`) and then merge new inputs into a corpus as described in +the qa-assets repo +(https://github.com/bitcoin-core/qa-assets/blob/main/.github/PULL_REQUEST_TEMPLATE.md). +Patience is useful; even with improved throughput, libFuzzer may need days and +10s of millions of executions to reach deep/hard targets. ## Reproduce a fuzzer crash reported by the CI @@ -112,7 +123,7 @@ Fuzzing on a harness compiled with `--with-sanitizers=address,fuzzer,undefined` more slowly with sanitizers enabled, but a crash should be reproducible very quickly from a crash case) - run the fuzzer with the case number appended to the seed corpus path: - `FUZZ=process_message src/test/fuzz/fuzz + `FUZZ=process_message build_fuzz/src/test/fuzz/fuzz qa-assets/fuzz_seed_corpus/process_message/1bc91feec9fc00b107d97dc225a9f2cdaa078eb6` ## Submit improved coverage @@ -131,10 +142,15 @@ You may also need to take care of giving the correct path for `clang` and `clang++`, like `CC=/path/to/clang CXX=/path/to/clang++` if the non-systems `clang` does not come first in your path. -Full configure that was tested on macOS with `brew` installed `llvm`: +Full configuration step that was tested on macOS with `brew` installed `llvm`: ```sh -./configure --enable-fuzz --with-sanitizers=fuzzer,address,undefined CC=$(brew --prefix llvm)/bin/clang CXX=$(brew --prefix llvm)/bin/clang++ +$ cmake -B build_fuzz \ + -DCMAKE_C_COMPILER="$(brew --prefix llvm)/bin/clang" \ + -DCMAKE_CXX_COMPILER="$(brew --prefix llvm)/bin/clang++" \ + -DBUILD_FOR_FUZZING=ON \ + -DSANITIZERS=undefined,address,fuzzer \ + -DAPPEND_LDFLAGS=-Wl,-no_warn_duplicate_libraries ``` Read the [libFuzzer documentation](https://llvm.org/docs/LibFuzzer.html) for more information. This [libFuzzer tutorial](https://github.com/google/fuzzing/blob/master/tutorial/libFuzzerTutorial.md) might also be of interest. @@ -150,16 +166,18 @@ $ git clone https://github.com/bitcoin/bitcoin $ cd bitcoin/ $ git clone https://github.com/AFLplusplus/AFLplusplus $ make -C AFLplusplus/ source-only -$ ./autogen.sh # If afl-clang-lto is not available, see # https://github.com/AFLplusplus/AFLplusplus#a-selecting-the-best-afl-compiler-for-instrumenting-the-target -$ CC=$(pwd)/AFLplusplus/afl-clang-lto CXX=$(pwd)/AFLplusplus/afl-clang-lto++ ./configure --enable-fuzz -$ make -# For macOS you may need to ignore x86 compilation checks when running "make". If so, -# try compiling using: AFL_NO_X86=1 make +$ cmake -B build_fuzz \ + -DCMAKE_C_COMPILER="$(pwd)/AFLplusplus/afl-clang-lto" \ + -DCMAKE_CXX_COMPILER="$(pwd)/AFLplusplus/afl-clang-lto++" \ + -DBUILD_FOR_FUZZING=ON +$ cmake --build build_fuzz +# For macOS you may need to ignore x86 compilation checks when running "cmake --build". If so, +# try compiling using: AFL_NO_X86=1 cmake --build build_fuzz $ mkdir -p inputs/ outputs/ $ echo A > inputs/thin-air-input -$ FUZZ=bech32 AFLplusplus/afl-fuzz -i inputs/ -o outputs/ -- src/test/fuzz/fuzz +$ FUZZ=bech32 ./AFLplusplus/afl-fuzz -i inputs/ -o outputs/ -- build_fuzz/src/test/fuzz/fuzz # You may have to change a few kernel parameters to test optimally - afl-fuzz # will print an error and suggestion if so. ``` @@ -175,15 +193,18 @@ To quickly get started fuzzing Bitcoin Core using [Honggfuzz](https://github.com ```sh $ git clone https://github.com/bitcoin/bitcoin $ cd bitcoin/ -$ ./autogen.sh $ git clone https://github.com/google/honggfuzz $ cd honggfuzz/ $ make $ cd .. -$ CC=$(pwd)/honggfuzz/hfuzz_cc/hfuzz-clang CXX=$(pwd)/honggfuzz/hfuzz_cc/hfuzz-clang++ ./configure --enable-fuzz --with-sanitizers=address,undefined -$ make +$ cmake -B build_fuzz \ + -DCMAKE_C_COMPILER="$(pwd)/honggfuzz/hfuzz_cc/hfuzz-clang" \ + -DCMAKE_CXX_COMPILER="$(pwd)/honggfuzz/hfuzz_cc/hfuzz-clang++" \ + -DBUILD_FOR_FUZZING=ON \ + -DSANITIZERS=address,undefined +$ cmake --build build_fuzz $ mkdir -p inputs/ -$ FUZZ=process_message honggfuzz/honggfuzz -i inputs/ -- src/test/fuzz/fuzz +$ FUZZ=process_message ./honggfuzz/honggfuzz -i inputs/ -- build_fuzz/src/test/fuzz/fuzz ``` Read the [Honggfuzz documentation](https://github.com/google/honggfuzz/blob/master/docs/USAGE.md) for more information. @@ -204,15 +225,10 @@ $ mkdir bitcoin-honggfuzz-p2p/ $ cd bitcoin-honggfuzz-p2p/ $ git clone https://github.com/bitcoin/bitcoin $ cd bitcoin/ -$ ./autogen.sh $ git clone https://github.com/google/honggfuzz $ cd honggfuzz/ $ make $ cd .. -$ CC=$(pwd)/honggfuzz/hfuzz_cc/hfuzz-clang \ - CXX=$(pwd)/honggfuzz/hfuzz_cc/hfuzz-clang++ \ - ./configure --disable-wallet --with-gui=no \ - --with-sanitizers=address,undefined $ git apply << "EOF" diff --git a/src/compat/compat.h b/src/compat/compat.h index 8195bceaec..cce2b31ff0 100644 @@ -254,11 +270,17 @@ index 7601a6ea84..702d0f56ce 100644 SanitizeString(msg.m_type), msg.m_message_size, HexStr(Span{hash}.first(CMessageHeader::CHECKSUM_SIZE)), EOF -$ make -C src/ bitcoind +$ cmake -B build_fuzz \ + -DCMAKE_C_COMPILER="$(pwd)/honggfuzz/hfuzz_cc/hfuzz-clang" \ + -DCMAKE_CXX_COMPILER="$(pwd)/honggfuzz/hfuzz_cc/hfuzz-clang++" \ + -DENABLE_WALLET=OFF \ + -DBUILD_GUI=OFF \ + -DSANITIZERS=address,undefined +$ cmake --build build_fuzz --target bitcoind $ mkdir -p inputs/ -$ honggfuzz/honggfuzz --exit_upon_crash --quiet --timeout 4 -n 1 -Q \ +$ ./honggfuzz/honggfuzz --exit_upon_crash --quiet --timeout 4 -n 1 -Q \ -E HFND_TCP_PORT=18444 -f inputs/ -- \ - src/bitcoind -regtest -discover=0 -dns=0 -dnsseed=0 -listenonion=0 \ + build_fuzz/src/bitcoind -regtest -discover=0 -dns=0 -dnsseed=0 -listenonion=0 \ -nodebuglogfile -bind=127.0.0.1:18444 -logthreadnames \ -debug ``` @@ -298,11 +320,9 @@ $ cd Eclipser $ git checkout v1.x $ make $ cd .. -$ ./autogen.sh -$ ./configure --enable-fuzz -$ make +$ cmake -B build_fuzz -DBUILD_FOR_FUZZING=ON $ mkdir -p outputs/ -$ FUZZ=bech32 dotnet Eclipser/build/Eclipser.dll fuzz -p src/test/fuzz/fuzz -t 36000 -o outputs --src stdin +$ FUZZ=bech32 dotnet ./Eclipser/build/Eclipser.dll fuzz -p build_fuzz/src/test/fuzz/fuzz -t 36000 -o outputs --src stdin ``` This will perform 10 hours of fuzzing. @@ -320,7 +340,7 @@ Fuzzing with Eclipser will likely be much more effective if using an existing co ```sh $ git clone https://github.com/bitcoin-core/qa-assets -$ FUZZ=bech32 dotnet Eclipser/build/Eclipser.dll fuzz -p src/test/fuzz/fuzz -t 36000 -i qa-assets/fuzz_seed_corpus/bech32 outputs --src stdin +$ FUZZ=bech32 dotnet Eclipser/build/Eclipser.dll fuzz -p build_fuzz/src/test/fuzz/fuzz -t 36000 -i qa-assets/fuzz_seed_corpus/bech32 outputs --src stdin ``` Note that fuzzing with Eclipser on certain targets (those that create 'full nodes', e.g. `process_message*`) will, diff --git a/doc/productivity.md b/doc/productivity.md index 323d86f7b8003..f025b4bf6e7f0 100644 --- a/doc/productivity.md +++ b/doc/productivity.md @@ -6,8 +6,8 @@ Table of Contents * [General](#general) * [Cache compilations with `ccache`](#cache-compilations-with-ccache) - * [Disable features with `./configure`](#disable-features-with-configure) - * [Make use of your threads with `make -j`](#make-use-of-your-threads-with-make--j) + * [Disable features when generating the build system](#disable-features-when-generating-the-build-system) + * [Make use of your threads with `-j`](#make-use-of-your-threads-with--j) * [Only build what you need](#only-build-what-you-need) * [Compile on multiple machines](#compile-on-multiple-machines) * [Multiple working directories with `git worktrees`](#multiple-working-directories-with-git-worktrees) @@ -31,7 +31,7 @@ The easiest way to faster compile times is to cache compiles. `ccache` is a way > ccache is a compiler cache. It speeds up recompilation by caching the result of previous compilations and detecting when the same compilation is being done again. Supported languages are C, C++, Objective-C and Objective-C++. -Install `ccache` through your distribution's package manager, and run `./configure` with your normal flags to pick it up. +Install `ccache` through your distribution's package manager, and run `cmake -B build` with your normal configuration options to pick it up. To use ccache for all your C/C++ projects, follow the symlinks method [here](https://ccache.dev/manual/latest.html#_run_modes) to set it up. @@ -46,38 +46,32 @@ Note: base_dir is required for ccache to share cached compiles of the same file You _must not_ set base_dir to "/", or anywhere that contains system headers (according to the ccache docs). -### Disable features with `./configure` +### Disable features when generating the build system -After running `./autogen.sh`, which generates the `./configure` file, use `./configure --help` to identify features that you can disable to save on compilation time. A few common flags: +During the generation of the build system only essential build options are enabled by default to save on compilation time. -```sh ---without-miniupnpc ---without-natpmp ---disable-bench ---disable-wallet ---without-gui -``` +Run `cmake -B build -LH` to see the full list of available options. GUI tools, such as `ccmake` and `cmake-gui`, can be also helpful. -If you do need the wallet enabled, it is common for devs to add `--with-incompatible-bdb`. This uses your system bdb version for the wallet, so you don't have to find a copy of bdb 4.8. Wallets from such a build will be incompatible with any release binary (and vice versa), so use with caution on mainnet. +If you do need the wallet enabled (`-DENABLE_WALLET=ON`), it is common for devs to use your system bdb version for the wallet, so you don't have to find a copy of bdb 4.8. Wallets from such a build will be incompatible with any release binary (and vice versa), so use with caution on mainnet. -### Make use of your threads with `make -j` +### Make use of your threads with `-j` -If you have multiple threads on your machine, you can tell `make` to utilize all of them with: +If you have multiple threads on your machine, you can utilize all of them with: ```sh -make -j"$(($(nproc)+1))" +cmake --build build -j "$(($(nproc)+1))" ``` ### Only build what you need -When rebuilding during development, note that running `make`, without giving a target, will do a lot of work you probably don't need. It will build the GUI (unless you've disabled it) and all the tests (which take much longer to build than the app does). +When rebuilding during development, note that running `cmake --build build`, without giving a target, will do a lot of work you probably don't need. It will build the GUI (if you've enabled it) and all the tests (which take much longer to build than the app does). Obviously, it is important to build and run the tests at appropriate times -- but when you just want a quick compile to check your work, consider picking one or a set of build targets relevant to what you're working on, e.g.: ```sh -make src/bitcoind src/bitcoin-cli -make src/qt/bitcoin-qt -make -C src bitcoin_bench +cmake --build build --target bitcoind bitcoin-cli +cmake --build build --target bitcoin-qt +cmake --build build --target bench_bitcoin ``` (You can and should combine this with `-j`, as above, for a parallel build.) @@ -110,9 +104,9 @@ To squash in `git commit --fixup` commits without rebasing over an updated maste git rebase -i --autosquash "$(git merge-base master HEAD)" ``` -To execute `make check` on every commit since last diverged from master, but without rebasing over an updated master, we can do the following: +To execute `cmake --build build && ctest --test-dir build` on every commit since last diverged from master, but without rebasing over an updated master, we can do the following: ```sh -git rebase -i --exec "make check" "$(git merge-base master HEAD)" +git rebase -i --exec "cmake --build build && ctest --test-dir build" "$(git merge-base master HEAD)" ``` ----- diff --git a/doc/release-process.md b/doc/release-process.md index fa2c53eb0c506..aeaed8d68c597 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -5,14 +5,14 @@ Release Process ### Before every release candidate -* Update release candidate version in `configure.ac` (`CLIENT_VERSION_RC`). +* Update release candidate version in `CMakeLists.txt` (`CLIENT_VERSION_RC`). * Update manpages (after rebuilding the binaries), see [gen-manpages.py](https://github.com/bitcoin/bitcoin/blob/master/contrib/devtools/README.md#gen-manpagespy). * Update bitcoin.conf and commit changes if they exist, see [gen-bitcoin-conf.sh](https://github.com/bitcoin/bitcoin/blob/master/contrib/devtools/README.md#gen-bitcoin-confsh). ### Before every major and minor release * Update [bips.md](bips.md) to account for changes since the last release. -* Update version in `configure.ac` (don't forget to set `CLIENT_VERSION_RC` to `0`). +* Update version in `CMakeLists.txt` (don't forget to set `CLIENT_VERSION_RC` to `0`). * Update manpages (see previous section) * Write release notes (see "Write the release notes" below) in doc/release-notes.md. If necessary, archive the previous release notes as doc/release-notes/release-notes-${VERSION}.md. @@ -20,8 +20,8 @@ Release Process ### Before every major release * On both the master branch and the new release branch: - - update `CLIENT_VERSION_MAJOR` in [`configure.ac`](../configure.ac) -* On the new release branch in [`configure.ac`](../configure.ac)(see [this commit](https://github.com/bitcoin/bitcoin/commit/742f7dd)): + - update `CLIENT_VERSION_MAJOR` in [`CMakeLists.txt`](../CMakeLists.txt) +* On the new release branch in [`CMakeLists.txt`](../CMakeLists.txt)(see [this commit](https://github.com/bitcoin/bitcoin/commit/742f7dd)): - set `CLIENT_VERSION_MINOR` to `0` - set `CLIENT_VERSION_BUILD` to `0` - set `CLIENT_VERSION_IS_RELEASE` to `true` diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000000000..18b2b5745d036 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,438 @@ +# 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}) + +# 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}") + +# Stable, backwards-compatible consensus functionality. +add_library(bitcoin_consensus STATIC EXCLUDE_FROM_ALL + arith_uint256.cpp + consensus/merkle.cpp + consensus/tx_check.cpp + hash.cpp + primitives/block.cpp + primitives/transaction.cpp + pubkey.cpp + script/interpreter.cpp + script/script.cpp + script/script_error.cpp + uint256.cpp +) +target_link_libraries(bitcoin_consensus + PRIVATE + core_interface + bitcoin_crypto + secp256k1 +) + +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 + addresstype.cpp + base58.cpp + bech32.cpp + chainparams.cpp + chainparamsbase.cpp + coins.cpp + common/args.cpp + common/bloom.cpp + common/config.cpp + common/init.cpp + common/interfaces.cpp + common/messages.cpp + common/run_command.cpp + common/settings.cpp + common/signmessage.cpp + common/system.cpp + common/url.cpp + compressor.cpp + core_read.cpp + core_write.cpp + deploymentinfo.cpp + external_signer.cpp + init/common.cpp + kernel/chainparams.cpp + key.cpp + key_io.cpp + merkleblock.cpp + net_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 + scheduler.cpp + script/descriptor.cpp + script/miniscript.cpp + script/parsing.cpp + script/sign.cpp + script/signingprovider.cpp + script/solver.cpp +) +target_link_libraries(bitcoin_common + PRIVATE + core_interface + bitcoin_consensus + bitcoin_util + univalue + 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 bitcoin-wallet-res.rc) + target_link_libraries(bitcoin-wallet + core_interface + bitcoin_wallet + bitcoin_common + bitcoin_util + Boost::headers + ) + 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 + addrdb.cpp + addrman.cpp + banman.cpp + bip324.cpp + blockencodings.cpp + blockfilter.cpp + chain.cpp + consensus/tx_verify.cpp + dbwrapper.cpp + deploymentstatus.cpp + flatfile.cpp + headerssync.cpp + httprpc.cpp + httpserver.cpp + i2p.cpp + index/base.cpp + index/blockfilterindex.cpp + index/coinstatsindex.cpp + index/txindex.cpp + init.cpp + kernel/chain.cpp + kernel/checks.cpp + kernel/coinstats.cpp + kernel/context.cpp + kernel/cs_main.cpp + kernel/disconnected_transactions.cpp + kernel/mempool_removal_reason.cpp + mapport.cpp + net.cpp + net_processing.cpp + netgroup.cpp + node/abort.cpp + node/blockmanager_args.cpp + node/blockstorage.cpp + node/caches.cpp + node/chainstate.cpp + node/chainstatemanager_args.cpp + node/coin.cpp + node/coins_view_args.cpp + node/connection_types.cpp + node/context.cpp + node/database_args.cpp + node/eviction.cpp + node/interface_ui.cpp + node/interfaces.cpp + node/kernel_notifications.cpp + node/mempool_args.cpp + node/mempool_persist.cpp + node/mempool_persist_args.cpp + node/miner.cpp + node/mini_miner.cpp + node/minisketchwrapper.cpp + node/peerman_args.cpp + node/psbt.cpp + node/timeoffsets.cpp + node/transaction.cpp + node/txreconciliation.cpp + node/utxo_snapshot.cpp + node/warnings.cpp + noui.cpp + policy/fees.cpp + policy/fees_args.cpp + policy/packages.cpp + policy/rbf.cpp + policy/settings.cpp + policy/truc_policy.cpp + pow.cpp + rest.cpp + rpc/blockchain.cpp + rpc/fees.cpp + rpc/mempool.cpp + rpc/mining.cpp + rpc/net.cpp + rpc/node.cpp + rpc/output_script.cpp + rpc/rawtransaction.cpp + rpc/server.cpp + rpc/server_util.cpp + rpc/signmessage.cpp + rpc/txoutproof.cpp + script/sigcache.cpp + signet.cpp + torcontrol.cpp + txdb.cpp + txmempool.cpp + txorphanage.cpp + txrequest.cpp + validation.cpp + validationinterface.cpp + versionbits.cpp + $<$:wallet/init.cpp> + $<$>:dummywallet.cpp> +) +target_link_libraries(bitcoin_node + PRIVATE + core_interface + bitcoin_common + bitcoin_util + leveldb + minisketch + univalue + Boost::headers + $ + $ + $ + $ + $ + $ +) + + +# Bitcoin Core bitcoind. +if(BUILD_DAEMON) + add_executable(bitcoind + bitcoind.cpp + init/bitcoind.cpp + ) + add_windows_resources(bitcoind bitcoind-res.rc) + target_link_libraries(bitcoind + core_interface + bitcoin_node + $ + ) + 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 + $ + ) + 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 bitcoin-cli-res.rc) + target_link_libraries(bitcoin-cli + core_interface + bitcoin_cli + bitcoin_common + bitcoin_util + $ + ) + list(APPEND installable_targets bitcoin-cli) +endif() + + +if(BUILD_TX) + add_executable(bitcoin-tx bitcoin-tx.cpp) + add_windows_resources(bitcoin-tx bitcoin-tx-res.rc) + target_link_libraries(bitcoin-tx + core_interface + bitcoin_common + bitcoin_util + univalue + ) + 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 + ) + list(APPEND installable_targets bitcoin-util) +endif() + + +if(BUILD_GUI) + add_subdirectory(qt) +endif() + + +if(BUILD_KERNEL_LIB) + add_subdirectory(kernel) +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 + bitcoinkernel + ) +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/bench/CMakeLists.txt b/src/bench/CMakeLists.txt new file mode 100644 index 0000000000000..61a1126904e58 --- /dev/null +++ b/src/bench/CMakeLists.txt @@ -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(GenerateHeaders) +generate_header_from_raw(data/block413567.raw) + +add_executable(bench_bitcoin + bench_bitcoin.cpp + bench.cpp + data.cpp + nanobench.cpp + ${CMAKE_CURRENT_BINARY_DIR}/data/block413567.raw.h +# Benchmarks: + addrman.cpp + base58.cpp + bech32.cpp + bip324_ecdh.cpp + block_assemble.cpp + ccoins_caching.cpp + chacha20.cpp + checkblock.cpp + checkblockindex.cpp + checkqueue.cpp + cluster_linearize.cpp + crypto_hash.cpp + descriptors.cpp + disconnected_transactions.cpp + duplicate_inputs.cpp + ellswift.cpp + examples.cpp + gcs_filter.cpp + hashpadding.cpp + index_blockfilter.cpp + load_external.cpp + lockedpool.cpp + logging.cpp + mempool_eviction.cpp + mempool_stress.cpp + merkle_root.cpp + parse_hex.cpp + peer_eviction.cpp + poly1305.cpp + pool.cpp + prevector.cpp + random.cpp + readblock.cpp + rollingbloom.cpp + rpc_blockchain.cpp + rpc_mempool.cpp + sign_transaction.cpp + streams_findbyte.cpp + strencodings.cpp + util_time.cpp + verify_script.cpp + xor.cpp +) + +target_link_libraries(bench_bitcoin + core_interface + test_util + bitcoin_node + Boost::headers +) + +if(ENABLE_WALLET) + target_sources(bench_bitcoin + PRIVATE + coin_selection.cpp + wallet_balance.cpp + wallet_create.cpp + wallet_create_tx.cpp + wallet_loading.cpp + wallet_ismine.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 0000000000000..03c6972dca010 --- /dev/null +++ b/src/crypto/CMakeLists.txt @@ -0,0 +1,68 @@ +# 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_crypto STATIC EXCLUDE_FROM_ALL + aes.cpp + chacha20.cpp + chacha20poly1305.cpp + hex_base.cpp + hkdf_sha256_32.cpp + hmac_sha256.cpp + hmac_sha512.cpp + muhash.cpp + poly1305.cpp + ripemd160.cpp + sha1.cpp + sha256.cpp + sha256_sse4.cpp + sha3.cpp + sha512.cpp + siphash.cpp + ../support/cleanse.cpp +) + +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() diff --git a/src/ipc/CMakeLists.txt b/src/ipc/CMakeLists.txt new file mode 100644 index 0000000000000..94b1ceb54e4d3 --- /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/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt new file mode 100644 index 0000000000000..ffb1a857ac17e --- /dev/null +++ b/src/kernel/CMakeLists.txt @@ -0,0 +1,106 @@ +# 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/. + +# TODO: libbitcoinkernel is a work in progress consensus engine +# library, as more and more modules are decoupled from the +# consensus engine, this list will shrink to only those +# which are absolutely necessary. +add_library(bitcoinkernel + bitcoinkernel.cpp + chain.cpp + checks.cpp + chainparams.cpp + coinstats.cpp + context.cpp + cs_main.cpp + disconnected_transactions.cpp + mempool_removal_reason.cpp + ../arith_uint256.cpp + ../chain.cpp + ../coins.cpp + ../compressor.cpp + ../consensus/merkle.cpp + ../consensus/tx_check.cpp + ../consensus/tx_verify.cpp + ../core_read.cpp + ../dbwrapper.cpp + ../deploymentinfo.cpp + ../deploymentstatus.cpp + ../flatfile.cpp + ../hash.cpp + ../logging.cpp + ../node/blockstorage.cpp + ../node/chainstate.cpp + ../node/utxo_snapshot.cpp + ../policy/feerate.cpp + ../policy/packages.cpp + ../policy/policy.cpp + ../policy/rbf.cpp + ../policy/settings.cpp + ../policy/truc_policy.cpp + ../pow.cpp + ../primitives/block.cpp + ../primitives/transaction.cpp + ../pubkey.cpp + ../random.cpp + ../randomenv.cpp + ../script/interpreter.cpp + ../script/script.cpp + ../script/script_error.cpp + ../script/sigcache.cpp + ../script/solver.cpp + ../signet.cpp + ../streams.cpp + ../support/lockedpool.cpp + ../sync.cpp + ../txdb.cpp + ../txmempool.cpp + ../uint256.cpp + ../util/chaintype.cpp + ../util/check.cpp + ../util/feefrac.cpp + ../util/fs.cpp + ../util/fs_helpers.cpp + ../util/hasher.cpp + ../util/moneystr.cpp + ../util/rbf.cpp + ../util/serfloat.cpp + ../util/signalinterrupt.cpp + ../util/strencodings.cpp + ../util/string.cpp + ../util/syserror.cpp + ../util/threadnames.cpp + ../util/time.cpp + ../util/tokenpipe.cpp + ../validation.cpp + ../validationinterface.cpp + ../versionbits.cpp +) +target_link_libraries(bitcoinkernel + PRIVATE + core_interface + bitcoin_clientversion + bitcoin_crypto + leveldb + secp256k1 + PUBLIC + Boost::headers +) + +# libbitcoinkernel requires default symbol visibility, explicitly +# specify that here so that things still work even when user +# configures with -DREDUCE_EXPORTS=ON +# +# Note this is a quick hack that will be removed as we +# incrementally define what to export from the library. +set_target_properties(bitcoinkernel PROPERTIES + CXX_VISIBILITY_PRESET default +) + +include(GNUInstallDirs) +install(TARGETS bitcoinkernel + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} +) diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt new file mode 100644 index 0000000000000..dc62d0f57e22d --- /dev/null +++ b/src/qt/CMakeLists.txt @@ -0,0 +1,334 @@ +# 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(bitcoin_locale.qrc bitcoin_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 + bantablemodel.cpp + bantablemodel.h + bitcoin.cpp + bitcoin.h + bitcoinaddressvalidator.cpp + bitcoinaddressvalidator.h + bitcoinamountfield.cpp + bitcoinamountfield.h + bitcoingui.cpp + bitcoingui.h + bitcoinunits.cpp + bitcoinunits.h + clientmodel.cpp + clientmodel.h + csvmodelwriter.cpp + csvmodelwriter.h + guiutil.cpp + guiutil.h + initexecutor.cpp + initexecutor.h + intro.cpp + intro.h + $<$:macdockiconhandler.h> + $<$:macdockiconhandler.mm> + $<$:macnotificationhandler.h> + $<$:macnotificationhandler.mm> + $<$:macos_appnap.h> + $<$:macos_appnap.mm> + modaloverlay.cpp + modaloverlay.h + networkstyle.cpp + networkstyle.h + notificator.cpp + notificator.h + optionsdialog.cpp + optionsdialog.h + optionsmodel.cpp + optionsmodel.h + peertablemodel.cpp + peertablemodel.h + peertablesortproxy.cpp + peertablesortproxy.h + platformstyle.cpp + platformstyle.h + qvalidatedlineedit.cpp + qvalidatedlineedit.h + qvaluecombobox.cpp + qvaluecombobox.h + rpcconsole.cpp + rpcconsole.h + splashscreen.cpp + splashscreen.h + trafficgraphwidget.cpp + trafficgraphwidget.h + utilitydialog.cpp + utilitydialog.h + $<$:winshutdownmonitor.cpp> + $<$:winshutdownmonitor.h> + bitcoin.qrc + ${CMAKE_CURRENT_BINARY_DIR}/bitcoin_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 + leveldb + 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 + editaddressdialog.cpp + editaddressdialog.h + openuridialog.cpp + openuridialog.h + overviewpage.cpp + overviewpage.h + paymentserver.cpp + paymentserver.h + psbtoperationsdialog.cpp + psbtoperationsdialog.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 + transactiondescdialog.cpp + transactiondescdialog.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 +) + +add_windows_resources(bitcoin-qt res/bitcoin-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 + ) + 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}/bitcoinstrings.cpp ${ui_files} ${qt_translatable_sources} -ts ${CMAKE_CURRENT_SOURCE_DIR}/locale/bitcoin_en.ts + COMMAND Qt5::lconvert -drop-translations -o ${CMAKE_CURRENT_SOURCE_DIR}/locale/bitcoin_en.xlf -i ${CMAKE_CURRENT_SOURCE_DIR}/locale/bitcoin_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/bitcoin_en.xlf + COMMAND ${CMAKE_COMMAND} -E rm ${CMAKE_CURRENT_SOURCE_DIR}/locale/bitcoin_en.xlf.old + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src + VERBATIM + ) +endif() diff --git a/src/qt/README.md b/src/qt/README.md index 20c712c98d8d4..124f08e8fab8d 100644 --- a/src/qt/README.md +++ b/src/qt/README.md @@ -4,7 +4,7 @@ The current precise version for Qt 5 is specified in [qt.mk](/depends/packages/q ## Compile and run -See build instructions: [Unix](/doc/build-unix.md), [macOS](/doc/build-osx.md), [Windows](/doc/build-windows.md), [FreeBSD](/doc/build-freebsd.md), [NetBSD](/doc/build-netbsd.md), [OpenBSD](/doc/build-openbsd.md) +See build instructions: [Unix](/doc/build-unix.md), [macOS](/doc/build-osx.md), [Windows](/doc/build-windows-msvc.md), [FreeBSD](/doc/build-freebsd.md), [NetBSD](/doc/build-netbsd.md), [OpenBSD](/doc/build-openbsd.md) When following your systems build instructions, make sure to install the `Qt` dependencies. diff --git a/src/qt/test/CMakeLists.txt b/src/qt/test/CMakeLists.txt new file mode 100644 index 0000000000000..582ed7146639d --- /dev/null +++ b/src/qt/test/CMakeLists.txt @@ -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/. + +add_executable(test_bitcoin-qt + apptests.cpp + optiontests.cpp + rpcnestedtests.cpp + test_main.cpp + uritests.cpp + util.cpp + ../../init/bitcoin-qt.cpp +) + +target_link_libraries(test_bitcoin-qt + core_interface + bitcoinqt + test_util + bitcoin_node + 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 0000000000000..a666a76f8f312 --- /dev/null +++ b/src/test/CMakeLists.txt @@ -0,0 +1,223 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +include(GenerateHeaders) +generate_header_from_json(data/base58_encode_decode.json) +generate_header_from_json(data/bip341_wallet_vectors.json) +generate_header_from_json(data/blockfilters.json) +generate_header_from_json(data/key_io_invalid.json) +generate_header_from_json(data/key_io_valid.json) +generate_header_from_json(data/script_tests.json) +generate_header_from_json(data/sighash.json) +generate_header_from_json(data/tx_invalid.json) +generate_header_from_json(data/tx_valid.json) +generate_header_from_raw(data/asmap.raw) + +# 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/bip341_wallet_vectors.json.h + ${CMAKE_CURRENT_BINARY_DIR}/data/blockfilters.json.h + ${CMAKE_CURRENT_BINARY_DIR}/data/key_io_invalid.json.h + ${CMAKE_CURRENT_BINARY_DIR}/data/key_io_valid.json.h + ${CMAKE_CURRENT_BINARY_DIR}/data/script_tests.json.h + ${CMAKE_CURRENT_BINARY_DIR}/data/sighash.json.h + ${CMAKE_CURRENT_BINARY_DIR}/data/tx_invalid.json.h + ${CMAKE_CURRENT_BINARY_DIR}/data/tx_valid.json.h + addrman_tests.cpp + allocator_tests.cpp + amount_tests.cpp + argsman_tests.cpp + arith_uint256_tests.cpp + banman_tests.cpp + base32_tests.cpp + base58_tests.cpp + base64_tests.cpp + bech32_tests.cpp + bip32_tests.cpp + bip324_tests.cpp + blockchain_tests.cpp + blockencodings_tests.cpp + blockfilter_index_tests.cpp + blockfilter_tests.cpp + blockmanager_tests.cpp + bloom_tests.cpp + bswap_tests.cpp + checkqueue_tests.cpp + cluster_linearize_tests.cpp + coins_tests.cpp + coinscachepair_tests.cpp + coinstatsindex_tests.cpp + common_url_tests.cpp + compilerbug_tests.cpp + compress_tests.cpp + crypto_tests.cpp + cuckoocache_tests.cpp + dbwrapper_tests.cpp + denialofservice_tests.cpp + descriptor_tests.cpp + disconnected_transactions.cpp + feefrac_tests.cpp + flatfile_tests.cpp + fs_tests.cpp + getarg_tests.cpp + hash_tests.cpp + headers_sync_chainwork_tests.cpp + httpserver_tests.cpp + i2p_tests.cpp + interfaces_tests.cpp + key_io_tests.cpp + key_tests.cpp + logging_tests.cpp + mempool_tests.cpp + merkle_tests.cpp + merkleblock_tests.cpp + miner_tests.cpp + miniminer_tests.cpp + miniscript_tests.cpp + minisketch_tests.cpp + multisig_tests.cpp + net_peer_connection_tests.cpp + net_peer_eviction_tests.cpp + net_tests.cpp + netbase_tests.cpp + node_warnings_tests.cpp + orphanage_tests.cpp + peerman_tests.cpp + pmt_tests.cpp + policy_fee_tests.cpp + policyestimator_tests.cpp + pool_tests.cpp + pow_tests.cpp + prevector_tests.cpp + raii_event_tests.cpp + random_tests.cpp + rbf_tests.cpp + rest_tests.cpp + result_tests.cpp + reverselock_tests.cpp + rpc_tests.cpp + sanity_tests.cpp + scheduler_tests.cpp + script_p2sh_tests.cpp + script_parse_tests.cpp + script_segwit_tests.cpp + script_standard_tests.cpp + script_tests.cpp + scriptnum_tests.cpp + serfloat_tests.cpp + serialize_tests.cpp + settings_tests.cpp + sighash_tests.cpp + sigopcount_tests.cpp + skiplist_tests.cpp + sock_tests.cpp + span_tests.cpp + streams_tests.cpp + sync_tests.cpp + system_tests.cpp + timeoffsets_tests.cpp + torcontrol_tests.cpp + transaction_tests.cpp + translation_tests.cpp + txindex_tests.cpp + txpackage_tests.cpp + txreconciliation_tests.cpp + txrequest_tests.cpp + txvalidation_tests.cpp + txvalidationcache_tests.cpp + uint256_tests.cpp + util_tests.cpp + util_threadnames_tests.cpp + validation_block_tests.cpp + validation_chainstate_tests.cpp + validation_chainstatemanager_tests.cpp + validation_flush_tests.cpp + validation_tests.cpp + validationinterface_tests.cpp + versionbits_tests.cpp +) + +target_link_libraries(test_bitcoin + core_interface + test_util + bitcoin_cli + bitcoin_node + minisketch + secp256k1 + Boost::headers + $ +) + +if(ENABLE_WALLET) + add_subdirectory(${PROJECT_SOURCE_DIR}/src/wallet/test wallet) +endif() + +if(WITH_MULTIPROCESS) + add_library(bitcoin_ipc_test STATIC EXCLUDE_FROM_ALL + ipc_test.cpp + ) + + target_capnp_sources(bitcoin_ipc_test ${PROJECT_SOURCE_DIR} + ipc_test.capnp + ) + + target_link_libraries(bitcoin_ipc_test + PRIVATE + core_interface + univalue + ) + + target_sources(test_bitcoin + PRIVATE + ipc_tests.cpp + ) + target_link_libraries(test_bitcoin bitcoin_ipc_test) +endif() + +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/README.md b/src/test/README.md index bab1a28f611ca..ace2b0b0cb802 100644 --- a/src/test/README.md +++ b/src/test/README.md @@ -12,22 +12,23 @@ that runs all of the unit tests. The main source file for the test library is fo ### Compiling/running unit tests -Unit tests will be automatically compiled if dependencies were met in `./configure` +Unit tests will be automatically compiled if dependencies were met +during the generation of the Bitcoin Core build system and tests weren't explicitly disabled. -After configuring, they can be run with `make check`, which includes unit tests from -subtrees, or `make && make -C src check-unit` for just the unit tests. +Assuming the build directory is named `build`, the unit tests can be run +with `ctests --test-dir build`, which includes unit tests from subtrees. -To run the unit tests manually, launch `src/test/test_bitcoin`. To recompile -after a test file was modified, run `make` and then run the test again. If you -modify a non-test file, use `make -C src/test` to recompile only what's needed +To run the unit tests manually, launch `build/src/test/test_bitcoin`. To recompile +after a test file was modified, run `cmake --build build` and then run the test again. If you +modify a non-test file, use `cmake --build build --target test_bitcoin` to recompile only what's needed to run the unit tests. To add more unit tests, add `BOOST_AUTO_TEST_CASE` functions to the existing .cpp files in the `test/` directory or add new .cpp files that implement new `BOOST_AUTO_TEST_SUITE` sections. -To run the GUI unit tests manually, launch `src/qt/test/test_bitcoin-qt` +To run the GUI unit tests manually, launch `build/src/qt/test/test_bitcoin-qt` To add more GUI unit tests, add them to the `src/qt/test/` directory and the `src/qt/test/test_main.cpp` file. @@ -38,7 +39,7 @@ the `src/qt/test/test_main.cpp` file. For example, to run just the `getarg_tests` suite of tests: ```bash -test_bitcoin --log_level=all --run_test=getarg_tests +build/src/test/test_bitcoin --log_level=all --run_test=getarg_tests ``` `log_level` controls the verbosity of the test framework, which logs when a @@ -48,7 +49,7 @@ test case is entered, for example. `bitcoind`. Use `--` to separate these sets of arguments: ```bash -test_bitcoin --log_level=all --run_test=getarg_tests -- -printtoconsole=1 +build/src/test/test_bitcoin --log_level=all --run_test=getarg_tests -- -printtoconsole=1 ``` The `-printtoconsole=1` after the two dashes sends debug logging, which @@ -58,7 +59,7 @@ standard terminal output. ... or to run just the doubledash test: ```bash -test_bitcoin --run_test=getarg_tests/doubledash +build/src/test/test_bitcoin --run_test=getarg_tests/doubledash ``` `test_bitcoin` creates a temporary working (data) directory with a randomly @@ -81,7 +82,7 @@ what the test wrote to `debug.log` after it completes, for example. so no leftover state is used.) ```bash -$ test_bitcoin --run_test=getarg_tests/doubledash -- -testdatadir=/somewhere/mydatadir +$ build/src/test/test_bitcoin --run_test=getarg_tests/doubledash -- -testdatadir=/somewhere/mydatadir Test directory (will not be deleted): "/somewhere/mydatadir/test_common_Bitcoin Core/getarg_tests/doubledash/datadir Running 1 test case... @@ -100,8 +101,9 @@ Run `test_bitcoin --help` for the full list of tests. ### Adding test cases -To add a new unit test file to our test suite you need -to add the file to `src/Makefile.test.include`. The pattern is to create +To add a new unit test file to our test suite, you need +to add the file to either `src/test/CMakeLists.txt` or +`src/wallet/test/CMakeLists.txt` for wallet-related tests. The pattern is to create one test file for each class or source file for which you want to create unit tests. The file naming convention is `_tests.cpp` and such files should wrap their tests in a test suite @@ -110,7 +112,8 @@ see `uint256_tests.cpp`. ### Logging and debugging in unit tests -`make check` will write to a log file `foo_tests.cpp.log` and display this file +`ctest --test-dir build` will write to a log file `build/Testing/Temporary/LastTest.log`. You can +additionaly use the `--output-on-failure` option to display logs of the failed tests automatically on failure. For running individual tests verbosely, refer to the section [above](#running-individual-tests). @@ -121,13 +124,13 @@ For debugging you can launch the `test_bitcoin` executable with `gdb` or `lldb` start debugging, just like you would with any other program: ```bash -gdb src/test/test_bitcoin +gdb build/src/test/test_bitcoin ``` #### Segmentation faults If you hit a segmentation fault during a test run, you can diagnose where the fault -is happening by running `gdb ./src/test/test_bitcoin` and then using the `bt` command +is happening by running `gdb ./build/src/test/test_bitcoin` and then using the `bt` command within gdb. Another tool that can be used to resolve segmentation faults is @@ -145,7 +148,7 @@ Running the tests and hitting a segmentation fault should now produce a file cal You can then explore the core dump using ```bash -gdb src/test/test_bitcoin core +gdb build/src/test/test_bitcoin core (gbd) bt # produce a backtrace for where a segfault occurred ``` diff --git a/src/test/fuzz/CMakeLists.txt b/src/test/fuzz/CMakeLists.txt new file mode 100644 index 0000000000000..134232e984a9b --- /dev/null +++ b/src/test/fuzz/CMakeLists.txt @@ -0,0 +1,144 @@ +# 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 + bitdeque.cpp + bitset.cpp + block.cpp + block_header.cpp + block_index.cpp + blockfilter.cpp + bloom_filter.cpp + buffered_file.cpp + chain.cpp + checkqueue.cpp + cluster_linearize.cpp + coins_view.cpp + coinscache_sim.cpp + connman.cpp + crypto.cpp + crypto_aes256.cpp + crypto_aes256cbc.cpp + crypto_chacha20.cpp + crypto_chacha20poly1305.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 + feefrac.cpp + fee_rate.cpp + feeratediagram.cpp + fees.cpp + flatfile.cpp + float.cpp + golomb_rice.cpp + headerssync.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 + mini_miner.cpp + muhash.cpp + multiplication_overflow.cpp + net.cpp + net_permissions.cpp + netaddress.cpp + netbase_dns_lookup.cpp + node_eviction.cpp + p2p_handshake.cpp + p2p_transport_serialization.cpp + package_eval.cpp + parse_hd_keypath.cpp + parse_numbers.cpp + parse_script.cpp + parse_univalue.cpp + partially_downloaded_block.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 + rbf.cpp + rolling_bloom_filter.cpp + rpc.cpp + script.cpp + script_assets_test_minimizer.cpp + script_descriptor_cache.cpp + script_flags.cpp + script_format.cpp + script_interpreter.cpp + script_ops.cpp + script_parsing.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 + signet.cpp + socks5.cpp + span.cpp + string.cpp + strprintf.cpp + system.cpp + timeoffsets.cpp + torcontrol.cpp + transaction.cpp + tx_in.cpp + tx_out.cpp + tx_pool.cpp + txorphan.cpp + txrequest.cpp + utxo_snapshot.cpp + utxo_total_supply.cpp + validation_load_mempool.cpp + vecdeque.cpp + versionbits.cpp +) +target_link_libraries(fuzz + core_interface + test_fuzz + bitcoin_cli + bitcoin_common + minisketch + leveldb + univalue + secp256k1 + Boost::headers + $ +) + +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 0000000000000..f73a1a83c2362 --- /dev/null +++ b/src/test/fuzz/util/CMakeLists.txt @@ -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/. + +add_library(test_fuzz STATIC EXCLUDE_FROM_ALL + descriptor.cpp + mempool.cpp + net.cpp + ../fuzz.cpp + ../util.cpp +) + +target_link_libraries(test_fuzz + PRIVATE + core_interface + test_util + bitcoin_node + Boost::headers +) + +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 0000000000000..5d88d1da3ecf6 --- /dev/null +++ b/src/test/util/CMakeLists.txt @@ -0,0 +1,29 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +add_library(test_util STATIC EXCLUDE_FROM_ALL + blockfilter.cpp + coins.cpp + index.cpp + json.cpp + logging.cpp + mining.cpp + net.cpp + random.cpp + script.cpp + setup_common.cpp + str.cpp + transaction_utils.cpp + txmempool.cpp + validation.cpp + $<$:${PROJECT_SOURCE_DIR}/src/wallet/test/util.cpp> +) + +target_link_libraries(test_util + PRIVATE + core_interface + Boost::headers + PUBLIC + univalue +) diff --git a/src/univalue/CMakeLists.txt b/src/univalue/CMakeLists.txt new file mode 100644 index 0000000000000..96733fe07725d --- /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 0000000000000..26c6271f9b794 --- /dev/null +++ b/src/util/CMakeLists.txt @@ -0,0 +1,45 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +add_library(bitcoin_util STATIC EXCLUDE_FROM_ALL + asmap.cpp + batchpriority.cpp + bip32.cpp + bytevectorhash.cpp + chaintype.cpp + check.cpp + exception.cpp + feefrac.cpp + fs.cpp + fs_helpers.cpp + hasher.cpp + moneystr.cpp + rbf.cpp + readwritefile.cpp + serfloat.cpp + signalinterrupt.cpp + sock.cpp + strencodings.cpp + string.cpp + syserror.cpp + thread.cpp + threadinterrupt.cpp + threadnames.cpp + time.cpp + tokenpipe.cpp + ../logging.cpp + ../random.cpp + ../randomenv.cpp + ../streams.cpp + ../support/lockedpool.cpp + ../sync.cpp +) + +target_link_libraries(bitcoin_util + PRIVATE + core_interface + bitcoin_clientversion + bitcoin_crypto + $<$:ws2_32> +) diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt new file mode 100644 index 0000000000000..121e6e3c83737 --- /dev/null +++ b/src/wallet/CMakeLists.txt @@ -0,0 +1,59 @@ +# 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 + coincontrol.cpp + coinselection.cpp + context.cpp + crypter.cpp + db.cpp + dump.cpp + external_signer_scriptpubkeyman.cpp + feebumper.cpp + fees.cpp + interfaces.cpp + load.cpp + migrate.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 + 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 0000000000000..7332674242f34 --- /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 + coinselector_tests.cpp + feebumper_tests.cpp + group_outputs_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 + walletload_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 0000000000000..70b02292c0029 --- /dev/null +++ b/src/wallet/test/fuzz/CMakeLists.txt @@ -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/. + +target_sources(fuzz + PRIVATE + coincontrol.cpp + coinselection.cpp + fees.cpp + $<$:${CMAKE_CURRENT_LIST_DIR}/notifications.cpp> + parse_iso8601.cpp + $<$:${CMAKE_CURRENT_LIST_DIR}/scriptpubkeyman.cpp> + wallet_bdb_parser.cpp +) +target_link_libraries(fuzz bitcoin_wallet) diff --git a/src/zmq/CMakeLists.txt b/src/zmq/CMakeLists.txt new file mode 100644 index 0000000000000..8ecb236b46003 --- /dev/null +++ b/src/zmq/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(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 + $ + $ +) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000000000..9fd4e6e84ea1a --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,48 @@ +# 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) + set_configure_variable(BUILD_FUZZ_BINARY ENABLE_FUZZ_BINARY) + 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/README.md b/test/README.md index 0d1e06c0adec3..74adc644b838c 100644 --- a/test/README.md +++ b/test/README.md @@ -13,13 +13,15 @@ interfaces. - [util](/test/util) which tests the utilities (bitcoin-util, bitcoin-tx, ...). - [lint](/test/lint/) which perform various static analysis checks. -The util tests are run as part of `make check` target. The fuzz tests, functional +The util tests are run as part of `ctest` invocation. The fuzz tests, functional tests and lint scripts can be run as explained in the sections below. # Running tests locally Before tests can be run locally, Bitcoin Core must be built. See the [building instructions](/doc#building) for help. +The following examples assume that the build directory is named `build`. + ## Fuzz tests See [/doc/fuzzing.md](/doc/fuzzing.md) @@ -45,19 +47,19 @@ set PYTHONUTF8=1 Individual tests can be run by directly calling the test script, e.g.: ``` -test/functional/feature_rbf.py +build/test/functional/feature_rbf.py ``` or can be run through the test_runner harness, eg: ``` -test/functional/test_runner.py feature_rbf.py +build/test/functional/test_runner.py feature_rbf.py ``` You can run any combination (incl. duplicates) of tests by calling: ``` -test/functional/test_runner.py ... +build/test/functional/test_runner.py ... ``` Wildcard test names can be passed, if the paths are coherent and the test runner @@ -65,34 +67,34 @@ is called from a `bash` shell or similar that does the globbing. For example, to run all the wallet tests: ``` -test/functional/test_runner.py test/functional/wallet* -functional/test_runner.py functional/wallet* (called from the test/ directory) -test_runner.py wallet* (called from the test/functional/ directory) +build/test/functional/test_runner.py test/functional/wallet* +functional/test_runner.py functional/wallet* # (called from the build/test/ directory) +test_runner.py wallet* # (called from the build/test/functional/ directory) ``` but not ``` -test/functional/test_runner.py wallet* +build/test/functional/test_runner.py wallet* ``` Combinations of wildcards can be passed: ``` -test/functional/test_runner.py ./test/functional/tool* test/functional/mempool* +build/test/functional/test_runner.py ./test/functional/tool* test/functional/mempool* test_runner.py tool* mempool* ``` Run the regression test suite with: ``` -test/functional/test_runner.py +build/test/functional/test_runner.py ``` Run all possible tests with ``` -test/functional/test_runner.py --extended +build/test/functional/test_runner.py --extended ``` In order to run backwards compatibility tests, first run: @@ -107,7 +109,7 @@ By default, up to 4 tests will be run in parallel by test_runner. To specify how many jobs to run, append `--jobs=n` The individual tests and the test_runner harness have many command-line -options. Run `test/functional/test_runner.py -h` to see them all. +options. Run `build/test/functional/test_runner.py -h` to see them all. #### Speed up test runs with a RAM disk @@ -130,7 +132,7 @@ For example running the test suite with `--jobs=100` might need a 4 GiB RAM disk To use, run the test suite specifying the RAM disk as the `cachedir` and `tmpdir`: ```bash -test/functional/test_runner.py --cachedir=/mnt/tmp/cache --tmpdir=/mnt/tmp +build/test/functional/test_runner.py --cachedir=/mnt/tmp/cache --tmpdir=/mnt/tmp ``` Once finished with the tests and the disk, and to free the RAM, simply unmount the disk: @@ -151,7 +153,7 @@ Configure the RAM disk size, expressed as the number of blocks, at the end of th (`4096 MiB * 2048 blocks/MiB = 8388608 blocks` for 4 GiB). To run the tests using the RAM disk: ```bash -test/functional/test_runner.py --cachedir=/Volumes/ramdisk/cache --tmpdir=/Volumes/ramdisk/tmp +build/test/functional/test_runner.py --cachedir=/Volumes/ramdisk/cache --tmpdir=/Volumes/ramdisk/tmp ``` To unmount: @@ -193,14 +195,14 @@ pkill -9 bitcoind ##### Data directory cache A pre-mined blockchain with 200 blocks is generated the first time a -functional test is run and is stored in test/cache. This speeds up +functional test is run and is stored in build/test/cache. This speeds up test startup times since new blockchains don't need to be generated for each test. However, the cache may get into a bad state, in which case tests will fail. If this happens, remove the cache directory (and make sure bitcoind processes are stopped as above): ```bash -rm -rf test/cache +rm -rf build/test/cache killall bitcoind ``` @@ -236,7 +238,7 @@ aggregate log by running the `combine_logs.py` script. The output can be plain text, colorized text or html. For example: ``` -test/functional/combine_logs.py -c | less -r +build/test/functional/combine_logs.py -c | less -r ``` will pipe the colorized logs from the test into less. @@ -297,7 +299,7 @@ See this link for considerations: https://www.kernel.org/doc/Documentation/secur Often while debugging RPC calls in functional tests, the test might time out before the process can return a response. Use `--timeout-factor 0` to disable all RPC timeouts for that particular -functional test. Ex: `test/functional/wallet_hd.py --timeout-factor 0`. +functional test. Ex: `build/test/functional/wallet_hd.py --timeout-factor 0`. ##### Profiling @@ -321,7 +323,7 @@ For ways to generate more granular profiles, see the README in ### Util tests -Util tests can be run locally by running `test/util/test_runner.py`. +Util tests can be run locally by running `build/test/util/test_runner.py`. Use the `-v` option for verbose output. ### Lint tests diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index b85bf1c668f8e..59c37aa18f405 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -595,7 +595,7 @@ def run_tests(*, test_list, src_dir, build_dir, tmpdir, jobs=1, enable_coverage= print(f"{BOLD[1]}WARNING!{BOLD[0]} There may be insufficient free space in {tmpdir} to run the Bitcoin functional test suite. " f"Running the test suite with fewer than {min_space // (1024 * 1024)} MB of free space might cause tests to fail.") - tests_dir = src_dir + '/test/functional/' + tests_dir = build_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) diff --git a/test/lint/test_runner/src/main.rs b/test/lint/test_runner/src/main.rs index 77388b78ffbbf..1a8c11dd428e3 100644 --- a/test/lint/test_runner/src/main.rs +++ b/test/lint/test_runner/src/main.rs @@ -318,20 +318,14 @@ Please add any false positives, such as subtrees, or externally sourced files to } fn lint_includes_build_config() -> LintResult { - let config_path = "./src/config/bitcoin-config.h.in"; - if !Path::new(config_path).is_file() { - assert!(Command::new("./autogen.sh") - .status() - .expect("command error") - .success()); - } + let config_path = "./cmake/bitcoin-config.h.in"; let defines_regex = format!( r"^\s*(?!//).*({})", - check_output(Command::new("grep").args(["undef ", "--", config_path])) + check_output(Command::new("grep").args(["define", "--", config_path])) .expect("grep failed") .lines() .map(|line| { - line.split("undef ") + line.split_whitespace() .nth(1) .unwrap_or_else(|| panic!("Could not extract name in line: {line}")) }) diff --git a/vcpkg.json b/vcpkg.json new file mode 100644 index 0000000000000..ecbccb072c23f --- /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" ] + } + } +}