Skip to content

Commit

Permalink
Create genrule to generate appmodules.so (facebook#41466)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: facebook#41466

## Context
In open source, all apps use the same turbomodulemanager delegate (i.e: the default delegate).

This diff introduces the buck infra that makes the oss default delegate work for meta apps.

Concretely, we are going to make React Native use the same  delegate for **all** Meta apps.

Each Meta app will:
1. At build time, generate a unique TMProvider map
2. At app init time, initialize the default delegate with the TMProvider map.

## Implementation
**Step facebook#1:** At build time, generate a unique TMProvider map

**Insight:** Buck genrules can accept, as input, the output of a buck query.

So, here's how we get this done:
1. Buck query (i.e: input to Genrule): Given the app's deps, query all the schemas in the app.
2. Genrule: Read the schemas to generate the TMProvider map. The TMProvider map will also contain **all** the app's C++ module codegen.

Concretely:
1. This diff introduces a macro: rn_codegen_appmodules(deps).
2. rn_codegen_appmodules(deps) generates appmodules.so, which contains the TMProvider map.

**Step facebook#2:** At app init time, initialize the default delegate with the TMProvider map.

This is how we'll initialize the DefaultTurboModuleManagerDelegate:
1. DefaultTurboModuleManagerDelegate will load appmodules.so during init.
2. When loaded, appmodules.so will assign the code-generated TMProvider map to DefaultTurboModuleManagerDelegate.

## Impact
This should allow us to:
1. Get one step closer to getting rid of the `js1 build turbomodule-manager-delegates --target <app>` script
3. Remove the TurboModuleManagerDelegate from React Native's public API. (Because we use one delegate for all React Native apps in Meta and OSS)

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D50988397

fbshipit-source-id: 0ca5dec14e2dae89ec97f5d39a182c7937c5c7bf
  • Loading branch information
RSNara authored and Othinn committed Jan 9, 2024
1 parent 289b741 commit b1a3a4e
Showing 1 changed file with 85 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/

'use strict';

import type {
ComponentSchema,
NativeModuleSchema,
SchemaType,
} from '../../CodegenSchema.js';

const assert = require('assert');
const fs = require('fs');
const util = require('util');

const {values: args} = util.parseArgs({
options: {
platform: {
type: 'string',
},
output: {
type: 'string',
},
['schema-query']: {
type: 'string',
},
},
});
if (!['iOS', 'android'].includes(args.platform)) {
throw new Error(`Invalid platform ${args.platform}`);
}
const platform = args.platform;
const output = args.output;
const schemaQuery: string = args['schema-query'];

if (!schemaQuery.startsWith('@')) {
throw new Error(
"The argument provided to --schema-query must be a filename that starts with '@'.",
);
}

const schemaQueryOutputFile = schemaQuery.replace(/^@/, '');
const schemaQueryOutput = fs.readFileSync(schemaQueryOutputFile, 'utf8');

const schemaFiles = schemaQueryOutput.split(' ');
const modules: {
[hasteModuleName: string]: NativeModuleSchema | ComponentSchema,
} = {};
const specNameToFile: {[hasteModuleName: string]: string} = {};

for (const file of schemaFiles) {
const schema: SchemaType = JSON.parse(fs.readFileSync(file, 'utf8'));

if (schema.modules) {
for (const specName in schema.modules) {
const module = schema.modules[specName];
if (modules[specName]) {
assert.deepEqual(
module,
modules[specName],
`App contained two specs with the same file name '${specName}'. Schemas: ${specNameToFile[specName]}, ${file}. Please rename one of the specs.`,
);
}

if (
module.excludedPlatforms &&
module.excludedPlatforms.indexOf(platform) >= 0
) {
continue;
}

modules[specName] = module;
specNameToFile[specName] = file;
}
}
}

fs.writeFileSync(output, JSON.stringify({modules}, null, 2));

0 comments on commit b1a3a4e

Please sign in to comment.