Skip to content

fix(build): fail with the cause when the setup is wrong - #1450

Merged
msluszniak merged 8 commits into
mainfrom
@ms/setup-guards
Sep 9, 2026
Merged

fix(build): fail with the cause when the setup is wrong#1450
msluszniak merged 8 commits into
mainfrom
@ms/setup-guards

Conversation

@msluszniak

@msluszniak msluszniak commented Sep 9, 2026

Copy link
Copy Markdown
Member

Description

Setup failures that reach the user as an error pointing somewhere else. All reproduced against the published 0.10.0.

Guards. The native artifacts are downloaded by the postinstall hook, which pnpm 10 blocks by default (Ignored build scripts), as do --ignore-scripts and npm ci --ignore-scripts. pod install still succeeds, because CocoaPods never checks that a vendored framework exists, and the build dies later on Build input files cannot be found. The podspec and build.gradle.kts now check first and name pnpm approve-builds / npm rebuild.

Config block in a monorepo. It was read only from INIT_CWD, the workspace root, so a block in apps/mobile/package.json was ignored and an app declaring "libs": [] got OpenCV anyway. The lookup now also walks up from the installed package and logs which manifest it read.

Android minSdkVersion. Default was 21, docs said Android 13+, nothing enforced either. .note.android.ident reads API 26 in all three shipped .so files, so anything lower shipped a library the linker is not guaranteed to load. Default is now 26.

Docs. A Troubleshooting page keyed by the exact error text covers the rest:

setup symptom
use_frameworks! dynamic transitive dependencies that include statically linked binaries
another OpenCV pod frameworks with conflicting names: opencv2.xcframework
Intel Mac, Rosetta, Intel CI None of the architectures in ARCHS (x86_64) are valid
Expo without expo-build-properties iOS 17 requirement is a warning only
default reactNativeArchitectures armeabi-v7a / x86 splits ship without the .so

The OpenCV conflict has a verified escape hatch: "libs": ["phonemis"] drops opencv-rne and pod install then succeeds, at the cost of every vision task.

Introduces a breaking change?

  • Yes
  • No

Type of change

  • Bug fix (change which fixes an issue)
  • New feature (change which adds functionality)
  • Documentation update (improves or adds clarity to existing documentation)
  • Other (chores, tests, code style improvements etc.)

Tested on

  • iOS
  • Android

Testing instructions

pod ipc spec react-native-executorch.podspec in a checkout without artifacts prints the missing paths and the fix, and passes once they exist. 7 tests in __tests__/api/nativeLibsConfig.test.ts cover the config lookup. Docs build and lint clean.

Checklist

  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have updated the documentation accordingly
  • My changes generate no new warnings

Additional notes

The Gradle guard has not been run. It configures at the top of build.gradle.kts, so please build an Android app on this branch before merging. Raising minSdkVersion can also break an app currently on 21-25; that build was already unsound, but it is a behaviour change.

The xcframeworks and jniLibs are not in the npm tarball; a postinstall hook
downloads them. When a package manager skips that hook - pnpm 10 blocks
dependency build scripts by default, and so do `--ignore-scripts` and
`npm ci --ignore-scripts` - nothing complains. `pod install` succeeds too,
because CocoaPods never checks that a vendored framework exists, and the
build only fails minutes later with

  error: Build input files cannot be found:
  '.../XnnpackBackend.xcframework/ios-arm64-simulator/libXnnpackBackend.a'

which names neither the cause nor the fix.

Check for the artifacts in the podspec and at Gradle configure time instead,
and name `pnpm approve-builds` / `npm rebuild` in the message.

Also document the setup failures that the library cannot prevent, each with
the exact error text: use_frameworks! (both linkages), a second pod vendoring
opencv2.xcframework and the config block that resolves it, the missing x86_64
simulator slice, the iOS 17 deployment target warning, the monorepo location
of the config block, and the two shipped Android ABIs.
@msluszniak msluszniak self-assigned this Sep 9, 2026
@msluszniak msluszniak added the bug fix PRs that are fixing bugs label Sep 9, 2026
@msluszniak
msluszniak marked this pull request as draft September 9, 2026 10:24
Two more setup failures that surface as something else.

The `react-native-executorch` block is read from INIT_CWD, the directory the
install ran in. In a workspace that is the root, so a block in
`apps/mobile/package.json` was silently ignored: every backend came down and
an app declaring `"libs": []` to dodge an OpenCV framework-name conflict got
OpenCV anyway. The lookup now also walks up from the installed package, which
lands on the app whenever it keeps its own node_modules, and logs which
manifest it read.

