From 81f3d4f043e07c8fbc1b97e5f7c117bb735c1c3a Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sun, 12 Nov 2023 16:40:10 +0000 Subject: [PATCH] ci: Test CMake edge cases Keep this commit at the top when rebasing. --- .github/workflows/ci.yml | 293 ------------------- .github/workflows/cmake.yml | 568 ++++++++++++++++++++++++++++++++++++ 2 files changed, 568 insertions(+), 293 deletions(-) delete mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/cmake.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index a86b00fdc6f38..0000000000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,293 +0,0 @@ -# Copyright (c) 2023 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -name: CI -on: - # See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request. - pull_request: - # See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#push. - push: - branches: - - '**' - tags-ignore: - - '**' - -concurrency: - group: ${{ github.event_name != 'pull_request' && github.run_id || github.ref }} - cancel-in-progress: true - -env: - DANGER_RUN_CI_ON_HOST: 1 - CI_FAILFAST_TEST_LEAVE_DANGLING: 1 # GHA does not care about dangling processes and setting this variable avoids killing the CI script itself on error - MAKEJOBS: '-j10' - -jobs: - test-each-commit: - name: 'test each commit' - runs-on: ubuntu-22.04 - if: github.event_name == 'pull_request' && github.event.pull_request.commits != 1 - timeout-minutes: 360 # Use maximum time, see https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idtimeout-minutes. Assuming a worst case time of 1 hour per commit, this leads to a --max-count=6 below. - env: - MAX_COUNT: 6 - steps: - - name: Determine fetch depth - run: echo "FETCH_DEPTH=$((${{ github.event.pull_request.commits }} + 2))" >> "$GITHUB_ENV" - - uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.sha }} - fetch-depth: ${{ env.FETCH_DEPTH }} - - name: Determine commit range - run: | - # Checkout HEAD~ and find the test base commit - # Checkout HEAD~ because it would be wasteful to rerun tests on the PR - # head commit that are already run by other jobs. - git checkout HEAD~ - # Figure out test base commit by listing ancestors of HEAD, excluding - # ancestors of the most recent merge commit, limiting the list to the - # newest MAX_COUNT ancestors, ordering it from oldest to newest, and - # taking the first one. - # - # If the branch contains up to MAX_COUNT ancestor commits after the - # most recent merge commit, all of those commits will be tested. If it - # contains more, only the most recent MAX_COUNT commits will be - # tested. - # - # In the command below, the ^@ suffix is used to refer to all parents - # of the merge commit as described in: - # https://git-scm.com/docs/git-rev-parse#_other_rev_parent_shorthand_notations - # and the ^ prefix is used to exclude these parents and all their - # ancestors from the rev-list output as described in: - # https://git-scm.com/docs/git-rev-list - echo "TEST_BASE=$(git rev-list -n$((${{ env.MAX_COUNT }} + 1)) --reverse HEAD ^$(git rev-list -n1 --merges HEAD)^@ | head -1)" >> "$GITHUB_ENV" - - run: | - sudo apt-get update - sudo apt-get install clang-15 ccache build-essential libtool autotools-dev automake pkg-config bsdmainutils python3-zmq libevent-dev libboost-dev libsqlite3-dev libdb++-dev systemtap-sdt-dev libminiupnpc-dev libnatpmp-dev libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools qtwayland5 libqrencode-dev -y - - name: Compile and run tests - run: | - # Run tests on commits after the last merge commit and before the PR head commit - # Use clang++, because it is a bit faster and uses less memory than g++ - git rebase --exec "echo Running test-one-commit on \$( git log -1 ) && ./autogen.sh && CC=clang-15 CXX=clang++-15 ./configure && make clean && make -j $(nproc) check && ./test/functional/test_runner.py -j $(( $(nproc) * 2 ))" ${{ env.TEST_BASE }} - - macos-native-x86_64: - name: 'macOS 13 native, x86_64, no depends, sqlite only, gui' - # Use latest image, but hardcode version to avoid silent upgrades (and breaks). - # See: https://github.com/actions/runner-images#available-images. - runs-on: macos-13 - - # No need to run on the read-only mirror, unless it is a PR. - if: github.repository != 'bitcoin-core/gui' || github.event_name == 'pull_request' - - timeout-minutes: 120 - - env: - FILE_ENV: './ci/test/00_setup_env_mac_native.sh' - BASE_ROOT_DIR: ${{ github.workspace }} - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Clang version - run: | - sudo xcode-select --switch /Applications/Xcode_15.0.app - clang --version - - - name: Install Homebrew packages - env: - HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1 - run: brew install automake libtool pkg-config gnu-getopt ccache boost libevent miniupnpc libnatpmp zeromq qt@5 qrencode - - - name: Set Ccache directory - run: echo "CCACHE_DIR=${RUNNER_TEMP}/ccache_dir" >> "$GITHUB_ENV" - - - name: Restore Ccache cache - id: ccache-cache - uses: actions/cache/restore@v4 - with: - path: ${{ env.CCACHE_DIR }} - key: ${{ github.job }}-ccache-${{ github.run_id }} - restore-keys: ${{ github.job }}-ccache- - - - name: CI script - run: ./ci/test_run_all.sh - - - name: Save Ccache cache - uses: actions/cache/save@v4 - if: github.event_name != 'pull_request' && steps.ccache-cache.outputs.cache-hit != 'true' - with: - path: ${{ env.CCACHE_DIR }} - # https://github.com/actions/cache/blob/main/tips-and-workarounds.md#update-a-cache - key: ${{ github.job }}-ccache-${{ github.run_id }} - - win64-native: - name: 'Win64 native, VS 2022' - # Use latest image, but hardcode version to avoid silent upgrades (and breaks). - # See: https://github.com/actions/runner-images#available-images. - runs-on: windows-2022 - - # No need to run on the read-only mirror, unless it is a PR. - if: github.repository != 'bitcoin-core/gui' || github.event_name == 'pull_request' - - env: - CCACHE_MAXSIZE: '200M' - CI_CCACHE_VERSION: '4.7.5' - CI_QT_CONF: '-release -silent -opensource -confirm-license -opengl desktop -static -static-runtime -mp -qt-zlib -qt-pcre -qt-libpng -nomake examples -nomake tests -nomake tools -no-angle -no-dbus -no-gif -no-gtk -no-ico -no-icu -no-libjpeg -no-libudev -no-sql-sqlite -no-sql-odbc -no-sqlite -no-vulkan -skip qt3d -skip qtactiveqt -skip qtandroidextras -skip qtcharts -skip qtconnectivity -skip qtdatavis3d -skip qtdeclarative -skip doc -skip qtdoc -skip qtgamepad -skip qtgraphicaleffects -skip qtimageformats -skip qtlocation -skip qtlottie -skip qtmacextras -skip qtmultimedia -skip qtnetworkauth -skip qtpurchasing -skip qtquick3d -skip qtquickcontrols -skip qtquickcontrols2 -skip qtquicktimeline -skip qtremoteobjects -skip qtscript -skip qtscxml -skip qtsensors -skip qtserialbus -skip qtserialport -skip qtspeech -skip qtsvg -skip qtvirtualkeyboard -skip qtwayland -skip qtwebchannel -skip qtwebengine -skip qtwebglplugin -skip qtwebsockets -skip qtwebview -skip qtx11extras -skip qtxmlpatterns -no-openssl -no-feature-bearermanagement -no-feature-printdialog -no-feature-printer -no-feature-printpreviewdialog -no-feature-printpreviewwidget -no-feature-sql -no-feature-sqlmodel -no-feature-textbrowser -no-feature-textmarkdownwriter -no-feature-textodfwriter -no-feature-xml' - CI_QT_DIR: 'qt-everywhere-src-5.15.11' - CI_QT_URL: 'https://download.qt.io/official_releases/qt/5.15/5.15.11/single/qt-everywhere-opensource-src-5.15.11.zip' - PYTHONUTF8: 1 - TEST_RUNNER_TIMEOUT_FACTOR: 40 - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Configure Developer Command Prompt for Microsoft Visual C++ - # Using microsoft/setup-msbuild is not enough. - uses: ilammy/msvc-dev-cmd@v1 - with: - arch: x64 - - - name: Get tool information - run: | - msbuild -version | Out-File -FilePath "$env:GITHUB_WORKSPACE\msbuild_version" - Get-Content -Path "$env:GITHUB_WORKSPACE\msbuild_version" - $env:VCToolsVersion | Out-File -FilePath "$env:GITHUB_WORKSPACE\toolset_version" - Write-Host "VCToolsVersion $(Get-Content -Path "$env:GITHUB_WORKSPACE\toolset_version")" - $env:CI_QT_URL | Out-File -FilePath "$env:GITHUB_WORKSPACE\qt_url" - $env:CI_QT_CONF | Out-File -FilePath "$env:GITHUB_WORKSPACE\qt_conf" - py -3 --version - - - 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-static.cmake" -Value "set(VCPKG_BUILD_TYPE release)" - Add-Content -Path "triplets\x64-windows-static.cmake" -Value "set(VCPKG_PLATFORM_TOOLSET_VERSION $env:VCToolsVersion)" - .\vcpkg.exe --vcpkg-root "$env:VCPKG_INSTALLATION_ROOT" integrate install - git rev-parse HEAD | Out-File -FilePath "$env:GITHUB_WORKSPACE\vcpkg_commit" - Get-Content -Path "$env:GITHUB_WORKSPACE\vcpkg_commit" - - - name: vcpkg tools cache - uses: actions/cache@v4 - with: - path: C:/vcpkg/downloads/tools - key: ${{ github.job }}-vcpkg-tools - - - name: vcpkg binary cache - uses: actions/cache@v4 - with: - path: ~/AppData/Local/vcpkg/archives - key: ${{ github.job }}-vcpkg-binary-${{ hashFiles('vcpkg_commit', 'msbuild_version', 'toolset_version', 'build_msvc/vcpkg.json') }} - - - name: Generate project files - run: py -3 build_msvc\msvc-autogen.py - - - name: Build - shell: cmd - run: | - ccache --zero-stats - msbuild build_msvc\bitcoin.sln -property:CLToolPath=C:\ccache;CLToolExe=cl.exe;UseMultiToolTask=true;Configuration=Release -maxCpuCount -verbosity:minimal -noLogo - - - name: Ccache stats - run: ccache --show-stats - - - name: Save Ccache cache - uses: actions/cache/save@v4 - if: github.event_name != 'pull_request' && steps.ccache-cache.outputs.cache-hit != 'true' - with: - path: ~/AppData/Local/ccache - # https://github.com/actions/cache/blob/main/tips-and-workarounds.md#update-a-cache - key: ${{ github.job }}-ccache-${{ github.run_id }} - - - name: Run unit tests - run: src\test_bitcoin.exe -l test_suite - - - name: Run benchmarks - run: src\bench_bitcoin.exe -sanity-check - - - name: Run util tests - run: py -3 test\util\test_runner.py - - - name: Run rpcauth test - run: py -3 test\util\rpcauth-test.py - - - name: Run functional tests - env: - 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% diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml new file mode 100644 index 0000000000000..9c54a933159d8 --- /dev/null +++ b/.github/workflows/cmake.yml @@ -0,0 +1,568 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +name: CMake +on: + # Running for pushes is enough in the cmake-staging branch. + # pull_request: + push: + branches: + - '**' + tags-ignore: + - '**' + +concurrency: + group: ${{ github.workflow }}${{ github.event_name != 'pull_request' && github.run_id || github.ref }} + cancel-in-progress: true + +jobs: + build-info: + name: 'Test obj/build.h generation' + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - run: cp cmake/script/GenerateBuildInfo.cmake ${{ runner.temp }} + + - name: Test at HEAD + run: | + rm -rf src/obj build/src/obj + mkdir -p src/obj build/src/obj + ./share/genbuild.sh ${PWD}/src/obj/build.h ${PWD} + cmake -DBUILD_INFO_HEADER_PATH=${PWD}/build/src/obj/build.h -DSOURCE_DIR=${PWD} -P ${{ runner.temp }}/GenerateBuildInfo.cmake + cat src/obj/build.h + diff -u src/obj/build.h build/src/obj/build.h + + - name: Test out of tree + run: | + rm -rf src/obj build/src/obj + mkdir -p src/obj build/src/obj + ./share/genbuild.sh ${PWD}/src/obj/build.h ${{ runner.temp }} + cmake -DBUILD_INFO_HEADER_PATH=${PWD}/build/src/obj/build.h -DSOURCE_DIR=${{ runner.temp }} -P ${{ runner.temp }}/GenerateBuildInfo.cmake + cat src/obj/build.h + diff -u src/obj/build.h build/src/obj/build.h + + - name: Test at tag + run: | + rm -rf src/obj build/src/obj + mkdir -p src/obj build/src/obj + git -c advice.detachedHead=false checkout v25.1 + ./share/genbuild.sh ${PWD}/src/obj/build.h ${PWD} + cmake -DBUILD_INFO_HEADER_PATH=${PWD}/build/src/obj/build.h -DSOURCE_DIR=${PWD} -P ${{ runner.temp }}/GenerateBuildInfo.cmake + cat src/obj/build.h + diff -u src/obj/build.h build/src/obj/build.h + + - name: Test dirty tree + run: | + rm -rf src/obj build/src/obj + mkdir -p src/obj build/src/obj + echo "test" >> README.md + ./share/genbuild.sh ${PWD}/src/obj/build.h ${PWD} + cmake -DBUILD_INFO_HEADER_PATH=${PWD}/build/src/obj/build.h -DSOURCE_DIR=${PWD} -P ${{ runner.temp }}/GenerateBuildInfo.cmake + cat src/obj/build.h + diff -u src/obj/build.h build/src/obj/build.h + + - name: Test BITCOIN_GENBUILD_NO_GIT + env: + BITCOIN_GENBUILD_NO_GIT: '1' + run: | + rm -rf src/obj build/src/obj + mkdir -p src/obj build/src/obj + ./share/genbuild.sh ${PWD}/src/obj/build.h ${PWD} + cmake -DBUILD_INFO_HEADER_PATH=${PWD}/build/src/obj/build.h -DSOURCE_DIR=${PWD} -P ${{ runner.temp }}/GenerateBuildInfo.cmake + cat src/obj/build.h + diff -u src/obj/build.h build/src/obj/build.h + + + deps-search: + name: 'Test dependency search' + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + conf: + # Boost: Header-only. Using CMake's FindBoost module. + # Libevent: Using CMake's FindPkgConfig module. + - system_packages: '' + depends_options: 'NO_BOOST=1 NO_LIBEVENT=1 NO_WALLET=1 NO_USDT=1' + build_options: '' + expected: 'fail' + - system_packages: 'libboost-dev libevent-dev' + depends_options: 'NO_BOOST=1 NO_LIBEVENT=1 NO_WALLET=1 NO_USDT=1' + build_options: '' + expected: 'fail' + - system_packages: 'libboost-dev libevent-dev' + depends_options: 'NO_LIBEVENT=1 NO_WALLET=1 NO_USDT=1' + build_options: '' + expected: 'fail' + - system_packages: 'libboost-dev libevent-dev' + depends_options: 'NO_BOOST=1 NO_WALLET=1 NO_USDT=1' + build_options: '' + expected: 'fail' + - system_packages: 'libboost-dev libevent-dev' + depends_options: 'NO_WALLET=1 NO_USDT=1' + build_options: '' + expected: 'pass' + + # BerkeleyDB: Using our own FindBerkeleyDB module. + - system_packages: 'libboost-dev libevent-dev' + depends_options: 'NO_BDB=1 NO_SQLITE=1 NO_USDT=1' + build_options: '-DWITH_BDB=ON' + expected: 'fail' + - system_packages: 'libboost-dev libevent-dev libdb-dev libdb++-dev' + depends_options: 'NO_BDB=1 NO_SQLITE=1 NO_USDT=1' + build_options: '-DWITH_BDB=ON' + expected: 'fail' + - system_packages: 'libboost-dev libevent-dev' + depends_options: 'NO_SQLITE=1 NO_USDT=1' + build_options: '-DWITH_BDB=ON' + expected: 'pass' + + # SQLite: Using CMake's FindSQLite3 module. + - system_packages: 'libboost-dev libevent-dev' + depends_options: 'NO_BDB=1 NO_SQLITE=1 NO_USDT=1' + build_options: '-DWITH_SQLITE=ON' + expected: 'fail' + - system_packages: 'libboost-dev libevent-dev libsqlite3-dev' + depends_options: 'NO_BDB=1 NO_SQLITE=1 NO_USDT=1' + build_options: '-DWITH_SQLITE=ON' + expected: 'fail' + - system_packages: 'libboost-dev libevent-dev' + depends_options: 'NO_BDB=1 NO_USDT=1' + build_options: '-DWITH_SQLITE=ON' + expected: 'pass' + + # USDT: Header-only. Using CMake's find_path function. + - system_packages: 'libboost-dev libevent-dev' + depends_options: 'NO_WALLET=1 NO_USDT=1' + build_options: '-DWITH_USDT=ON' + expected: 'fail' + - system_packages: 'libboost-dev libevent-dev systemtap-sdt-dev' + depends_options: 'NO_WALLET=1 NO_USDT=1' + build_options: '-DWITH_USDT=ON' + expected: 'fail' + - system_packages: 'libboost-dev libevent-dev' + depends_options: 'NO_WALLET=1' + build_options: '-DWITH_USDT=ON' + expected: 'pass' + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install system packages + if: ${{ matrix.conf.system_packages != '' }} + run: | + sudo apt-get update + sudo apt-get install --no-install-recommends ${{ matrix.conf.system_packages }} + + - name: Build depends + working-directory: depends + run: | + make -j $(nproc) ${{ matrix.conf.depends_options }} NO_QT=1 NO_ZMQ=1 NO_UPNP=1 NO_NATPMP=1 LOG=1 + + - name: Generate build system. Expected to FAIL + if: ${{ matrix.conf.expected == 'fail' }} + run: | + ! cmake -B build -DCMAKE_TOOLCHAIN_FILE=depends/x86_64-pc-linux-gnu/share/toolchain.cmake ${{ matrix.conf.build_options }} + + - name: Generate build system. Expected to PASS + if: ${{ matrix.conf.expected == 'pass' }} + run: | + cmake -B build -DCMAKE_TOOLCHAIN_FILE=depends/x86_64-pc-linux-gnu/share/toolchain.cmake + + + ubuntu-focal-native: + name: 'Ubuntu 20.04, CMake 3.16, Boost ${{ matrix.conf.boost_version }}' + runs-on: ubuntu-20.04 + + strategy: + fail-fast: false + matrix: + conf: + - boost_version: '1.73.0' + boost_archive: 'boost_1_73_0' + - boost_version: '1.78.0' + boost_archive: 'boost_1_78_0' + - boost_version: '1.84.0' + boost_archive: 'boost_1_84_0' + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Remove preinstalled CMake + run: | + sudo rm /usr/local/bin/cmake /usr/local/bin/ctest + + - name: Install packages + run: | + sudo apt-get update + sudo apt-get install --no-install-recommends curl g++10 cmake ccache libevent-dev libsqlite3-dev libdb-dev libdb++-dev libminiupnpc-dev libnatpmp-dev libzmq3-dev systemtap-sdt-dev + echo "CCACHE_DIR=${{ runner.temp }}/ccache" >> "$GITHUB_ENV" + + - name: CMake version + run: | + cmake --version + ctest --version + + - name: Download Boost + run: | + curl --location --remote-name https://boostorg.jfrog.io/artifactory/main/release/${{ matrix.conf.boost_version }}/source/${{ matrix.conf.boost_archive }}.tar.gz + tar -xf ${{ matrix.conf.boost_archive }}.tar.gz + + - name: Restore Ccache cache + uses: actions/cache/restore@v4 + id: ccache-cache + with: + path: ${{ env.CCACHE_DIR }} + key: ${{ github.job }}-ccache-${{ github.run_id }} + restore-keys: ${{ github.job }}-ccache- + + - name: Generate build system + run: | + cmake -B build -DCMAKE_C_COMPILER=gcc-10 -DCMAKE_CXX_COMPILER=g++-10 -DBoost_INCLUDE_DIR="${PWD}/${{ matrix.conf.boost_archive }}" -DENABLE_WALLET=ON -DWITH_EXTERNAL_SIGNER=ON -DWITH_MINIUPNPC=ON -DWITH_NATPMP=ON -DWITH_ZMQ=ON -DWITH_USDT=ON -DWERROR=ON + + - name: Build + working-directory: build + run: | + cmake --build . -j $(nproc) + + - name: Ccache stats + run: | + ccache --version | head -n 1 + ccache --show-stats + + - name: Save Ccache cache + uses: actions/cache/save@v4 + if: github.event_name != 'pull_request' && steps.ccache-cache.outputs.cache-hit != 'true' + with: + path: ${{ env.CCACHE_DIR }} + key: ${{ github.job }}-ccache-${{ github.run_id }} + + - name: Test + working-directory: build + run: | + ctest -j $(nproc) + + - name: Install and run + run: | + cmake --install build --prefix install + tree install + ./install/bin/bitcoind -version + + + cross-build: + name: ${{ matrix.host.name }} + runs-on: ubuntu-22.04 + + strategy: + fail-fast: false + matrix: + host: + - name: 'Linux 32-bit, Clang, link to libatomic' + triplet: 'i686-pc-linux-gnu' + packages: 'clang-14 g++-multilib' + c_compiler: 'clang-14 -m32' + cxx_compiler: 'clang++-14 -m32' + depends_options: '' + configure_options: '-DWERROR=ON' + - name: 'MinGW-w64' + triplet: 'x86_64-w64-mingw32' + packages: 'g++-mingw-w64-x86-64-posix' + depends_options: '' + exe_extension: '.exe' + - name: 'MinGW-w64, debug' + triplet: 'x86_64-w64-mingw32' + packages: 'g++-mingw-w64-x86-64-posix' + depends_options: 'DEBUG=1' + configure_options: '-DCMAKE_BUILD_TYPE=Debug' + cache_suffix: '-debug' + exe_extension: '.exe' + # Avoid "No space left on device" error. + skip_install: 'true' + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install dependency packages + run: | + sudo apt-get update + sudo apt-get install --no-install-recommends ccache ${{ matrix.host.packages }} + echo "CCACHE_DIR=${{ runner.temp }}/ccache" >> "$GITHUB_ENV" + + - name: Depends fingerprint (1) + if: ${{ matrix.host.c_compiler != '' }} + run: | + ${{ matrix.host.c_compiler }} -v 2>&1 | tee depends/c_compiler_version + + - name: Depends fingerprint (2) + if: ${{ matrix.host.cxx_compiler != '' }} + run: | + ${{ matrix.host.cxx_compiler }} -v 2>&1 | tee depends/cxx_compiler_version + + - name: Depends fingerprint (3) + run: | + echo ${{ matrix.host.depends_options }} > depends/depends_options + + - name: Depends fingerprint (4) + id: depends_fingerprint + run: | + echo "hash=${{ hashFiles('depends/**') }}" >> "$GITHUB_OUTPUT" + + - name: Depends cache + id: depends_cache + uses: actions/cache@v4 + with: + path: | + depends/built + key: ${{ matrix.host.triplet }}${{ matrix.host.cache_suffix }}-depends-${{ steps.depends_fingerprint.outputs.hash }} + + - name: Build depends + working-directory: depends + env: + CC: ${{ matrix.host.c_compiler }} + CXX: ${{ matrix.host.cxx_compiler }} + run: | + make -j$(nproc) HOST=${{ matrix.host.triplet }} ${{ matrix.host.depends_options }} LOG=1 + + - name: Restore Ccache cache + uses: actions/cache/restore@v4 + id: ccache-cache + with: + path: ${{ env.CCACHE_DIR }} + key: ${{ matrix.host.triplet }}${{ matrix.host.cache_suffix }}-ccache-${{ github.run_id }} + restore-keys: ${{ matrix.host.triplet }}${{ matrix.host.cache_suffix }}-ccache- + + - name: Generate build system + run: | + cmake -B build --toolchain depends/${{ matrix.host.triplet }}/share/toolchain.cmake ${{ matrix.host.configure_options }} + + - name: Build + run: | + ccache --zero-stats + cmake --build build -j $(nproc) + file build/src/bitcoind${{ matrix.host.exe_extension }} + + - name: Ccache stats + run: | + ccache --version | head -n 1 + ccache --show-stats --verbose + + - name: Save Ccache cache + uses: actions/cache/save@v4 + if: github.event_name != 'pull_request' && steps.ccache-cache.outputs.cache-hit != 'true' + with: + path: ${{ env.CCACHE_DIR }} + key: ${{ matrix.host.triplet }}${{ matrix.host.cache_suffix }}-ccache-${{ github.run_id }} + + - name: Test + if: ${{ matrix.host.triplet == 'i686-pc-linux-gnu' }} + run: | + ctest --test-dir build -j $(nproc) + + - name: Install + if: ${{ matrix.host.skip_install != 'true' }} + run: | + cmake --install build --prefix install + tree install + + + win64-native-builtin-tools: + name: ${{ matrix.conf.name }} + runs-on: windows-2022 + + strategy: + fail-fast: false + matrix: + conf: + - name: 'Win64, VS 2022, dynamic' + triplet: 'x64-windows' + preset: 'vs2022' + skip_install_and_run: 'true' + - name: 'Win64, VS 2022, static' + triplet: 'x64-windows-static' + preset: 'vs2022-static' + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Remove non-MSVC tool installations + run: | + Remove-Item -Path "$env:ProgramFiles/CMake" -Recurse -Force + Remove-Item -Path "$env:VCPKG_INSTALLATION_ROOT" -Recurse -Force + + - name: Configure Visual Studio Developer PowerShell + # Using microsoft/setup-msbuild is not enough as it does not add other Visual Studio tools to PATH. + uses: ilammy/msvc-dev-cmd@v1 + + - name: Check build tools + run: | + cmake --version | Out-File -FilePath "cmake_version" + Get-Content -Path "cmake_version" + Write-Output "---" + msbuild -version | Out-File -FilePath "msbuild_version" + Get-Content -Path "msbuild_version" + Write-Output "---" + $env:VCToolsVersion | Out-File -FilePath "toolset_version" + Get-Content -Path "toolset_version" + # GHA Windows images have different versions of MSVC toolsets being installed + # side-by-side. Therefore, the VCPKG_PLATFORM_TOOLSET_VERSION must be set explicitly + # to avoid linker errors when using vcpkg in the manifest mode. + # See: https://github.com/bitcoin/bitcoin/pull/28934 + Add-Content -Path "$env:VCPKG_ROOT\triplets\${{ matrix.conf.triplet }}.cmake" -Value "set(VCPKG_PLATFORM_TOOLSET_VERSION $env:VCToolsVersion)" + # Skip debug configuration to speed up build and minimize cache size. + Add-Content -Path "$env:VCPKG_ROOT\triplets\x64-windows.cmake" -Value "set(VCPKG_BUILD_TYPE release)" + Add-Content -Path "$env:VCPKG_ROOT\triplets\${{ matrix.conf.triplet }}.cmake" -Value "set(VCPKG_BUILD_TYPE release)" + + - name: Restore vcpkg binary cache + uses: actions/cache/restore@v4 + id: vcpkg-binary-cache + with: + path: ~/AppData/Local/vcpkg/archives + key: ${{ matrix.conf.triplet }}-vcpkg-binary-${{ hashFiles('cmake_version', 'msbuild_version', 'toolset_version', 'vcpkg.json') }} + + - name: Install Ccache + run: | + choco install --yes --no-progress ccache + + - name: Generate build system + run: | + cmake -B build --preset ${{ matrix.conf.preset }} + + - name: Save vcpkg binary cache + uses: actions/cache/save@v4 + if: github.event_name != 'pull_request' && steps.vcpkg-binary-cache.outputs.cache-hit != 'true' + with: + path: ~/AppData/Local/vcpkg/archives + key: ${{ matrix.conf.triplet }}-vcpkg-binary-${{ hashFiles('cmake_version', 'msbuild_version', 'toolset_version', 'vcpkg.json') }} + + - name: Restore Ccache cache + id: ccache-cache + uses: actions/cache/restore@v4 + with: + path: ~/AppData/Local/ccache + key: ${{ matrix.conf.triplet }}-ccache-${{ github.run_id }} + restore-keys: ${{ matrix.conf.triplet }}-ccache- + + - name: Build Release configuration + working-directory: build + run: | + ccache --zero-stats + cmake --build . -j $env:NUMBER_OF_PROCESSORS --config Release + dumpbin /imports src\Release\bitcoind.exe | Select-String -Pattern "\.(?i:dll)" | Sort-Object + "" + (Get-Item src\Release\bitcoind.exe).Length + + - name: Ccache stats + run: | + ccache --version | head -n 1 + ccache --show-stats --verbose + + - name: Save Ccache cache + uses: actions/cache/save@v4 + if: github.event_name != 'pull_request' && steps.ccache-cache.outputs.cache-hit != 'true' + with: + path: ~/AppData/Local/ccache + key: ${{ matrix.conf.triplet }}-ccache-${{ github.run_id }} + + - name: Test Release configuration + working-directory: build + run: | + ctest -j $env:NUMBER_OF_PROCESSORS -C Release + + - name: Install and run Release configuration + if: ${{ matrix.conf.skip_install_and_run != 'true' }} + run: | + cmake --install build --prefix install --config Release + tree /f install + .\install\bin\bitcoind.exe -version + + + macos-native-x86_64: + name: '${{ matrix.os.name }}, ${{ matrix.xcode.name }}' + runs-on: ${{ matrix.os.os }} + + strategy: + fail-fast: false + matrix: + os: + - name: 'macOS 13 native, x86_64' + os: macos-13 + - name: 'macOS 14 native, arm64' + os: macos-14 + xcode: + - name: 'Xcode 14.3' + id: 'xcode-14.3' + path: '/Applications/Xcode_14.3.app' + - name: 'Xcode 15.2' + id: 'xcode-15.2' + path: '/Applications/Xcode_15.2.app' + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Clang version, ${{ runner.arch }} + run: | + sudo xcode-select --switch ${{ matrix.xcode.path }} + clang --version + + - name: Install Homebrew packages + env: + HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1 + run: | + brew install ccache cmake pkg-config boost libevent berkeley-db@4 qt@5 libnatpmp miniupnpc zeromq tree + echo "CCACHE_DIR=${{ runner.temp }}/ccache" >> "$GITHUB_ENV" + + - name: CMake version + run: | + cmake --version + ctest --version + + - name: Restore Ccache cache + uses: actions/cache/restore@v4 + id: ccache-cache + with: + path: ${{ env.CCACHE_DIR }} + key: ${{ matrix.os.os }}-${{ matrix.xcode.id }}-ccache-${{ github.run_id }} + restore-keys: ${{ matrix.os.os }}-${{ matrix.xcode.id }}-ccache- + + - name: Generate build system + run: | + cmake -B build + + - name: Build + run: | + ccache --zero-stats + cmake --build build -j $(sysctl -n hw.logicalcpu) + + - name: Ccache stats + run: | + ccache --version | head -n 1 + ccache --show-stats --verbose + + - name: Save Ccache cache + uses: actions/cache/save@v4 + if: github.event_name != 'pull_request' && steps.ccache-cache.outputs.cache-hit != 'true' + with: + path: ${{ env.CCACHE_DIR }} + key: ${{ matrix.os.os }}-${{ matrix.xcode.id }}-ccache-${{ github.run_id }} + + - name: Test + run: | + ctest --test-dir build -j $(sysctl -n hw.logicalcpu) + + - name: Install and run + run: | + cmake --install build --prefix install + tree install + ./install/bin/bitcoind -version