Repository navigation
fix: build RNGH 3 Expo apps for Android on Windows at short roots - #3669
Merged
Merged
Conversation
Shorten the Windows CMake profile directory to 4 hex characters, size the STIM_PATH_TOO_LONG preflight for react-native-gesture-handler 3 shared shadow nodes, and replace the subst remedy, which Expo autolinking defeats, with moving the project under a short real path. Fixes #3641
CMake's single-config Ninja generator measures objects from <target>.dir/./, so a shortened object path fits only up to 238 characters. A trailhead build at a 25-character root failed at 239.
Collaborator
Author
|
Fresh review of e4d6f64 (issue #3641, diff vs origin/main). No blocking findings. Checked
Non-blocking
No needs-human area is touched. Adding |
On Linux CI the temp root is short enough to fit a project without RNGH 3, so the refusal case needs a root longer than 51 characters everywhere.
Collaborator
Author
Fresh review of 795a982 (full diff vs main)Verdict: clear. No blocking or actionable findings. Checked
Ran locally
Nits (non-blocking)
No needs-human category applies: there is no network, secret, ownership-widening, release or breaking on-disk change. Labeled |
This was referenced Oct 13, 2026
janicduplessis
marked this pull request as ready for review
October 13, 2026 21:21
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
trailhead (Expo SDK 58, RN 0.88, react-native-gesture-handler 3) cannot build for Android on Windows at any realistic root. The NDK's ninja is not long-path aware, and RNGH 3 compiles
shared/shadowNodes/.../RNGestureHandlerDetectorShadowNode.cppinto its app-level codegen library. That source is outside the CMake source dir, so CMake names the object after its mangled absolute path. CMake can hash the leading directories only when<object dir>/<md5>/RNGestureHandlerDetectorShadowNode.cpp.ofitsCMAKE_OBJECT_PATH_MAX=240, measured from<target>.dir/./. With the shim'sstim-<16 hex>staging dir, that needs a root of at most 7 characters for x86_64 (4 for arm64-v8a). Past that, CMake keeps the 330+ character name and ninja fails:STIM_PATH_TOO_LONGlet those roots through because its tail (198) was measured on safeareacontext, whose object is 27 characters shorter. It was also off by one: CMake's single-config Ninja generator measures the object directory as<target>.dir/./(source; the base generator'sGetCMakeCFGIntDir()is"."), so a shortened path fits only up to 238, and the preflight allowed 239. Itssubst X:remedy fails for Expo projects: Node's native realpath, which expo-modules-autolinking uses, resolves the subst drive back to the real path, so Gradle sees two roots (evidence in #3641).Solution
Shorter Windows staging name. On Windows the shim stages CMake under
.cxx/<first 4 profile hex chars>instead of.cxx/stim-<16 hex>. This keeps per-profile separation and ccache/build-cache keying as they are, and gives back 17 characters. A 4-hex collision between two profiles of one module would only make them share a CMake directory, which is how builds worked before profiles existed. macOS and Linux keepstim-<16 hex>. Editing the shim changes the profile hash on every platform, so each module configures CMake once more after upgrading.Project-aware preflight, limit 238.
androidPathRoomuses the RNGH tail (208) whenreact-native-gesture-handler/shared/shadowNodesresolves from the project, and the safeareacontext tail (181) otherwise, and refuses a shortened path over 238. A single RNGH-sized constant would refuse the bare e2e fixture's 33-character CI root (and other projects without RNGH 3) even though they build. Max roots:C:\src\trailhead(16) and the build worker'sC:\stimw\<8 hex>(17) fit.Remedy. The error,
stim guide errors STIM_PATH_TOO_LONG, doctor and the requirements page now say to move or clone the project under a short real path such asC:\src\<name>, and that a subst drive does not work.doctor --fix's legacy.cxxrepair recognizes the 4-hex profile directories as managed, as it already did forstim-<16 hex>.I considered staging outside the project at a short global path. It would make the root length irrelevant for these objects, but it would need its own uniqueness, ownership and
worktree remove/gccleanup. The in-project rename fixes trailhead at normalC:\src\<name>roots without that machinery.Measurement. I dumped every object from all 9 CMake modules of a trailhead build on Windows and replayed CMake 3.22's shortening rule (
cmLocalGeneratorShortenObjectName, with the./) over root lengths. For every staging length tried, the RNGH detector object is the binding one. x86_64 max roots per staging name:stim-<16>7,<6 hex>22,<4 hex>24, none 28. Nestednode_modules/expo/node_modules/expo-modules-coreobjects (with the 4-hex staging dir) are hashed, so CMake caps them at 237 characters at a 16-character root, and their hashed form keeps fitting well past the RNGH limit, so they never bind. The hashed detector object came to 230 characters atC:\src\trailhead, which matches 16 + 208 + 6.Test plan
On a
windows-latestrunner (NDK 27.1.12297006, CMake 3.22.1, android-34 x86_64 emulator), with trailheadff910e0cloned toC:\src\trailhead:dd09744):stim androidfails after 31 min at:app:buildCMakeDebug[x86_64]with the ninjaFilename longer than 260 characterserror above.stim androidgivesbuild ok (9m40s), installs and launchescom.appandflow.trailhead. Metro served the bundle and the app reported[stim:readiness] readyshortly after the 20 s launch check (which printed UNVERIFIED), and a screenshot shows the trails list.C:\src\trailhead-abcdefg(24) with--no-build-cacheand fresh.cxx,build ok (4m35s)and launch. The detector object is hashed to exactly 238 characters. AtC:\src\trailhead-abcdefgh(25), before the 238 correction, the build failed in ninja with the sameFilename longer than 260 characterserror (the path came to 239, CMake did not hash it). With the correction,stim androidat that root refuses:STIM_PATH_TOO_LONG: ... (react_codegen_rngesturehandler_codegen for x86_64) reaches 239 characters, past the 238 ... the root can be at most 24 characters.doctor --platform androidatC:\Users\runneradmin\src\trailhead(34) reports the finding with the move-or-clone remedy. (stim androidthere stopped earlier, at emulator creation, because the runner's C: drive was full.)pnpm test,test:runtimeandtest:e2epass. The unit tests cover the RNGH and safeareacontext boundaries, the shared-shadow-node detection (including a hoistednode_modules), and doctor keeping the 4-hex profile directories.Fixes #3641