From ce4aa9317370cbbf4e8c80c0a8db3db5a80ef70b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ramos?= Date: Thu, 22 Sep 2022 13:41:51 -0700 Subject: [PATCH] Build separate tarballs for Hermes with and without debugger (#34704) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/34704 Create separate hermes-engine tarballs for release and debug builds, and only include the debugger in debug builds. Changes the hermes-engine podspec to use a debug Hermes build by default in order to preserve the inclusion of the debugger. Upcoming changes should split the hermes-engine Pod to allow Xcode to use release and debug builds as needed. Changelog: [iOS][Changed] - Use debug Hermes builds by default Reviewed By: cipolleschi Differential Revision: D39326467 fbshipit-source-id: 94c5fe7db80194d22fced6717c5efc7accd36d48 --- .circleci/config.yml | 160 ++++++++++++++---- sdks/hermes-engine/hermes-engine.podspec | 14 +- .../utils/build-apple-framework.sh | 18 +- 3 files changed, 141 insertions(+), 51 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 424227e1a9b7fb..2aa83b58a5b508 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -47,13 +47,27 @@ references: checkout_cache_key: &checkout_cache_key v1-checkout gems_cache_key: &gems_cache_key v1-gems-{{ checksum "Gemfile.lock" }} gradle_cache_key: &gradle_cache_key v1-gradle-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}-{{ checksum "ReactAndroid/gradle.properties" }} - hermes_cache_key: &hermes_cache_key v3-hermes-{{ .Environment.CIRCLE_JOB }}-{{ checksum "/tmp/hermes/hermesversion" }} + hermes_workspace_cache_key: &hermes_workspace_cache_key v4-hermes-{{ .Environment.CIRCLE_JOB }}-{{ checksum "/tmp/hermes/hermesversion" }} + hermes_workspace_debug_cache_key: &hermes_workspace_debug_cache_key v1-hermes-{{ .Environment.CIRCLE_JOB }}-debug-{{ checksum "/tmp/hermes/hermesversion" }} + hermes_workspace_release_cache_key: &hermes_workspace_release_cache_key v1-hermes-{{ .Environment.CIRCLE_JOB }}-release-{{ checksum "/tmp/hermes/hermesversion" }} hermes_windows_cache_key: &hermes_windows_cache_key v3-hermes-{{ .Environment.CIRCLE_JOB }}-{{ checksum "tmp/hermes/hermesversion" }} - hermes_tarball_cache_key: &hermes_tarball_cache_key v3-hermes-tarball-{{ checksum "/tmp/hermes/hermesversion" }} + hermes_tarball_debug_cache_key: &hermes_tarball_debug_cache_key v2-hermes-tarball-debug-{{ checksum "/tmp/hermes/hermesversion" }} + hermes_tarball_release_cache_key: &hermes_tarball_release_cache_key v1-hermes-tarball-release-{{ checksum "/tmp/hermes/hermesversion" }} pods_cache_key: &pods_cache_key v8-pods-{{ .Environment.CIRCLE_JOB }}-{{ checksum "packages/rn-tester/Podfile.lock.bak" }}-{{ checksum "packages/rn-tester/Podfile" }} windows_yarn_cache_key: &windows_yarn_cache_key v1-win-yarn-cache-{{ arch }}-{{ checksum "yarn.lock" }} yarn_cache_key: &yarn_cache_key v5-yarn-cache-{{ .Environment.CIRCLE_JOB }} + cache_paths: + hermes_workspace_macos_cache_paths: &hermes_workspace_macos_cache_paths + - ~/react-native/sdks/hermes/build_host_hermesc + - ~/react-native/sdks/hermes/build_iphoneos + - ~/react-native/sdks/hermes/build_catalyst + - ~/react-native/sdks/hermes/build_iphonesimulator + - ~/react-native/sdks/hermes/build_macosx + - ~/react-native/sdks/hermes/destroot + hermes_tarball_cache_paths: &hermes_tarball_cache_paths + - /tmp/hermes/hermes-runtime-darwin/ + # ------------------------- # Filters # ------------------------- @@ -252,34 +266,68 @@ commands: set_tarball_path: type: boolean default: False + flavor: + type: string + default: "Debug" steps: - - restore_cache: - keys: - - *hermes_tarball_cache_key + - when: + condition: + equal: [ << parameters.flavor >>, "Debug"] + steps: + - restore_cache: + keys: + - *hermes_tarball_debug_cache_key + - when: + condition: + equal: [ << parameters.flavor >>, "Release"] + steps: + - restore_cache: + keys: + - *hermes_tarball_release_cache_key - when: condition: << parameters.set_tarball_path >> steps: - run: - name: Set HERMES_TARBALL_PATH if present + name: Set HERMES_ENGINE_TARBALL_PATH if present command: | BASE_PATH=/tmp/hermes/hermes-runtime-darwin/ if [ ! -d $BASE_PATH ]; then echo "Hermes tarball base path not present ($BASE_PATH). Build it from source." exit 0 fi - TARBALL=$(ls /tmp/hermes/hermes-runtime-darwin/) - TARBALL_PATH=$BASE_PATH$TARBALL + if [[ << parameters.flavor >> == "Debug" ]]; then + TARBALL_FILENAME=hermes-runtime-darwin-debug-*.tar.gz + elif [[ << parameters.flavor >> == "Release" ]]; then + TARBALL_FILENAME=hermes-runtime-darwin-release-*.tar.gz + else + echo "Unsupported build type << parameters.flavor >>." + exit 0 + fi + # /tmp/hermes/hermes-runtime-darwin/hermes-runtime-darwin-release-v0.70.0.tar.gz + # /tmp/hermes/hermes-runtime-darwin/hermes-runtime-darwin-debug-v0.70.0.tar.gz + TARBALL_PATH=$(ls $BASE_PATH$TARBALL_FILENAME) if [ ! -f $TARBALL_PATH ]; then echo "Hermes tarball not present ($TARBALL_PATH). Build it from source." exit 0 fi + echo "Found Hermes tarball at $TARBALL_PATH" echo "export HERMES_ENGINE_TARBALL_PATH=$TARBALL_PATH" >> $BASH_ENV - steps: << parameters.steps >> - - save_cache: - key: *hermes_tarball_cache_key - paths: - - /tmp/hermes/hermes-runtime-darwin/ + - when: + condition: + equal: [ << parameters.flavor >>, "Debug"] + steps: + - save_cache: + key: *hermes_tarball_debug_cache_key + paths: *hermes_tarball_cache_paths + - when: + condition: + equal: [ << parameters.flavor >>, "Release"] + steps: + - save_cache: + key: *hermes_tarball_release_cache_key + paths: *hermes_tarball_cache_paths # ------------------------- # JOBS @@ -963,7 +1011,7 @@ jobs: fi cat /tmp/hermes/hermesversion - restore_cache: - key: *hermes_cache_key + key: *hermes_workspace_cache_key - run: name: Download Hermes tarball command: | @@ -973,7 +1021,7 @@ jobs: cat /tmp/hermes/hermesversion - save_cache: - key: *hermes_cache_key + key: *hermes_workspace_cache_key paths: - /tmp/hermes/download/ - /tmp/hermes/hermes/ @@ -998,7 +1046,7 @@ jobs: libreadline-dev libicu-dev zip python3 - *attach_hermes_workspace - restore_cache: - key: *hermes_cache_key + key: *hermes_workspace_cache_key - run: name: Set up workspace command: | @@ -1017,7 +1065,7 @@ jobs: cp /tmp/hermes/build/bin/hermesc /tmp/hermes/linux64-bin/. fi - save_cache: - key: *hermes_cache_key + key: *hermes_workspace_cache_key paths: - /tmp/hermes/linux64-bin/ - /tmp/hermes/hermes/destroot/ @@ -1029,61 +1077,98 @@ jobs: - linux64-bin build_hermes_macos: + parameters: + flavor: + type: string + default: "Debug" executor: reactnativeios environment: - HERMES_WS_DIR: *hermes_workspace_root steps: - checkout_code_with_cache - *attach_hermes_workspace - - restore_cache: - key: *hermes_cache_key + - when: + condition: + equal: [ << parameters.flavor >>, "Debug"] + steps: + - restore_cache: + keys: + - *hermes_workspace_debug_cache_key + - when: + condition: + equal: [ << parameters.flavor >>, "Release"] + steps: + - restore_cache: + keys: + - *hermes_workspace_release_cache_key - run: name: Set up workspace command: | mkdir -p /tmp/hermes/osx-bin mkdir -p ~/react-native/sdks/hermes cp -r $HERMES_WS_DIR/hermes/* ~/react-native/sdks/hermes/. - - run: - name: Install dependencies - command: | - brew install cmake + - brew_install: + package: cmake - with_hermes_tarball_cache_span: + flavor: << parameters.flavor >> steps: - run: name: Build the Hermes iOS frameworks command: | cd ~/react-native/sdks/hermes - ./utils/build-ios-framework.sh + BUILD_TYPE="<< parameters.flavor >>" ./utils/build-ios-framework.sh - run: name: Build the Hermes Mac frameworks command: | cd ~/react-native/sdks/hermes - ./utils/build-mac-framework.sh + BUILD_TYPE="<< parameters.flavor >>" ./utils/build-mac-framework.sh cp build_macosx/bin/hermesc /tmp/hermes/osx-bin/. - run: name: Package the Hermes Apple frameworks command: | + echo "Packaging Hermes Apple frameworks for << parameters.flavor >> build type" + cd ~/react-native/sdks/hermes - . ./utils/build-apple-framework.sh + BUILD_TYPE="<< parameters.flavor >>" source ./utils/build-apple-framework.sh mkdir -p /tmp/cocoapods-package-root/destroot mkdir -p /tmp/hermes/output cp -R ./destroot /tmp/cocoapods-package-root cp LICENSE /tmp/cocoapods-package-root - tar -C /tmp/cocoapods-package-root/ -czvf /tmp/hermes/output/hermes-runtime-darwin-v$(get_release_version).tar.gz . + if [[ << parameters.flavor >> == "Debug" ]]; then + TARBALL_FILENAME=hermes-runtime-darwin-debug-v$(get_release_version).tar.gz + elif [[ << parameters.flavor >> == "Release" ]]; then + TARBALL_FILENAME=hermes-runtime-darwin-release-v$(get_release_version).tar.gz + else + echo "Unsupported build type << parameters.flavor >>." + exit 0 + fi + + tar -C /tmp/cocoapods-package-root/ -czvf /tmp/hermes/output/$TARBALL_FILENAME . mkdir -p /tmp/hermes/hermes-runtime-darwin - cp /tmp/hermes/output/hermes-runtime-darwin-v$(get_release_version).tar.gz /tmp/hermes/hermes-runtime-darwin/. - - save_cache: - key: *hermes_cache_key - paths: - - ~/react-native/sdks/hermes/build_host_hermesc - - ~/react-native/sdks/hermes/build_iphoneos - - ~/react-native/sdks/hermes/build_catalyst - - ~/react-native/sdks/hermes/build_iphonesimulator - - ~/react-native/sdks/hermes/build_macosx - - ~/react-native/sdks/hermes/destroot + cp /tmp/hermes/output/$TARBALL_FILENAME /tmp/hermes/hermes-runtime-darwin/. + + # TODO: Remove this once the client side is aware of -release and -debug tarballs + if [[ << parameters.flavor >> == "Debug" ]]; then + cp /tmp/hermes/hermes-runtime-darwin/hermes-runtime-darwin-debug-v$(get_release_version).tar.gz /tmp/hermes/hermes-runtime-darwin/hermes-runtime-darwin-v$(get_release_version).tar.gz + fi + ls /tmp/hermes/hermes-runtime-darwin/ + - when: + condition: + equal: [ << parameters.flavor >>, "Debug"] + steps: + - save_cache: + key: *hermes_workspace_debug_cache_key + paths: *hermes_workspace_macos_cache_paths + - when: + condition: + equal: [ << parameters.flavor >>, "Release"] + steps: + - save_cache: + key: *hermes_workspace_release_cache_key + paths: *hermes_workspace_macos_cache_paths - store_artifacts: path: /tmp/hermes/hermes-runtime-darwin/ - store_artifacts: @@ -1421,6 +1506,9 @@ workflows: filters: *only_release_tags requires: - prepare_hermes_workspace + matrix: + parameters: + flavor: ["Debug", "Release"] - build_hermesc_windows: filters: *only_release_tags requires: diff --git a/sdks/hermes-engine/hermes-engine.podspec b/sdks/hermes-engine/hermes-engine.podspec index 430ab9e7639a6c..9ddda78620a629 100644 --- a/sdks/hermes-engine/hermes-engine.podspec +++ b/sdks/hermes-engine/hermes-engine.podspec @@ -41,8 +41,8 @@ else end module HermesHelper - # BUILD_TYPE = :debug - BUILD_TYPE = :release + BUILD_TYPE = :debug + # BUILD_TYPE = :release end Pod::Spec.new do |spec| @@ -63,13 +63,15 @@ Pod::Spec.new do |spec| spec.ios.vendored_frameworks = "destroot/Library/Frameworks/universal/hermes.xcframework" spec.osx.vendored_frameworks = "destroot/Library/Frameworks/macosx/hermes.framework" - spec.xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => "c++17", "CLANG_CXX_LIBRARY" => "compiler-default", "GCC_PREPROCESSOR_DEFINITIONS" => "HERMES_ENABLE_DEBUGGER=1" } + spec.xcconfig = { + "CLANG_CXX_LANGUAGE_STANDARD" => "c++17", + "CLANG_CXX_LIBRARY" => "compiler-default", + "GCC_PREPROCESSOR_DEFINITIONS" => "HERMES_ENABLE_DEBUGGER=#{HermesHelper::BUILD_TYPE == :debug ? "1" : "0"}" + } if source[:git] then spec.prepare_command = <<-EOS - # When true, debug build will be used. - # See `build-apple-framework.sh` for details - DEBUG=#{HermesHelper::BUILD_TYPE == :debug} + BUILD_TYPE=#{HermesHelper::BUILD_TYPE == :debug ? "Debug" : "Release"} # Set HERMES_OVERRIDE_HERMESC_PATH if pre-built HermesC is available #{File.exist?(import_hermesc_file) ? "export HERMES_OVERRIDE_HERMESC_PATH=#{import_hermesc_file}" : ""} diff --git a/sdks/hermes-engine/utils/build-apple-framework.sh b/sdks/hermes-engine/utils/build-apple-framework.sh index f1f1e421023e12..646c73b5986b1b 100755 --- a/sdks/hermes-engine/utils/build-apple-framework.sh +++ b/sdks/hermes-engine/utils/build-apple-framework.sh @@ -4,12 +4,6 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -if [ "$DEBUG" = true ]; then - BUILD_TYPE="Debug" -else - BUILD_TYPE="Release" -fi - NUM_CORES=$(sysctl -n hw.ncpu) IMPORT_HERMESC_PATH=${HERMES_OVERRIDE_HERMESC_PATH:-$PWD/build_host_hermesc/ImportHermesc.cmake} REACT_NATIVE_PATH=${REACT_NATIVE_PATH:-$PWD/../..} @@ -29,13 +23,14 @@ function get_mac_deployment_target { # Build host hermes compiler for internal bytecode function build_host_hermesc { + echo "Building hermesc" cmake -S . -B build_host_hermesc cmake --build ./build_host_hermesc --target hermesc -j ${NUM_CORES} } # Utility function to configure an Apple framework function configure_apple_framework { - local build_cli_tools enable_bitcode + local build_cli_tools enable_bitcode enable_debugger if [[ $1 == iphoneos || $1 == catalyst ]]; then enable_bitcode="true" @@ -47,12 +42,17 @@ function configure_apple_framework { else build_cli_tools="false" fi + if [[ $BUILD_TYPE == "Debug" ]]; then + enable_debugger="true" + else + enable_debugger="false" + fi cmake -S . -B "build_$1" \ -DHERMES_APPLE_TARGET_PLATFORM:STRING="$1" \ -DCMAKE_OSX_ARCHITECTURES:STRING="$2" \ -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING="$3" \ - -DHERMES_ENABLE_DEBUGGER:BOOLEAN=true \ + -DHERMES_ENABLE_DEBUGGER:BOOLEAN="$enable_debugger" \ -DHERMES_ENABLE_INTL:BOOLEAN=true \ -DHERMES_ENABLE_LIBFUZZER:BOOLEAN=false \ -DHERMES_ENABLE_FUZZILLI:BOOLEAN=false \ @@ -70,7 +70,7 @@ function configure_apple_framework { # Utility function to build an Apple framework function build_apple_framework { - echo "Building framework for $1 with architectures: $2" + echo "Building $BUILD_TYPE framework for $1 with architectures: $2" # Only build host HermesC if no file found at $IMPORT_HERMESC_PATH [ ! -f "$IMPORT_HERMESC_PATH" ] &&