Skip to content

[RNE Rewrite] feat: on-demand native lib download and backend splitting#1283

Open
msluszniak wants to merge 6 commits into
rne-rewritefrom
@ms/on-demand-native-libs
Open

[RNE Rewrite] feat: on-demand native lib download and backend splitting#1283
msluszniak wants to merge 6 commits into
rne-rewritefrom
@ms/on-demand-native-libs

Conversation

@msluszniak

@msluszniak msluszniak commented Jun 25, 2026

Copy link
Copy Markdown
Member

Description

Ports PR #1039's on-demand native-lib mechanism into the rewrite flow. Apps declare what they need via a react-native-executorch block (backends / libs / features) in package.json; the postinstall scripts/download-libs.js expands features via the forward-looking FEATURE_MAP, writes rne-build-config.json, and downloads only the requested per-backend artifacts from GitHub Releases into third-party/. The podspec and android/build.gradle.kts read that config to gate RNE_ENABLE_* and link backends as separate libs (Xnnpack/CoreML/MLX xcframeworks, lib*_executorch_backend.so); MLX is the iOS device slice only.

Adapted to the rewrite: cpp/ layout (opencv kept as an extensible source list, guarded in RnExecutorch.cpp), Kotlin-DSL gradle config read, single android/CMakeLists.txt. The scripts, FEATURE_MAP, and artifact contract are kept identical to #1039 so future rewrite work stays code-only. CI (TS-only) skips the download via RNET_SKIP_DOWNLOAD in the setup action.

Backed by software-mansion-labs/executorch@ms/separate-backends (already ET 1.3.1). Release artifacts (device-only MLX) are built/uploaded separately; committed headers / executorch.jar / ExecutorchLib wrapper are provisioned alongside.

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

  1. Config flow: set an app's react-native-executorch.features (e.g. ["llm"]), run yarn install, and check rne-build-config.json reflects it (enableOpencv:false, enableCoreml:false, enableXnnpack:true). Setting legacy extras errors.
  2. Download flow: RNET_BASE_URL=https://github.com/software-mansion/react-native-executorch/releases/download/v0.0.0-rewrite-libs-test RNET_TARGET=android-arm64-v8a INIT_CWD=<app> node scripts/download-libs.js — tarballs extract (checksum-verified) into third-party/android/libs/... exactly where CMakeLists.txt/podspec expect.
  3. CI gates: yarn lint, yarn workspace react-native-executorch prepare, yarn typecheck (all green; install with RNET_SKIP_DOWNLOAD=1).

Test artifacts uploaded to the v0.0.0-rewrite-libs-test pre-release: Android freshly built from @ms/separate-backends (ET 1.3.1, split backends, arm64-v8a + x86_64); iOS reused from the same separate-backends 1.3.1 lineage (#1039) with MLX stripped to the device slice only. Full download/extract/checksum flow verified across iOS + both Android ABIs. On-device app build still to be run.

Related issues

#1208

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

Draft: all of third-party/ (headers + binaries) is downloaded on demand, not committed — headers ship as a platform-independent headers.tar.gz alongside the binary artifacts (built with device-only MLX), uploaded separately.

Header provenance: headers.tar.gz is assembled from the @ms/separate-backends ExecuTorch CMake install include tree (cmake-out*/include/: executorch, pytorch/{c10,torch,headeronly}, the tokenizer third-party headers absl/re2/nlohmann, and cpuinfo/pthreadpool — all platform-independent, identical across ABIs/SDKs) plus the opencv2 headers from the OpenCV prebuilt (same source as the opencv-rne pod / Android static libopencv_*.a, not built from executorch).

Docs getting-started is deferred (no rewrite getting-started page exists yet).

Port PR #1039's on-demand native-lib mechanism into the rewrite. Apps opt in
via a `react-native-executorch` block (`backends`/`libs`/`features`) in their
package.json; the postinstall `scripts/download-libs.js` expands `features` via
the full forward-looking FEATURE_MAP, writes `rne-build-config.json`, and
downloads only the requested per-backend artifacts from GitHub Releases into
third-party/. The podspec and android/build.gradle.kts read that config to gate
`RNE_ENABLE_*` and link backends as separate libs (Xnnpack/CoreML/MLX
xcframeworks, lib*_executorch_backend.so) — MLX device-slice only.

Adapted to the rewrite: cpp/ layout (opencv gated as an extensible source list,
guarded in RnExecutorch.cpp), Kotlin-DSL gradle config read, single
android/CMakeLists.txt. scripts + FEATURE_MAP + artifact contract kept identical
to #1039 so future rewrite work is code-only. CI (TS-only) skips the download
via RNET_SKIP_DOWNLOAD in the setup action.

Verified: config expansion, download/extract/checksum (local server), and CI
gates (lint, bob build, typecheck). Release artifacts (executorch fork build) +
committed headers/jar/ExecutorchLib wrapper are provisioned separately.
@msluszniak msluszniak force-pushed the @ms/on-demand-native-libs branch from 94f8547 to ab793e1 Compare June 25, 2026 11:43
Rebased onto rne-rewrite incl. #1280 keypoint detection. Rename the
poseEstimation FEATURE_MAP entry to keypointDetection (tracks the
useKeypointDetector hook) and set backends to xnnpack+coreml+mlx (RF-DETR
keypoint ships CoreML + MLX variants) + opencv. Declare it in the
computer-vision demo app.
Drop the committed third-party/include header set (~200K LOC of vendored
ExecuTorch/c10/torch/opencv headers). Headers are now downloaded like the
binaries: a platform-independent headers.tar.gz fetched by download-libs.js
and produced by package-release-artifacts.sh. Keeps the rewrite's 'no
third-party in git' philosophy and avoids churn on ExecuTorch bumps.
@msluszniak msluszniak force-pushed the @ms/on-demand-native-libs branch from ab793e1 to 45ec2cb Compare June 25, 2026 11:53
@msluszniak msluszniak self-assigned this Jun 25, 2026
@msluszniak msluszniak added refactoring improvement PRs or issues focused on improvements in the current codebase labels Jun 25, 2026
core-android/core-ios drop the separately-shipped pthreadpool+cpuinfo
(statically linked into libexecutorch.so / libthreadpool_*.a for the rewrite),
and the ABI-independent executorch.jar rides in the core-android-arm64 artifact
(downloaded to third-party, not committed).
Two gaps surfaced building apps/computer-vision on a physical device:
- libexecutorch.so references OpenMP runtime symbols (optimized kernels), so
  link -fopenmp -static-openmp into libRnExecutorch.so (matches main #1039).
- abiFilters was hardcoded to both ABIs, ignoring the app's
  reactNativeArchitectures; read it (filtered to arm64-v8a/x86_64) so device
  builds only compile + need the ABI they target. Build now succeeds, installs,
  and launches on device (arm64-v8a).
@msluszniak msluszniak marked this pull request as ready for review June 25, 2026 14:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

improvement PRs or issues focused on improvements in the current codebase refactoring

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant