Skip to content

Conversation

@0xBigBoss
Copy link

@0xBigBoss 0xBigBoss commented Jan 2, 2026

Summary

This PR implements Android CMake integration for polygen-generated native code, equivalent to iOS's ReactNativeWebAssemblyHost.podspec auto-linking mechanism.

Key Changes:

  • New android-cmake.ts plugin - Generates CMakeLists.txt in .polygen-out/host/ for Android builds
  • Modified polygen/android/CMakeLists.txt - Detects and includes generated code from .polygen-out/host/
  • Fixed duplicate symbol errors - Module variable names are now unique per module (e.g., ExampleModuleInfo instead of generic moduleInfo)
  • Updated wasm-rt runtime to 1.0.39 - Fixed wasm_rt_allocate_memory API (5 arguments with pageSize parameter)
  • Updated Memory.h - Constructor now matches new wasm-rt API signature
  • Support for wasm2c 1.0.36 and 1.0.39 - Version check updated to accept both versions

Features:

  • Automatic detection of polygen-generated code in monorepo setups via POLYGEN_APP_ROOT
  • Proper include path setup for ReactNativePolygen headers and JSI
  • Conditional exclusion of ModuleBagStub when generated code is available
  • Compatible with both new architecture and old architecture builds

Test plan

  • Android new architecture build succeeds
  • Android old architecture build succeeds
  • iOS build succeeds (no regressions)
  • External Module (simple-sha256-wasm) loads successfully on Android
  • External Module loads successfully on iOS
  • SHA256 hash computation produces correct results on both platforms

Verified output:

Module loaded: true
sha256(foo) = 2C26B46B68FFC68FF99B453C1D30413413422D706483BFA0F98A5E886266E7AE

Closes #132

Screenshot 2026-01-02 at 13 12 36

Fixes the Android new architecture build failure caused by incorrect
codegen configuration that generated NativePolygenSpec in
com.callstack.polygen while Kotlin code expected NativeWasmSpec in
com.wasm package.

Changes:
- Align build.gradle codegen config with package.json:
  - libraryName="RNPolygenSpec" (matches codegenConfig.name)
  - codegenJavaPackageName="com.callstack.polygen"
- Update Android namespace from com.wasm to com.callstack.polygen
- Rename Wasm* Kotlin files to Polygen* with correct package
- Add PolygenModule implementing all NativePolygenSpec abstract methods
  (with stub implementations that throw UnsupportedOperationException)
- Add @ReactMethod annotations to oldarch PolygenSpec for old architecture
  compatibility
- Remove outdated C++ native build config (cpp-adapter.cpp, CMakeLists)
- Update react-native.config.js with correct package import path
- Add PLAN.md documenting steps for full C++ implementation including:
  - CMake setup with OnLoad.cpp
  - SoLoader.loadLibrary for JNI_OnLoad trigger
  - C++ TurboModule registration

Note: The Android module now compiles successfully but the actual WASM
runtime implementation is not yet wired up. Methods will throw
UnsupportedOperationException at runtime until the C++ implementation
is properly integrated via JNI.

Fixes callstackincubator#132
- Rewrite CMakeLists.txt with proper React Native prefab integration
- Enable externalNativeBuild and prefab in build.gradle
- Add OnLoad.cpp for JNI_OnLoad registration
- Add ModuleBagStub.cpp for runtime-only usage
- Update PolygenPackage.kt with SoLoader and isCxxModule=true
- Add cmakeListsPath to react-native.config.js
- Fix missing #include <string> in w2c.h
- Use GLOB_RECURSE to include utils/checksum.cpp
- Link ReactAndroid::folly_runtime for fmt support
- Move react{} DSL to subprojects afterEvaluate (plugin not at root)
- Add packagingOptions to exclude React Native .so files from AAR
- Re-enable newArchEnabled for TurboModule support
- getModule now returns null when new architecture is enabled,
  allowing the system to use the C++ module registered via JNI_OnLoad
- CMake conditionally includes codegen files only when they exist
- Fixes issue where Java TurboModule stub would be used instead of C++
Wrap externalNativeBuild, CMake path, prefab, and packagingOptions
inside isNewArchitectureEnabled() checks. This prevents old-arch builds
from failing due to missing codegen-generated headers that only exist
when the React Gradle plugin runs with new architecture enabled.
- Only call SoLoader.loadLibrary("polygen") when new arch is enabled,
  since old arch builds don't produce libpolygen.so
- Make isCxxModule conditional on IS_NEW_ARCHITECTURE_ENABLED to avoid
  mismatched metadata in legacy bridge registration
Verified Android C++ TurboModule works at runtime:
- App launches successfully via ADB
- UI visible and interactive
- Polygen TurboModule loads without crashes
- No UnsatisfiedLinkError or registration errors
- Import Validation test works correctly
The C++ TurboModule infrastructure is working correctly:
- JNI_OnLoad registers the module
- libpolygen.so loads without UnsatisfiedLinkError
- API is accessible from JavaScript

Module loading returns "not precompiled" errors because:
- iOS uses ReactNativeWebAssemblyHost.podspec to auto-link generated code
- Android has no equivalent mechanism yet
- ModuleBagStub.cpp returns empty bag as fallback

This is expected behavior - implementing Android generated-code integration
is a separate feature beyond the C++ TurboModule wiring scope.
Implements the Android equivalent of iOS's ReactNativeWebAssemblyHost.podspec
mechanism for linking polygen-generated native code.

Changes:
- Add android-cmake.ts plugin to polygen-codegen that generates
  CMakeLists.txt in .polygen-out/host/ during code generation
- Modify polygen library's CMakeLists.txt to detect and include
  generated code when available
- Pass POLYGEN_APP_ROOT from Gradle to CMake to support monorepo setups
- Conditionally exclude ModuleBagStub.cpp when generated loader.cpp
  provides getModuleBag()

The generated code is now being compiled and linked, but there's a
pre-existing wasm-rt API mismatch that needs to be fixed separately:
wasm2c generates code calling wasm_rt_allocate_memory with 5 args,
but bundled wasm-rt expects 4 args.
- Fix include paths in generated CMakeLists.txt to find Module.h in
  WebAssembly subdirectory and link against ReactAndroid::jsi for JSI headers
- Fix duplicate symbol errors by making moduleInfo/moduleSharedInfo variable
  names unique per module (e.g., ExampleModuleInfo, ExampleModuleSharedInfo)
- Update wasm-rt runtime to 1.0.39 API which uses 5-argument
  wasm_rt_allocate_memory (adds page_size parameter)
- Update Memory.h constructor to match new wasm_rt_allocate_memory signature
- Support wasm2c versions 1.0.36 and 1.0.39

These changes enable successful Android builds with polygen-generated code
for both new architecture and old architecture configurations.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Execution failed for task ':callstack_polygen:compileDebugKotlin'

1 participant