react / react/react-native

[Android] ReactRootProjectPlugin drops :app:preBuild -> library preBuild dependency under --configure-on-demand, breaking codegen before CMake

Open
#58,149 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Needs: Author Feedback Needs: Repro
Dominant language
C++
Stars
127k
Forks
25.3k
Avg merge
1d 23h
Merged PRs (30d)
4

Description

Description

ReactRootProjectPlugin makes :app:preBuild depend on every library's preBuild so that library codegen runs before the app's CMake configure:

project.gradle.projectsEvaluated {
  val appProject = project.rootProject.subprojects.find { it.name == "app" }
  val appPreBuild = appProject?.tasks?.findByName("preBuild")
  if (appPreBuild != null) {
    val otherPreBuildTasks =
        project.rootProject.subprojects
            .filter { it != appProject }
            .mapNotNull { it.tasks.findByName("preBuild") }
    appPreBuild.dependsOn(otherPreBuildTasks)
  }
}

When Gradle runs with --configure-on-demand (Expo CLI passes it unconditionally in expo run:android), a library project that has not been evaluated by the time projectsEvaluated fires has no preBuild task yet, so findByName returns null and the dependency is silently dropped. The app's configureCMake<Variant> then runs before that library's generateCodegenArtifactsFromSchema, and the autolinking CMake file fails with:

CMake Error at android/app/build/generated/autolinking/src/main/jni/Android-autolinking.cmake:19 (add_subdirectory):
  add_subdirectory given source
  ".../node_modules/react-native-sherpa-onnx/android/build/generated/source/codegen/jni/"
  which is not an existing directory.
CMake Error at .../ReactAndroid/cmake-utils/ReactNative-application.cmake:97 (target_link_libraries):
  Cannot specify link libraries for target "react_codegen_SherpaOnnxSpec"
  which is not built by this project.

Which libraries are affected depends on evaluation order, so it looks flaky per project. In my project @stripe/stripe-react-native (also a codegen TurboModule library) happened to be evaluated in time and worked, while react-native-sherpa-onnx was not. The same failure was reported independently against that library (XDcobra/react-native-sherpa-onnx#63) and closed as not reproducible, which fits an ordering-dependent bug.

Running the identical build without --configure-on-demand (./gradlew :app:assembleDebug -PreactNativeArchitectures=arm64-v8a) succeeds; the task log shows :react-native-sherpa-onnx:generateCodegenArtifactsFromSchema:app:preBuild:app:configureCMakeDebug[arm64-v8a].

Workaround (verified): in the app's build.gradle, add an explicit task-path dependency, which forces on-demand configuration of that project:

preBuild.dependsOn(':react-native-sherpa-onnx:preBuild')

A robust fix would be to wire the dependency per subproject as each one is evaluated (e.g. subproject.afterEvaluate { appPreBuild.dependsOn(subproject.tasks.named("preBuild")) }, or dependsOn("${subproject.path}:preBuild") by task path) instead of snapshotting subprojects at projectsEvaluated.

Steps to reproduce
  1. npx create-expo-app repro && cd repro
  2. npx expo install react-native-sherpa-onnx @dr.pogodin/react-native-fs (any third-party library with codegenConfig and a JNI target that Gradle happens to evaluate late)
  3. npx expo run:android (Expo CLI runs Gradle with --configure-on-demand)
  4. Build fails in :app:configureCMakeDebug[<abi>] as above.
  5. cd android && ./gradlew :app:assembleDebug succeeds.
React Native Version

0.86.0

Affected Platforms

Build - Android

Output of npx @react-native-community/cli info
System:
  OS: macOS 26.6.2
  CPU: (14) arm64 Apple M4 Pro
Binaries:
  Node: 24.12.0
  npm: 11.6.2
  Watchman: Not Found
Managers:
  CocoaPods: 1.17.0
IDEs:
  Android Studio: 2025.3
  Xcode: 26.2/17C52
Languages:
  Java: 17.0.12
Expo SDK 57 (expo 57.0.8), Gradle 9.3.1, AGP as shipped with RN 0.86.0, NDK 27.1.12297006, CMake 3.22.1
Stacktrace or Logs
> Task :stripe_stripe-react-native:generateCodegenArtifactsFromSchema
> Task :app:preBuild
...
> Task :react-native-sherpa-onnx:downloadNativeLibsIfNeeded
> Task :app:configureCMakeDebug[arm64-v8a] FAILED
(no :react-native-sherpa-onnx:generateCodegenArtifactsFromSchema before the failure)

Execution failed for task ':app:configureCMakeDebug[arm64-v8a]'.
> [CXX1429] error when building with cmake using .../ReactAndroid/cmake-utils/default-app-setup/CMakeLists.txt
  CMake Error at .../Android-autolinking.cmake:19 (add_subdirectory):
    add_subdirectory given source ".../react-native-sherpa-onnx/android/build/generated/source/codegen/jni/" which is not an existing directory.
MANDATORY Reproducer

Steps above (create-expo-app + react-native-sherpa-onnx + expo run:android). The failure depends on Gradle's on-demand evaluation order, so the library that gets skipped may differ by project.

Screenshots and Videos

N/A

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating ReactRootProjectPlugin and tracing how projectsEvaluated discovers library preBuild tasks. Reproduce with the mandatory Expo and react-native-sherpa-onnx steps, then compare the --configure-on-demand and ordinary Gradle task order. Done means library codegen runs before app configureCMake and the autolinking CMake generation succeeds.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, cmake, kotlin, react-native
Domain
build-system, mobile
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.