Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,18 @@ function getInputFiles(appPath /*: string */, appPkgJson /*: $FlowFixMe */) {
return `[${list}]`;
}

function codegenScripts(appPath /*: string */, outputPath /*: string */) {
const relativeAppPath = path.relative(outputPath, appPath);
function codegenScripts(appPath /*: string */, baseOutputPath /*: string */) {
const relativeAppPath = path.relative(baseOutputPath, appPath);
const relativeReactNativeRootFolder = path.relative(
baseOutputPath,
REACT_NATIVE_PACKAGE_ROOT_FOLDER,
);
return `<<-SCRIPT
pushd "$PODS_ROOT/../" > /dev/null
RCT_SCRIPT_POD_INSTALLATION_ROOT=$(pwd)
popd >/dev/null

export RCT_SCRIPT_RN_DIR="$RCT_SCRIPT_POD_INSTALLATION_ROOT/${path.relative(outputPath, REACT_NATIVE_PACKAGE_ROOT_FOLDER)}"
export RCT_SCRIPT_RN_DIR="$RCT_SCRIPT_POD_INSTALLATION_ROOT/${relativeReactNativeRootFolder}"
export RCT_SCRIPT_APP_PATH="$RCT_SCRIPT_POD_INSTALLATION_ROOT/${relativeAppPath.length === 0 ? '.' : relativeAppPath}"
export RCT_SCRIPT_OUTPUT_DIR="$RCT_SCRIPT_POD_INSTALLATION_ROOT"
export RCT_SCRIPT_TYPE="withCodegenDiscovery"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const path = require('path');
function execute(
projectRoot /*: string */,
targetPlatform /*: string */,
baseOutputPath /*: string */,
optionalBaseOutputPath /*: ?string */,
source /*: string */,
runReactNativeCodegen /*: boolean */ = true,
) {
Expand All @@ -88,32 +88,35 @@ function execute(
buildCodegenIfNeeded();
}

const reactNativeConfig = readReactNativeConfig(
projectRoot,
// NOTE: Used to load `build/generated/autolinking/autolinking.json` generated by `scripts/cocoapods/autolinking.rb`
// If we have RCT_SCRIPT_OUTPUT_DIR (set in `react_native_pods_utils/script_phases.sh`, it takes precedence, otherwise
// we search for the `autolinking.json` output in the `baseOutputPath`
process.env.RCT_SCRIPT_OUTPUT_DIR != null &&
process.env.RCT_SCRIPT_OUTPUT_DIR.length > 0
? process.env.RCT_SCRIPT_OUTPUT_DIR
: baseOutputPath,
);

const codegenEnabledLibraries = findCodegenEnabledLibraries(
pkgJson,
projectRoot,
baseOutputPath,
reactNativeConfig,
);

if (codegenEnabledLibraries.length === 0) {
codegenLog('No codegen-enabled libraries found.', true);
}

let platforms =
const platforms =
targetPlatform === 'all' ? supportedPlatforms : [targetPlatform];

// NOTE: We cache the external libraries search (which may not run) across platforms to not change previous behaviour
const externalLibrariesCache /*: { current?: ?Array<$FlowFixMe> } */ = {};

for (const platform of platforms) {
// NOTE: This needs to be computed per-platform since `platform` can alter the path via a `package.json:codegenConfig.outputDir[platform]` override
const baseOutputPath = computeBaseOutputPath(
projectRoot,
optionalBaseOutputPath,
pkgJson,
platform,
);
const reactNativeConfig = readReactNativeConfig(
projectRoot,
baseOutputPath,
);
const codegenEnabledLibraries = findCodegenEnabledLibraries(
pkgJson,
projectRoot,
baseOutputPath,
reactNativeConfig,
externalLibrariesCache,
);
if (codegenEnabledLibraries.length === 0) {
codegenLog('No codegen-enabled libraries found.', true);
}

const disabledLibraries = findDisabledLibrariesByPlatform(
reactNativeConfig,
platform,
Expand Down Expand Up @@ -208,22 +211,38 @@ function readOutputDirFromPkgJson(
return null;
}

function computeOutputPath(
function computeBaseOutputPath(
projectRoot /*: string */,
baseOutputPath /*: string */,
optionalBaseOutputPath /*: ?string */,
pkgJson /*: $FlowFixMe */,
platform /*: string */,
) {
if (baseOutputPath == null) {
if (
process.env.RCT_SCRIPT_OUTPUT_DIR != null &&
process.env.RCT_SCRIPT_OUTPUT_DIR.length > 0
) {
return process.env.RCT_SCRIPT_OUTPUT_DIR;
}
let baseOutputPath /*: string */;
if (optionalBaseOutputPath == null) {
const outputDirFromPkgJson = readOutputDirFromPkgJson(pkgJson, platform);
if (outputDirFromPkgJson != null) {
// $FlowFixMe[reassign-const]
baseOutputPath = path.join(projectRoot, outputDirFromPkgJson);
} else {
// $FlowFixMe[reassign-const]
baseOutputPath = projectRoot;
}
} else {
baseOutputPath = optionalBaseOutputPath;
}
return baseOutputPath;
}

function computeOutputPath(
projectRoot /*: string */,
baseOutputPath /*: string */,
pkgJson /*: $FlowFixMe */,
platform /*: string */,
) /*: string */ {
if (pkgJsonIncludesGeneratedCode(pkgJson)) {
// Don't create nested directories for libraries to make importing generated headers easier.
return baseOutputPath;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,11 @@ function cleanupEmptyFilesAndFolders(filepath /*: string */) {
}

function readGeneratedAutolinkingOutput(
projectRoot /*: string */,
baseOutputPath /*: string */,
) /*: $FlowFixMe */ {
// NOTE: Generated by scripts/cocoapods/autolinking.rb in list_native_modules (called by use_native_modules)
// The `baseOutputPath` is based on a CLI argument and optional
const autolinkingGeneratedPath = path.resolve(
baseOutputPath,
'build/generated/autolinking/autolinking.json',
Expand All @@ -120,7 +122,10 @@ function readReactNativeConfig(
projectRoot /*: string */,
baseOutputPath /*: string */,
) /*: $FlowFixMe */ {
const autolinkingOutput = readGeneratedAutolinkingOutput(baseOutputPath);
const autolinkingOutput = readGeneratedAutolinkingOutput(
projectRoot,
baseOutputPath,
);
const rnConfigFilePath = path.resolve(projectRoot, 'react-native.config.js');
if (autolinkingOutput) {
return autolinkingOutput;
Expand All @@ -141,6 +146,7 @@ function findCodegenEnabledLibraries(
projectRoot /*: string */,
baseOutputPath /*: string */,
reactNativeConfig /*: $FlowFixMe */,
externalLibrariesCache /*: { current?: ?Array<$FlowFixMe> } */ = {},
) /*: Array<$FlowFixMe> */ {
const projectLibraries = findProjectRootLibraries(pkgJson, projectRoot);
if (pkgJsonIncludesGeneratedCode(pkgJson)) {
Expand All @@ -149,8 +155,14 @@ function findCodegenEnabledLibraries(
const libraries = [...projectLibraries];
// If we ran autolinking, we shouldn't try to run our own "autolinking-like"
// library discovery
if (!readGeneratedAutolinkingOutput(baseOutputPath)) {
libraries.push(...findExternalLibraries(pkgJson, projectRoot));
if (!readGeneratedAutolinkingOutput(projectRoot, baseOutputPath)) {
const externalLibraries =
externalLibrariesCache.current ??
(externalLibrariesCache.current = findExternalLibraries(
pkgJson,
projectRoot,
));
libraries.push(...externalLibraries);
}
libraries.push(
...findLibrariesFromReactNativeConfig(projectRoot, reactNativeConfig),
Expand Down
Loading