The Android `minSdkVersion` default was 21 while the prebuilt runtime is
compiled against API 26 - `.note.android.ident` reads 26 in libexecutorch.so,
libxnnpack_executorch_backend.so and libvulkan_executorch_backend.so alike -
so a build below that shipped a library the linker is not guaranteed to load,
and failed on the device instead. Default to 26 and say so in the docs, which
claimed Android 13+ with nothing enforcing it.
@msluszniak msluszniak changed the title fix(build): fail with the cause when the native artifacts are missing fix(build): fail with the cause when the setup is wrong Sep 9, 2026
@msluszniak
msluszniak marked this pull request as ready for review September 9, 2026 11:08
@msluszniak
msluszniak requested a review from barhanc September 9, 2026 11:09
@msluszniak msluszniak added the important ❗ This issue has high priority label Sep 9, 2026
Comment thread docs/docs/01-fundamentals/01-getting-started.md Outdated
Comment on lines +82 to +84
Another pod in the app vendors its own OpenCV under the same framework name —
`react-native-fast-opencv` (via `FastOpenCV-iOS`) is the common one. CocoaPods
cannot install both.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if we don't want to patch it some other way so it is possible to use rne with react-native-fast-opencv, as it wouldnt be that weird if someone wanted to use our lower level API for nn inference and opencv for some image transformations we don't support.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I solve this by linking to fast open cv in case of both fast open cv and rne are available.

msluszniak and others added 4 commits September 9, 2026 15:02
Co-authored-by: Bartosz Hanc <bartosz.hanc02@gmail.com>
CocoaPods installs one framework named opencv2, so an app with
react-native-fast-opencv could not also install us. Wanting both is
reasonable: our inference API with their image transformations.

When that library is present we now depend on the pod it vendors rather than
opencv-rne. Headers have to come from the same place as the binary, so the
include root becomes a mirror of ours without opencv2: we ship OpenCV 4.13
headers and they vendor 4.9, and the mismatch fails at link time on cvtColor,
which gained an AlgorithmHint parameter in 4.10. `opencvPod` overrides the
choice either way.

Verified on an Expo app with both libraries: pod install and a simulator build
both succeed, and forcing opencv-rne reproduces the original conflict.
@msluszniak
msluszniak requested a review from barhanc September 9, 2026 14:46
Mateusz Słuszniak and others added 2 commits September 9, 2026 17:06
0.10.0 is `lastVersion`, so the pages users land on still carried the
pre-#1448/#1449/#1450 state: React Native 0.81+ / Expo SDK 54+, no
worklets floor, no troubleshooting.

- getting-started and the compatibility table take the #1449 changes
  verbatim, plus the minSdkVersion and troubleshooting pointers
- native-libraries takes the monorepo and pnpm notes
- a Troubleshooting page written against what 0.10.0 actually ships:
  the `use_frameworks!` header collision needs the Podfile
  `pre_install` workaround, the OpenCV conflict has no `opencvPod`
  escape hatch, and `minSdkVersion` defaults to 21 against API 26 `.so`
  files

Also corrects the monorepo note on the current docs, which still said an
app-level block is always ignored - the lookup now walks up from the
installed package too.
@msluszniak
msluszniak merged commit a1ff6c9 into main Sep 9, 2026
6 checks passed
@msluszniak
msluszniak deleted the @ms/setup-guards branch September 9, 2026 16:44
msluszniak added a commit that referenced this pull request Sep 9, 2026
#1452)

## Description

Two defects in #1450, both reproduced against `main` at `a1ff6c9`.

**`if enable_opencv` was never closed.** Its `end` sat at the bottom of
the spec, one line above `install_modules_dependencies(s)`, and the
indentation of everything after the `s.dependency` call reads as if the
block had already ended. So five attributes were assigned only when
OpenCV was on:

| attribute | what an app loses without it |
| --- | --- |
| `pod_target_xcconfig` | every `HEADER_SEARCH_PATHS` entry |
| `vendored_frameworks` | `ExecutorchLib.xcframework` |
| `static_framework` | the `use_frameworks!` fix from #1448 |
| `libraries` | `z`, `sqlite3` |
| `frameworks` | `Accelerate`, `CoreML`, Metal |

An app that turns OpenCV off through the `libs` config block installs
fine and then fails to compile or link. #1450 is what made this
reachable: before it, a config block in an app package was ignored and
OpenCV was always on.

**`rne_build_config` was nil without a config file.** The `else` branch
set the five `enable_*` flags but never assigned the hash, and #1450
added `rne_build_config["opencvPod"]` on the path that branch reaches,
so a checkout without `rne-build-config.json` raised `NoMethodError`
during `pod install`. The comment above it names that case as supported
("a fresh checkout where the native libs were provisioned manually").
The branch is gone: the config is a hash either way, and every flag
already reads `!= false`, so an empty hash means all-enabled.

**Test.** `pod install` is the only thing that runs this file, and every
example app takes the same config row, so a misplaced `end` passes lint,
types, tests and review. `__tests__/api/podspecAttributes.test.ts`
evaluates the real podspec under a stubbed `Pod::Spec` and asserts the
build-critical attributes are assigned, for eight config rows. Against
`a1ff6c9` it fails three of them:

