Skip to content

Commit

Permalink
Prepare dummy hermes.xcframework before pod install
Browse files Browse the repository at this point in the history
Summary:
This diff adds prepare command to hermes-engine.podspec. That command creates dummy `universal/hermes.xcframework` and `maocosx/hermes.framework`. This allow us to utilise CocoaPods auto-linking, and remove manual linking/cleanup code.
Also we now do not pollute user project with "Copy Hermes Framework" script phase. Which was quite bad on its own, and also caused annoying bugs on the CI.
allow-large-files

Changelog:
[iOS][Changed] - Prepare dummy hermes.xcframework before pod install.

Reviewed By: cipolleschi

Differential Revision: D41533994

fbshipit-source-id: d7d098ba5e882ac2d036335c23d7cda447d75b8d
  • Loading branch information
dmytrorykun authored and facebook-github-bot committed Dec 13, 2022
1 parent 65e0f79 commit 2344860
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 98 deletions.
6 changes: 3 additions & 3 deletions packages/rn-tester/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -932,7 +932,7 @@ SPEC CHECKSUMS:
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
FBLazyVector: d68947eddece25638eb0f642d1b957c90388afd1
FBReactNativeSpec: 0ded2dec004001d5888590a9c13df3e0c357a59f
FBReactNativeSpec: c530d2df977f98d0d72ce4440c074cb73bff6289
Flipper: 26fc4b7382499f1281eb8cb921e5c3ad6de91fe0
Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c
Flipper-DoubleConversion: 2dc99b02f658daf147069aad9dbd29d8feb06d30
Expand All @@ -944,7 +944,7 @@ SPEC CHECKSUMS:
FlipperKit: cbdee19bdd4e7f05472a66ce290f1b729ba3cb86
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
hermes-engine: 62aa33fe860de4c9fde92adea000ce2e56c70370
hermes-engine: b5817966bad2f5e14014102dbf97e26a17fe256e
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c
RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1
Expand All @@ -958,7 +958,7 @@ SPEC CHECKSUMS:
React-cxxreact: 97903bdac0fb53409663fd312e2183ae1dd730e5
React-Fabric: 4d08ce0b0f15513b2724ae1000c2aaedf73ebc32
React-graphics: cb8a85648695c60f33a00d732b985f734d1470d8
React-hermes: e35ea664b36773a2ce84c583febf1396080e59f7
React-hermes: 73a4f97e9cd712476f9b93ae4838a576279feb78
React-jsi: e4c75a1cf727c8761908ac2eeb1084e47ba88a26
React-jsiexecutor: dcc8c2b89b6e0b5abb9bbbfb6df86adf44e3e877
React-jsinspector: 9b56a373a6797114e1d89a7dffa98ee98af67a8f
Expand Down
26 changes: 0 additions & 26 deletions scripts/cocoapods/__tests__/jsengine-test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -125,30 +125,4 @@ def test_setupHermes_installsPods_installsFabricSubspecWhenFabricEnabled
assert_equal($podInvocation["libevent"][:version], "~> 2.1.12")
end

# ================================= #
# TEST - isBuildingHermesFromSource #
# ================================= #
def test_isBuildingHermesFromSource_whenTarballIsNilAndVersionIsNotNightly_returnTrue
assert_true(is_building_hermes_from_source("1000.0.0", '../..'))
end

def test_isBuildingHermesFromSource_whenTarballIsNilAndInReleaseBranch_returnTrue
ENV['CI'] = 'true'
File.mocked_existing_files(['../../sdks/.hermesversion'])
assert_true(is_building_hermes_from_source("0.999.0", '../..'))
end

def test_isBuildingHermesFromSource_whenTarballIsNotNil_returnFalse
ENV['HERMES_ENGINE_TARBALL_PATH'] = "~/Downloads/hermes-ios-debug.tar.gz"
assert_false(is_building_hermes_from_source("1000.0.0", '../..'))
end

def test_isBuildingHermesFromSource_whenIsNigthly_returnsFalse
assert_false(is_building_hermes_from_source("0.0.0-", '../..'))
end

def test_isBuildingHermesFromSource_whenIsStbleRelease_returnsFalse
assert_false(is_building_hermes_from_source("0.71.0", '../..'))
end

