Add GitHub Actions CMake workflows backed by sccache. Cold cache runtime: 17m Warm cache runtime: 4m Replaces the Kokoro CMake presubmit configurations with a reusable GitHub Actions CMake workflow (cmake.yml) and orchestrator jobs in ci.yml covering Linux (GCC/libstdc++, Alpine musl, and install tests via Docker containers), macOS (Xcode), and Windows (MSVC 2022) across Debug/Release and static/shared/monolithic-shared link modes. Compilation is accelerated using Ninja and sccache backed by Google Cloud Storage. Because CMake builds and tests run directly on GitHub Actions runners rather than RBE, Debug builds enable compiler optimizations (-Og on GCC/Clang, -O1 -Ob1 -Zc:inline on MSVC) while keeping NDEBUG unset so debug assertions remain active without excessive unoptimized test runtimes (unoptimized -O0 builds with NDEBUG unset remain covered by the RBE-backed Bazel fastbuild jobs). Debug builds also omit debug symbol generation (-g on GCC/Clang, global /Zi or /Z7 and /DEBUG on MSVC) for CI compile/link speed and sccache cache efficiency (on Linux and macOS, Abseil's ELF/Mach-O symbolizer still symbolizes stack traces via standard symbol tables without DWARF sections). PiperOrigin-RevId: 1001259523
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a761a51..0e9e9b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml
@@ -46,7 +46,7 @@ jobs: # Mirrors the 11 Linux Bazel Kokoro jobs (parallelized to 1 job per Bazel # invocation). Not yet covered here: - # - CMake, macOS, and Windows Kokoro jobs + # - macOS Bazel and Windows Bazel Kokoro jobs linux: name: Linux ${{ matrix.config.name }} Bazel strategy: @@ -90,7 +90,7 @@ - name: GCC/libstdc++ (floor) toolchain: gcc remote_config: remote-floor - container_image: gcr.io/google.com/absl-177019/oss-linux-toolchain-floor@sha256:f3d8a0f76a88d5edbba70250de47fb862271297b9ff41ff317240e564c95d65e + container_image: gcr.io/google.com/absl-177019/oss-linux-toolchain-floor@sha256:5a5d17e588e14d5f0d993ea828b7ba844c72b02980bcf731ccf5a4cddf8db599 stds: '["c++17"]' # linux_arm_clang-latest_libcxx_bazel.cfg (c++17 and c++20 only) - name: ARM64 Clang/libc++ @@ -104,15 +104,57 @@ os: ${{ matrix.config.os || 'ubuntu-24.04' }} toolchain: ${{ matrix.config.toolchain }} remote_config: ${{ matrix.config.remote_config || 'remote' }} - container_image: ${{ matrix.config.container_image || 'gcr.io/google.com/absl-177019/oss-linux-toolchain-latest@sha256:8dfd8bff496cce2b3aaa5d2f1b63ebb6790f2bc78a02cdc0ca9898372fbc38f3' }} + container_image: ${{ matrix.config.container_image || 'gcr.io/google.com/absl-177019/oss-linux-toolchain-latest@sha256:5a19067585ce5e5ee45640fd0287f05038d6b3f9574d6a5cdf08241e022d0f4a' }} alternate_options: ${{ matrix.config.alternate_options || false }} stds: ${{ matrix.config.stds || '["c++17", "c++20", "c++23"]' }} compilation_modes: ${{ matrix.config.compilation_modes || '["opt", "fastbuild"]' }} + cmake: + name: ${{ matrix.config.name }} CMake + strategy: + fail-fast: false # Don't cancel all jobs if one fails. + matrix: + config: + # linux_gcc-latest_libstdcxx_cxx17_cmake.cfg + - name: Linux GCC/libstdc++ + os: ubuntu-24.04 + container_image: gcr.io/google.com/absl-177019/oss-linux-latest@sha256:9f7f104e4857e3528e8bf5f14968183f5a0e786ca9ef63601eae4e4136f011d6 + # linux_gcc_alpine_cmake.cfg + - name: Alpine Linux GCC (musl) + os: ubuntu-24.04 + container_image: gcr.io/google.com/absl-177019/alpine@sha256:ae26b80601cebb14595056a94e070f0f865d24baaf3ce19bcd52f53be9f99c80 + build_types: '["Debug"]' + link_modes: '["static"]' + # cmake-install.cfg + - name: Linux Install + os: ubuntu-24.04 + container_image: gcr.io/google.com/absl-177019/oss-linux-latest@sha256:9f7f104e4857e3528e8bf5f14968183f5a0e786ca9ef63601eae4e4136f011d6 + build_types: '["Release"]' + link_modes: '["static", "shared"]' + install_test: true + # macos_xcode_cmake.cfg + - name: macOS Xcode + os: macos-latest + build_types: '["Debug"]' + # windows-msvc-2022-cxx17-dbg-cmake.cfg + # windows-msvc-2022-cxx17-dbg-dll-cmake.cfg + - name: Windows MSVC 2022 + os: windows-2022 + build_types: '["Debug"]' + link_modes: '["static", "shared"]' + uses: ./.github/workflows/cmake.yml + secrets: inherit + with: + os: ${{ matrix.config.os }} + container_image: ${{ matrix.config.container_image || '' }} + build_types: ${{ matrix.config.build_types || '["Debug", "Release"]' }} + link_modes: ${{ matrix.config.link_modes || '["static", "shared", "monolithic-shared"]' }} + install_test: ${{ matrix.config.install_test || false }} + # Provide a single predictably-named job for copybara to look for all-blocking-tests: name: All Blocking Tests - needs: [linux] + needs: [linux, cmake] runs-on: ubuntu-latest steps: - name: Check for cancellations
diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml new file mode 100644 index 0000000..2080af3 --- /dev/null +++ b/.github/workflows/cmake.yml
@@ -0,0 +1,148 @@ +# Copyright 2026 The Abseil Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: CMake Tests + +on: + workflow_call: + inputs: + os: + description: "GitHub Actions runner OS (e.g. ubuntu-24.04, macos-latest, windows-2022)" + required: true + type: string + container_image: + description: "Docker container image to run in (empty string for host execution)" + required: false + default: "" + type: string + build_types: + description: "JSON array of CMAKE_BUILD_TYPE values to test" + required: false + default: '["Debug", "Release"]' + type: string + link_modes: + description: "JSON array of link modes to test (static, shared, monolithic-shared)" + required: false + default: '["static", "shared", "monolithic-shared"]' + type: string + install_test: + description: "Whether to run the CMake installation integration test" + required: false + default: false + type: boolean + +permissions: + contents: read + +jobs: + test: + runs-on: ${{ inputs.os }} + name: (${{ matrix.build_type }}, ${{ matrix.link_mode }}) + container: + image: ${{ inputs.container_image }} + # core=1 skips kernel pipe core_pattern handlers (e.g. apport) on death tests. + options: --cap-add=SYS_PTRACE --ulimit core=1 + credentials: + # TODO(b/573304451): Switch to Workload Identity Federation to avoid the need for secrets. + username: _json_key + password: ${{ secrets.GAR_SERVICE_ACCOUNT }} + strategy: + fail-fast: false # Don't cancel all jobs if one fails. + matrix: + build_type: ${{ fromJSON(inputs.build_types) }} + link_mode: ${{ fromJSON(inputs.link_modes) }} + defaults: + run: + shell: bash + env: + CC: ${{ startsWith(inputs.os, 'ubuntu') && 'gcc' || '' }} + CFLAGS: ${{ !inputs.install_test && startsWith(inputs.os, 'ubuntu') && '-Werror' || '' }} + CXX: ${{ startsWith(inputs.os, 'ubuntu') && 'g++' || '' }} + CXXFLAGS: ${{ !inputs.install_test && (startsWith(inputs.os, 'ubuntu') && '-Werror' || startsWith(inputs.os, 'windows') && '-WX') || '' }} + CMAKE_BUILD_PARALLEL_LEVEL: 16 + CMAKE_C_COMPILER_LAUNCHER: sccache + CMAKE_CXX_COMPILER_LAUNCHER: sccache + CMAKE_GENERATOR: Ninja + CTEST_OUTPUT_ON_FAILURE: 1 + CTEST_PARALLEL_LEVEL: 16 + SCCACHE_GCS_BUCKET: absl-cmake-sccache + SCCACHE_GCS_RW_MODE: READ_WRITE + SCCACHE_IDLE_TIMEOUT: 0 + SCCACHE_IGNORE_SERVER_IO_ERROR: 1 + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # 7.0.0 + + - name: Set up MSVC + if: ${{ runner.os == 'Windows' }} + uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0 + with: + arch: x64 + vsversion: "2022" + + - name: Authenticate to Google Cloud + id: auth + uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0 + with: + credentials_json: ${{ secrets.GAR_SERVICE_ACCOUNT }} + + - name: Set up sccache + uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10 + + - name: Start sccache + env: + SCCACHE_GCS_KEY_PATH: ${{ steps.auth.outputs.credentials_file_path }} + run: sccache --start-server + + - name: Run installation test + if: ${{ inputs.install_test }} + env: + LINK_TYPE: ${{ matrix.link_mode == 'shared' && 'DYNAMIC' || 'STATIC' }} + run: > + source ci/cmake_common.sh && + export ABSL_GOOGLETEST_VERSION ABSL_GOOGLETEST_DOWNLOAD_URL && + CMake/install_test_project/test.sh + + - name: Configure + if: ${{ !inputs.install_test }} + run: > + source ci/cmake_common.sh && + cmake -B build + -DABSL_BUILD_TESTING=ON + -DABSL_GOOGLETEST_DOWNLOAD_URL=${ABSL_GOOGLETEST_DOWNLOAD_URL} + -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} + -DCMAKE_C_FLAGS_DEBUG="${{ runner.os == 'Windows' && '-O1 -Ob1 -Zc:inline' || '-Og' }}" + -DCMAKE_CXX_FLAGS_DEBUG="${{ runner.os == 'Windows' && '-O1 -Ob1 -Zc:inline' || '-Og' }}" + -DCMAKE_EXE_LINKER_FLAGS_DEBUG="" + -DCMAKE_SHARED_LINKER_FLAGS_DEBUG="" + -DCMAKE_CXX_STANDARD=17 + -DBUILD_SHARED_LIBS=${{ matrix.link_mode != 'static' }} + -DABSL_BUILD_MONOLITHIC_SHARED_LIBS=${{ matrix.link_mode == 'monolithic-shared' }} + -DCMAKE_POLICY_DEFAULT_CMP0141=NEW + -DCMAKE_MSVC_DEBUG_INFORMATION_FORMAT="" + -DCMAKE_JOB_POOLS="link=$(nproc 2>/dev/null || sysctl -n hw.logicalcpu)" + -DCMAKE_JOB_POOL_LINK=link + + - name: Build + if: ${{ !inputs.install_test }} + run: cmake --build build + + - name: Run tests + if: ${{ !inputs.install_test }} + env: + TZDIR: ${{ github.workspace }}/absl/time/internal/cctz/testdata/zoneinfo + run: > + ctest --test-dir build + --repeat until-pass:3 + ${{ runner.os == 'Windows' && '-E "absl_lifetime_test|absl_symbolize_test"' || '' }}
diff --git a/CMake/install_test_project/test.sh b/CMake/install_test_project/test.sh index 962bc8d..2d25696 100755 --- a/CMake/install_test_project/test.sh +++ b/CMake/install_test_project/test.sh
@@ -19,8 +19,9 @@ # Fail on any error. Treat unset variables an error. Print commands as executed. set -euox pipefail -absl_dir=/abseil-cpp +absl_dir="${PWD}" absl_build_dir=/buildfs +mkdir -p "${absl_build_dir}" googletest_builddir=/googletest_builddir googletest_archive="googletest-${ABSL_GOOGLETEST_VERSION}.tar.gz" project_dir="${absl_dir}/CMake/install_test_project" @@ -40,8 +41,8 @@ mkdir build pushd build cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS="${build_shared_libs}" .. -make -j $(nproc) -make install +cmake --build . +cmake --install . ldconfig popd popd @@ -57,10 +58,12 @@ -DABSL_FIND_GOOGLETEST=ON \ -DCMAKE_BUILD_TYPE=Release \ -DABSL_BUILD_TESTING=ON \ - -DBUILD_SHARED_LIBS="${build_shared_libs}" -make -j $(nproc) -ctest -j $(nproc) --output-on-failure -make install + -DBUILD_SHARED_LIBS="${build_shared_libs}" \ + -DCMAKE_JOB_POOLS="link=$(nproc)" \ + -DCMAKE_JOB_POOL_LINK=link +cmake --build . +ctest --output-on-failure --repeat until-pass:3 +cmake --install . ldconfig popd
diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index 2ee5c2b..b242b90 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel
@@ -514,6 +514,7 @@ visibility = ["//absl:__subpackages__"], deps = [ ":config", + ":core_headers", ":pretty_function", "//absl/memory", "//absl/meta:type_traits",
diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt index 5325df7..d1ce0f9 100644 --- a/absl/base/CMakeLists.txt +++ b/absl/base/CMakeLists.txt
@@ -367,6 +367,7 @@ ${ABSL_TEST_COPTS} DEPS absl::config + absl::core_headers absl::memory absl::meta absl::pretty_function
diff --git a/absl/base/internal/exception_safety_testing.h b/absl/base/internal/exception_safety_testing.h index e600b85..b4be3ec 100644 --- a/absl/base/internal/exception_safety_testing.h +++ b/absl/base/internal/exception_safety_testing.h
@@ -40,6 +40,7 @@ #include <vector> #include "gtest/gtest.h" +#include "absl/base/attributes.h" #include "absl/base/internal/pretty_function.h" #include "absl/memory/memory.h" #include "absl/meta/type_traits.h" @@ -547,7 +548,7 @@ } // Memory management operators - static void* operator new(size_t s) noexcept( + ABSL_ATTRIBUTE_NOINLINE static void* operator new(size_t s) noexcept( IsSpecified(TypeSpec::kNoThrowNew)) { if (!IsSpecified(TypeSpec::kNoThrowNew)) { exceptions_internal::MaybeThrow(ABSL_INTERNAL_PRETTY_FUNCTION, true); @@ -555,7 +556,7 @@ return ::operator new(s); } - static void* operator new[](size_t s) noexcept( + ABSL_ATTRIBUTE_NOINLINE static void* operator new[](size_t s) noexcept( IsSpecified(TypeSpec::kNoThrowNew)) { if (!IsSpecified(TypeSpec::kNoThrowNew)) { exceptions_internal::MaybeThrow(ABSL_INTERNAL_PRETTY_FUNCTION, true); @@ -564,8 +565,8 @@ } template <typename... Args> - static void* operator new(size_t s, Args&&... args) noexcept( - IsSpecified(TypeSpec::kNoThrowNew)) { + ABSL_ATTRIBUTE_NOINLINE static void* operator new( + size_t s, Args&&... args) noexcept(IsSpecified(TypeSpec::kNoThrowNew)) { if (!IsSpecified(TypeSpec::kNoThrowNew)) { exceptions_internal::MaybeThrow(ABSL_INTERNAL_PRETTY_FUNCTION, true); } @@ -573,8 +574,8 @@ } template <typename... Args> - static void* operator new[](size_t s, Args&&... args) noexcept( - IsSpecified(TypeSpec::kNoThrowNew)) { + ABSL_ATTRIBUTE_NOINLINE static void* operator new[]( + size_t s, Args&&... args) noexcept(IsSpecified(TypeSpec::kNoThrowNew)) { if (!IsSpecified(TypeSpec::kNoThrowNew)) { exceptions_internal::MaybeThrow(ABSL_INTERNAL_PRETTY_FUNCTION, true); } @@ -583,17 +584,23 @@ // Abseil doesn't support throwing overloaded operator delete. These are // provided so a throwing operator-new can clean up after itself. - void operator delete(void* p) noexcept { ::operator delete(p); } + ABSL_ATTRIBUTE_NOINLINE void operator delete(void* p) noexcept { + ::operator delete(p); + } template <typename... Args> - void operator delete(void* p, Args&&... args) noexcept { + ABSL_ATTRIBUTE_NOINLINE void operator delete(void* p, + Args&&... args) noexcept { ::operator delete(p, std::forward<Args>(args)...); } - void operator delete[](void* p) noexcept { return ::operator delete[](p); } + ABSL_ATTRIBUTE_NOINLINE void operator delete[](void* p) noexcept { + return ::operator delete[](p); + } template <typename... Args> - void operator delete[](void* p, Args&&... args) noexcept { + ABSL_ATTRIBUTE_NOINLINE void operator delete[](void* p, + Args&&... args) noexcept { return ::operator delete[](p, std::forward<Args>(args)...); }
diff --git a/ci/BUILD.bazel b/ci/BUILD.bazel index d0e2b8f..c83d079 100644 --- a/ci/BUILD.bazel +++ b/ci/BUILD.bazel
@@ -23,7 +23,7 @@ exec_properties = { "OSArch": "amd64", "cache-silo-key": "n2-highcpu-2-2026-10-14", - "container-image": "docker://gcr.io/google.com/absl-177019/oss-linux-latest@sha256:fd9e2ce179533e027466d47157a7581aec99de5a72b46ac43165a5d58855d3ba", + "container-image": "docker://gcr.io/google.com/absl-177019/oss-linux-latest@sha256:9f7f104e4857e3528e8bf5f14968183f5a0e786ca9ef63601eae4e4136f011d6", "dockerRunAsRoot": "true", }, ) @@ -37,7 +37,7 @@ exec_properties = { "OSArch": "amd64", "cache-silo-key": "n2-highcpu-2-2026-10-14", - "container-image": "docker://gcr.io/google.com/absl-177019/oss-linux-floor@sha256:81041c514c7ee412a5677afc652b9eb3a02e0f6dfe8d71164d80e6e39820b09d", + "container-image": "docker://gcr.io/google.com/absl-177019/oss-linux-floor@sha256:60898eb3b0dbcf85cd60e346f103fbf3169d966d391dcb2362b243d528b1183b", "dockerRunAsRoot": "true", }, ) @@ -51,7 +51,7 @@ exec_properties = { "OSArch": "arm64", "cache-silo-key": "t2a-standard-4-2026-10-14", - "container-image": "docker://gcr.io/google.com/absl-177019/oss-linux-latest@sha256:fd9e2ce179533e027466d47157a7581aec99de5a72b46ac43165a5d58855d3ba", + "container-image": "docker://gcr.io/google.com/absl-177019/oss-linux-latest@sha256:9f7f104e4857e3528e8bf5f14968183f5a0e786ca9ef63601eae4e4136f011d6", "dockerRunAsRoot": "true", }, )