Skip to content

Commit 2d227ef

Browse files
committed
ci: put ccache in front of the Hermes build
Hermes dominates the iOS build. In run 31691647982 the build step took 18m58s, of which '[RN] [1] Build Hermesc' was 3m40s and '[RN] [2] Build Hermes' 13m35s — 17m15s, or 91%. It is not hidden concurrency either: no CompileC task appears during that window, and all 54 of them land in the final 66 seconds. Hermes serialises the build. Ccache never saw any of it. C_COMPILER_LAUNCHER is an Xcode build setting, while Hermes is built by CMake from a script phase, so the two never meet — ccache logged 549 calls for that whole job, of which only 68 were cacheable. React Native hard-codes the CMake flags in build-hermes-xcode.sh with no hook for extra arguments, but it does not sanitise the environment, and CMake reads CMAKE_TOOLCHAIN_FILE from there (verified locally: the toolchain is applied and the launcher reaches the compile rule). So point it at a generated toolchain file that sets CMAKE_C/CXX_COMPILER_LAUNCHER, which needs no patching of React Native. '[1] Build Hermesc' is out of reach: it runs its CMake under `env -i` with only PATH and SDKROOT, so it keeps costing its 3m40s. Also raises the ccache ceiling to 6G, since Hermes is much larger than anything cached so far.
1 parent 0b3df68 commit 2d227ef

1 file changed

Lines changed: 17 additions & 2 deletions

File tree

.github/workflows/check.yml

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,9 @@ jobs:
225225
key: ${{ github.job }}-${{ runner.os }}
226226
# The action defaults to 500M, which a from-source React Native build
227227
# fills mid-build: it evicted 88 times in one run, discarding most of
228-
# what it had just cached.
229-
max-size: 3G
228+
# what it had just cached. Raised again to also hold Hermes, which is
229+
# by far the largest thing compiled here.
230+
max-size: 6G
230231
- run: rustup target add aarch64-apple-ios-sim x86_64-apple-ios
231232
- run: pnpm install
232233
- run: pnpm run bootstrap
@@ -238,12 +239,26 @@ jobs:
238239
# to it) and so no longer does now that it runs as a compiler launcher.
239240
# Without this sloppiness Xcode's modules, PCH and index-store flags leave
240241
# ccache treating almost every compile as uncacheable.
242+
#
243+
# Hermes is built from source (the Node-API fork), from a CMake build that
244+
# React Native drives in a script phase — so C_COMPILER_LAUNCHER, an Xcode
245+
# build setting, never reaches it. It is the dominant cost of the build:
246+
# 17m15s of an 18m58s build step in run 31691647982. CMake reads
247+
# CMAKE_TOOLCHAIN_FILE from the environment, so a toolchain file is enough
248+
# to put ccache in front of its compiler without patching React Native.
249+
# Only '[RN] [2] Build Hermes' benefits; '[1] Build Hermesc' runs under
250+
# `env -i` and cannot see this.
241251
- name: Tune ccache for Xcode
242252
run: |
243253
ccache --set-config sloppiness=clang_index_store,file_stat_matches,include_file_ctime,include_file_mtime,ivfsoverlay,pch_defines,modules,system_headers,time_macros
244254
ccache --set-config file_clone=true
245255
ccache --set-config depend_mode=true
246256
ccache --set-config inode_cache=true
257+
cat > "$RUNNER_TEMP/hermes-ccache-toolchain.cmake" <<EOF
258+
set(CMAKE_C_COMPILER_LAUNCHER "$(command -v ccache)" CACHE STRING "")
259+
set(CMAKE_CXX_COMPILER_LAUNCHER "$(command -v ccache)" CACHE STRING "")
260+
EOF
261+
echo "CMAKE_TOOLCHAIN_FILE=$RUNNER_TEMP/hermes-ccache-toolchain.cmake" >> $GITHUB_ENV
247262
# Must precede `pod install`: react-native-test-app embeds the resources
248263
# declared in app.json when generating the workspace, skipping missing
249264
# ones, and the app would then expect a Metro dev server at runtime.

0 commit comments

Comments
 (0)