From 1fe7514465d40e0f50db10e4745ef57ae1ae382c Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Wed, 30 Sep 2026 18:15:17 +0200 Subject: [PATCH] Download prebuilt CMake binaries on Linux x86_64 instead of building from source (#5715 item 6) ci_get_cmake() downloaded the source tarball of CMake 3.5.0, 3.31.6, and 4.0.0 and compiled each one completely (including CMake's own test helpers) with -DCMAKE_POLICY_VERSION_MINIMUM=3.5 as a workaround for building old CMake with a newer one. On CI this made the ci_cmake_options (ci_cmake_flags) job take about 11 minutes, most of it spent building CMake itself, even though Kitware has published ready-to-run Linux x86_64 archives for all three of these releases since 3.20 (lowercase platform name). On Linux x86_64, download and unpack the prebuilt cmake--linux-x86_64.tar.gz archive instead and point the existing ${var} output at its bin/cmake, skipping the configure/build steps and CMAKE_POLICY_VERSION_MINIMUM entirely. Keep the previous source build as a fallback for any other platform (macOS, Linux aarch64), since Kitware does not publish binaries for every CMake/platform combination this project might build on. Verify the downloaded archive against Kitware's own published checksum before unpacking it: download cmake--SHA-256.txt alongside the archive and run `sha256sum -c` on the matching line. A CI job that wgets and untars a binary from a release page with no integrity check is a supply-chain gap; Kitware has published this file for every release since 3.20, so checking it costs one extra download and one grep. As a separate, mechanical change: the ci_cmake_options job's container only needed to stay on ubuntu:focal for the source build's libssl-dev dependency and its own aging toolchain; now that the Linux/x86_64 path never compiles CMake, drop libssl-dev from its apt install line and move the job to ubuntu:24.04 (Ubuntu 20.04 left standard support in May 2025). ci_clean already removes the cmake-3.5.0/cmake-3.31.6/cmake-4.0.0 directories from the #5715 item 3 fix, and the prebuilt path reuses those same directory names, so no further cleanup changes are needed. Overlaps #5598, which edits the same ci_cmake_options matrix line in ubuntu.yml; a rebase may be needed once that lands. Verified locally: `cmake -S . -B build -DJSON_CI=On` configures cleanly on macOS/arm64 (source-build fallback branch) and on Linux/x86_64 in an ubuntu:24.04 Docker container (47 `ci_cmake_flag_*` targets generated, one built and run successfully); `.github/workflows/ubuntu.yml` still parses as valid YAML; downloaded the real v3.31.6 Linux x86_64 archive and SHA-256 file from Kitware and confirmed the `grep | sha256sum -c` pipeline both accepts the genuine file and is anchored to the exact filename (not a prefix match). CI must confirm: the prebuilt-binary path actually runs on the ubuntu-latest/ubuntu:24.04 x86_64 runner, all `ci_cmake_options` entries still pass with the new container's GCC, and the job's runtime drops from roughly 11 minutes. Signed-off-by: Niels Lohmann --- .github/workflows/ubuntu.yml | 4 ++-- cmake/ci.cmake | 41 ++++++++++++++++++++++++++---------- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 44d373b16..2d1e7f9bc 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -97,13 +97,13 @@ jobs: ci_cmake_options: runs-on: ubuntu-latest - container: ubuntu:focal + container: ubuntu:24.04 strategy: matrix: target: [ci_cmake_flags, ci_test_diagnostics, ci_test_diagnostic_positions, ci_test_noexceptions, ci_test_noimplicitconversions, ci_test_legacycomparison, ci_test_noglobaludls, ci_test_disableenumserialization, ci_test_skiplibraryversioncheck, ci_test_simdutf, ci_test_strict_nul_handling, ci_test_no_thread_local] steps: - name: Install build-essential - run: apt-get update ; apt-get install -y build-essential unzip wget git libssl-dev + run: apt-get update ; apt-get install -y build-essential unzip wget git - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false diff --git a/cmake/ci.cmake b/cmake/ci.cmake index 0f434f46a..63771ac80 100644 --- a/cmake/ci.cmake +++ b/cmake/ci.cmake @@ -598,17 +598,36 @@ add_custom_target(ci_benchmarks function(ci_get_cmake version var) set(${var} ${PROJECT_BINARY_DIR}/cmake-${version}/bin/cmake) - add_custom_command( - OUTPUT ${${var}} - COMMAND wget -nc https://github.com/Kitware/CMake/releases/download/v${version}/cmake-${version}.tar.gz - COMMAND tar xfz cmake-${version}.tar.gz - COMMAND rm cmake-${version}.tar.gz - # -DCMAKE_POLICY_VERSION_MINIMUM=3.5 required to compile older CMake versions with CMake 4.0.0 - COMMAND cmake -S cmake-${version} -B cmake-${version} -DCMAKE_POLICY_VERSION_MINIMUM=3.5 - COMMAND cmake --build cmake-${version} --parallel 10 - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - COMMENT "Download CMake ${version}" - ) + if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "^(x86_64|amd64)$") + # Kitware publishes a prebuilt Linux x86_64 archive for every release; unpacking it is far + # cheaper than compiling all of CMake (including its own test helpers) from source. + add_custom_command( + OUTPUT ${${var}} + COMMAND wget -nc https://github.com/Kitware/CMake/releases/download/v${version}/cmake-${version}-linux-x86_64.tar.gz + COMMAND wget -nc https://github.com/Kitware/CMake/releases/download/v${version}/cmake-${version}-SHA-256.txt + # verify the archive against Kitware's published SHA-256 sums before unpacking it + COMMAND sh -c "grep ' cmake-${version}-linux-x86_64[.]tar[.]gz$' cmake-${version}-SHA-256.txt | sha256sum -c -" + COMMAND tar xfz cmake-${version}-linux-x86_64.tar.gz + COMMAND rm cmake-${version}-linux-x86_64.tar.gz cmake-${version}-SHA-256.txt + COMMAND ${CMAKE_COMMAND} -E rm -rf cmake-${version} + COMMAND ${CMAKE_COMMAND} -E rename cmake-${version}-linux-x86_64 cmake-${version} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + COMMENT "Download prebuilt CMake ${version}" + ) + else() + # no prebuilt archive for this platform (e.g. macOS or Linux aarch64): build from source + add_custom_command( + OUTPUT ${${var}} + COMMAND wget -nc https://github.com/Kitware/CMake/releases/download/v${version}/cmake-${version}.tar.gz + COMMAND tar xfz cmake-${version}.tar.gz + COMMAND rm cmake-${version}.tar.gz + # -DCMAKE_POLICY_VERSION_MINIMUM=3.5 required to compile older CMake versions with CMake 4.0.0 + COMMAND cmake -S cmake-${version} -B cmake-${version} -DCMAKE_POLICY_VERSION_MINIMUM=3.5 + COMMAND cmake --build cmake-${version} --parallel 10 + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + COMMENT "Download and build CMake ${version} from source" + ) + endif() set(${var} ${${var}} PARENT_SCOPE) endfunction()