```
● with no config file (manual provisioning)
  podspec:242: undefined method `[]' for nil:NilClass (NoMethodError)
● with opencv off
● with every optional library off
  missing: pod_target_xcconfig, static_framework, vendored_frameworks, libraries, frameworks
```

### Introduces a breaking change?

- [ ] Yes
- [x] No

### Type of change

- [x] Bug fix (change which fixes an issue)
- [ ] New feature (change which adds functionality)
- [ ] Documentation update (improves or adds clarity to existing
documentation)
- [ ] Other (chores, tests, code style improvements etc.)

### Tested on

- [ ] iOS
- [ ] Android

### Testing instructions

```bash
yarn workspace react-native-executorch test __tests__/api/podspecAttributes.test.ts
git stash && yarn workspace react-native-executorch test __tests__/api/podspecAttributes.test.ts  # 3 failures
```

Needs an `enableOpencv: false` `pod install` on a device build before
merge; I have only run the podspec evaluation.

### Related issues

Follow-up to #1450.

### Additional notes

Backport to `release/0.10` goes on top of #1451.
msluszniak added a commit that referenced this pull request Sep 9, 2026
)

## Description

Backports the three 0.10.0 setup fixes from `main` to `release/0.10`,
plus the follow-up that fixes two defects in the third one.
Cherry-picked with `-x`, no manual edits to any of them.

| commit | PR |
| --- | --- |
| `12ce3bb` | #1448 fix(ios): narrow the podspec's public headers |
| `c51f76a` | #1449 fix(deps): require worklets >=0.10.0 <0.13.0 and
document it |
| `a1ff6c9` | #1450 fix(build): fail with the cause when the setup is
wrong |
| `080e764` | #1452 fix(ios): keep the podspec's build attributes out of
the OpenCV branch |

All four are now on `main`; #1452 merged as `c8f44f6`.

Only conflict was `docs/versioned_docs/version-0.10.0/**`: that snapshot
exists on `main` only, since on this branch `docs/docs` **is** the 0.10
documentation. Those three hunks were dropped and the equivalent
`docs/docs` changes came across in the same commits.

`packages/react-native-executorch/package.json` keeps `0.10.0`; only the
worklets peer range changed.

### Introduces a breaking change?

- [ ] Yes
- [x] No

### Type of change

- [x] Bug fix (change which fixes an issue)
- [ ] New feature (change which adds functionality)
- [ ] Documentation update (improves or adds clarity to existing
documentation)
- [ ] Other (chores, tests, code style improvements etc.)

### Tested on

- [ ] iOS
- [ ] Android

### Testing instructions

`yarn workspace react-native-executorch test` passes, 3868 tests across
34 suites.

The podspec, `android/build.gradle.kts`, `scripts/download-libs.js` and
the new podspec test on this branch are byte-identical to `main`:

```bash
git fetch origin main
git diff origin/main HEAD -- packages/react-native-executorch/react-native-executorch.podspec \
  packages/react-native-executorch/android/build.gradle.kts \
  packages/react-native-executorch/scripts/download-libs.js \
  packages/react-native-executorch/__tests__/api/podspecAttributes.test.ts
```

### Related issues

#1448, #1449, #1450, #1452

---------

Co-authored-by: Bartosz Hanc <bartosz.hanc02@gmail.com>
Co-authored-by: Mateusz Słuszniak <msluszniak1@gmail.com>
@msluszniak msluszniak mentioned this pull request Sep 9, 2026
7 tasks
msluszniak added a commit that referenced this pull request Sep 9, 2026
## Description

Patch release **v0.10.1**. The fixes are already on `release/0.10` via
#1451 (backports of #1448, #1449, #1450, #1452); this PR only bumps the
version.

- `packages/react-native-executorch/package.json`: `0.10.0` -> `0.10.1`.
`nativeLibsVersion` stays `0.10.0`; the native artifacts release is
unchanged.
- `src/fetcher/telemetry.ts`: `LIB_VERSION` -> `0.10.1`, asserted equal
to the package version by `__tests__/fetcher/telemetry.test.ts`.

Satellites (`bare-resource-fetcher`, `expo-resource-fetcher`, `webrtc`)
are untouched by the backports, so their versions stay at `0.10.0`.
`models.ts` stays on `resolve/v0.10.0`; no model files moved.

### Introduces a breaking change?

- [ ] Yes
- [x] No

### Type of change

- [x] Other (chores, tests, code style improvements etc.)

### Tested on

- [ ] iOS
- [ ] Android

### Testing instructions

CI runs `yarn workspace react-native-executorch test`; the telemetry
version assertion covers the bump.

### Related issues

#1451

### Checklist

- [x] I have performed a self-review of my code
- [x] My changes generate no new warnings
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug fix PRs that are fixing bugs important ❗ This issue has high priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants