Skip to content

Commit 5852dc1

Browse files
Saadnajmiclaude
andcommitted
chore: include macOS slice in universal hermes xcframework
Consolidates the three separate Hermes Apple build scripts into a single `build-apple-framework.sh` that builds all platforms — including macOS — into one universal `hermesvm.xcframework`. Previously macOS was built as a standalone `.framework` by a separate script and excluded from the universal xcframework. This blocked SPM-based macOS builds since `Package.swift` references the universal xcframework. - Merge `build-ios-framework.sh` and `build-mac-framework.sh` into `build-apple-framework.sh` using the `PLATFORMS` array as single source of truth - Update podspec Pre-built subspec to point macOS at the universal xcframework (matching iOS, tvOS, and visionOS) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 36a0d9e commit 5852dc1

4 files changed

Lines changed: 95 additions & 126 deletions

File tree

packages/react-native/sdks/hermes-engine/hermes-engine.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ Pod::Spec.new do |spec|
7373
ss.ios.vendored_frameworks = "destroot/Library/Frameworks/universal/hermesvm.xcframework"
7474
ss.visionos.vendored_frameworks = "destroot/Library/Frameworks/universal/hermesvm.xcframework"
7575
ss.tvos.vendored_frameworks = "destroot/Library/Frameworks/universal/hermesvm.xcframework"
76-
ss.osx.vendored_frameworks = "destroot/Library/Frameworks/macosx/hermesvm.framework"
76+
ss.osx.vendored_frameworks = "destroot/Library/Frameworks/universal/hermesvm.xcframework"
7777
end
7878

7979
# When using the local prebuilt tarball, it should include hermesc compatible with the used VM.

packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh

Lines changed: 94 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,18 @@
44
# This source code is licensed under the MIT license found in the
55
# LICENSE file in the root directory of this source tree.
66

7-
# Defines functions for building various Hermes frameworks.
8-
# See build-ios-framework.sh and build-mac-framework.sh for usage examples.
7+
# Builds Hermes Apple frameworks for all platforms (iOS, macOS, tvOS, visionOS,
8+
# Mac Catalyst) and combines them into a single universal xcframework.
9+
#
10+
# Usage:
11+
# ./build-apple-framework.sh # build all platforms + universal xcframework
12+
# ./build-apple-framework.sh <platform> # build a single platform (e.g. macosx, iphoneos)
13+
# ./build-apple-framework.sh build_framework # combine already-built slices into xcframework
14+
15+
if [ "$CI" ]; then
16+
set -x
17+
fi
18+
set -e
919

1020
CURR_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
1121

@@ -56,6 +66,35 @@ function get_mac_deployment_target {
5666
use_env_var "${MAC_DEPLOYMENT_TARGET}" "MAC_DEPLOYMENT_TARGET"
5767
}
5868

