From 1dcdcbd4f2a258696b9e7270f13926f3c8d02bc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ramos?= Date: Fri, 13 May 2022 14:43:14 -0700 Subject: [PATCH] iOS: Use pre-built hermesc if available (#33827) Summary: Use pre-built hermesc if available by generating a ImportHermesc.cmake file that points to the hermesc binary. Recent `react-native` releases should have hermesc available in sdks/hermesc. Hermes build scripts have been updated to support a `HERMES_OVERRIDE_HERMESC_PATH` envvar which can point to this generated ImportHermesc.cmake file. Pull Request resolved: https://github.com/facebook/react-native/pull/33827 Changelog: [iOS] [Changed] - Use pre-built HermesC if available in current React Native release Reviewed By: cortinico Differential Revision: D36024615 fbshipit-source-id: 476569f73309f9bd142f28cb02d1f7d57b6cbc6a --- .gitignore | 3 ++- scripts/hermes/hermes-utils.js | 26 +++++++++++++++++++ scripts/hermes/prepare-hermes-for-build.js | 7 +++++ sdks/hermes-engine/hermes-engine.podspec | 6 +++++ .../utils/build-apple-framework.sh | 9 +++++-- 5 files changed, 48 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 0fbaf688032..c954afb75a0 100644 --- a/.gitignore +++ b/.gitignore @@ -115,8 +115,9 @@ package-lock.json /packages/rn-tester/NativeModuleExample/ScreenshotManagerSpec* # Additional SDKs -/sdks/hermes /sdks/download +/sdks/hermes +/sdks/hermesc # Visual studio .vscode diff --git a/scripts/hermes/hermes-utils.js b/scripts/hermes/hermes-utils.js index 5729a3ec83a..84fd59d520f 100644 --- a/scripts/hermes/hermes-utils.js +++ b/scripts/hermes/hermes-utils.js @@ -18,6 +18,12 @@ const HERMES_DIR = path.join(SDKS_DIR, 'hermes'); const HERMES_TAG_FILE_PATH = path.join(SDKS_DIR, '.hermesversion'); const HERMES_TARBALL_BASE_URL = 'https://github.com/facebook/hermes/tarball/'; const HERMES_TARBALL_DOWNLOAD_DIR = path.join(SDKS_DIR, 'download'); +const MACOS_BIN_DIR = path.join(SDKS_DIR, 'hermesc', 'osx-bin'); +const MACOS_HERMESC_PATH = path.join(MACOS_BIN_DIR, 'hermesc'); +const MACOS_IMPORT_HERMESC_PATH = path.join( + MACOS_BIN_DIR, + 'ImportHermesc.cmake', +); function prepareFileSystem() { if (!fs.existsSync(SDKS_DIR)) { @@ -135,11 +141,31 @@ function copyBuildScripts() { ); } +function shouldUsePrebuiltHermesC(os) { + if (os === 'macos') { + return fs.existsSync(MACOS_HERMESC_PATH); + } + + return false; +} + +function configureMakeForPrebuiltHermesC() { + const IMPORT_HERMESC_TEMPLATE = `add_executable(native-hermesc IMPORTED) +set_target_properties(native-hermesc PROPERTIES + IMPORTED_LOCATION "${MACOS_HERMESC_PATH}" + )`; + + fs.mkdirSync(MACOS_BIN_DIR, {recursive: true}); + fs.writeFileSync(MACOS_IMPORT_HERMESC_PATH, IMPORT_HERMESC_TEMPLATE); +} + module.exports = { + configureMakeForPrebuiltHermesC, copyBuildScripts, downloadHermesTarball, expandHermesTarball, getHermesTagSHA, readHermesTag, setHermesTag, + shouldUsePrebuiltHermesC, }; diff --git a/scripts/hermes/prepare-hermes-for-build.js b/scripts/hermes/prepare-hermes-for-build.js index 8fc505853ed..3a244225800 100644 --- a/scripts/hermes/prepare-hermes-for-build.js +++ b/scripts/hermes/prepare-hermes-for-build.js @@ -14,11 +14,18 @@ * iOS build pipeline on macOS. */ const { + configureMakeForPrebuiltHermesC, copyBuildScripts, downloadHermesTarball, expandHermesTarball, + shouldUsePrebuiltHermesC, } = require('./hermes-utils'); downloadHermesTarball(); expandHermesTarball(); copyBuildScripts(); + +if (shouldUsePrebuiltHermesC('macos')) { + console.log('[Hermes] Using pre-built HermesC'); + configureMakeForPrebuiltHermesC(); +} diff --git a/sdks/hermes-engine/hermes-engine.podspec b/sdks/hermes-engine/hermes-engine.podspec index f98e0486bce..96f2bd5249a 100644 --- a/sdks/hermes-engine/hermes-engine.podspec +++ b/sdks/hermes-engine/hermes-engine.podspec @@ -18,6 +18,8 @@ end Pod::UI.puts '[Hermes] Hermes needs to be compiled, installing hermes-engine may take a while...'.yellow if Object.const_defined?("Pod::UI") +import_hermesc_path=File.join(__dir__, "../hermesc/osx-bin/ImportHermesc.cmake") + Pod::Spec.new do |spec| spec.name = "hermes-engine" spec.version = "1000.0.0-#{hermes_tag_sha.slice(0,6)}" @@ -43,6 +45,10 @@ Pod::Spec.new do |spec| # See `build-apple-framework.sh` for details DEBUG=#{HermesHelper::BUILD_TYPE == :debug} + # Set HERMES_OVERRIDE_HERMESC_PATH if pre-built HermesC is available + #{File.exist?(import_hermesc_path) ? "export HERMES_OVERRIDE_HERMESC_PATH=#{import_hermesc_path}" : ""} + #{File.exist?(import_hermesc_path) ? "echo \"Overriding HermesC path...\"" : ""} + # Build iOS framework ./utils/build-ios-framework.sh diff --git a/sdks/hermes-engine/utils/build-apple-framework.sh b/sdks/hermes-engine/utils/build-apple-framework.sh index bd506600442..364b067653b 100755 --- a/sdks/hermes-engine/utils/build-apple-framework.sh +++ b/sdks/hermes-engine/utils/build-apple-framework.sh @@ -11,6 +11,7 @@ else fi NUM_CORES=$(sysctl -n hw.ncpu) +IMPORT_HERMESC_PATH=${HERMES_OVERRIDE_HERMESC_PATH:-$PWD/build_host_hermesc/ImportHermesc.cmake} function get_release_version { ruby -rcocoapods-core -rjson -e "puts Pod::Specification.from_file('hermes-engine.podspec').version" @@ -57,7 +58,7 @@ function configure_apple_framework { -DHERMES_BUILD_APPLE_FRAMEWORK:BOOLEAN=true \ -DHERMES_BUILD_APPLE_DSYM:BOOLEAN=true \ -DHERMES_ENABLE_TOOLS:BOOLEAN="$build_cli_tools" \ - -DIMPORT_HERMESC:PATH="$PWD/build_host_hermesc/ImportHermesc.cmake" \ + -DIMPORT_HERMESC:PATH="$IMPORT_HERMESC_PATH" \ -DCMAKE_INSTALL_PREFIX:PATH=../destroot \ -DCMAKE_BUILD_TYPE="$BUILD_TYPE" } @@ -66,8 +67,12 @@ function configure_apple_framework { function build_apple_framework { echo "Building framework for $1 with architectures: $2" + # Only build host HermesC if no file found at $IMPORT_HERMESC_PATH + [ ! -f "$IMPORT_HERMESC_PATH" ] && build_host_hermesc - [ ! -f "$PWD/build_host_hermesc/ImportHermesc.cmake" ] && + + # Confirm ImportHermesc.cmake is now available. + [ ! -f "$IMPORT_HERMESC_PATH" ] && echo "Host hermesc is required to build apple frameworks!" configure_apple_framework "$1" "$2" "$3"