end
42 changes: 0 additions & 42 deletions scripts/cocoapods/jsengine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,45 +34,3 @@ def setup_hermes!(react_native_path: "../node_modules/react-native", fabric_enab
pod 'React-hermes', :path => "#{react_native_path}/ReactCommon/hermes"
pod 'libevent', '~> 2.1.12'
end

def add_copy_hermes_framework_script_phase(installer, react_native_path)
utils_dir = File.join(react_native_path, "sdks", "hermes-engine", "utils")
phase_name = "[RN] Copy Hermes Framework"
project = installer.generated_aggregate_targets.first.user_project
target = project.targets.first
if target.shell_script_build_phases.none? { |phase| phase.name == phase_name }
phase = target.new_shell_script_build_phase(phase_name)
phase.shell_script = ". #{utils_dir}/copy-hermes-xcode.sh"
project.save()
end
end

def remove_copy_hermes_framework_script_phase(installer, react_native_path)
utils_dir = File.join(react_native_path, "sdks", "hermes-engine", "utils")
phase_name = "[RN] Copy Hermes Framework"
project = installer.generated_aggregate_targets.first.user_project
target = project.native_targets.first
target.shell_script_build_phases.each do |phase|
if phase.name == phase_name
target.build_phases.delete(phase)
end
end
project.save()
end

# TODO: Use this same function in the `hermes-engine.podspec` somehow
def is_building_hermes_from_source(react_native_version, react_native_path)
if ENV['HERMES_ENGINE_TARBALL_PATH'] != nil
return false
end

isInMain = react_native_version.include?('1000.0.0')

hermestag_file = File.join(react_native_path, "sdks", ".hermesversion")
isInCI = ENV['CI'] === 'true'

isReleaseBranch = File.exist?(hermestag_file) && isInCI


return isInMain || isReleaseBranch
end
6 changes: 0 additions & 6 deletions scripts/react_native_pods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -205,12 +205,6 @@ def react_native_post_install(installer, react_native_path = "../node_modules/re
package = JSON.parse(File.read(File.join(react_native_path, "package.json")))
version = package['version']

if ReactNativePodsUtils.has_pod(installer, 'hermes-engine') && is_building_hermes_from_source(version, react_native_path)
add_copy_hermes_framework_script_phase(installer, react_native_path)
else
remove_copy_hermes_framework_script_phase(installer, react_native_path)
end

ReactNativePodsUtils.exclude_i386_architecture_while_using_hermes(installer)
ReactNativePodsUtils.fix_library_search_paths(installer)
ReactNativePodsUtils.set_node_modules_user_settings(installer, react_native_path)
Expand Down
10 changes: 5 additions & 5 deletions sdks/hermes-engine/hermes-engine.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ Pod::Spec.new do |spec|
"CLANG_CXX_LIBRARY" => "compiler-default"
}.merge!(build_type == :debug ? { "GCC_PREPROCESSOR_DEFINITIONS" => "HERMES_ENABLE_DEBUGGER=1" } : {})

spec.ios.vendored_frameworks = "destroot/Library/Frameworks/ios/hermes.framework"
spec.osx.vendored_frameworks = "destroot/Library/Frameworks/macosx/hermes.framework"

if source[:http] then

spec.subspec 'Pre-built' do |ss|
Expand Down Expand Up @@ -111,14 +114,11 @@ Pod::Spec.new do |spec|
end

spec.user_target_xcconfig = {
'FRAMEWORK_SEARCH_PATHS' => '"$(PODS_ROOT)/hermes-engine/destroot/Library/Frameworks/iphoneos" ' +
'"$(PODS_ROOT)/hermes-engine/destroot/Library/Frameworks/iphonesimulator" ' +
'"$(PODS_ROOT)/hermes-engine/destroot/Library/Frameworks/macosx" ' +
'"$(PODS_ROOT)/hermes-engine/destroot/Library/Frameworks/catalyst"',
'OTHER_LDFLAGS' => '-framework "hermes"',
'HERMES_CLI_PATH' => "#{hermesc_path}/bin/hermesc"
}

spec.prepare_command = ". #{react_native_path}/sdks/hermes-engine/utils/create-dummy-hermes-xcframework.sh"

CMAKE_BINARY = %x(command -v cmake | tr -d '\n')
# NOTE: Script phases are sorted alphabetically inside Xcode project
spec.script_phases = [
Expand Down
7 changes: 7 additions & 0 deletions sdks/hermes-engine/utils/build-hermes-xcode.sh
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,10 @@ echo "Build Apple framework"
--build "${PODS_ROOT}/hermes-engine/build/${PLATFORM_NAME}" \
--target "install/strip" \
-j "$(sysctl -n hw.ncpu)"

echo "Copy Apple framework to destroot/Library/Frameworks"

cp -pfR \
"${PODS_ROOT}/hermes-engine/destroot/Library/Frameworks/${PLATFORM_NAME}/hermes.framework" \
"${PODS_ROOT}/hermes-engine/destroot/Library/Frameworks/ios"
rm -rf "${PODS_ROOT}/hermes-engine/destroot/Library/Frameworks/${PLATFORM_NAME}"
17 changes: 1 addition & 16 deletions sdks/hermes-engine/utils/copy-hermes-xcode.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,4 @@
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

set -x

src="${PODS_ROOT}/hermes-engine/destroot/Library/Frameworks/${PLATFORM_NAME}/hermes.framework"

if [[ ! -e "$src" ]]; then
echo "$src does not exist."
exit 1
fi

dst1="${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes"
[ ! -f "$dst1" ] && mkdir -p "$dst1"
cp -R "$src" "$dst1"

dst2="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
[ ! -f "$dst2" ] && mkdir -p "$dst2"
cp -R "$src" "$dst2"
echo "This file is no-op now. Remove \"[RN] Copy Hermes Framework\" script phase from your main target if you don't want to see this message."
30 changes: 30 additions & 0 deletions sdks/hermes-engine/utils/create-dummy-hermes-xcframework.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/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.

set -x

# CocoaPods requires vendored frameworks to exist before `pod install` is run,
# and to be proper Moch-O binaries in order to auto-link them to the user's Xcode project.
# This script creates dummy hermes.framework for macosx and ios.
# They are then get rewritten by `build-hermes-xcode.sh` during Xcode build.

rm -rf destroot

mkdir -p destroot/Library/Frameworks

pushd destroot/Library/Frameworks > /dev/null || exit 1

echo '' > dummy.c

mkdir -p macosx/hermes.framework
clang dummy.c -dynamiclib -o macosx/hermes.framework/hermes

mkdir -p ios/hermes.framework
clang dummy.c -dynamiclib -o ios/hermes.framework/hermes

rm dummy.c

popd > /dev/null || exit 1

0 comments on commit 2344860

Please sign in to comment.