diff --git a/packages/core-cli-utils/src/private/app.js b/packages/core-cli-utils/src/private/app.js index 3b727e61283..8db159563ff 100644 --- a/packages/core-cli-utils/src/private/app.js +++ b/packages/core-cli-utils/src/private/app.js @@ -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: /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: diff --git a/packages/core-cli-utils/src/private/apple.js b/packages/core-cli-utils/src/private/apple.js index b4ca9e60b0d..c6a41b74370 100644 --- a/packages/core-cli-utils/src/private/apple.js +++ b/packages/core-cli-utils/src/private/apple.js @@ -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}); }), diff --git a/packages/helloworld/cli.flow.js b/packages/helloworld/cli.flow.js index adaeb9d5d43..e3b1ccfaf62 100644 --- a/packages/helloworld/cli.flow.js +++ b/packages/helloworld/cli.flow.js @@ -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', }, }), );