69+
# Given a specific target, retrieve the right architecture for it
70+
# $1 the target you want to build. Allowed values: iphoneos, iphonesimulator, catalyst, macosx, xros, xrsimulator, appletvos, appletvsimulator
71+
function get_architecture {
72+
if [[ $1 == "iphoneos" || $1 == "xros" ]]; then
73+
echo "arm64"
74+
elif [[ $1 == "iphonesimulator" || $1 == "xrsimulator" ]]; then
75+
echo "x86_64;arm64"
76+
elif [[ $1 == "appletvos" ]]; then
77+
echo "arm64"
78+
elif [[ $1 == "appletvsimulator" ]]; then
79+
echo "x86_64;arm64"
80+
elif [[ $1 == "catalyst" || $1 == "macosx" ]]; then
81+
echo "x86_64;arm64"
82+
else
83+
echo "Error: unknown architecture passed $1"
84+
exit 1
85+
fi
86+
}
87+
88+
function get_deployment_target {
89+
if [[ $1 == "xros" || $1 == "xrsimulator" ]]; then
90+
echo "$(get_visionos_deployment_target)"
91+
elif [[ $1 == "macosx" ]]; then
92+
echo "$(get_mac_deployment_target)"
93+
else # tvOS and iOS use the same deployment target
94+
echo "$(get_ios_deployment_target)"
95+
fi
96+
}
97+
5998
# Build host hermes compiler for internal bytecode
6099
function build_host_hermesc {
61100
echo "Building hermesc"
@@ -65,6 +104,14 @@ function build_host_hermesc {
65104
popd > /dev/null || exit 1
66105
}
67106

107+
function build_host_hermesc_if_needed {
108+
if [[ ! -f "$IMPORT_HOST_COMPILERS_PATH" ]]; then
109+
build_host_hermesc
110+
else
111+
echo "[HermesC] Skipping! Found an existent hermesc already at: $IMPORT_HOST_COMPILERS_PATH"
112+
fi
113+
}
114+
68115
# Utility function to configure an Apple framework
69116
function configure_apple_framework {
70117
local enable_debugger cmake_build_type xcode_15_flags xcode_major_version
@@ -117,15 +164,8 @@ function configure_apple_framework {
117164
popd > /dev/null || exit 1
118165
}
119166

120-
function build_host_hermesc_if_needed {
121-
if [[ ! -f "$IMPORT_HOST_COMPILERS_PATH" ]]; then
122-
build_host_hermesc
123-
else
124-
echo "[HermesC] Skipping! Found an existent hermesc already at: $IMPORT_HOST_COMPILERS_PATH"
125-
fi
126-
}
127-
128-
# Utility function to build an Apple framework
167+
# Utility function to build an Apple framework for a single platform
168+
# $1: platform, $2: architectures, $3: deployment target
129169
function build_apple_framework {
130170
# Only build host HermesC if no file found at $IMPORT_HOST_COMPILERS_PATH
131171
build_host_hermesc_if_needed
@@ -134,7 +174,6 @@ function build_apple_framework {
134174
[ ! -f "$IMPORT_HOST_COMPILERS_PATH" ] &&
135175
echo "Host hermesc is required to build apple frameworks!"
136176

137-
# $1: platform, $2: architectures, $3: deployment target
138177
echo "Building $BUILD_TYPE framework for $1 with architectures: $2"
139178
configure_apple_framework "$1" "$2" "$3"
140179

@@ -223,7 +262,7 @@ function create_universal_framework {
223262
# shellcheck disable=SC2086
224263
if xcodebuild -create-xcframework $args -output "universal/hermesvm.xcframework"
225264
then
226-
# # Remove the thin iOS hermesvm.frameworks that are now part of the universal
265+
# # Remove the thin hermesvm.frameworks that are now part of the universal
227266
# XCFramework
228267
for platform in "${platforms[@]}"; do
229268
rm -r "$platform"
@@ -232,3 +271,45 @@ function create_universal_framework {
232271

233272
popd > /dev/null || exit 1
234273
}
274+
275+
# Build a single framework for a given platform
276+
# $1 is the target to build (e.g. iphoneos, macosx, etc.)
277+
function build_framework {
278+
if [ ! -d destroot/Library/Frameworks/universal/hermesvm.xcframework ]; then
279+
deployment_target=$(get_deployment_target "$1")
280+
architecture=$(get_architecture "$1")
281+
build_apple_framework "$1" "$architecture" "$deployment_target"
282+
else
283+
echo "Skipping; Clean \"destroot\" to rebuild".
284+
fi
285+
}
286+
287+
# Combine already-built slices into a universal xcframework
288+
function build_universal_framework {
289+
if [ ! -d destroot/Library/Frameworks/universal/hermesvm.xcframework ]; then
290+
create_universal_framework "${PLATFORMS[@]}"
291+
else
292+
echo "Skipping; Clean \"destroot\" to rebuild".
293+
fi
294+
}
295+
296+
# Build all platforms sequentially then combine into a universal xcframework
297+
function create_framework {
298+
if [ ! -d destroot/Library/Frameworks/universal/hermesvm.xcframework ]; then
299+
for platform in "${PLATFORMS[@]}"; do
300+
build_framework "$platform"
301+
done
302+
build_universal_framework
303+
else
304+
echo "Skipping; Clean \"destroot\" to rebuild".
305+
fi
306+
}
307+
308+
# --- Entry point ---
309+
if [[ -z $1 ]]; then
310+
create_framework
311+
elif [[ $1 == "build_framework" ]]; then
312+
build_universal_framework
313+
else
314+
build_framework "$1"
315+
fi

packages/react-native/sdks/hermes-engine/utils/build-ios-framework.sh

Lines changed: 0 additions & 90 deletions
This file was deleted.

packages/react-native/sdks/hermes-engine/utils/build-mac-framework.sh

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)