1# Copyright (c) Meta Platforms, Inc. and affiliates. 2# 3# This source code is licensed under the MIT license found in the 4# LICENSE file in the root directory of this source tree. 5 6require "json" 7require_relative "./hermes-utils.rb" 8 9react_native_path = File.join(__dir__, "..", "..") 10 11# Whether Hermes is built for Release or Debug is determined by the PRODUCTION envvar. 12build_type = ENV['PRODUCTION'] == "1" ? :release : :debug 13 14# package.json 15package = JSON.parse(File.read(File.join(react_native_path, "package.json"))) 16version = package['version'] 17 18# sdks/.hermesversion 19hermestag_file = File.join(react_native_path, "sdks", ".hermesversion") 20isInCI = ENV['REACT_NATIVE_CI'] === 'true' 21 22source = {} 23git = "https://github.com/facebook/hermes.git" 24 25isInMain = version.include?('1000.0.0') 26isNightly = version.start_with?('0.0.0-') 27 28if ENV.has_key?('HERMES_ENGINE_TARBALL_PATH') 29 if !File.exist?(ENV['HERMES_ENGINE_TARBALL_PATH']) 30 abort "[Hermes] HERMES_ENGINE_TARBALL_PATH is set, but points to a non-existing file: \"#{ENV['HERMES_ENGINE_TARBALL_PATH']}\"\nIf you don't want to use tarball, run `unset HERMES_ENGINE_TARBALL_PATH`" 31 end 32end 33 34if ENV.has_key?('HERMES_ENGINE_TARBALL_PATH') 35 Pod::UI.puts "[Hermes] Using pre-built Hermes binaries from local path: #{ENV['HERMES_ENGINE_TARBALL_PATH']}".yellow if Object.const_defined?("Pod::UI") 36 source[:http] = "file://#{ENV['HERMES_ENGINE_TARBALL_PATH']}" 37elsif isInMain 38 Pod::UI.puts '[Hermes] Installing hermes-engine may take slightly longer, building Hermes compiler from source...'.yellow if Object.const_defined?("Pod::UI") 39 source[:git] = git 40 source[:commit] = `git ls-remote https://github.com/facebook/hermes main | cut -f 1`.strip 41elsif isNightly 42 Pod::UI.puts '[Hermes] Nightly version, download pre-built for Hermes'.yellow if Object.const_defined?("Pod::UI") 43 destination_path = download_nightly_hermes(react_native_path, version) 44 # set tarball as hermes engine 45 source[:http] = "file://#{destination_path}" 46elsif File.exist?(hermestag_file) && isInCI 47 Pod::UI.puts '[Hermes] Detected that you are on a React Native release branch, building Hermes from source but fetched from tag...'.yellow if Object.const_defined?("Pod::UI") 48 hermestag = File.read(hermestag_file).strip 49 source[:git] = git 50 source[:tag] = hermestag 51else 52 # Sample url from Maven: 53 # https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/0.71.0/react-native-artifacts-0.71.0-hermes-ios-debug.tar.gz 54 if File.exist?(File.join(__dir__, "destroot")) 55 source[:path] = '.' 56 else 57 source[:http] = 'https://github.com/expo/react-native/releases/download/sdk-48.0.0/ABI48_0_0hermes.tar.gz' 58 end 59end 60 61Pod::Spec.new do |spec| 62 spec.name = "ABI48_0_0hermes-engine" 63 spec.version = version 64 spec.summary = "Hermes is a small and lightweight JavaScript engine optimized for running React Native." 65 spec.description = "Hermes is a JavaScript engine optimized for fast start-up of React Native apps. It features ahead-of-time static optimization and compact bytecode." 66 spec.homepage = "https://hermesengine.dev" 67 spec.license = package['license'] 68 spec.author = "Facebook" 69 spec.source = source 70 spec.platforms = { :osx => "10.13", :ios => "12.4" } 71 72 spec.preserve_paths = '**/*.*' 73 spec.source_files = '' 74 75 spec.xcconfig = { 76 "CLANG_CXX_LANGUAGE_STANDARD" => "c++17", 77 "CLANG_CXX_LIBRARY" => "compiler-default" 78 }.merge!(build_type == :debug ? { "GCC_PREPROCESSOR_DEFINITIONS" => "HERMES_ENABLE_DEBUGGER=1" } : {}) 79 80 if source[:http] then 81 82 spec.subspec 'Pre-built' do |ss| 83 ss.preserve_paths = ["destroot/bin/*"].concat(build_type == :debug ? ["**/*.{h,c,cpp}"] : []) 84 ss.source_files = "destroot/include/**/*.h" 85 ss.exclude_files = ["destroot/include/jsi/jsi/JSIDynamic.{h,cpp}", "destroot/include/jsi/jsi/jsilib-*.{h,cpp}"] 86 ss.header_mappings_dir = "destroot/include" 87 ss.ios.vendored_frameworks = "destroot/Library/Frameworks/universal/ABI48_0_0hermes.xcframework" 88 ss.osx.vendored_frameworks = "destroot/Library/Frameworks/macosx/hermes.framework" 89 end 90 91 elsif source[:git] then 92 93 spec.subspec 'Hermes' do |ss| 94 ss.source_files = '' 95 ss.public_header_files = 'API/hermes/*.h' 96 ss.header_dir = 'ABI48_0_0hermes' 97 end 98 99 spec.subspec 'JSI' do |ss| 100 ss.source_files = '' 101 ss.public_header_files = 'API/jsi/jsi/*.h' 102 ss.header_dir = 'ABI48_0_0jsi' 103 end 104 105 spec.subspec 'Public' do |ss| 106 ss.source_files = '' 107 ss.public_header_files = 'public/hermes/Public/*.h' 108 ss.header_dir = 'ABI48_0_0hermes/Public' 109 end 110 111 hermesc_path = "" 112 113 if ENV.has_key?('HERMES_OVERRIDE_HERMESC_PATH') && File.exist?(ENV['HERMES_OVERRIDE_HERMESC_PATH']) then 114 hermesc_path = ENV['HERMES_OVERRIDE_HERMESC_PATH'] 115 else 116 # Keep hermesc_path synchronized with .gitignore entry. 117 ENV['REACT_NATIVE_PATH'] = react_native_path 118 hermesc_path = "${REACT_NATIVE_PATH}/sdks/hermes-engine/build_host_hermesc" 119 # NOTE: Prepare command is not run if the pod is not downloaded. 120 spec.prepare_command = ". #{react_native_path}/sdks/hermes-engine/utils/build-hermesc-xcode.sh #{hermesc_path}" 121 end 122 123 spec.user_target_xcconfig = { 124 'FRAMEWORK_SEARCH_PATHS' => '"$(PODS_ROOT)/hermes-engine/destroot/Library/Frameworks/iphoneos" ' + 125 '"$(PODS_ROOT)/hermes-engine/destroot/Library/Frameworks/iphonesimulator" ' + 126 '"$(PODS_ROOT)/hermes-engine/destroot/Library/Frameworks/macosx" ' + 127 '"$(PODS_ROOT)/hermes-engine/destroot/Library/Frameworks/catalyst"', 128 'OTHER_LDFLAGS' => '-framework "hermes"', 129 'HERMES_CLI_PATH' => "#{hermesc_path}/bin/hermesc" 130 } 131 132 spec.script_phases = [ 133 { 134 :name => 'Build Hermes', 135 :script => <<-EOS 136 . ${PODS_ROOT}/../.xcode.env 137 export CMAKE_BINARY=${CMAKE_BINARY:-#{%x(command -v cmake | tr -d '\n')}} 138 . ${REACT_NATIVE_PATH}/sdks/hermes-engine/utils/build-hermes-xcode.sh #{version} #{hermesc_path}/ImportHermesc.cmake 139 EOS 140 }, 141 { 142 :name => 'Copy Hermes Framework', 143 :script => ". ${REACT_NATIVE_PATH}/sdks/hermes-engine/utils/copy-hermes-xcode.sh" 144 } 145 ] 146 end 147end 148