From eb619468c1b61b7261846e62e33f94d89e121455 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Thu, 8 Feb 2024 08:15:28 -0800 Subject: [PATCH] Fix linking of local app modules turbomodules (#42921) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/42921 I realized that we were missing a bit to properly link app modules on Android. The `_ModuleProvider` was never linked correctly so the TM won't be loaded at all. With this change I'm getting the App Target (say `AppModule`) and passing it down to the default-app-setup with a couple of macros. This makes sure that if there is a codegen local module, we import the correct header and query the `AppModule_ModuleProvider` correctly. Changelog: [Android] [Fixed] - Fix linking of local app modules turbomodules Reviewed By: cipolleschi Differential Revision: D53567201 fbshipit-source-id: d14e61b7f2d86f15363600cd9dd1ed1ca27bd1fc --- .../cmake-utils/ReactNative-application.cmake | 9 +++++++++ .../cmake-utils/default-app-setup/OnLoad.cpp | 20 +++++++++++++++---- .../android/app/src/main/jni/OnLoad.cpp | 15 +++++++++----- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/packages/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake b/packages/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake index 13bba97da633ab..3f2bd1237c5340 100644 --- a/packages/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake +++ b/packages/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake @@ -134,4 +134,13 @@ if(EXISTS ${PROJECT_BUILD_DIR}/generated/source/codegen/jni/CMakeLists.txt) get_property(APP_CODEGEN_TARGET DIRECTORY ${PROJECT_BUILD_DIR}/generated/source/codegen/jni/ PROPERTY BUILDSYSTEM_TARGETS) target_link_libraries(${CMAKE_PROJECT_NAME} ${APP_CODEGEN_TARGET}) target_link_libraries(${APP_CODEGEN_TARGET} common_flags) + + # We need to pass the generated header and module provider to the OnLoad.cpp file so + # local app modules can properly be linked. + string(REGEX REPLACE "react_codegen_" "" APP_CODEGEN_HEADER "${APP_CODEGEN_TARGET}") + target_compile_options(${CMAKE_PROJECT_NAME} + PRIVATE + -DREACT_NATIVE_APP_CODEGEN_HEADER="${APP_CODEGEN_HEADER}.h" + -DREACT_NATIVE_APP_MODULE_PROVIDER=${APP_CODEGEN_HEADER}_ModuleProvider + ) endif() diff --git a/packages/react-native/ReactAndroid/cmake-utils/default-app-setup/OnLoad.cpp b/packages/react-native/ReactAndroid/cmake-utils/default-app-setup/OnLoad.cpp index eff504b9c2106a..4452ca8aea6cb1 100644 --- a/packages/react-native/ReactAndroid/cmake-utils/default-app-setup/OnLoad.cpp +++ b/packages/react-native/ReactAndroid/cmake-utils/default-app-setup/OnLoad.cpp @@ -33,6 +33,10 @@ #include #include +#ifdef REACT_NATIVE_APP_CODEGEN_HEADER +#include REACT_NATIVE_APP_CODEGEN_HEADER +#endif + namespace facebook::react { void registerComponents( @@ -41,7 +45,7 @@ void registerComponents( // components coming from your App or from 3rd party libraries here. // // providerRegistry->add(concreteComponentDescriptorProvider< - // AocViewerComponentDescriptor>()); + // MyComponentDescriptor>()); // By default we just use the components autolinked by RN CLI rncli_registerProviders(registry); @@ -61,13 +65,21 @@ std::shared_ptr javaModuleProvider( // either your application or from external libraries. The approach to follow // is similar to the following (for a library called `samplelibrary`): // - // auto module = samplelibrary_ModuleProvider(moduleName, params); + // auto module = samplelibrary_ModuleProvider(name, params); // if (module != nullptr) { // return module; // } - // return rncore_ModuleProvider(moduleName, params); + // return rncore_ModuleProvider(name, params); + + // We link app local modules if available +#ifdef REACT_NATIVE_APP_MODULE_PROVIDER + auto module = REACT_NATIVE_APP_MODULE_PROVIDER(name, params); + if (module != nullptr) { + return module; + } +#endif - // By default we just use the module providers autolinked by RN CLI + // And we fallback to the module providers autolinked by RN CLI return rncli_ModuleProvider(name, params); } diff --git a/packages/rn-tester/android/app/src/main/jni/OnLoad.cpp b/packages/rn-tester/android/app/src/main/jni/OnLoad.cpp index 4fd2a640de0a85..99f8b74255fe15 100644 --- a/packages/rn-tester/android/app/src/main/jni/OnLoad.cpp +++ b/packages/rn-tester/android/app/src/main/jni/OnLoad.cpp @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -#include #include #include #include @@ -14,6 +13,10 @@ #include #include +#ifdef REACT_NATIVE_APP_CODEGEN_HEADER +#include REACT_NATIVE_APP_CODEGEN_HEADER +#endif + namespace facebook { namespace react { @@ -37,14 +40,16 @@ std::shared_ptr cxxModuleProvider( std::shared_ptr javaModuleProvider( const std::string& name, const JavaTurboModule::InitParams& params) { - auto module = AppSpecs_ModuleProvider(name, params); + auto module = SampleTurboModuleSpec_ModuleProvider(name, params); if (module != nullptr) { return module; - } - module = SampleTurboModuleSpec_ModuleProvider(name, params); + }; +#ifdef REACT_NATIVE_APP_MODULE_PROVIDER + module = REACT_NATIVE_APP_MODULE_PROVIDER(name, params); if (module != nullptr) { return module; - }; + } +#endif return nullptr; }