Enable ccache for CMake builds.
This uses ccache + github caching to substantially decrease the time it takes to run CMake builds. Due to Bazel caching, these are some of our slowest tests, causing one of the biggest presubmit bottlenecks
PiperOrigin-RevId: 507667813
diff --git a/.github/actions/ccache/action.yml b/.github/actions/ccache/action.yml
new file mode 100644
index 0000000..2fdcc7e
--- /dev/null
+++ b/.github/actions/ccache/action.yml
@@ -0,0 +1,65 @@
+name: 'CCache Setup'
+description: 'Run a Bazel-based docker image for Protobuf CI testing'
+inputs:
+ cache-prefix:
+ required: true
+ description: A unique prefix to prevent cache pollution
+ type: string
+ support-modules:
+ required: false
+ description: Whether or not we need to support modules. This can result in extra cache misses.
+
+runs:
+ using: 'composite'
+ steps:
+ - name: Setup ccache on Windows
+ if: ${{ runner.os == 'Windows' }}
+ uses: ./.github/actions/internal/ccache-setup-windows
+ - name: Setup ccache on Mac
+ if: ${{ runner.os == 'macOS' }}
+ shell: bash
+ run: brew install ccache
+
+ - name: Setup fixed path ccache caching
+ uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920 # v3.2.4
+ with:
+ path: .ccache
+ # Always push to a cache key unique to this commit.
+ key: ${{ format('ccache-{0}-{1}-{2}', inputs.cache-prefix, github.ref, github.sha) }}
+ # Select a cache to restore from with the follow order of preference:
+ # 1) The exact same commit we're running over
+ # 2) The latest cache from the current ref branch
+ # 3) The latest push to the base ref of a pull request
+ restore-keys: |
+ ${{ format('ccache-{0}-{1}-{2}', inputs.cache-prefix, github.ref, github.sha) }}
+ ${{ format('ccache-{0}-{1}', inputs.cache-prefix, github.ref) }}
+ ${{ format('ccache-{0}-{1}', inputs.cache-prefix, github.base_ref) }}
+
+ - name: Configure ccache environment variables
+ shell: bash
+ run: |
+ echo "CCACHE_BASEDIR=${{ github.workspace }}" >> $GITHUB_ENV
+ echo "CCACHE_DIR=${{ github.workspace }}/.ccache" >> $GITHUB_ENV
+ echo "CCACHE_COMPRESS=true" >> $GITHUB_ENV
+ echo "CCACHE_COMPRESSLEVEL=6" >> $GITHUB_ENV
+ echo "CCACHE_MAXSIZE=600M" >> $GITHUB_ENV
+ echo "CCACHE_SLOPPINESS=clang_index_store,include_file_ctime,include_file_mtime,file_macro,time_macros" >> $GITHUB_ENV
+ echo "CCACHE_DIRECT=true" >> $GITHUB_ENV
+ echo "CCACHE_CMAKE_FLAGS=-Dprotobuf_ALLOW_CCACHE=ON -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache $CCACHE_CMAKE_FLAGS" >> $GITHUB_ENV
+
+ - name: Enable module support
+ if: ${{ inputs.support-modules }}
+ shell: bash
+ run: |
+ echo "CCACHE_SLOPPINESS=$CCACHE_SLOPPINESS,modules" >> $GITHUB_ENV
+ echo "CCACHE_DEPEND=true" >> $GITHUB_ENV
+
+ - name: Zero out ccache
+ if: ${{ runner.os == 'macOS' }}
+ shell: bash
+ run: ccache -z
+
+ - name: Zero out ccache
+ if: ${{ runner.os == 'Windows' }}
+ shell: pwsh
+ run: ${{ github.workspace }}\ccache.exe -z
diff --git a/.github/actions/internal/ccache-setup-windows/action.yml b/.github/actions/internal/ccache-setup-windows/action.yml
new file mode 100644
index 0000000..5479cd3
--- /dev/null
+++ b/.github/actions/internal/ccache-setup-windows/action.yml
@@ -0,0 +1,36 @@
+name: 'CCache Setup'
+description: 'Setup ccache for us in Windows CI'
+inputs:
+ ccache-version:
+ required: false
+ default: '4.7.4'
+ description: A pinned version of ccache
+ type: string
+
+runs:
+ using: 'composite'
+ steps:
+ - name: Configure ccache environment variables
+ shell: pwsh
+ run: |
+ Write-Host $Env:GITHUB_REF
+ $cllocation = (Get-Command cl.exe).Path
+ echo "CCACHE_COMPILER=$cllocation" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
+ echo "CCACHE_COMPILERTYPE=msvc" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
+
+ - name: Download ccache
+ shell: bash
+ run: |
+ curl -kLSs "https://github.com/ccache/ccache/releases/download/v${{ inputs.ccache-version }}/ccache-${{ inputs.ccache-version }}-windows-x86_64.zip" -o ccache.zip
+ unzip ccache.zip
+ cp ccache-${{ inputs.ccache-version }}-windows-x86_64/ccache.exe ccache.exe
+ cp ccache.exe cl.exe
+ rm ccache.zip
+
+ - name: Configure msbuild flags
+ shell: bash
+ run: echo "CCACHE_MSBUILD_FLAGS=/p:CLToolExe=cl.exe /p:CLToolPath=${{ github.workspace}}" >> $GITHUB_ENV
+
+ - name: Configure cmake flags
+ shell: bash
+ run: echo "CCACHE_CMAKE_FLAGS=-Dprotobuf_ALLOW_CCACHE=ON" >> $GITHUB_ENV
diff --git a/.github/workflows/test_cpp.yml b/.github/workflows/test_cpp.yml
index 66c6677..345bf05 100644
--- a/.github/workflows/test_cpp.yml
+++ b/.github/workflows/test_cpp.yml
@@ -56,39 +56,23 @@
fail-fast: false # Don't cancel all jobs if one fails.
matrix:
include:
- - command: >
+ - command: >-
/test.sh
-Dprotobuf_BUILD_CONFORMANCE=ON
-Dprotobuf_BUILD_EXAMPLES=ON
-DCMAKE_CXX_STANDARD=14
- name: Ninja
- command: >
+ command: >-
/test.sh
-G Ninja
-Dprotobuf_BUILD_CONFORMANCE=ON
-DCMAKE_CXX_STANDARD=14
- name: Shared
- command: >
+ command: >-
/test.sh
-Dprotobuf_BUILD_CONFORMANCE=ON
-Dprotobuf_BUILD_SHARED_LIBS=ON
-DCMAKE_CXX_STANDARD=14
- - name: Install
- command: >
- /install.sh -DCMAKE_CXX_STANDARD=14 \&\& /test.sh
- -Dprotobuf_REMOVE_INSTALLED_HEADERS=ON
- -Dprotobuf_BUILD_PROTOBUF_BINARIES=OFF
- -Dprotobuf_BUILD_CONFORMANCE=ON
- -DCMAKE_CXX_STANDARD=14
- - name: 32-bit
- image: us-docker.pkg.dev/protobuf-build/containers/test/linux/32bit@sha256:6651a299483f7368876db7aed0802ad4ebf038d626d8995ba7df08978ff43210
- platform: linux/386
- command: >-
- /bin/bash -c '
- cd /workspace;
- cmake . -DCMAKE_CXX_STANDARD=14;
- cmake --build . --parallel 20;
- ctest --verbose --parallel 20'
name: Linux CMake ${{ matrix.name}}
runs-on: ubuntu-latest
@@ -98,13 +82,78 @@
with:
submodules: recursive
ref: ${{ inputs.safe-checkout }}
+
+ - name: Setup ccache
+ uses: ./.github/actions/ccache
+ with:
+ cache-prefix: linux-cmake-${{ matrix.name }}
+
- name: Run tests
uses: ./.github/actions/docker
with:
- image: ${{ matrix.image || 'us-docker.pkg.dev/protobuf-build/containers/test/linux/cmake@sha256:cc23dbe065668158ca2732aa305a07bd0913a175b2079d27d9c16925d23f2335' }}
- platform: ${{ matrix.platform }}
+ image: us-docker.pkg.dev/protobuf-build/containers/test/linux/cmake@sha256:7d5efe13c7a94f742e2f54af0550ffeec7a695e5f981ff3a0197af478f9f2a86
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
- command: ${{ matrix.command }}
+ command: ${{ matrix.command }} ${{ env.CCACHE_CMAKE_FLAGS }}
+
+ linux-cmake-install:
+ name: Linux CMake Install
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout pending changes
+ uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
+ with:
+ submodules: recursive
+ ref: ${{ inputs.safe-checkout }}
+
+ - name: Setup ccache
+ uses: ./.github/actions/ccache
+ with:
+ cache-prefix: linux-cmake-install
+
+ - name: Run tests
+ uses: ./.github/actions/docker
+ with:
+ image: us-docker.pkg.dev/protobuf-build/containers/test/linux/cmake@sha256:7d5efe13c7a94f742e2f54af0550ffeec7a695e5f981ff3a0197af478f9f2a86
+ credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
+ command: >-
+ /install.sh -DCMAKE_CXX_STANDARD=14 ${{ env.CCACHE_CMAKE_FLAGS }} \&\&
+ /test.sh
+ ${{ env.CCACHE_CMAKE_FLAGS }}
+ -Dprotobuf_REMOVE_INSTALLED_HEADERS=ON
+ -Dprotobuf_BUILD_PROTOBUF_BINARIES=OFF
+ -Dprotobuf_BUILD_CONFORMANCE=ON
+ -DCMAKE_CXX_STANDARD=14
+
+ linux-cmake-32-bit:
+ name: Linux CMake 32-bit
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout pending changes
+ uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
+ with:
+ submodules: recursive
+ ref: ${{ inputs.safe-checkout }}
+
+ - name: Setup ccache
+ uses: ./.github/actions/ccache
+ with:
+ cache-prefix: linux-cmake-32-bit
+
+ - name: Run tests
+ uses: ./.github/actions/docker
+ with:
+ image: us-docker.pkg.dev/protobuf-build/containers/test/linux/32bit@sha256:f99f051daa8b12f4ebad5927f389bc71372f771ab080290ab451cbaf1648f9ea
+ platform: linux/386
+ credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
+ command: >-
+ /bin/bash -c '
+ cd /workspace;
+ ccache -z;
+ cmake . -DCMAKE_CXX_STANDARD=14 ${{ env.CCACHE_CMAKE_FLAGS }};
+ cmake --build . --parallel 20;
+ ctest --verbose --parallel 20;
+ ccache -s'
+
non-linux:
strategy:
fail-fast: false # Don't cancel all jobs if one fails.
@@ -140,16 +189,25 @@
submodules: recursive
ref: ${{ inputs.safe-checkout }}
+ - name: Setup ccache
+ uses: ./.github/actions/ccache
+ with:
+ cache-prefix: macos-cmake
+
- name: Configure CMake
uses: ./.github/actions/bash
with:
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
- command: cmake . -DCMAKE_CXX_STANDARD=14
+ command: cmake . -DCMAKE_CXX_STANDARD=14 ${{ env.CCACHE_CMAKE_FLAGS }}
- name: Build
run: cmake --build . --parallel 8
- name: Test
run: ctest --verbose -C Debug
+ - name: Report ccache stats
+ shell: bash
+ run: ccache -s -v
+
windows-cmake:
strategy:
fail-fast: false # Don't cancel all jobs if one fails.
@@ -172,10 +230,15 @@
ref: ${{ inputs.safe-checkout }}
- name: Setup MSVC
- uses: microsoft/setup-msbuild@d3ea839497466fb4c6b91ce85831f3a251a2fe3f # v1.0.0
+ uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1
with:
- vs-version: '15'
- msbuild-architecture: x64
+ arch: x64
+ vsversion: '2019'
+
+ - name: Setup ccache
+ uses: ./.github/actions/ccache
+ with:
+ cache-prefix: windows-cmake-${{ matrix.name }}
- name: Configure CMake
uses: ./.github/actions/bash
@@ -183,6 +246,7 @@
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
command: |
cmake . -G "Visual Studio 16 2019" -A x64 \
+ ${{ env.CCACHE_CMAKE_FLAGS }} \
-Dprotobuf_BUILD_CONFORMANCE=OFF \
-Dprotobuf_WITH_ZLIB=OFF \
${{ matrix.flags }}
@@ -191,10 +255,14 @@
run: >-
msbuild.exe protobuf.sln /maxcpucount:8 /p:BuildInParallel=true
/p:Configuration=Debug /p:Platform=x64 /p:VisualStudioVersion=15.0
+ ${{ env.CCACHE_MSBUILD_FLAGS }}
- name: Run Tests
run: ctest --verbose -C Debug
+ - name: Report ccache stats
+ run: ${{ github.workspace }}\ccache.exe -s -v
+
windows-cmake-install:
name: Windows CMake Install
runs-on: windows-2019
@@ -206,10 +274,15 @@
ref: ${{ inputs.safe-checkout }}
- name: Setup MSVC
- uses: microsoft/setup-msbuild@d3ea839497466fb4c6b91ce85831f3a251a2fe3f # v1.0.0
+ uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1
with:
- vs-version: '15'
- msbuild-architecture: x64
+ arch: x64
+ vsversion: '2019'
+
+ - name: Setup ccache
+ uses: ./.github/actions/ccache
+ with:
+ cache-prefix: windows-cmake
- name: Configure CMake for Install
uses: ./.github/actions/bash
@@ -219,6 +292,7 @@
mkdir build
pushd build
cmake .. -G "Visual Studio 16 2019" -A x64 \
+ ${{ env.CCACHE_CMAKE_FLAGS }} \
-Dprotobuf_BUILD_CONFORMANCE=OFF \
-Dprotobuf_WITH_ZLIB=OFF
popd
@@ -226,7 +300,7 @@
- name: Build and Install Protobuf for Windows 15 2017
run: |
pushd build
- msbuild.exe INSTALL.vcxproj /p:Platform=x64 /p:VisualStudioVersion=15.0 /maxcpucount:8 /p:BuildInParallel=true
+ msbuild.exe INSTALL.vcxproj /p:Platform=x64 /p:VisualStudioVersion=15.0 /maxcpucount:8 /p:BuildInParallel=true ${{ env.CCACHE_MSBUILD_FLAGS }}
popd
- name: Clear CMake cache
@@ -234,19 +308,23 @@
run: rm -rf build/*
- name: Configure CMake
- uses: ./.github/actions/bash
- with:
- credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
- command: |
- cmake . -G "Visual Studio 16 2019" -A x64 \
- -Dprotobuf_REMOVE_INSTALLED_HEADERS=ON \
- -Dprotobuf_BUILD_PROTOBUF_BINARIES=OFF \
- -Dprotobuf_BUILD_CONFORMANCE=OFF
+ shell: bash
+ run: |
+ cmake . -G "Visual Studio 16 2019" -A x64 \
+ ${{ env.CCACHE_CMAKE_FLAGS }} \
+ -Dprotobuf_REMOVE_INSTALLED_HEADERS=ON \
+ -Dprotobuf_BUILD_PROTOBUF_BINARIES=OFF \
+ -Dprotobuf_BUILD_CONFORMANCE=OFF \
+ -Dprotobuf_WITH_ZLIB=OFF
- name: Build for Windows 15 2017
run: >-
msbuild.exe protobuf.sln /maxcpucount:8 /p:BuildInParallel=true
/p:Configuration=Debug /p:Platform=x64 /p:VisualStudioVersion=15.0
+ ${{ env.CCACHE_MSBUILD_FLAGS }}
- name: Run Tests
run: ctest --verbose -C Debug
+
+ - name: Report ccache stats
+ run: ${{ github.workspace }}\ccache.exe -s -v
diff --git a/.github/workflows/test_php.yml b/.github/workflows/test_php.yml
index dfcf025..2d93d8f 100644
--- a/.github/workflows/test_php.yml
+++ b/.github/workflows/test_php.yml
@@ -68,7 +68,7 @@
name: Linux 32-bit ${{ matrix.version}}${{ matrix.suffix_name }}${{ matrix.test_name }}
runs-on: ubuntu-latest
env:
- image: us-docker.pkg.dev/protobuf-build/containers/test/linux/32bit@sha256:6651a299483f7368876db7aed0802ad4ebf038d626d8995ba7df08978ff43210
+ image: us-docker.pkg.dev/protobuf-build/containers/test/linux/32bit@sha256:97f50ab24582380012d7ddef5f82f08e19b9dff55d09a4a8d90a87421ae66a45
steps:
- name: Checkout pending changes
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
@@ -92,7 +92,7 @@
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
command: >-
/bin/bash -c '
- cd /workspace/php && php -v && php -m;
+ cd php && php -v && php -m;
composer update --ignore-platform-reqs;
PROTOC=/workspace/${{ steps.cross-compile.outputs.protoc }}
PATH="/usr/local/php-${{ matrix.version }}${{matrix.suffix}}/bin:$PATH"
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ca4144b..5c5513c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -61,6 +61,7 @@
option(protobuf_BUILD_LIBPROTOC "Build libprotoc" OFF)
option(protobuf_DISABLE_RTTI "Remove runtime type information in the binaries" OFF)
option(protobuf_TEST_XML_OUTDIR "Output directory for XML logs from tests." "")
+option(protobuf_ALLOW_CCACHE "Adjust build flags to allow for ccache support." OFF)
if (BUILD_SHARED_LIBS)
set(protobuf_BUILD_SHARED_LIBS_DEFAULT ON)
else (BUILD_SHARED_LIBS)
@@ -290,6 +291,16 @@
string(REPLACE "/" "\\" PROTOBUF_BINARY_WIN32_PATH ${protobuf_BINARY_DIR})
string(REPLACE "." "," protobuf_RC_FILEVERSION "${protobuf_VERSION}")
+ if (protobuf_ALLOW_CCACHE)
+ # In order to support ccache, we replace the /Zi option with /Z7. This
+ # embeds debug symbols into the object files instead of creating a separate
+ # pdb file, which isn't currently supported by ccache.
+ string(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
+ string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
+ string(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
+ string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
+ endif()
+
# Suppress linker warnings about files with no symbols defined.
string(APPEND CMAKE_STATIC_LINKER_FLAGS " /ignore:4221")
diff --git a/regenerate_stale_files.sh b/regenerate_stale_files.sh
index 881ebf6..1c38104 100755
--- a/regenerate_stale_files.sh
+++ b/regenerate_stale_files.sh
@@ -5,6 +5,8 @@
set -ex
+echo "::group::Regenerate stale files"
+
# Cd to the repo root.
cd $(dirname -- "$0")
@@ -20,3 +22,5 @@
# so just regenerating in place should be harmless.
${BazelBin} build src/google/protobuf/compiler:protoc "$@"
(export PROTOC=$PWD/bazel-bin/protoc && cd csharp && ./generate_protos.sh)
+
+echo "::endgroup::"