mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-07 18:43:26 -08:00
[CI] Give the Windows leg a compiler cache (#7797)
ccache drives MSVC since 4.7, but it rejects /Zi and /ZI because the debug information lives in a shared PDB it cannot restore. /Z7 puts it in the object file instead, which is what makes the compilation cacheable and also removes the shared PDB as a serialisation point on a 4-core runner. Allow ccache on Windows in CMake, install it with Chocolatey, and persist it under ccache-Windows10 the same way the Linux legs do.
This commit is contained in:
parent
3931447729
commit
ee66e73b2c
2 changed files with 70 additions and 21 deletions
69
.github/workflows/desktop-build.yml
vendored
69
.github/workflows/desktop-build.yml
vendored
|
|
@ -248,20 +248,23 @@ jobs:
|
||||||
# Debian 13 Release + suite 625 MB 800M
|
# Debian 13 Release + suite 625 MB 800M
|
||||||
# Fedora 45 debug Debug + suite 660 MB 850M
|
# Fedora 45 debug Debug + suite 660 MB 850M
|
||||||
# Fedora 45 release Release + package 614 MB 800M
|
# Fedora 45 release Release + package 614 MB 800M
|
||||||
|
# Windows 10 Release + package 1.2 GB working set 1300M
|
||||||
#
|
#
|
||||||
# That is 3.3 GB of bounds, and with the fixed entries above (about 4.4 GB) it puts
|
# That is 4.6 GB of bounds; what lands in the quota is 4.3 GB of compiler cache,
|
||||||
# the quota at roughly 7.7 GB of 10 - so only legs worth their share get one. A leg
|
# 2.97 GB stored by the Linux legs and 1.30 GB by Windows, for 8.4 GB of 10 in total.
|
||||||
# keeps no cache when it duplicates another leg's coverage (Ubuntu 26.04 behind
|
# So only legs worth their share get one. A leg keeps no cache when it duplicates
|
||||||
# Debian 13's Release + suite; the macOS legs behind the Linux ones) or finishes well
|
# another leg's coverage (Ubuntu 26.04 behind Debian 13's Release + suite; the macOS
|
||||||
# inside the Windows leg (Servatrice covers the server alone in 4.7 min). A macOS
|
# legs behind the Linux ones) or finishes well inside the Windows leg (Servatrice
|
||||||
|
# covers the server alone in 4.7 min). A macOS
|
||||||
# cache served 42% and saved about 32s on a 20 min leg that is already shorter than
|
# cache served 42% and saved about 32s on a 20 min leg that is already shorter than
|
||||||
# Windows, so that bound is better spent here. The four Linux legs that stay compile
|
# Windows, so that bound is better spent here. The four Linux legs that stay compile
|
||||||
# the client on the toolchains a change can break and are the ones a cache shortens
|
# the client on the toolchains a change can break and are the ones a cache shortens
|
||||||
# by the most.
|
# by the most.
|
||||||
# Measured job totals on master 2026-11-04 also show the ceiling this leaves:
|
# Measured job totals on master 2026-11-04 also show the ceiling this leaves:
|
||||||
# Windows 10 is 29.5 min and compiles for 23.7 of it with no compiler cache at all, so
|
# Windows 10 is 29.5 min and compiles for 23.7 of it, so Windows sets the
|
||||||
# Windows still sets the pull-request wall clock no matter how warm these legs are
|
# pull-request wall clock no matter how warm these legs are. That is why the Windows
|
||||||
# (see build-vcpkg).
|
# leg is the one macOS's share went to (see build-vcpkg): MSVC has no -g level to
|
||||||
|
# shrink, and with /Z7 the whole configuration is cacheable, PCH included.
|
||||||
#
|
#
|
||||||
# Steady-state master data corrected this on 2026-11-07: Arch 90.1% and Debian 13
|
# Steady-state master data corrected this on 2026-11-07: Arch 90.1% and Debian 13
|
||||||
# 96.75% per-run hits at the 850M/800M bounds, Fedora 45 debug 99.18% and release
|
# 96.75% per-run hits at the 850M/800M bounds, Fedora 45 debug 99.18% and release
|
||||||
|
|
@ -676,6 +679,9 @@ jobs:
|
||||||
qt_version: 6.11.*
|
qt_version: 6.11.*
|
||||||
qt_modules: qtimageformats qtmultimedia qtshadertools qtwebsockets
|
qt_modules: qtimageformats qtmultimedia qtshadertools qtwebsockets
|
||||||
type: Release
|
type: Release
|
||||||
|
ccache_eviction_age: 7d
|
||||||
|
ccache_size: 1300M # Release plus the package: 1.2 GB working set at /Z7
|
||||||
|
use_ccache: 1
|
||||||
# Scope is named after the vs2026 toolchain, not the generator: the
|
# Scope is named after the vs2026 toolchain, not the generator: the
|
||||||
# ABI hash covers cl.exe, which is identical, so this leg keeps
|
# ABI hash covers cl.exe, which is identical, so this leg keeps
|
||||||
# restoring the warm archives. Renaming would orphan them.
|
# restoring the warm archives. Renaming would orphan them.
|
||||||
|
|
@ -689,8 +695,13 @@ jobs:
|
||||||
runs-on: ${{ matrix.runner }}
|
runs-on: ${{ matrix.runner }}
|
||||||
timeout-minutes: 100
|
timeout-minutes: 100
|
||||||
env:
|
env:
|
||||||
# No leg in this job keeps a compiler cache: neither the macOS legs nor the Windows
|
# Only the Windows leg keeps a compiler cache; the macOS legs build without one
|
||||||
# leg can fill one across runs. See the note on the removed macOS ccache steps below.
|
# (see the note where their ccache steps used to be). ccache drives MSVC as long as
|
||||||
|
# the compiler emits /Z7, which CMakeLists.txt sets for exactly this reason, and it
|
||||||
|
# caches the PCH-backed targets with the sloppiness that .ci/compile.sh re-asserts.
|
||||||
|
CCACHE_DIR: ${{ github.workspace }}/.cache/
|
||||||
|
CCACHE_SIZE: ${{ matrix.ccache_size || '700M' }}
|
||||||
|
PERSIST_CCACHE: ${{ matrix.persist_ccache || 'true' }}
|
||||||
# MSVC has no -g level, so the Windows leg does not ask for one.
|
# MSVC has no -g level, so the Windows leg does not ask for one.
|
||||||
COCKATRICE_DEBUG_INFO_LEVEL: ${{ matrix.os != 'Windows' && github.ref_type != 'tag' && '1' || '' }}
|
COCKATRICE_DEBUG_INFO_LEVEL: ${{ matrix.os != 'Windows' && github.ref_type != 'tag' && '1' || '' }}
|
||||||
|
|
||||||
|
|
@ -707,6 +718,19 @@ jobs:
|
||||||
with:
|
with:
|
||||||
msbuild-architecture: x64
|
msbuild-architecture: x64
|
||||||
|
|
||||||
|
- name: "[Windows] Setup ccache"
|
||||||
|
if: matrix.os == 'Windows' && matrix.use_ccache == 1
|
||||||
|
shell: bash
|
||||||
|
run: choco install ccache --no-progress -y
|
||||||
|
|
||||||
|
- name: "[Windows] Restore compiler cache (ccache)"
|
||||||
|
if: matrix.os == 'Windows' && matrix.use_ccache == 1 && env.PERSIST_CCACHE == 'true'
|
||||||
|
id: restore_ccache
|
||||||
|
uses: actions/cache/restore@v6
|
||||||
|
with:
|
||||||
|
key: ccache-${{ matrix.os }}${{ matrix.target }}
|
||||||
|
path: ${{ env.CCACHE_DIR }}
|
||||||
|
|
||||||
# No macOS leg runs ccache. A restored macOS cache served 42% of calls and saved
|
# No macOS leg runs ccache. A restored macOS cache served 42% of calls and saved
|
||||||
# about 32s on a 20 min leg that is already shorter than the Windows leg, which did
|
# about 32s on a 20 min leg that is already shorter than the Windows leg, which did
|
||||||
# not pay for its 800M slice of the quota; with nothing restored, the remaining
|
# not pay for its 800M slice of the quota; with nothing restored, the remaining
|
||||||
|
|
@ -820,6 +844,7 @@ jobs:
|
||||||
shell: bash
|
shell: bash
|
||||||
env:
|
env:
|
||||||
BUILDTYPE: '${{ matrix.type }}'
|
BUILDTYPE: '${{ matrix.type }}'
|
||||||
|
CCACHE_EVICTION_AGE: ${{ matrix.ccache_eviction_age }}
|
||||||
CMAKE_GENERATOR: ${{ matrix.cmake_generator }}
|
CMAKE_GENERATOR: ${{ matrix.cmake_generator }}
|
||||||
# Tag builds only: artifacts from master pushes and PR branches must not report to
|
# Tag builds only: artifacts from master pushes and PR branches must not report to
|
||||||
# Sentry. Forks get no secrets on pull_request, so they keep the mock fallback either way.
|
# Sentry. Forks get no secrets on pull_request, so they keep the mock fallback either way.
|
||||||
|
|
@ -834,6 +859,7 @@ jobs:
|
||||||
MAKE_PACKAGE: '${{ matrix.make_package }}'
|
MAKE_PACKAGE: '${{ matrix.make_package }}'
|
||||||
PACKAGE_SUFFIX: '${{ matrix.package_suffix }}'
|
PACKAGE_SUFFIX: '${{ matrix.package_suffix }}'
|
||||||
TARGET_MACOS_VERSION: ${{ matrix.override_target }}
|
TARGET_MACOS_VERSION: ${{ matrix.override_target }}
|
||||||
|
USE_CCACHE: ${{ matrix.use_ccache }}
|
||||||
# Only pushes to the default branch may write the shared binary cache: the
|
# Only pushes to the default branch may write the shared binary cache: the
|
||||||
# archives a run compiles are only as trustworthy as the code they were
|
# archives a run compiles are only as trustworthy as the code they were
|
||||||
# built from, and only merged code may populate the scope that master and
|
# built from, and only merged code may populate the scope that master and
|
||||||
|
|
@ -1034,6 +1060,27 @@ jobs:
|
||||||
path: ${{ runner.temp }}/vcpkg-new
|
path: ${{ runner.temp }}/vcpkg-new
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
|
|
||||||
|
# Delete used cache to emulate a ccache update. See https://github.com/actions/cache/issues/342
|
||||||
|
- name: "[Windows] Delete remote compiler cache (ccache)"
|
||||||
|
if: matrix.os == 'Windows' && matrix.use_ccache == 1 && env.PERSIST_CCACHE == 'true' && github.ref == 'refs/heads/master' && steps.restore_ccache.outputs.cache-hit
|
||||||
|
continue-on-error: true
|
||||||
|
# Bash, not the runner's default pwsh, which cannot parse this `if`.
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
CACHE_PRIMARY_KEY: ${{ steps.restore_ccache.outputs.cache-primary-key }}
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
|
run: |
|
||||||
|
if gh cache delete --repo "$GITHUB_REPOSITORY" "$CACHE_PRIMARY_KEY"; then
|
||||||
|
echo "Cache deleted successfully"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: "[Windows] Cache updated compiler cache (ccache)"
|
||||||
|
if: matrix.os == 'Windows' && matrix.use_ccache == 1 && env.PERSIST_CCACHE == 'true' && github.ref == 'refs/heads/master'
|
||||||
|
uses: actions/cache/save@v6
|
||||||
|
with:
|
||||||
|
key: ${{ steps.restore_ccache.outputs.cache-primary-key }}
|
||||||
|
path: ${{ env.CCACHE_DIR }}
|
||||||
|
|
||||||
- name: "[macOS] Sign app bundle"
|
- name: "[macOS] Sign app bundle"
|
||||||
if: matrix.os == 'macOS' && matrix.make_package && needs.configure.outputs.tag != null
|
if: matrix.os == 'macOS' && matrix.make_package && needs.configure.outputs.tag != null
|
||||||
id: sign_macos
|
id: sign_macos
|
||||||
|
|
@ -1222,7 +1269,7 @@ jobs:
|
||||||
# The nightly legs and the pull-request legs that finish under the Windows leg
|
# The nightly legs and the pull-request legs that finish under the Windows leg
|
||||||
# keep none, so their leftover entries are reclaimed here instead of waiting out
|
# keep none, so their leftover entries are reclaimed here instead of waiting out
|
||||||
# the age rule.
|
# the age rule.
|
||||||
LIVE_CCACHE_KEYS: 'ccache-Arch ccache-Debian13 ccache-Fedora45debug ccache-Fedora45release'
|
LIVE_CCACHE_KEYS: 'ccache-Arch ccache-Debian13 ccache-Fedora45debug ccache-Fedora45release ccache-Windows10'
|
||||||
run: |
|
run: |
|
||||||
gh api --paginate "repos/$GITHUB_REPOSITORY/actions/caches?per_page=100" \
|
gh api --paginate "repos/$GITHUB_REPOSITORY/actions/caches?per_page=100" \
|
||||||
--jq '.actions_caches[] | [.id, .ref, .key, .last_accessed_at] | @tsv' >"$RUNNER_TEMP/caches.tsv"
|
--jq '.actions_caches[] | [.id, .ref, .key, .last_accessed_at] | @tsv' >"$RUNNER_TEMP/caches.tsv"
|
||||||
|
|
|
||||||
|
|
@ -48,11 +48,12 @@ if(NOT CMAKE_BUILD_TYPE)
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# ccache does not support MSVC and must not auto-engage on Windows
|
# ccache drives MSVC too (since 4.7), but only when the compiler writes debug
|
||||||
# (it is installed unintentionally on the Windows CI runner).
|
# information into the object file: /Zi and /ZI keep it in a shared PDB, and ccache
|
||||||
# NOTE: this keys off the target OS, so a mingw/Ninja configuration on Windows
|
# reports them as unsupported rather than risk a stale one. The MSVC flags below
|
||||||
# also opts out of ccache even though the GNUCXX branch below supports it.
|
# therefore use /Z7. MSVC precompiled headers are cached as well, with the same
|
||||||
if(USE_CCACHE AND NOT WIN32)
|
# sloppiness the other toolchains need.
|
||||||
|
if(USE_CCACHE)
|
||||||
find_program(CCACHE_PROGRAM ccache)
|
find_program(CCACHE_PROGRAM ccache)
|
||||||
if(CCACHE_PROGRAM)
|
if(CCACHE_PROGRAM)
|
||||||
# Support Unix Makefiles and Ninja
|
# Support Unix Makefiles and Ninja
|
||||||
|
|
@ -66,10 +67,10 @@ if(USE_CCACHE AND NOT WIN32)
|
||||||
# check for every project on the machine, not just this one.
|
# check for every project on the machine, not just this one.
|
||||||
execute_process(COMMAND ${CCACHE_PROGRAM} --set-config sloppiness=pch_defines,time_macros)
|
execute_process(COMMAND ${CCACHE_PROGRAM} --set-config sloppiness=pch_defines,time_macros)
|
||||||
message(STATUS "Found CCache ${CCACHE_PROGRAM}")
|
message(STATUS "Found CCache ${CCACHE_PROGRAM}")
|
||||||
|
else()
|
||||||
|
# An explicit opt-in must not disappear silently.
|
||||||
|
message(STATUS "ccache requested but not found; building without a compiler cache")
|
||||||
endif()
|
endif()
|
||||||
elseif(USE_CCACHE AND WIN32)
|
|
||||||
# An explicit opt-in must not disappear silently on Windows.
|
|
||||||
message(STATUS "ccache disabled: not supported for the MSVC toolchain on Windows")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WIN32 OR USE_VCPKG)
|
if(WIN32 OR USE_VCPKG)
|
||||||
|
|
@ -174,8 +175,9 @@ if(MSVC) # Microsoft Visual C++ compiler
|
||||||
# /utf-8 Set source file encoding and execution character set to UTF-8
|
# /utf-8 Set source file encoding and execution character set to UTF-8
|
||||||
# /W4 Enable warning level 4
|
# /W4 Enable warning level 4
|
||||||
# /Zc:__cplusplus Enable correct __cplusplus reporting
|
# /Zc:__cplusplus Enable correct __cplusplus reporting
|
||||||
# /Zi Generate debugging information (Program Database, PDB)
|
# /Z7 Generate debugging information in each object file (ccache-cacheable)
|
||||||
set(CMAKE_CXX_FLAGS "/EHsc /MP /permissive- /utf-8 /W4 /Zc:__cplusplus /Zi")
|
# instead of a compiler-shared PDB, which ccache rejects
|
||||||
|
set(CMAKE_CXX_FLAGS "/EHsc /MP /permissive- /utf-8 /W4 /Zc:__cplusplus /Z7")
|
||||||
# /O2 Balanced optimization
|
# /O2 Balanced optimization
|
||||||
# /MD Link against the multi-threaded DLL runtime library (Release CRT)
|
# /MD Link against the multi-threaded DLL runtime library (Release CRT)
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "/O2 /MD")
|
set(CMAKE_CXX_FLAGS_RELEASE "/O2 /MD")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue