build and bundle (#44720)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/44720

Bug fixes to bootstrap, build and bundle on iOS.

Changelog: [Internal]

Reviewed By: cipolleschi

Differential Revision: D57915363

fbshipit-source-id: 1c82f0020572d7d9bf599a7c568dfc6f3a3292e8
This commit is contained in:
Blake Friedman
2024-06-03 06:01:43 -07:00
committed by Facebook GitHub Bot
parent 910cde6134
commit ec1742a6bb
3 changed files with 69 additions and 21 deletions
+23 -7
View File
@@ -41,14 +41,17 @@ type BundlerOptions = {
outputBundle: string,
cwd: string,
target: 'hermes' | 'jsc',
jsvm: 'hermes' | 'jsc',
hermes?: HermesConfig,
...Bundler,
};
type HermesConfig = {
// iOS: Pods/hermes-engine/destroot/bin/hermesc
// Path where hermes is is installed
// iOS: Pods/hermes-engine
path: string,
// iOS: <hermes.path>/destroot/bin/hermesc
hermesc: string,
};
@@ -124,7 +127,7 @@ const bundleApp = (
// to then be converted to bytecode in the outputBundle. Otherwise just write to
// the outputBundle directly.
let output =
options.target === 'hermes' ? options.outputJsBundle : options.outputBundle;
options.jsvm === 'hermes' ? options.outputJsBundle : options.outputBundle;
// TODO: Fix this by not using Metro CLI, which appends a .js extension
if (output === options.outputJsBundle && !output.endsWith('.js')) {
@@ -146,7 +149,7 @@ const bundleApp = (
'--out',
output,
];
if (options.target === 'hermes' && !options.dev) {
if (options.jsvm === 'hermes' && !options.dev) {
// Hermes doesn't require JS minification
args.push('--minify', 'false');
} else {
@@ -159,12 +162,25 @@ const bundleApp = (
}),
};
if (options.target === 'jsc') {
if (options.jsvm === 'jsc') {
return bundle;
}
// $FlowIgnore[incompatible-use] We know it's a Hermes config
const hermesc: string = options.hermes.hermesc;
if (options.hermes?.path == null || options.hermes?.hermesc == null) {
throw new Error('If jsvm == "hermes", hermes config must be provided.');
}
const hermes: HermesConfig = options.hermes;
const isHermesInstalled: boolean = fs.existsSync(hermes.path);
if (!isHermesInstalled) {
throw new Error(
'Hermes Pod must be installed before bundling.\n' +
'Did you forget to bootstrap?',
);
}
const hermesc: string = path.join(hermes.path, hermes.hermesc);
/*
* Hermes only tasks:
+43 -5
View File
@@ -24,7 +24,7 @@ type AppleBuildOptions = {
name: string,
mode: AppleBuildMode,
scheme?: string,
destination?: string, // Device or Simulator or UUID
destination: 'device' | 'simulator' | string,
...AppleOptions,
};
@@ -32,6 +32,7 @@ type AppleBootstrapOption = {
// Enabled by default
hermes: boolean,
newArchitecture: boolean,
frameworks?: 'static' | 'dynamic',
...AppleOptions,
};
@@ -51,6 +52,23 @@ type AppleOptions = {
env?: {[key: string]: string | void, ...},
};
function checkPodfileInSyncWithManifest(
lockfilePath: string,
manifestLockfilePath: string,
) {
try {
const expected = fs.readFileSync(lockfilePath, 'utf8');
const found = fs.readFileSync(manifestLockfilePath, 'utf8');
if (expected !== found) {
throw new Error(
'Please run: yarn bootstrap ios, Podfile.lock and Pods/Manifest.lock are out of sync',
);
}
} catch (e) {
throw new Error('Please run: yarn run boostrap ios: ' + e.message);
}
}
const FIRST = 1,
SECOND = 2,
THIRD = 3;
@@ -79,8 +97,12 @@ export const tasks = {
installDependencies: task(THIRD, 'Install CocoaPods dependencies', () => {
const env = {
RCT_NEW_ARCH_ENABLED: options.newArchitecture ? '1' : '0',
HERMES: options.hermes ? '1' : '0',
USE_FRAMEWORKS: options.frameworks,
USE_HERMES: options.hermes ? '1' : '0',
};
if (options.frameworks == null) {
delete env.USE_FRAMEWORKS;
}
return execa('bundle', ['exec', 'pod', 'install'], {
cwd: options.cwd,
env,
@@ -112,22 +134,38 @@ export const tasks = {
/* eslint-disable-next-line no-bitwise */
fs.constants.F_OK | fs.constants.R_OK,
);
} catch {
throw new Error('Please run: yarn run boostrap ios');
} catch (e) {
throw new Error('Please run: yarn run boostrap ios: ' + e.message);
}
}
checkPodfileInSyncWithManifest(
path.join(options.cwd, 'Podfile.lock'),
path.join(options.cwd, 'Pods/Manifest.lock'),
);
}),
build: task(SECOND, 'build an app artifact', () => {
const _args = [
options.isWorkspace ? '-workspace' : '-project',
options.name,
'-configuration',
options.mode,
];
if (options.scheme != null) {
_args.push('-scheme', options.scheme);
}
if (options.destination != null) {
_args.push('-destination', options.destination);
// The user doesn't want a generic target, they know better.
switch (options.destination) {
case 'simulator':
_args.push('-sdk', 'iphonesimulator');
break;
case 'device':
default:
_args.push('-destination', options.destination);
break;
}
}
_args.push(...args);
return execa('xcodebuild', _args, {cwd: options.cwd, env: options.env});
}),
+3 -9
View File
@@ -148,16 +148,10 @@ build
outputSourceMap: settings.bundleResourceDir,
outputBundle: binaryBundlePath,
dev: true,
target: 'hermes',
jsvm: 'hermes',
hermes: {
hermesc: path.join(
cwd.ios,
'Pods',
'hermes-engine',
'build_host_hermesc',
'bin',
'hermesc',
),
path: path.join(cwd.ios, 'Pods/hermes-engine'),
hermesc: 'build_host_hermesc/bin/hermesc',
},
}),
);