Skip to content

Commit ed3adba

Browse files
authored
ci: Various ccache save/restore improvements for CI runs (AcademySoftwareFoundation#4797)
Improvements to the way our CI utilizes ccache to speed up build. Ported from OSL: - Split caching into separate restore/save, and rearrange the step order so we save cache before tests run. This allows us to save the ccache even for jobs with failed tests (where the all-in-one unsplit approach would skip the cache save step for a failed job), or for jobs that we purposely end early (maybe because we see failing tests), not only when all tests finish and succeed. This makes subsequent builds, that we do on the same branch while attempting to fix failures, go faster by using the cache. - Make subsequent pushes to the same PR or REF to cancel any previous jobs, so if we push updates before the last CI run of the same branch completes, it won't keep those going as useless zombie jobs. - Change the cache key names we use to remove the github ref to encourage cache reuse across different commits or branches (I think), and to fix a couple errors where we had mis-named things and were sharing caches between jobs when we shouldn't or vice versa. - Be more careful about the location of the cache, making sure we were for sure telling the GHA cache action to be saving/restoring the same directory location that we told ccache to use as its cache location. - Use CCACHE_COMPRESSION env var to be extra sure we're using compressed caches to be sure we get the best bang for buck on the limited cache storage we're allowed. - Set CMAKE_CXX_COMPILER_LAUNCHER and CMAKE_C_COMPILER_LAUNCHER in the shell for CI in the hopes of making more dependencies we build also use ccache. - Alternate launcher structure -- use LANG_COMPILER_LAUNCHER, not RULE_LAUNCH. A sampling of typical results: test build deps build oiio ----------------------- ---------- ---------- VP 2024 (cold) N/A 6:22 VP 2024 (cached) N/A 0:55 (7x) latest rels (cold) 8:29 5:30 latest rels (cached) 2:24 (3.5x) 0:45 (7.3x) (The N/A is because that run gets all its dependencies from the container and doesn't have to build any from scratch.) Signed-off-by: Larry Gritz <lg@larrygritz.com>
1 parent 725885f commit ed3adba

5 files changed

Lines changed: 75 additions & 70 deletions

File tree

.github/workflows/build-steps.yml

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -106,25 +106,23 @@ jobs:
106106
steps:
107107
- name: Checkout repo
108108
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
109-
- name: Prepare ccache timestamp
110-
id: ccache_cache_keys
111-
shell: bash
112-
run: echo "date=`date -u +'%Y-%m-%dT%H:%M:%SZ'`" >> $GITHUB_OUTPUT
113-
- name: ccache
114-
id: ccache
115-
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
116-
with:
117-
path: ./ccache
118-
key: ${{github.job}}-${{inputs.nametag}}-${{steps.ccache_cache_keys.outputs.date}}
119-
restore-keys: ${{github.job}}-
120-
- name: Setup Nuget.exe (Windows only)
121-
if: runner.os == 'Windows'
122-
uses: nuget/setup-nuget@a21f25cd3998bf370fde17e3f1b4c12c175172f9 # v2.0.0
123109
- name: Build setup
124110
shell: bash
125111
run: |
126112
${{inputs.setenvs}}
127113
src/build-scripts/ci-startup.bash
114+
- name: Prepare ccache timestamp
115+
id: ccache_cache_keys
116+
shell: bash
117+
run: echo "date=`date -u +'%Y-%m-%dT%H:%M:%SZ'`" >> $GITHUB_OUTPUT
118+
- name: ccache-restore
119+
id: ccache-restore
120+
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
121+
with:
122+
path: ${{ env.CCACHE_DIR }}
123+
# path: ./ccache
124+
key: ${{inputs.nametag}}-${{steps.ccache_cache_keys.outputs.date}}
125+
restore-keys: ${{inputs.nametag}}
128126
- name: Dependencies
129127
shell: bash
130128
run: |
@@ -143,6 +141,26 @@ jobs:
143141
if: inputs.skip_build != '1'
144142
shell: bash
145143
run: src/build-scripts/ci-build.bash
144+
- name: Check out ABI standard
145+
if: inputs.abi_check != ''
146+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
147+
with:
148+
ref: ${{inputs.abi_check}}
149+
path: abi_standard
150+
- name: Build ABI standard
151+
if: inputs.abi_check != ''
152+
shell: bash
153+
run: |
154+
mkdir -p abi_standard/build
155+
pushd abi_standard
156+
src/build-scripts/ci-build.bash
157+
popd
158+
- name: ccache-save
159+
id: ccache-save
160+
uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
161+
with:
162+
path: ${{ env.CCACHE_DIR }}
163+
key: ${{inputs.nametag}}-${{steps.ccache_cache_keys.outputs.date}}
146164
- name: Testsuite
147165
if: inputs.skip_tests != '1'
148166
shell: bash
@@ -171,20 +189,6 @@ jobs:
171189
# sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"
172190
time sonar-scanner --define sonar.host.url="${{ env.SONAR_SERVER_URL }}" --define sonar.cfamily.build-wrapper-output="$BUILD_WRAPPER_OUT_DIR" --define sonar.cfamily.gcov.reportsPath="_coverage" --define sonar.cfamily.threads="$PARALLEL"
173191
# Consult https://docs.sonarcloud.io/advanced-setup/ci-based-analysis/sonarscanner-cli/ for more information and options
174-
- name: Check out ABI standard
175-
if: inputs.abi_check != ''
176-
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
177-
with:
178-
ref: ${{inputs.abi_check}}
179-
path: abi_standard
180-
- name: Build ABI standard
181-
if: inputs.abi_check != ''
182-
shell: bash
183-
run: |
184-
mkdir -p abi_standard/build
185-
pushd abi_standard
186-
src/build-scripts/ci-build.bash
187-
popd
188192
- name: Check ABI
189193
if: inputs.abi_check != ''
190194
shell: bash

.github/workflows/ci.yml

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ on:
3232

3333
permissions: read-all
3434

35+
# Allow subsequent pushes to the same PR or REF to cancel any previous jobs.
36+
concurrency:
37+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
38+
cancel-in-progress: true
39+
3540

3641
jobs:
3742

@@ -176,51 +181,42 @@ jobs:
176181
# egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
177182
- name: Checkout repo
178183
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
179-
- name: Prepare ccache timestamp
180-
id: ccache_cache_keys
181-
run: echo "date=`date -u +'%Y-%m-%dT%H:%M:%SZ'`" >> $GITHUB_OUTPUT
182-
- name: ccache
183-
id: ccache
184-
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
185-
with:
186-
path: /tmp/ccache
187-
key: ${{github.job}}-${{matrix.nametag}}-${{steps.ccache_cache_keys.outputs.date}}
188-
restore-keys: ${{github.job}}-
189184
- name: Build setup
190185
run: |
191186
${{matrix.setenvs}}
192187
src/build-scripts/ci-startup.bash
188+
- name: Prepare ccache timestamp
189+
id: ccache_cache_keys
190+
shell: bash
191+
run: echo "date=`date -u +'%Y-%m-%dT%H:%M:%SZ'`" >> $GITHUB_OUTPUT
192+
- name: ccache-restore
193+
id: ccache-restore
194+
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
195+
with:
196+
path: ${{ env.CCACHE_DIR }}
197+
# path: ./ccache
198+
key: ${{matrix.nametag}}-${{steps.ccache_cache_keys.outputs.date}}
199+
restore-keys: ${{matrix.nametag}}
193200
- name: Dependencies
194201
run: |
195202
${{matrix.depcmds}}
196203
src/build-scripts/gh-installdeps.bash
197204
- name: Build
198205
if: matrix.skip_build != '1'
199206
run: src/build-scripts/ci-build.bash
207+
- name: ccache-save
208+
id: ccache-save
209+
uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
210+
with:
211+
path: ${{ env.CCACHE_DIR }}
212+
key: ${{matrix.nametag}}-${{steps.ccache_cache_keys.outputs.date}}
200213
- name: Testsuite
201214
if: matrix.skip_tests != '1'
202215
run: src/build-scripts/ci-test.bash
203216
- name: Benchmarks
204217
if: matrix.benchmark == '1'
205218
shell: bash
206219
run: src/build-scripts/ci-benchmark.bash
207-
- name: Check out ABI standard
208-
if: matrix.abi_check != ''
209-
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
210-
with:
211-
ref: ${{matrix.abi_check}}
212-
path: abi_standard
213-
- name: Build ABI standard
214-
if: matrix.abi_check != ''
215-
run: |
216-
mkdir -p abi_standard/build
217-
pushd abi_standard
218-
src/build-scripts/ci-build.bash
219-
popd
220-
- name: Check ABI
221-
if: matrix.abi_check != ''
222-
run: |
223-
src/build-scripts/ci-abicheck.bash ./build abi_standard/build libOpenImageIO libOpenImageIO_Util
224220
- name: Build Docs
225221
if: matrix.build_docs == '1'
226222
run: |
@@ -472,7 +468,7 @@ jobs:
472468
WEBP_VERSION=v1.4.0
473469

474470
- desc: clang15 C++17 avx2 exr3.1 ocio2.2
475-
nametag: linux-clang14
471+
nametag: linux-clang15
476472
runner: ubuntu-22.04
477473
cxx_compiler: clang++-15
478474
cc_compiler: clang-15

src/build-scripts/ci-build.bash

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ if [[ "$BUILDTARGET" != "none" ]] ; then
5454
echo "Using build wrapper '${OIIO_CMAKE_BUILD_WRAPPER}'"
5555
fi
5656
time ${OIIO_CMAKE_BUILD_WRAPPER} cmake --build ${OIIO_BUILD_DIR} --target ${BUILDTARGET} --config ${CMAKE_BUILD_TYPE}
57+
ccache --show-stats || true
5758
fi
5859
# popd
5960

src/build-scripts/ci-startup.bash

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ export PATH=/usr/local/bin/_ccache:/usr/lib/ccache:$PATH
1313
export USE_CCACHE=${USE_CCACHE:=1}
1414
export CCACHE_CPP2=
1515
export CCACHE_DIR=$HOME/.ccache
16+
export CCACHE_COMPRESSION=yes
17+
if [[ "$(which ccache)" != "" ]] ; then
18+
# Try to coax dependency building into also using ccache
19+
export CMAKE_CXX_COMPILER_LAUNCHER="ccache"
20+
export CMAKE_C_COMPILER_LAUNCHER="ccache"
21+
ccache -z
22+
fi
1623
mkdir -p $CCACHE_DIR
1724

1825
export OpenImageIO_ROOT=$PWD/dist

src/cmake/compiler.cmake

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -224,9 +224,6 @@ if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
224224
add_compile_options ("-fno-math-errno")
225225
endif ()
226226

227-
# We will use this for ccache and timing
228-
set (MY_RULE_LAUNCH "")
229-
230227

231228
###########################################################################
232229
# Use ccache if found
@@ -236,12 +233,18 @@ set (MY_RULE_LAUNCH "")
236233
# logic here makes it work even if the user is unaware of ccache. If it's
237234
# not found on the system, it will simply be silently not used.
238235
option (USE_CCACHE "Use ccache if found" ON)
239-
find_program (CCACHE_FOUND ccache)
240-
if (CCACHE_FOUND AND USE_CCACHE)
236+
find_program (CCACHE_EXE ccache)
237+
if (CCACHE_EXE AND USE_CCACHE)
241238
if (CMAKE_COMPILER_IS_CLANG AND USE_QT AND (NOT DEFINED ENV{CCACHE_CPP2}))
242239
message (STATUS "Ignoring ccache because clang + Qt + env CCACHE_CPP2 is not set")
243240
else ()
244-
set (MY_RULE_LAUNCH ccache)
241+
if (NOT ${CXX_COMPILER_LAUNCHER} MATCHES "ccache")
242+
set (CXX_COMPILER_LAUNCHER ${CCACHE_EXR} ${CXX_COMPILER_LAUNCHER})
243+
endif ()
244+
if (NOT ${C_COMPILER_LAUNCHER} MATCHES "ccache")
245+
set (C_COMPILER_LAUNCHER ${CCACHE_EXR} ${C_COMPILER_LAUNCHER})
246+
endif ()
247+
message (STATUS "ccache enabled: ${CCACHE_EXE}")
245248
endif ()
246249
endif ()
247250

@@ -254,14 +257,8 @@ endif ()
254257
# set `-j 1` or CMAKE_BUILD_PARALLEL_LEVEL to 1.
255258
option (TIME_COMMANDS "Time each compile and link command" OFF)
256259
if (TIME_COMMANDS)
257-
set (MY_RULE_LAUNCH "${CMAKE_COMMAND} -E time ${MY_RULE_LAUNCH}")
258-
endif ()
259-
260-
261-
# Note: This must be after any option that alters MY_RULE_LAUNCH
262-
if (MY_RULE_LAUNCH)
263-
set_property (GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${MY_RULE_LAUNCH})
264-
set_property (GLOBAL PROPERTY RULE_LAUNCH_LINK ${MY_RULE_LAUNCH})
260+
set (CXX_COMPILER_LAUNCHER ${CMAKE_COMMAND} -E time ${CXX_COMPILER_LAUNCHER})
261+
set (C_COMPILER_LAUNCHER ${CMAKE_COMMAND} -E time ${C_COMPILER_LAUNCHER})
265262
endif ()
266263

267264

0 commit comments

Comments
 (0)