226 lines
7.2 KiB
Bash
226 lines
7.2 KiB
Bash
|
#!/bin/bash
|
||
|
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||
|
#
|
||
|
# This source code is licensed under the MIT license found in the
|
||
|
# LICENSE file in the root directory of this source tree.
|
||
|
|
||
|
# Defines functions for building various Hermes frameworks.
|
||
|
# See build-ios-framework.sh and build-mac-framework.sh for usage examples.
|
||
|
|
||
|
CURR_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
|
||
|
|
||
|
IMPORT_HERMESC_PATH=${HERMES_OVERRIDE_HERMESC_PATH:-$PWD/build_host_hermesc/ImportHermesc.cmake}
|
||
|
BUILD_TYPE=${BUILD_TYPE:-Debug}
|
||
|
|
||
|
HERMES_PATH="$CURR_SCRIPT_DIR/.."
|
||
|
REACT_NATIVE_PATH=${REACT_NATIVE_PATH:-$CURR_SCRIPT_DIR/../../..}
|
||
|
|
||
|
NUM_CORES=$(sysctl -n hw.ncpu)
|
||
|
|
||
|
PLATFORMS=("macosx" "iphoneos" "iphonesimulator" "catalyst" "xros" "xrsimulator" "appletvos" "appletvsimulator")
|
||
|
|
||
|
if [[ -z "$JSI_PATH" ]]; then
|
||
|
JSI_PATH="$REACT_NATIVE_PATH/ReactCommon/jsi"
|
||
|
fi
|
||
|
|
||
|
function use_env_var_or_ruby_prop {
|
||
|
if [[ -n "$1" ]]; then
|
||
|
echo "$1"
|
||
|
else
|
||
|
ruby -rcocoapods-core -rjson -e "puts Pod::Specification.from_file('hermes-engine.podspec').$2"
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
function use_env_var {
|
||
|
if [[ -n "$1" ]]; then
|
||
|
echo "$1"
|
||
|
else
|
||
|
echo "error: Missing $2 environment variable"
|
||
|
exit 1
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
function get_release_version {
|
||
|
use_env_var_or_ruby_prop "${RELEASE_VERSION}" "version"
|
||
|
}
|
||
|
|
||
|
function get_ios_deployment_target {
|
||
|
use_env_var "${IOS_DEPLOYMENT_TARGET}" "IOS_DEPLOYMENT_TARGET"
|
||
|
}
|
||
|
|
||
|
function get_visionos_deployment_target {
|
||
|
use_env_var "${XROS_DEPLOYMENT_TARGET}" "XROS_DEPLOYMENT_TARGET"
|
||
|
}
|
||
|
|
||
|
function get_mac_deployment_target {
|
||
|
use_env_var "${MAC_DEPLOYMENT_TARGET}" "MAC_DEPLOYMENT_TARGET"
|
||
|
}
|
||
|
|
||
|
# Build host hermes compiler for internal bytecode
|
||
|
function build_host_hermesc {
|
||
|
echo "Building hermesc"
|
||
|
pushd "$HERMES_PATH" > /dev/null || exit 1
|
||
|
cmake -S . -B build_host_hermesc -DJSI_DIR="$JSI_PATH"
|
||
|
cmake --build ./build_host_hermesc --target hermesc -j "${NUM_CORES}"
|
||
|
popd > /dev/null || exit 1
|
||
|
}
|
||
|
|
||
|
# Utility function to configure an Apple framework
|
||
|
function configure_apple_framework {
|
||
|
local enable_debugger cmake_build_type xcode_15_flags xcode_major_version
|
||
|
|
||
|
if [[ $BUILD_TYPE == "Debug" ]]; then
|
||
|
enable_debugger="true"
|
||
|
else
|
||
|
enable_debugger="false"
|
||
|
fi
|
||
|
if [[ $BUILD_TYPE == "Debug" ]]; then
|
||
|
# JS developers aren't VM developers.
|
||
|
# Therefore we're passing as build type Release, to provide a faster build.
|
||
|
cmake_build_type="Release"
|
||
|
else
|
||
|
cmake_build_type="MinSizeRel"
|
||
|
fi
|
||
|
|
||
|
xcode_15_flags=""
|
||
|
xcode_major_version=$(xcodebuild -version | grep -oE '[0-9]*' | head -n 1)
|
||
|
if [[ $xcode_major_version -ge 15 ]]; then
|
||
|
xcode_15_flags="LINKER:-ld_classic"
|
||
|
fi
|
||
|
|
||
|
pushd "$HERMES_PATH" > /dev/null || exit 1
|
||
|
cmake -S . -B "build_$1" \
|
||
|
-DHERMES_EXTRA_LINKER_FLAGS="$xcode_15_flags" \
|
||
|
-DHERMES_APPLE_TARGET_PLATFORM:STRING="$1" \
|
||
|
-DCMAKE_OSX_ARCHITECTURES:STRING="$2" \
|
||
|
-DCMAKE_OSX_DEPLOYMENT_TARGET:STRING="$3" \
|
||
|
-DHERMES_ENABLE_DEBUGGER:BOOLEAN="$enable_debugger" \
|
||
|
-DHERMES_ENABLE_INTL:BOOLEAN=true \
|
||
|
-DHERMES_ENABLE_LIBFUZZER:BOOLEAN=false \
|
||
|
-DHERMES_ENABLE_FUZZILLI:BOOLEAN=false \
|
||
|
-DHERMES_ENABLE_TEST_SUITE:BOOLEAN=false \
|
||
|
-DHERMES_ENABLE_BITCODE:BOOLEAN=false \
|
||
|
-DHERMES_BUILD_APPLE_FRAMEWORK:BOOLEAN=true \
|
||
|
-DHERMES_BUILD_SHARED_JSI:BOOLEAN=false \
|
||
|
-DHERMES_BUILD_APPLE_DSYM:BOOLEAN=true \
|
||
|
-DIMPORT_HERMESC:PATH="$IMPORT_HERMESC_PATH" \
|
||
|
-DJSI_DIR="$JSI_PATH" \
|
||
|
-DHERMES_RELEASE_VERSION="for RN $(get_release_version)" \
|
||
|
-DCMAKE_BUILD_TYPE="$cmake_build_type"
|
||
|
popd > /dev/null || exit 1
|
||
|
}
|
||
|
|
||
|
function build_host_hermesc_if_needed {
|
||
|
if [[ ! -f "$IMPORT_HERMESC_PATH" ]]; then
|
||
|
build_host_hermesc
|
||
|
else
|
||
|
echo "[HermesC] Skipping! Found an existent hermesc already at: $IMPORT_HERMESC_PATH"
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
# Utility function to build an Apple framework
|
||
|
function build_apple_framework {
|
||
|
# Only build host HermesC if no file found at $IMPORT_HERMESC_PATH
|
||
|
build_host_hermesc_if_needed
|
||
|
|
||
|
# Confirm ImportHermesc.cmake is now available.
|
||
|
[ ! -f "$IMPORT_HERMESC_PATH" ] &&
|
||
|
echo "Host hermesc is required to build apple frameworks!"
|
||
|
|
||
|
# $1: platform, $2: architectures, $3: deployment target
|
||
|
echo "Building $BUILD_TYPE framework for $1 with architectures: $2"
|
||
|
configure_apple_framework "$1" "$2" "$3"
|
||
|
|
||
|
pushd "$HERMES_PATH" > /dev/null || exit 1
|
||
|
mkdir -p "destroot/Library/Frameworks/$1"
|
||
|
cmake --build "./build_$1" --target libhermes -j "${NUM_CORES}"
|
||
|
cp -R "./build_$1"/API/hermes/hermes.framework* "destroot/Library/Frameworks/$1"
|
||
|
|
||
|
# In a MacOS build, also produce the hermes and hermesc CLI tools.
|
||
|
if [[ $1 == macosx ]]; then
|
||
|
cmake --build "./build_$1" --target hermesc hermes -j "${NUM_CORES}"
|
||
|
mkdir -p destroot/bin
|
||
|
cp "./build_$1/bin"/* "destroot/bin"
|
||
|
fi
|
||
|
|
||
|
# Copy over Hermes and JSI API headers.
|
||
|
mkdir -p destroot/include/hermes/Public
|
||
|
cp public/hermes/Public/*.h destroot/include/hermes/Public
|
||
|
|
||
|
mkdir -p destroot/include/hermes
|
||
|
cp API/hermes/*.h destroot/include/hermes
|
||
|
|
||
|
mkdir -p destroot/include/hermes/cdp
|
||
|
cp API/hermes/cdp/*.h destroot/include/hermes/cdp
|
||
|
|
||
|
mkdir -p destroot/include/hermes/inspector
|
||
|
cp API/hermes/inspector/*.h destroot/include/hermes/inspector
|
||
|
|
||
|
mkdir -p destroot/include/hermes/inspector/chrome
|
||
|
cp API/hermes/inspector/chrome/*.h destroot/include/hermes/inspector/chrome
|
||
|
|
||
|
mkdir -p destroot/include/jsi
|
||
|
cp "$JSI_PATH"/jsi/*.h destroot/include/jsi
|
||
|
popd > /dev/null || exit 1
|
||
|
}
|
||
|
|
||
|
function prepare_dest_root_for_ci {
|
||
|
mkdir -p "destroot/bin"
|
||
|
for platform in "${PLATFORMS[@]}"; do
|
||
|
mkdir -p "destroot/Library/Frameworks/$platform"
|
||
|
cp -R "./build_$platform/API/hermes/hermes.framework"* "destroot/Library/Frameworks/$platform"
|
||
|
done
|
||
|
|
||
|
cp "./build_macosx/bin/"* "destroot/bin"
|
||
|
|
||
|
# Copy over Hermes and JSI API headers.
|
||
|
mkdir -p destroot/include/hermes/Public
|
||
|
cp public/hermes/Public/*.h destroot/include/hermes/Public
|
||
|
|
||
|
mkdir -p destroot/include/hermes
|
||
|
cp API/hermes/*.h destroot/include/hermes
|
||
|
|
||
|
mkdir -p destroot/include/hermes/cdp
|
||
|
cp API/hermes/cdp/*.h destroot/include/hermes/cdp
|
||
|
|
||
|
mkdir -p destroot/include/hermes/inspector
|
||
|
cp API/hermes/inspector/*.h destroot/include/hermes/inspector
|
||
|
|
||
|
mkdir -p destroot/include/hermes/inspector/chrome
|
||
|
cp API/hermes/inspector/chrome/*.h destroot/include/hermes/inspector/chrome
|
||
|
|
||
|
mkdir -p destroot/include/jsi
|
||
|
cp "$JSI_PATH"/jsi/*.h destroot/include/jsi
|
||
|
}
|
||
|
|
||
|
# Accepts an array of frameworks and will place all of
|
||
|
# the architectures into an universal folder and then remove
|
||
|
# the merged frameworks from destroot
|
||
|
function create_universal_framework {
|
||
|
pushd "$HERMES_PATH/destroot/Library/Frameworks" > /dev/null || exit 1
|
||
|
|
||
|
local platforms=("$@")
|
||
|
local args=""
|
||
|
|
||
|
echo "Creating universal framework for platforms: ${platforms[*]}"
|
||
|
|
||
|
for i in "${!platforms[@]}"; do
|
||
|
local platform="${platforms[$i]}"
|
||
|
local hermes_framework_path="${platform}/hermes.framework"
|
||
|
args+="-framework $hermes_framework_path "
|
||
|
done
|
||
|
|
||
|
mkdir -p universal
|
||
|
# shellcheck disable=SC2086
|
||
|
if xcodebuild -create-xcframework $args -output "universal/hermes.xcframework"
|
||
|
then
|
||
|
# # Remove the thin iOS hermes.frameworks that are now part of the universal
|
||
|
# XCFramework
|
||
|
for platform in "${platforms[@]}"; do
|
||
|
rm -r "$platform"
|
||
|
done
|
||
|
fi
|
||
|
|
||
|
popd > /dev/null || exit 1
|
||
|
}
|