From fc6b49afd095fefaeb71e76e3ad3f8db67e6a1f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Thu, 5 May 2022 11:22:20 +0200 Subject: [PATCH 01/13] feat: generate new arch files with hardcoded values --- CONTRIBUTING.md | 2 +- .../platform-android/native_modules.gradle | 140 ++++++++++++++++++ 2 files changed, 141 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9024300cb..bd1738b6d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -39,7 +39,7 @@ And then: ```sh cd /my/new/react-native/project/ -yarn link "@react-native-community/cli-platform-ios" "@react-native-community/cli-platform-android" "@react-native-community/cli" "@react-native-community/cli-server-api" "@react-native-community/cli-types" "@react-native-community/cli-tools" "@react-native-community/cli-debugger-ui" "@react-native-community/cli-hermes" "@react-native-community/cli-plugin-metro" +yarn link "@react-native-community/cli-platform-ios" "@react-native-community/cli-platform-android" "@react-native-community/cli" "@react-native-community/cli-server-api" "@react-native-community/cli-types" "@react-native-community/cli-tools" "@react-native-community/cli-debugger-ui" "@react-native-community/cli-hermes" "@react-native-community/cli-plugin-metro" "@react-native-community/cli-clean" ``` Once you're done with testing and you'd like to get back to regular setup, run `yarn unlink` instead of `yarn link` from above command. Then `yarn install --force`. diff --git a/packages/platform-android/native_modules.gradle b/packages/platform-android/native_modules.gradle index 20c858ba5..93e6b6209 100644 --- a/packages/platform-android/native_modules.gradle +++ b/packages/platform-android/native_modules.gradle @@ -68,6 +68,63 @@ public class PackageList { } """ +def androidMkTemplate = """ +# This code was generated by [React Native CLI](https://www.npmjs.com/package/@react-native-community/cli) + +{{ libraryIncludes }} + +import-codegen-modules := {{ libraryModules }} +""" + +def rncliCppTemplate = """ +/** + * This code was generated by [React Native CLI](https://www.npmjs.com/package/@react-native-community/cli). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + */ + +#include "rncli.h" +{{ rncliCppIncludes }} + +namespace facebook { +namespace react { + +std::shared_ptr rncli_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms) { + {{ rncliCppModuleProviders }} + + return nullptr; +} + +} // namespace react +} // namespace facebook +""" + +def rncliHTemplate = """ +/** + * This code was generated by [React Native CLI](https://www.npmjs.com/package/@react-native-community/cli). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + */ + +#pragma once + +#include +#include +#include + +namespace facebook { +namespace react { + +std::shared_ptr rncli_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms); + +} // namespace react +} // namespace facebook +""" + class ReactNativeModules { private Logger logger private String packageName @@ -187,6 +244,76 @@ class ReactNativeModules { } } + void generateAndroidMkFile(File outputDir, String generatedFileName, String generatedFileContentsTemplate) { + ArrayList> packages = this.reactNativeModules + String packageName = this.packageName + + String libraryIncludes = "" + String libraryModules = "" + + String androidMkPath = "android/build/generated/source/codegen/jni/Android.mk" + + if (packages.size() > 0) { + libraryIncludes = packages.collect { + "include \$(NODE_MODULES_DIR)/${it.name}/${androidMkPath}" + }.join('\n') + libraryModules = packages.collect { + "libreact_codegen_colorview" + }.join(" ") + } + + String generatedFileContents = generatedFileContentsTemplate + .replace("{{ libraryIncludes }}", libraryIncludes) + .replace("{{ libraryModules }}", libraryModules) + + outputDir.mkdirs() + final FileTreeBuilder treeBuilder = new FileTreeBuilder(outputDir) + treeBuilder.file(generatedFileName).newWriter().withWriter { w -> + w << generatedFileContents + } + } + + void generateRncliCpp(File outputDir, String generatedFileName, String generatedFileContentsTemplate) { + ArrayList> packages = this.reactNativeModules + + String rncliCppIncludes = "" + String rncliCppModuleProviders = "" + + if (packages.size() > 0) { + rncliCppIncludes = packages.collect { + "#include " + }.join('\n') + rncliCppModuleProviders = packages.collect { + """ + auto module_colorview = colorview_ModuleProvider(moduleName, params); + if(module_colorview != nullptr) { + return module_colorview; + } + """ + }.join("\n") + } + + String generatedFileContents = generatedFileContentsTemplate + .replace("{{ rncliCppIncludes }}", rncliCppIncludes) + .replace("{{ rncliCppModuleProviders }}", rncliCppModuleProviders) + + outputDir.mkdirs() + final FileTreeBuilder treeBuilder = new FileTreeBuilder(outputDir) + treeBuilder.file(generatedFileName).newWriter().withWriter { w -> + w << generatedFileContents + } + } + + void generateRncliH(File outputDir, String generatedFileName, String generatedFileContentsTemplate) { + String generatedFileContents = generatedFileContentsTemplate + + outputDir.mkdirs() + final FileTreeBuilder treeBuilder = new FileTreeBuilder(outputDir) + treeBuilder.file(generatedFileName).newWriter().withWriter { w -> + w << generatedFileContents + } + } + /** * Runs a specified command using Runtime exec() in a specified directory. * Throws when the command result is empty. @@ -326,6 +453,7 @@ ext.applyNativeModulesAppBuildGradle = { Project project, String root = null -> def generatedSrcDir = new File(buildDir, "generated/rncli/src/main/java") def generatedCodeDir = new File(generatedSrcDir, generatedFilePackage.replace('.', '/')) + def generatedJniDir = new File(buildDir, "generated/rncli/src/main/jni") task generatePackageList { doLast { @@ -333,7 +461,16 @@ ext.applyNativeModulesAppBuildGradle = { Project project, String root = null -> } } + task generateNewArchitectureFiles { + doLast { + autoModules.generateAndroidMkFile(generatedJniDir, "Android-rncli.mk", androidMkTemplate) + autoModules.generateRncliCpp(generatedJniDir, "rncli.cpp", rncliCppTemplate) + autoModules.generateRncliH(generatedJniDir, "rncli.h", rncliHTemplate) + } + } + preBuild.dependsOn generatePackageList + preBuild.dependsOn generateNewArchitectureFiles android { sourceSets { @@ -341,6 +478,9 @@ ext.applyNativeModulesAppBuildGradle = { Project project, String root = null -> java { srcDirs += generatedSrcDir } + jni { + generatedJniDir + } } } } From b55b7cd0d47fa30dc0581615adb02f2c30ed8831 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Thu, 5 May 2022 14:37:08 +0200 Subject: [PATCH 02/13] feat: add libraryName to android dependency config --- packages/cli-config/src/schema.ts | 2 ++ packages/cli-types/src/android.ts | 2 ++ .../platform-android/native_modules.gradle | 32 ++++++++++--------- .../src/config/findLibraryName.ts | 14 ++++++++ packages/platform-android/src/config/index.ts | 3 ++ 5 files changed, 38 insertions(+), 15 deletions(-) create mode 100644 packages/platform-android/src/config/findLibraryName.ts diff --git a/packages/cli-config/src/schema.ts b/packages/cli-config/src/schema.ts index e1079bd6f..80bcb3d3f 100644 --- a/packages/cli-config/src/schema.ts +++ b/packages/cli-config/src/schema.ts @@ -83,6 +83,7 @@ export const dependencyConfig = t packageInstance: t.string(), dependencyConfiguration: t.string(), buildTypes: t.array().items(t.string()).default([]), + libraryName: t.string(), }) .default({}), }) @@ -131,6 +132,7 @@ export const projectConfig = t packageInstance: t.string(), dependencyConfiguration: t.string(), buildTypes: t.array().items(t.string()).default([]), + libraryName: t.string(), }) .allow(null), }), diff --git a/packages/cli-types/src/android.ts b/packages/cli-types/src/android.ts index a74112da6..f7350457b 100644 --- a/packages/cli-types/src/android.ts +++ b/packages/cli-types/src/android.ts @@ -19,6 +19,7 @@ export type AndroidDependencyConfig = { packageInstance: string; dependencyConfiguration?: string; buildTypes: string[]; + libraryName?: string; }; export type AndroidDependencyParams = { @@ -29,4 +30,5 @@ export type AndroidDependencyParams = { packageImportPath?: string; packageInstance?: string; buildTypes?: string[]; + libraryName?: string; }; diff --git a/packages/platform-android/native_modules.gradle b/packages/platform-android/native_modules.gradle index 93e6b6209..024adf184 100644 --- a/packages/platform-android/native_modules.gradle +++ b/packages/platform-android/native_modules.gradle @@ -68,16 +68,14 @@ public class PackageList { } """ -def androidMkTemplate = """ -# This code was generated by [React Native CLI](https://www.npmjs.com/package/@react-native-community/cli) +def androidMkTemplate = """# This code was generated by [React Native CLI](https://www.npmjs.com/package/@react-native-community/cli) {{ libraryIncludes }} import-codegen-modules := {{ libraryModules }} """ -def rncliCppTemplate = """ -/** +def rncliCppTemplate = """/** * This code was generated by [React Native CLI](https://www.npmjs.com/package/@react-native-community/cli). * * Do not edit this file as changes may cause incorrect behavior and will be lost @@ -97,12 +95,16 @@ std::shared_ptr rncli_ModuleProvider(const std::string moduleName, return nullptr; } +void rncli_registerProviders(std::shared_ptr providerRegistry) { + providerRegistry->add(concreteComponentDescriptorProvider()); + return; +} + } // namespace react } // namespace facebook """ -def rncliHTemplate = """ -/** +def rncliHTemplate = """/** * This code was generated by [React Native CLI](https://www.npmjs.com/package/@react-native-community/cli). * * Do not edit this file as changes may cause incorrect behavior and will be lost @@ -115,11 +117,13 @@ def rncliHTemplate = """ #include #include #include +#include namespace facebook { namespace react { std::shared_ptr rncli_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms); +void rncli_registerProviders(std::shared_ptr providerRegistry); } // namespace react } // namespace facebook @@ -247,7 +251,6 @@ class ReactNativeModules { void generateAndroidMkFile(File outputDir, String generatedFileName, String generatedFileContentsTemplate) { ArrayList> packages = this.reactNativeModules String packageName = this.packageName - String libraryIncludes = "" String libraryModules = "" @@ -258,7 +261,7 @@ class ReactNativeModules { "include \$(NODE_MODULES_DIR)/${it.name}/${androidMkPath}" }.join('\n') libraryModules = packages.collect { - "libreact_codegen_colorview" + "libreact_codegen_${it.libraryName}" }.join(" ") } @@ -275,21 +278,19 @@ class ReactNativeModules { void generateRncliCpp(File outputDir, String generatedFileName, String generatedFileContentsTemplate) { ArrayList> packages = this.reactNativeModules - String rncliCppIncludes = "" String rncliCppModuleProviders = "" if (packages.size() > 0) { rncliCppIncludes = packages.collect { - "#include " + "#include <${it.libraryName}.h>\n#include " }.join('\n') rncliCppModuleProviders = packages.collect { """ - auto module_colorview = colorview_ModuleProvider(moduleName, params); - if(module_colorview != nullptr) { - return module_colorview; - } - """ + auto module_${it.libraryName} = ${it.libraryName}_ModuleProvider(moduleName, params); + if (module_${it.libraryName} != nullptr) { + return module_${it.libraryName}; + }""" }.join("\n") } @@ -399,6 +400,7 @@ class ReactNativeModules { reactNativeModuleConfig.put("androidSourceDir", androidConfig["sourceDir"]) reactNativeModuleConfig.put("packageInstance", androidConfig["packageInstance"]) reactNativeModuleConfig.put("packageImportPath", androidConfig["packageImportPath"]) + reactNativeModuleConfig.put("libraryName", androidConfig["libraryName"]) if (androidConfig["buildTypes"] && !androidConfig["buildTypes"].isEmpty()) { reactNativeModulesBuildVariants.put(nameCleansed, androidConfig["buildTypes"]) } diff --git a/packages/platform-android/src/config/findLibraryName.ts b/packages/platform-android/src/config/findLibraryName.ts new file mode 100644 index 000000000..cfc760441 --- /dev/null +++ b/packages/platform-android/src/config/findLibraryName.ts @@ -0,0 +1,14 @@ +import fs from 'fs'; +import path from 'path'; + +export function findLibraryName(sourceDir: string) { + const buildGradlePath = path.join(sourceDir, 'build.gradle'); + if (fs.existsSync(buildGradlePath)) { + const buildGradleContents = fs.readFileSync(buildGradlePath, 'utf-8'); + const match = buildGradleContents.match(/libraryName = "(.+)"/); + if (match) { + return match[1]; + } + } + return undefined; +} diff --git a/packages/platform-android/src/config/index.ts b/packages/platform-android/src/config/index.ts index b4bf86ecb..ff1316c05 100644 --- a/packages/platform-android/src/config/index.ts +++ b/packages/platform-android/src/config/index.ts @@ -18,6 +18,7 @@ import { AndroidDependencyConfig, } from '@react-native-community/cli-types'; import {getPackageName} from './getAndroidProject'; +import {findLibraryName} from './findLibraryName'; /** * Gets android project config by analyzing given folder and taking some @@ -114,6 +115,7 @@ export function dependencyConfig( const buildTypes = userConfig.buildTypes || []; const dependencyConfiguration = userConfig.dependencyConfiguration; + const libraryName = userConfig.libraryName || findLibraryName(sourceDir); return { sourceDir, @@ -121,5 +123,6 @@ export function dependencyConfig( packageInstance, buildTypes, dependencyConfiguration, + libraryName, }; } From 5a92357f7aa516a3dbf09696b0ea4a05d8717ff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Thu, 5 May 2022 16:36:50 +0200 Subject: [PATCH 03/13] feat: add componentNames and componentDescriptors to android dependency config --- packages/cli-config/src/schema.ts | 4 ++++ packages/cli-types/src/android.ts | 4 ++++ .../platform-android/native_modules.gradle | 14 ++++++++++++-- .../src/config/findComponentNames.ts | 18 ++++++++++++++++++ packages/platform-android/src/config/index.ts | 7 +++++++ 5 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 packages/platform-android/src/config/findComponentNames.ts diff --git a/packages/cli-config/src/schema.ts b/packages/cli-config/src/schema.ts index 80bcb3d3f..dd529fca0 100644 --- a/packages/cli-config/src/schema.ts +++ b/packages/cli-config/src/schema.ts @@ -84,6 +84,8 @@ export const dependencyConfig = t dependencyConfiguration: t.string(), buildTypes: t.array().items(t.string()).default([]), libraryName: t.string(), + componentNames: t.array().items(t.string()), + componentDescriptors: t.array().items(t.string()), }) .default({}), }) @@ -133,6 +135,8 @@ export const projectConfig = t dependencyConfiguration: t.string(), buildTypes: t.array().items(t.string()).default([]), libraryName: t.string(), + componentNames: t.array().items(t.string()), + componentDescriptors: t.array().items(t.string()), }) .allow(null), }), diff --git a/packages/cli-types/src/android.ts b/packages/cli-types/src/android.ts index f7350457b..9e8bf8e38 100644 --- a/packages/cli-types/src/android.ts +++ b/packages/cli-types/src/android.ts @@ -20,6 +20,8 @@ export type AndroidDependencyConfig = { dependencyConfiguration?: string; buildTypes: string[]; libraryName?: string; + componentNames?: string[]; + componentDescriptors?: string[]; }; export type AndroidDependencyParams = { @@ -31,4 +33,6 @@ export type AndroidDependencyParams = { packageInstance?: string; buildTypes?: string[]; libraryName?: string; + componentNames?: string[]; + componentDescriptors?: string[]; }; diff --git a/packages/platform-android/native_modules.gradle b/packages/platform-android/native_modules.gradle index 024adf184..69e6615ce 100644 --- a/packages/platform-android/native_modules.gradle +++ b/packages/platform-android/native_modules.gradle @@ -96,7 +96,7 @@ std::shared_ptr rncli_ModuleProvider(const std::string moduleName, } void rncli_registerProviders(std::shared_ptr providerRegistry) { - providerRegistry->add(concreteComponentDescriptorProvider()); + {{ rncliCppComponentDescriptors }} return; } @@ -253,7 +253,6 @@ class ReactNativeModules { String packageName = this.packageName String libraryIncludes = "" String libraryModules = "" - String androidMkPath = "android/build/generated/source/codegen/jni/Android.mk" if (packages.size() > 0) { @@ -280,6 +279,7 @@ class ReactNativeModules { ArrayList> packages = this.reactNativeModules String rncliCppIncludes = "" String rncliCppModuleProviders = "" + String rncliCppComponentDescriptors = "" if (packages.size() > 0) { rncliCppIncludes = packages.collect { @@ -292,11 +292,19 @@ class ReactNativeModules { return module_${it.libraryName}; }""" }.join("\n") + rncliCppComponentDescriptors = packages.collect { + if (it.componentDescriptors.size() > 0) { + it.componentDescriptors.collect { + "providerRegistry->add(concreteComponentDescriptorProvider<${it}>());" + }.join('\n') + } + }.join("\n") } String generatedFileContents = generatedFileContentsTemplate .replace("{{ rncliCppIncludes }}", rncliCppIncludes) .replace("{{ rncliCppModuleProviders }}", rncliCppModuleProviders) + .replace("{{ rncliCppComponentDescriptors }}", rncliCppComponentDescriptors) outputDir.mkdirs() final FileTreeBuilder treeBuilder = new FileTreeBuilder(outputDir) @@ -401,6 +409,8 @@ class ReactNativeModules { reactNativeModuleConfig.put("packageInstance", androidConfig["packageInstance"]) reactNativeModuleConfig.put("packageImportPath", androidConfig["packageImportPath"]) reactNativeModuleConfig.put("libraryName", androidConfig["libraryName"]) + reactNativeModuleConfig.put("componentDescriptors", androidConfig["componentDescriptors"]) + if (androidConfig["buildTypes"] && !androidConfig["buildTypes"].isEmpty()) { reactNativeModulesBuildVariants.put(nameCleansed, androidConfig["buildTypes"]) } diff --git a/packages/platform-android/src/config/findComponentNames.ts b/packages/platform-android/src/config/findComponentNames.ts new file mode 100644 index 000000000..adc45443d --- /dev/null +++ b/packages/platform-android/src/config/findComponentNames.ts @@ -0,0 +1,18 @@ +import fs from 'fs'; +import path from 'path'; +import glob from 'glob'; + +const CODEGEN_NATIVE_COMPONENT_REGEX = /codegenNativeComponent(<.*>)?\(\s+["'`](\w+)["'`]\s+\)/m; + +export function findComponentNames(packageRoot: string) { + const files = glob.sync('**/+(*.js|*.jsx|*.ts|*.tsx)', {cwd: packageRoot}); + const codegenComponent = files + .map((filePath) => + fs.readFileSync(path.join(packageRoot, filePath), 'utf8'), + ) + .map((contents) => contents.match(CODEGEN_NATIVE_COMPONENT_REGEX)) + .map((match) => (match ? match[2] : match)) + .filter(Boolean); + + return codegenComponent as string[]; +} diff --git a/packages/platform-android/src/config/index.ts b/packages/platform-android/src/config/index.ts index ff1316c05..2e63a84f5 100644 --- a/packages/platform-android/src/config/index.ts +++ b/packages/platform-android/src/config/index.ts @@ -19,6 +19,7 @@ import { } from '@react-native-community/cli-types'; import {getPackageName} from './getAndroidProject'; import {findLibraryName} from './findLibraryName'; +import {findComponentNames} from './findComponentNames'; /** * Gets android project config by analyzing given folder and taking some @@ -116,6 +117,10 @@ export function dependencyConfig( const buildTypes = userConfig.buildTypes || []; const dependencyConfiguration = userConfig.dependencyConfiguration; const libraryName = userConfig.libraryName || findLibraryName(sourceDir); + const componentNames = userConfig.componentNames || findComponentNames(root); + const componentDescriptors = + userConfig.componentDescriptors || + componentNames.map((name) => `${name}ComponentDescriptor`); return { sourceDir, @@ -124,5 +129,7 @@ export function dependencyConfig( buildTypes, dependencyConfiguration, libraryName, + componentNames, + componentDescriptors, }; } From a2e951caef146690e00d5820db1e52d9dd552d9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Thu, 5 May 2022 16:42:33 +0200 Subject: [PATCH 04/13] feat: add androidMkPath to android dependency config --- packages/cli-config/src/schema.ts | 2 ++ packages/cli-types/src/android.ts | 2 ++ packages/platform-android/native_modules.gradle | 4 ++-- packages/platform-android/src/config/index.ts | 4 ++++ 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/cli-config/src/schema.ts b/packages/cli-config/src/schema.ts index dd529fca0..752491fd1 100644 --- a/packages/cli-config/src/schema.ts +++ b/packages/cli-config/src/schema.ts @@ -86,6 +86,7 @@ export const dependencyConfig = t libraryName: t.string(), componentNames: t.array().items(t.string()), componentDescriptors: t.array().items(t.string()), + androidMkPath: t.string(), }) .default({}), }) @@ -137,6 +138,7 @@ export const projectConfig = t libraryName: t.string(), componentNames: t.array().items(t.string()), componentDescriptors: t.array().items(t.string()), + androidMkPath: t.string(), }) .allow(null), }), diff --git a/packages/cli-types/src/android.ts b/packages/cli-types/src/android.ts index 9e8bf8e38..e90a0a0f2 100644 --- a/packages/cli-types/src/android.ts +++ b/packages/cli-types/src/android.ts @@ -22,6 +22,7 @@ export type AndroidDependencyConfig = { libraryName?: string; componentNames?: string[]; componentDescriptors?: string[]; + androidMkPath?: string; }; export type AndroidDependencyParams = { @@ -35,4 +36,5 @@ export type AndroidDependencyParams = { libraryName?: string; componentNames?: string[]; componentDescriptors?: string[]; + androidMkPath?: string; }; diff --git a/packages/platform-android/native_modules.gradle b/packages/platform-android/native_modules.gradle index 69e6615ce..93d5cf280 100644 --- a/packages/platform-android/native_modules.gradle +++ b/packages/platform-android/native_modules.gradle @@ -253,11 +253,10 @@ class ReactNativeModules { String packageName = this.packageName String libraryIncludes = "" String libraryModules = "" - String androidMkPath = "android/build/generated/source/codegen/jni/Android.mk" if (packages.size() > 0) { libraryIncludes = packages.collect { - "include \$(NODE_MODULES_DIR)/${it.name}/${androidMkPath}" + "include ${it.androidMkPath}" }.join('\n') libraryModules = packages.collect { "libreact_codegen_${it.libraryName}" @@ -410,6 +409,7 @@ class ReactNativeModules { reactNativeModuleConfig.put("packageImportPath", androidConfig["packageImportPath"]) reactNativeModuleConfig.put("libraryName", androidConfig["libraryName"]) reactNativeModuleConfig.put("componentDescriptors", androidConfig["componentDescriptors"]) + reactNativeModuleConfig.put("androidMkPath", androidConfig["androidMkPath"]) if (androidConfig["buildTypes"] && !androidConfig["buildTypes"].isEmpty()) { reactNativeModulesBuildVariants.put(nameCleansed, androidConfig["buildTypes"]) diff --git a/packages/platform-android/src/config/index.ts b/packages/platform-android/src/config/index.ts index 2e63a84f5..e7f1ca7a8 100644 --- a/packages/platform-android/src/config/index.ts +++ b/packages/platform-android/src/config/index.ts @@ -121,6 +121,9 @@ export function dependencyConfig( const componentDescriptors = userConfig.componentDescriptors || componentNames.map((name) => `${name}ComponentDescriptor`); + const androidMkPath = userConfig.androidMkPath + ? path.join(sourceDir, userConfig.androidMkPath) + : path.join(sourceDir, 'build/generated/source/codegen/jni/Android.mk'); return { sourceDir, @@ -131,5 +134,6 @@ export function dependencyConfig( libraryName, componentNames, componentDescriptors, + androidMkPath, }; } From 1a24013a691d5071d215bb91f10c8a734079fca6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Thu, 5 May 2022 17:25:13 +0200 Subject: [PATCH 05/13] fix: remove duplicate component names --- packages/platform-android/src/config/findComponentNames.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/platform-android/src/config/findComponentNames.ts b/packages/platform-android/src/config/findComponentNames.ts index adc45443d..734611026 100644 --- a/packages/platform-android/src/config/findComponentNames.ts +++ b/packages/platform-android/src/config/findComponentNames.ts @@ -2,7 +2,7 @@ import fs from 'fs'; import path from 'path'; import glob from 'glob'; -const CODEGEN_NATIVE_COMPONENT_REGEX = /codegenNativeComponent(<.*>)?\(\s+["'`](\w+)["'`]\s+\)/m; +const CODEGEN_NATIVE_COMPONENT_REGEX = /codegenNativeComponent(<.*>)?\s*\(\s*["'`](\w+)["'`]/m; export function findComponentNames(packageRoot: string) { const files = glob.sync('**/+(*.js|*.jsx|*.ts|*.tsx)', {cwd: packageRoot}); @@ -14,5 +14,5 @@ export function findComponentNames(packageRoot: string) { .map((match) => (match ? match[2] : match)) .filter(Boolean); - return codegenComponent as string[]; + return Array.from(new Set(codegenComponent as string[])); } From 9052b35dfae3792742856ce1cd76c32b778e2475 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Thu, 5 May 2022 18:47:30 +0200 Subject: [PATCH 06/13] chore: run generateNewArchitectureFiles when new architecture is turned on --- packages/platform-android/native_modules.gradle | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/platform-android/native_modules.gradle b/packages/platform-android/native_modules.gradle index 93d5cf280..b29136a9e 100644 --- a/packages/platform-android/native_modules.gradle +++ b/packages/platform-android/native_modules.gradle @@ -91,7 +91,6 @@ namespace react { std::shared_ptr rncli_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms) { {{ rncliCppModuleProviders }} - return nullptr; } @@ -482,7 +481,10 @@ ext.applyNativeModulesAppBuildGradle = { Project project, String root = null -> } preBuild.dependsOn generatePackageList - preBuild.dependsOn generateNewArchitectureFiles + + if (isNewArchitectureEnabled()) { + preBuild.dependsOn generateNewArchitectureFiles + } android { sourceSets { @@ -497,3 +499,5 @@ ext.applyNativeModulesAppBuildGradle = { Project project, String root = null -> } } } + + From ed3839375da5349dbdfe4100a647c4085edf41c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Fri, 6 May 2022 15:13:02 +0200 Subject: [PATCH 07/13] feat: use only componentDescriptors, take interfacesOnly into account --- packages/cli-config/src/schema.ts | 2 - packages/cli-types/src/android.ts | 2 - .../extractComponentDescriptors.test.ts | 57 +++++++++++++++++++ .../src/config/extractComponentDescriptors.ts | 9 +++ ...ntNames.ts => findComponentDescriptors.ts} | 10 ++-- packages/platform-android/src/config/index.ts | 7 +-- 6 files changed, 73 insertions(+), 14 deletions(-) create mode 100644 packages/platform-android/src/config/__tests__/extractComponentDescriptors.test.ts create mode 100644 packages/platform-android/src/config/extractComponentDescriptors.ts rename packages/platform-android/src/config/{findComponentNames.ts => findComponentDescriptors.ts} (51%) diff --git a/packages/cli-config/src/schema.ts b/packages/cli-config/src/schema.ts index 752491fd1..264f4933c 100644 --- a/packages/cli-config/src/schema.ts +++ b/packages/cli-config/src/schema.ts @@ -84,7 +84,6 @@ export const dependencyConfig = t dependencyConfiguration: t.string(), buildTypes: t.array().items(t.string()).default([]), libraryName: t.string(), - componentNames: t.array().items(t.string()), componentDescriptors: t.array().items(t.string()), androidMkPath: t.string(), }) @@ -136,7 +135,6 @@ export const projectConfig = t dependencyConfiguration: t.string(), buildTypes: t.array().items(t.string()).default([]), libraryName: t.string(), - componentNames: t.array().items(t.string()), componentDescriptors: t.array().items(t.string()), androidMkPath: t.string(), }) diff --git a/packages/cli-types/src/android.ts b/packages/cli-types/src/android.ts index e90a0a0f2..c86810e1b 100644 --- a/packages/cli-types/src/android.ts +++ b/packages/cli-types/src/android.ts @@ -20,7 +20,6 @@ export type AndroidDependencyConfig = { dependencyConfiguration?: string; buildTypes: string[]; libraryName?: string; - componentNames?: string[]; componentDescriptors?: string[]; androidMkPath?: string; }; @@ -34,7 +33,6 @@ export type AndroidDependencyParams = { packageInstance?: string; buildTypes?: string[]; libraryName?: string; - componentNames?: string[]; componentDescriptors?: string[]; androidMkPath?: string; }; diff --git a/packages/platform-android/src/config/__tests__/extractComponentDescriptors.test.ts b/packages/platform-android/src/config/__tests__/extractComponentDescriptors.test.ts new file mode 100644 index 000000000..9055d7839 --- /dev/null +++ b/packages/platform-android/src/config/__tests__/extractComponentDescriptors.test.ts @@ -0,0 +1,57 @@ +import {extractComponentDescriptors} from '../extractComponentDescriptors'; + +test('extracts TestComponentComponentDescriptor from basic fixture', () => { + const fixture = + "export default (codegenNativeComponent('TestComponent'): ComponentType);"; + expect(extractComponentDescriptors(fixture)).toEqual( + 'TestComponentComponentDescriptor', + ); +}); + +test('extracts TestComponentComponentDescriptor from when untyped', () => { + const fixture = "export default codegenNativeComponent('TestComponent')"; + expect(extractComponentDescriptors(fixture)).toEqual( + 'TestComponentComponentDescriptor', + ); +}); + +test('extracts TestComponentComponentDescriptor from when options are passed', () => { + const fixture = `export default (codegenNativeComponent('TestComponent', { + abc: d + }): ComponentType);`; + expect(extractComponentDescriptors(fixture)).toEqual( + 'TestComponentComponentDescriptor', + ); +}); + +test('extracts TestComponentComponentDescriptor from when options are passed 2', () => { + const fixture = + "export default (codegenNativeComponent('TestComponent', {abc: d}): ComponentType);"; + expect(extractComponentDescriptors(fixture)).toEqual( + 'TestComponentComponentDescriptor', + ); +}); + +test('extracts TestComponentComponentDescriptor from when options are passed empty', () => { + const fixture = + "export default (codegenNativeComponent('TestComponent', {}): ComponentType);"; + expect(extractComponentDescriptors(fixture)).toEqual( + 'TestComponentComponentDescriptor', + ); +}); + +test('skip when interfaceOnly is true', () => { + const fixture = `export default (codegenNativeComponent('TestComponent', { + interfaceOnly: true, + abc: d + }): ComponentType);`; + expect(extractComponentDescriptors(fixture)).toBeNull(); +}); + +test('skip when interfaceOnly is true 2', () => { + const fixture = `export default (codegenNativeComponent('TestComponent', { + abc: d, + interfaceOnly: true, + }): ComponentType);`; + expect(extractComponentDescriptors(fixture)).toBeNull(); +}); diff --git a/packages/platform-android/src/config/extractComponentDescriptors.ts b/packages/platform-android/src/config/extractComponentDescriptors.ts new file mode 100644 index 000000000..5224b4081 --- /dev/null +++ b/packages/platform-android/src/config/extractComponentDescriptors.ts @@ -0,0 +1,9 @@ +const CODEGEN_NATIVE_COMPONENT_REGEX = /codegenNativeComponent(<.*>)?\s*\(\s*["'`](\w+)["'`](,?[\s\S]+interfaceOnly:\s*(\w+))?/m; + +export function extractComponentDescriptors(contents: string) { + const match = contents.match(CODEGEN_NATIVE_COMPONENT_REGEX); + if (!(match?.[4] === 'true') && match?.[2]) { + return `${match[2]}ComponentDescriptor`; + } + return null; +} diff --git a/packages/platform-android/src/config/findComponentNames.ts b/packages/platform-android/src/config/findComponentDescriptors.ts similarity index 51% rename from packages/platform-android/src/config/findComponentNames.ts rename to packages/platform-android/src/config/findComponentDescriptors.ts index 734611026..8575e82ed 100644 --- a/packages/platform-android/src/config/findComponentNames.ts +++ b/packages/platform-android/src/config/findComponentDescriptors.ts @@ -1,18 +1,18 @@ import fs from 'fs'; import path from 'path'; import glob from 'glob'; +import {extractComponentDescriptors} from './extractComponentDescriptors'; -const CODEGEN_NATIVE_COMPONENT_REGEX = /codegenNativeComponent(<.*>)?\s*\(\s*["'`](\w+)["'`]/m; - -export function findComponentNames(packageRoot: string) { +export function findComponentDescriptors(packageRoot: string) { const files = glob.sync('**/+(*.js|*.jsx|*.ts|*.tsx)', {cwd: packageRoot}); const codegenComponent = files .map((filePath) => fs.readFileSync(path.join(packageRoot, filePath), 'utf8'), ) - .map((contents) => contents.match(CODEGEN_NATIVE_COMPONENT_REGEX)) - .map((match) => (match ? match[2] : match)) + .map(extractComponentDescriptors) .filter(Boolean); + // Filter out duplicates as it happens that libraries contain multiple outputs due to package publishing. + // TODO: consider using "codegenConfig" to avoid this. return Array.from(new Set(codegenComponent as string[])); } diff --git a/packages/platform-android/src/config/index.ts b/packages/platform-android/src/config/index.ts index e7f1ca7a8..c97916e8f 100644 --- a/packages/platform-android/src/config/index.ts +++ b/packages/platform-android/src/config/index.ts @@ -19,7 +19,7 @@ import { } from '@react-native-community/cli-types'; import {getPackageName} from './getAndroidProject'; import {findLibraryName} from './findLibraryName'; -import {findComponentNames} from './findComponentNames'; +import {findComponentDescriptors} from './findComponentDescriptors'; /** * Gets android project config by analyzing given folder and taking some @@ -117,10 +117,8 @@ export function dependencyConfig( const buildTypes = userConfig.buildTypes || []; const dependencyConfiguration = userConfig.dependencyConfiguration; const libraryName = userConfig.libraryName || findLibraryName(sourceDir); - const componentNames = userConfig.componentNames || findComponentNames(root); const componentDescriptors = - userConfig.componentDescriptors || - componentNames.map((name) => `${name}ComponentDescriptor`); + userConfig.componentDescriptors || findComponentDescriptors(root); const androidMkPath = userConfig.androidMkPath ? path.join(sourceDir, userConfig.androidMkPath) : path.join(sourceDir, 'build/generated/source/codegen/jni/Android.mk'); @@ -132,7 +130,6 @@ export function dependencyConfig( buildTypes, dependencyConfiguration, libraryName, - componentNames, componentDescriptors, androidMkPath, }; From 2a84ade95968df25b5bb4ede64927022bdf00e7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Fri, 6 May 2022 15:57:02 +0200 Subject: [PATCH 08/13] docs: document new architecture autolinking --- docs/autolinking.md | 6 ++++++ docs/dependencies.md | 21 +++++++++++++++++++++ docs/platforms.md | 3 +++ 3 files changed, 30 insertions(+) diff --git a/docs/autolinking.md b/docs/autolinking.md index b6d84d8b4..63a11bd0e 100644 --- a/docs/autolinking.md +++ b/docs/autolinking.md @@ -48,6 +48,10 @@ The [native_modules.gradle](https://github.com/react-native-community/cli/blob/m 1. At build time, before the build script is run: 1. A first Gradle plugin (in `settings.gradle`) runs `applyNativeModulesSettingsGradle` method. It uses the package metadata from `react-native config` to add Android projects. 1. A second Gradle plugin (in `app/build.gradle`) runs `applyNativeModulesAppBuildGradle` method. It creates a list of React Native packages to include in the generated `/android/build/generated/rn/src/main/java/com/facebook/react/PackageList.java` file. + 1. When the new architecture is turned on, the `generateNewArchitectureFiles` task is fired, generating `/android/build/generated/rn/src/main/jni` directory with the following files: + - `Android-rncli.mk` – creates a list of codegen'd libs. Used by the project's `Android.mk`. + - `rncli.cpp` – registers codegen'd Turbo Modules and Fabric component providers. Used by `MainApplicationModuleProvider.cpp` and `MainComponentsRegistry.cpp`. + - `rncli.h` - a header file for `rncli.cpp`. 1. At runtime, the list of React Native packages generated in step 1.2 is registered by `getPackages` method of `ReactNativeHost` in `MainApplication.java`. 1. You can optionally pass in an instance of `MainPackageConfig` when initializing `PackageList` if you want to override the default configuration of `MainReactPackage`. @@ -124,6 +128,7 @@ correct location and update them accordingly: - path to `native_modules.gradle` in your `android/app/build.gradle` Dependencies are only linked if they are listed in the package.json of the mobile workspace, where "react-native" dependency is defined. For example, with this file structure: + ``` /root /packages @@ -135,4 +140,5 @@ Dependencies are only linked if they are listed in the package.json of the mobil package.json <-- Dependencies here are ignored when auto-linking package.json ``` + In this example, if you add a package with native code as a dependency of `components`, you need to also add it as a dependency of `mobile` for auto-linking to work. diff --git a/docs/dependencies.md b/docs/dependencies.md index 30d574519..f4737fce6 100644 --- a/docs/dependencies.md +++ b/docs/dependencies.md @@ -55,6 +55,9 @@ type AndroidDependencyParams = { packageImportPath?: string; packageInstance?: string; buildTypes?: string[]; + libraryName?: string; + componentDescriptors?: string[]; + androidMkPath?: string; }; ``` @@ -119,3 +122,21 @@ An array of build variants or flavors which will include the dependency. If the A string that defines which method other than `implementation` do you want to use for autolinking inside `build.gradle` i.e: `'embed project(path: ":$dependencyName", configuration: "default")',` - `"dependencyName` will be replaced by the actual package's name. You can achieve the same result by directly defining this key per `dependency` _(without placeholder)_ and it will have higher priority than this option. + +#### platforms.android.libraryName + +> Note: Only applicable when new architecture is turned on. + +A string indicating your custom library name. By default it's taken from the `libraryName` variable in your library's `build.gradle`. + +#### platforms.android.componentDescriptors + +> Note: Only applicable when new architecture is turned on. + +An array of custom component descriptor strings. By default they're generated based on `codegenNativeComponent` calls. + +#### platforms.android.androidMkPath + +> Note: Only applicable when new architecture is turned on. + +A relative path to a custom _Android.mk_ file not registered by codegen. Relative to `sourceDir`. diff --git a/docs/platforms.md b/docs/platforms.md index 1d187ad37..a2f9700c1 100644 --- a/docs/platforms.md +++ b/docs/platforms.md @@ -118,5 +118,8 @@ type AndroidDependencyConfig = { packageInstance: string; dependencyConfiguration?: string; buildTypes: string[]; + libraryName?: string; + componentDescriptors?: string[]; + androidMkPath?: string; }; ``` From c5bea261064c905121a132fc58f429e637d90342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Fri, 6 May 2022 16:00:57 +0200 Subject: [PATCH 09/13] chore: add comments --- .../platform-android/src/config/extractComponentDescriptors.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/platform-android/src/config/extractComponentDescriptors.ts b/packages/platform-android/src/config/extractComponentDescriptors.ts index 5224b4081..c3765a703 100644 --- a/packages/platform-android/src/config/extractComponentDescriptors.ts +++ b/packages/platform-android/src/config/extractComponentDescriptors.ts @@ -1,3 +1,5 @@ +// TODO: avoid the regex and improve reliability by reading this data from codegen schema.json. +// Need to find a way to run "generateNewArchitectureFiles" gradle task after each library's "generateCodegenSchemaFromJavaScript" task. const CODEGEN_NATIVE_COMPONENT_REGEX = /codegenNativeComponent(<.*>)?\s*\(\s*["'`](\w+)["'`](,?[\s\S]+interfaceOnly:\s*(\w+))?/m; export function extractComponentDescriptors(contents: string) { From 98bb2b7b41b444c202ee9b336fec4787f80ccfeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Fri, 6 May 2022 17:56:48 +0200 Subject: [PATCH 10/13] fix: TurboModule support and indentation --- .../platform-android/native_modules.gradle | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/platform-android/native_modules.gradle b/packages/platform-android/native_modules.gradle index b29136a9e..a51f39466 100644 --- a/packages/platform-android/native_modules.gradle +++ b/packages/platform-android/native_modules.gradle @@ -90,12 +90,12 @@ namespace facebook { namespace react { std::shared_ptr rncli_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms) { - {{ rncliCppModuleProviders }} +{{ rncliCppModuleProviders }} return nullptr; } void rncli_registerProviders(std::shared_ptr providerRegistry) { - {{ rncliCppComponentDescriptors }} +{{ rncliCppComponentDescriptors }} return; } @@ -281,21 +281,26 @@ class ReactNativeModules { if (packages.size() > 0) { rncliCppIncludes = packages.collect { - "#include <${it.libraryName}.h>\n#include " + def result = "#include <${it.libraryName}.h>" + if (it.componentDescriptors.size() > 0) { + result += "\n#include " + } + result }.join('\n') rncliCppModuleProviders = packages.collect { - """ - auto module_${it.libraryName} = ${it.libraryName}_ModuleProvider(moduleName, params); + """ auto module_${it.libraryName} = ${it.libraryName}_ModuleProvider(moduleName, params); if (module_${it.libraryName} != nullptr) { return module_${it.libraryName}; }""" }.join("\n") rncliCppComponentDescriptors = packages.collect { + def result = "" if (it.componentDescriptors.size() > 0) { - it.componentDescriptors.collect { - "providerRegistry->add(concreteComponentDescriptorProvider<${it}>());" + result += it.componentDescriptors.collect { + " providerRegistry->add(concreteComponentDescriptorProvider<${it}>());" }.join('\n') - } + } + result }.join("\n") } From eac476bc507a25d40e0a1d859717a1e0fed001a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Sun, 8 May 2022 11:20:50 +0200 Subject: [PATCH 11/13] chore: prettify mk output; remove jni sourceset; extract variables --- packages/platform-android/native_modules.gradle | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/platform-android/native_modules.gradle b/packages/platform-android/native_modules.gradle index a51f39466..3a66757c1 100644 --- a/packages/platform-android/native_modules.gradle +++ b/packages/platform-android/native_modules.gradle @@ -72,7 +72,8 @@ def androidMkTemplate = """# This code was generated by [React Native CLI](https {{ libraryIncludes }} -import-codegen-modules := {{ libraryModules }} +import-codegen-modules := \\ + {{ libraryModules }} """ def rncliCppTemplate = """/** @@ -250,6 +251,7 @@ class ReactNativeModules { void generateAndroidMkFile(File outputDir, String generatedFileName, String generatedFileContentsTemplate) { ArrayList> packages = this.reactNativeModules String packageName = this.packageName + String codegenLibPrefix = "libreact_codegen_" String libraryIncludes = "" String libraryModules = "" @@ -258,8 +260,8 @@ class ReactNativeModules { "include ${it.androidMkPath}" }.join('\n') libraryModules = packages.collect { - "libreact_codegen_${it.libraryName}" - }.join(" ") + "${codegenLibPrefix}${it.libraryName}" + }.join(" \\\n ") } String generatedFileContents = generatedFileContentsTemplate @@ -278,12 +280,14 @@ class ReactNativeModules { String rncliCppIncludes = "" String rncliCppModuleProviders = "" String rncliCppComponentDescriptors = "" + String codegenComponentDescriptorsHeaderFile = "ComponentDescriptors.h" + String codegenReactComponentsDir = "react/renderer/components" if (packages.size() > 0) { rncliCppIncludes = packages.collect { def result = "#include <${it.libraryName}.h>" if (it.componentDescriptors.size() > 0) { - result += "\n#include " + result += "\n#include <${codegenReactComponentsDir}/${it.libraryName}/${codegenComponentDescriptorsHeaderFile}>" } result }.join('\n') @@ -497,9 +501,6 @@ ext.applyNativeModulesAppBuildGradle = { Project project, String root = null -> java { srcDirs += generatedSrcDir } - jni { - generatedJniDir - } } } } From 58b71220bc810f7231e3e9ee54527b35eaa201f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Mon, 16 May 2022 17:43:36 +0200 Subject: [PATCH 12/13] feat: make new config nullable --- docs/dependencies.md | 6 ++--- docs/platforms.md | 6 ++--- packages/cli-config/src/schema.ts | 12 +++++----- packages/cli-types/src/android.ts | 12 +++++----- .../platform-android/native_modules.gradle | 23 +++++++++++-------- 5 files changed, 31 insertions(+), 28 deletions(-) diff --git a/docs/dependencies.md b/docs/dependencies.md index f4737fce6..ef32d8389 100644 --- a/docs/dependencies.md +++ b/docs/dependencies.md @@ -55,9 +55,9 @@ type AndroidDependencyParams = { packageImportPath?: string; packageInstance?: string; buildTypes?: string[]; - libraryName?: string; - componentDescriptors?: string[]; - androidMkPath?: string; + libraryName?: string | null; + componentDescriptors?: string[] | null; + androidMkPath?: string | null; }; ``` diff --git a/docs/platforms.md b/docs/platforms.md index a2f9700c1..053ada04f 100644 --- a/docs/platforms.md +++ b/docs/platforms.md @@ -118,8 +118,8 @@ type AndroidDependencyConfig = { packageInstance: string; dependencyConfiguration?: string; buildTypes: string[]; - libraryName?: string; - componentDescriptors?: string[]; - androidMkPath?: string; + libraryName?: string | null; + componentDescriptors?: string[] | null; + androidMkPath?: string | null; }; ``` diff --git a/packages/cli-config/src/schema.ts b/packages/cli-config/src/schema.ts index 264f4933c..c777f273d 100644 --- a/packages/cli-config/src/schema.ts +++ b/packages/cli-config/src/schema.ts @@ -83,9 +83,9 @@ export const dependencyConfig = t packageInstance: t.string(), dependencyConfiguration: t.string(), buildTypes: t.array().items(t.string()).default([]), - libraryName: t.string(), - componentDescriptors: t.array().items(t.string()), - androidMkPath: t.string(), + libraryName: t.string().allow(null), + componentDescriptors: t.array().items(t.string()).allow(null), + androidMkPath: t.string().allow(null), }) .default({}), }) @@ -134,9 +134,9 @@ export const projectConfig = t packageInstance: t.string(), dependencyConfiguration: t.string(), buildTypes: t.array().items(t.string()).default([]), - libraryName: t.string(), - componentDescriptors: t.array().items(t.string()), - androidMkPath: t.string(), + libraryName: t.string().allow(null), + componentDescriptors: t.array().items(t.string()).allow(null), + androidMkPath: t.string().allow(null), }) .allow(null), }), diff --git a/packages/cli-types/src/android.ts b/packages/cli-types/src/android.ts index c86810e1b..aa2a796f6 100644 --- a/packages/cli-types/src/android.ts +++ b/packages/cli-types/src/android.ts @@ -19,9 +19,9 @@ export type AndroidDependencyConfig = { packageInstance: string; dependencyConfiguration?: string; buildTypes: string[]; - libraryName?: string; - componentDescriptors?: string[]; - androidMkPath?: string; + libraryName?: string | null; + componentDescriptors?: string[] | null; + androidMkPath?: string | null; }; export type AndroidDependencyParams = { @@ -32,7 +32,7 @@ export type AndroidDependencyParams = { packageImportPath?: string; packageInstance?: string; buildTypes?: string[]; - libraryName?: string; - componentDescriptors?: string[]; - androidMkPath?: string; + libraryName?: string | null; + componentDescriptors?: string[] | null; + androidMkPath?: string | null; }; diff --git a/packages/platform-android/native_modules.gradle b/packages/platform-android/native_modules.gradle index 3a66757c1..3fa41853c 100644 --- a/packages/platform-android/native_modules.gradle +++ b/packages/platform-android/native_modules.gradle @@ -257,11 +257,11 @@ class ReactNativeModules { if (packages.size() > 0) { libraryIncludes = packages.collect { - "include ${it.androidMkPath}" - }.join('\n') + it.androidMkPath ? "include ${it.androidMkPath}" : null + }.minus(null).join('\n') libraryModules = packages.collect { - "${codegenLibPrefix}${it.libraryName}" - }.join(" \\\n ") + it.libraryName ? "${codegenLibPrefix}${it.libraryName}" : null + }.minus(null).join(" \\\n ") } String generatedFileContents = generatedFileContentsTemplate @@ -285,21 +285,24 @@ class ReactNativeModules { if (packages.size() > 0) { rncliCppIncludes = packages.collect { + if (!it.libraryName) { + return null + } def result = "#include <${it.libraryName}.h>" - if (it.componentDescriptors.size() > 0) { + if (it.componentDescriptors && it.componentDescriptors.size() > 0) { result += "\n#include <${codegenReactComponentsDir}/${it.libraryName}/${codegenComponentDescriptorsHeaderFile}>" } result - }.join('\n') + }.minus(null).join('\n') rncliCppModuleProviders = packages.collect { - """ auto module_${it.libraryName} = ${it.libraryName}_ModuleProvider(moduleName, params); + it.libraryName ? """ auto module_${it.libraryName} = ${it.libraryName}_ModuleProvider(moduleName, params); if (module_${it.libraryName} != nullptr) { return module_${it.libraryName}; - }""" - }.join("\n") + }""" : null + }.minus(null).join("\n") rncliCppComponentDescriptors = packages.collect { def result = "" - if (it.componentDescriptors.size() > 0) { + if (it.componentDescriptors && it.componentDescriptors.size() > 0) { result += it.componentDescriptors.collect { " providerRegistry->add(concreteComponentDescriptorProvider<${it}>());" }.join('\n') From 7f70fe5f93465c78eb68ea3e94a25c31071ba221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Wed, 18 May 2022 11:38:11 +0200 Subject: [PATCH 13/13] chore: update docs on how to disable new arch autolinking --- docs/autolinking.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/autolinking.md b/docs/autolinking.md index 63a11bd0e..4e763efd5 100644 --- a/docs/autolinking.md +++ b/docs/autolinking.md @@ -16,6 +16,7 @@ yarn react-native run-android That's it. No more editing build config files to use native code. Also, removing a library is similar to adding a library: + ```sh # uninstall yarn remove react-native-webview @@ -101,6 +102,27 @@ module.exports = { }; ``` +## How can I disable autolinking for new architecture (Fabric, TurboModules)? + +It happens that packages come with their own linking setup for the new architecture. To disable autolinking in such cases (currently `react-native-screens`, `react-native-safe-area-context`, `react-native-reanimated`, `react-native-gesture-handler`), update your `react-native.config.js`'s `dependencies` entry to look like this: + +```js +// react-native.config.js +module.exports = { + dependencies: { + 'fabric-or-tm-library': { + platforms: { + android: { + libraryName: null, + componentDescriptors: null, + androidMkPath: null, + }, + }, + }, + }, +}; +``` + ## How can I autolink a local library? We can leverage CLI configuration to make it "see" React Native libraries that are not part of our 3rd party dependencies. To do so, update your `react-native.config.js`'s `dependencies` entry to look like this: