feat(smart-app): implement complete mobile app MVP

- App.tsx: full navigation (Auth stack + Main tabs with 5 screens)
- Auth: LoginScreen, RegisterScreen, ForgotPasswordScreen
- HomeScreen: dashboard with IoT metrics, weather widget, alerts, quick actions, sensors
- MapScreen: interactive map with layer toggles (6 layers)
- MarketplaceScreen: categories (6), products (5), search
- ChatScreen: AI chat with quick prompts (4), bot responses
- ProfileScreen: user info, stats, menu (9 items), logout
- AlertsScreen: alert list with severity, acknowledge
- SensorsScreen: sensor list with type filters (6 types), search
- ZonesScreen: zone cards with stats
- SettingsScreen: language picker (FR/EN/ES/DE), privacy, about
- Stores: iotStore (sensors, zones, alerts), notificationStore, uiStore + i18n
- Hooks: useSensors, useAlerts, useNotifications, useLocation
- Components: Card, Button, LoadingSpinner, ErrorBoundary, Header
- Services: iotService, notificationService (with axios API client)
- Utils: formatters (temp, AQI, noise, dates), validators (email, password, IBAN)
- Theme: colors.ts with full design system (Blue Ocean palette)
- Ditto: fixed MongoDB connection, new JWT secrets, official gateway image
This commit is contained in:
Eric FELIXINE
2026-06-01 18:00:35 -04:00
parent 08ca495bde
commit e30ae8ed09
35578 changed files with 3703534 additions and 43 deletions

View File

@@ -0,0 +1 @@
hermes-2024-02-20-RNv0.74.0-999cfd9979b5f57b1269119679ab8cdf60897de9

View File

@@ -0,0 +1,144 @@
# 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.
require "json"
require_relative "./hermes-utils.rb"
react_native_path = File.join(__dir__, "..", "..")
# package.json
package = JSON.parse(File.read(File.join(react_native_path, "package.json")))
version = package['version']
source_type = hermes_source_type(version, react_native_path)
source = podspec_source(source_type, version, react_native_path)
Pod::Spec.new do |spec|
spec.name = "hermes-engine"
spec.version = version
spec.summary = "Hermes is a small and lightweight JavaScript engine optimized for running React Native."
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."
spec.homepage = "https://hermesengine.dev"
spec.license = package['license']
spec.author = "Facebook"
spec.source = source
spec.platforms = { :osx => "10.13", :ios => "13.4" }
spec.preserve_paths = '**/*.*'
spec.source_files = ''
spec.pod_target_xcconfig = {
"CLANG_CXX_LANGUAGE_STANDARD" => "c++20",
"CLANG_CXX_LIBRARY" => "compiler-default"
}
spec.ios.vendored_frameworks = "destroot/Library/Frameworks/ios/hermes.framework"
spec.osx.vendored_frameworks = "destroot/Library/Frameworks/macosx/hermes.framework"
if HermesEngineSourceType::isPrebuilt(source_type) then
spec.subspec 'Pre-built' do |ss|
ss.preserve_paths = ["destroot/bin/*"].concat(["**/*.{h,c,cpp}"])
ss.source_files = "destroot/include/hermes/**/*.h"
ss.header_mappings_dir = "destroot/include"
ss.ios.vendored_frameworks = "destroot/Library/Frameworks/universal/hermes.xcframework"
ss.osx.vendored_frameworks = "destroot/Library/Frameworks/macosx/hermes.framework"
end
# Right now, even reinstalling pods with the PRODUCTION flag turned on, does not change the version of hermes that is downloaded
# To remove the PRODUCTION flag, we want to download the right version of hermes on the flight
# we do so in a pre-build script we invoke from the Xcode build pipeline
# We use this only for Apps created using the template. RNTester and Nightlies should not be used to build for Release.
# We ignore this if we provide a specific tarball: the assumption here is that if you are providing a tarball, is because you want to
# test something specific for that tarball.
if source_type == HermesEngineSourceType::DOWNLOAD_PREBUILD_RELEASE_TARBALL
spec.script_phase = {
:name => "[Hermes] Replace Hermes for the right configuration, if needed",
:execution_position => :before_compile,
:script => <<-EOS
. "$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh"
CONFIG="Release"
if echo $GCC_PREPROCESSOR_DEFINITIONS | grep -q "DEBUG=1"; then
CONFIG="Debug"
fi
"$NODE_BINARY" "$REACT_NATIVE_PATH/sdks/hermes-engine/utils/replace_hermes_version.js" -c "$CONFIG" -r "#{version}" -p "$PODS_ROOT"
EOS
}
end
elsif HermesEngineSourceType::isFromSource(source_type) then
spec.subspec 'Hermes' do |ss|
ss.source_files = ''
ss.public_header_files = 'API/hermes/*.h'
ss.header_dir = 'hermes'
end
spec.subspec 'inspector' do |ss|
ss.source_files = ''
ss.public_header_files = 'API/hermes/inspector/*.h'
ss.header_dir = 'hermes/inspector'
end
spec.subspec 'inspector_chrome' do |ss|
ss.source_files = ''
ss.public_header_files = 'API/hermes/inspector/chrome/*.h'
ss.header_dir = 'hermes/inspector/chrome'
end
spec.subspec 'Public' do |ss|
ss.source_files = ''
ss.public_header_files = 'public/hermes/Public/*.h'
ss.header_dir = 'hermes/Public'
end
hermesc_path = "${PODS_ROOT}/hermes-engine/build_host_hermesc"
if ENV.has_key?('HERMES_OVERRIDE_HERMESC_PATH') && File.exist?(ENV['HERMES_OVERRIDE_HERMESC_PATH']) then
hermesc_path = ENV['HERMES_OVERRIDE_HERMESC_PATH']
end
spec.user_target_xcconfig = {
'HERMES_CLI_PATH' => "#{hermesc_path}/bin/hermesc"
}
spec.prepare_command = ". #{react_native_path}/sdks/hermes-engine/utils/create-dummy-hermes-xcframework.sh"
# This podspec is also run in CI to build Hermes without using Pod install
# and sometimes CI fails because `Pod::Executable` does not exist if it is not run with Pod Install.
if defined?(Pod::Executable.to_s)
CMAKE_BINARY = Pod::Executable::which!('cmake')
# NOTE: Script phases are sorted alphabetically inside Xcode project
spec.script_phases = [
{
:name => '[RN] [1] Build Hermesc',
:output_files => [
"#{hermesc_path}/ImportHermesc.cmake"
],
:script => <<-EOS
. "${REACT_NATIVE_PATH}/scripts/xcode/with-environment.sh"
export CMAKE_BINARY=${CMAKE_BINARY:-#{CMAKE_BINARY}}
. ${REACT_NATIVE_PATH}/sdks/hermes-engine/utils/build-hermesc-xcode.sh #{hermesc_path} ${REACT_NATIVE_PATH}/ReactCommon/jsi
EOS
},
{
:name => '[RN] [2] Build Hermes',
:input_files => ["#{hermesc_path}/ImportHermesc.cmake"],
:output_files => [
"${PODS_ROOT}/hermes-engine/build/iphonesimulator/API/hermes/hermes.framework/hermes"
],
:script => <<-EOS
. "${REACT_NATIVE_PATH}/scripts/xcode/with-environment.sh"
export CMAKE_BINARY=${CMAKE_BINARY:-#{CMAKE_BINARY}}
. ${REACT_NATIVE_PATH}/sdks/hermes-engine/utils/build-hermes-xcode.sh #{version} #{hermesc_path}/ImportHermesc.cmake ${REACT_NATIVE_PATH}/ReactCommon/jsi
EOS
}
]
end
end
end

View File

@@ -0,0 +1,262 @@
# 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.
require 'net/http'
require 'rexml/document'
HERMES_GITHUB_URL = "https://github.com/facebook/hermes.git"
ENV_BUILD_FROM_SOURCE = "RCT_BUILD_HERMES_FROM_SOURCE"
module HermesEngineSourceType
LOCAL_PREBUILT_TARBALL = :local_prebuilt_tarball
DOWNLOAD_PREBUILD_RELEASE_TARBALL = :download_prebuild_release_tarball
DOWNLOAD_PREBUILT_NIGHTLY_TARBALL = :download_prebuilt_nightly_tarball
BUILD_FROM_GITHUB_COMMIT = :build_from_github_commit
BUILD_FROM_GITHUB_TAG = :build_from_github_tag
BUILD_FROM_GITHUB_MAIN = :build_from_github_main
BUILD_FROM_LOCAL_SOURCE_DIR = :build_from_local_source_dir
def HermesEngineSourceType.isPrebuilt(source_type)
return source_type == LOCAL_PREBUILT_TARBALL || source_type == DOWNLOAD_PREBUILD_RELEASE_TARBALL || source_type == DOWNLOAD_PREBUILT_NIGHTLY_TARBALL
end
def HermesEngineSourceType.isFromSource(source_type)
return source_type == BUILD_FROM_GITHUB_COMMIT || source_type == BUILD_FROM_GITHUB_TAG || source_type == BUILD_FROM_GITHUB_MAIN || source_type == BUILD_FROM_LOCAL_SOURCE_DIR
end
end
# Computes the hermes-engine.podspec's source type.
# - To use a specific tarball, install the dependencies with:
# `HERMES_ENGINE_TARBALL_PATH=<path_to_tarball> bundle exec pod install`
# - To force a build from source, install the dependencies with:
# `RCT_BUILD_HERMES_FROM_SOURCE=true bundle exec pod install`
# If none of the two are provided, Cocoapods will check whether there is a tarball for the current version
# (either release or nightly). If not, it will fall back to building from source (the latest commit on main).
#
# Parameters:
# - version: current version of the pod
# - react_native_path: path to react native
#
# Returns: hermes-engine source type
def hermes_source_type(version, react_native_path)
if override_hermes_dir_envvar_defined()
return HermesEngineSourceType::BUILD_FROM_LOCAL_SOURCE_DIR
end
if hermes_engine_tarball_envvar_defined()
return HermesEngineSourceType::LOCAL_PREBUILT_TARBALL
end
if hermes_commit_envvar_defined()
return HermesEngineSourceType::BUILD_FROM_GITHUB_COMMIT
end
if force_build_from_tag(react_native_path)
return HermesEngineSourceType::BUILD_FROM_GITHUB_TAG
end
if force_build_from_main(react_native_path)
return HermesEngineSourceType::BUILD_FROM_GITHUB_MAIN
end
if release_artifact_exists(version)
return HermesEngineSourceType::DOWNLOAD_PREBUILD_RELEASE_TARBALL
end
if nightly_artifact_exists(version)
return HermesEngineSourceType::DOWNLOAD_PREBUILT_NIGHTLY_TARBALL
end
return HermesEngineSourceType::BUILD_FROM_GITHUB_MAIN
end
def override_hermes_dir_envvar_defined()
return ENV.has_key?('REACT_NATIVE_OVERRIDE_HERMES_DIR')
end
def hermes_engine_tarball_envvar_defined()
return ENV.has_key?('HERMES_ENGINE_TARBALL_PATH')
end
def hermes_commit_envvar_defined()
return ENV.has_key?('HERMES_COMMIT')
end
def force_build_from_tag(react_native_path)
return ENV[ENV_BUILD_FROM_SOURCE] === 'true' && File.exist?(hermestag_file(react_native_path))
end
def force_build_from_main(react_native_path)
return ENV[ENV_BUILD_FROM_SOURCE] === 'true' && !File.exist?(hermestag_file(react_native_path))
end
def release_artifact_exists(version)
return hermes_artifact_exists(release_tarball_url(version, :debug))
end
def nightly_artifact_exists(version)
return hermes_artifact_exists(nightly_tarball_url(version).gsub("\\", ""))
end
def podspec_source(source_type, version, react_native_path)
case source_type
when HermesEngineSourceType::BUILD_FROM_LOCAL_SOURCE_DIR
return podspec_source_build_from_local_source_dir(react_native_path)
when HermesEngineSourceType::LOCAL_PREBUILT_TARBALL
return podspec_source_local_prebuilt_tarball()
when HermesEngineSourceType::BUILD_FROM_GITHUB_COMMIT
return podspec_source_build_from_github_commit()
when HermesEngineSourceType::BUILD_FROM_GITHUB_TAG
return podspec_source_build_from_github_tag(react_native_path)
when HermesEngineSourceType::BUILD_FROM_GITHUB_MAIN
return podspec_source_build_from_github_main()
when HermesEngineSourceType::DOWNLOAD_PREBUILD_RELEASE_TARBALL
return podspec_source_download_prebuild_release_tarball(react_native_path, version)
when HermesEngineSourceType::DOWNLOAD_PREBUILT_NIGHTLY_TARBALL
return podspec_source_download_prebuilt_nightly_tarball(version)
else
abort "[Hermes] Unsupported or invalid source type provided: #{source_type}"
end
end
def podspec_source_build_from_local_source_dir(react_native_path)
source_dir_path = ENV['REACT_NATIVE_OVERRIDE_HERMES_DIR']
if Dir.exist?(source_dir_path)
hermes_log("Using source code from local path: #{source_dir_path}")
tarball_path = File.join(artifacts_dir(), "hermes-engine-from-local-source-dir.tar.gz")
exclude_paths = [
"__tests__",
"./external/flowtest",
"./external/esprima/test_fixtures"
]
.map {|path| "--exclude=#{path}"}
.join(' ')
tar_command = "tar #{exclude_paths} -czvf #{tarball_path} -C #{source_dir_path} . 2> /dev/null"
success = system(tar_command)
if !success
abort "Failed to create a tarball with the contents of \"#{source_dir_path}\""
end
return {:http => "file://#{tarball_path}"}
else
abort <<-EOS
[Hermes] REACT_NATIVE_OVERRIDE_HERMES_DIR is set, but points to a non-existing directory: \"#{source_dir_path}\"
If you don't want to use local source, run `unset REACT_NATIVE_OVERRIDE_HERMES_DIR`
EOS
end
end
def podspec_source_local_prebuilt_tarball()
tarball_path = ENV['HERMES_ENGINE_TARBALL_PATH']
if File.exist?(tarball_path)
hermes_log("Using pre-built binary from local path defined by HERMES_ENGINE_TARBALL_PATH envvar: #{tarball_path}")
return {:http => "file://#{tarball_path}"}
end
abort <<-EOS
[Hermes] HERMES_ENGINE_TARBALL_PATH is set, but points to a non-existing file: \"#{tarball_path}\"
If you don't want to use tarball, run `unset HERMES_ENGINE_TARBALL_PATH`
EOS
end
def podspec_source_build_from_github_commit()
commit = ENV['HERMES_COMMIT']
hermes_log("Using commit defined by HERMES_COMMIT envvar: #{commit}")
return {:git => HERMES_GITHUB_URL, :commit => commit}
end
def podspec_source_build_from_github_tag(react_native_path)
tag = File.read(hermestag_file(react_native_path)).strip
hermes_log("Using tag difined in sdks/.hermesversion: #{tag}")
return {:git => HERMES_GITHUB_URL, :tag => tag}
end
def podspec_source_build_from_github_main()
hermes_log("Using the latest commit from main.")
return {:git => HERMES_GITHUB_URL, :commit => `git ls-remote #{HERMES_GITHUB_URL} main | cut -f 1`.strip}
end
def podspec_source_download_prebuild_release_tarball(react_native_path, version)
url = release_tarball_url(version, :debug)
hermes_log("Using release tarball from URL: #{url}")
download_stable_hermes(react_native_path, version, :debug)
download_stable_hermes(react_native_path, version, :release)
return {:http => url}
end
def podspec_source_download_prebuilt_nightly_tarball(version)
url = nightly_tarball_url(version)
hermes_log("Using nightly tarball from URL: #{url}")
return {:http => url}
end
# HELPERS
def artifacts_dir()
return File.join(Pod::Config.instance.project_pods_root, "hermes-engine-artifacts")
end
def hermestag_file(react_native_path)
return File.join(react_native_path, "sdks", ".hermesversion")
end
def release_tarball_url(version, build_type)
# Sample url from Maven:
# 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
return "https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/#{version}/react-native-artifacts-#{version}-hermes-ios-#{build_type.to_s}.tar.gz"
end
def download_stable_hermes(react_native_path, version, configuration)
tarball_url = release_tarball_url(version, configuration)
download_hermes_tarball(react_native_path, tarball_url, version, configuration)
end
def download_hermes_tarball(react_native_path, tarball_url, version, configuration)
destination_path = configuration == nil ?
"#{artifacts_dir()}/hermes-ios-#{version}.tar.gz" :
"#{artifacts_dir()}/hermes-ios-#{version}-#{configuration}.tar.gz"
unless File.exist?(destination_path)
# Download to a temporary file first so we don't cache incomplete downloads.
tmp_file = "#{artifacts_dir()}/hermes-ios.download"
`mkdir -p "#{artifacts_dir()}" && curl "#{tarball_url}" -Lo "#{tmp_file}" && mv "#{tmp_file}" "#{destination_path}"`
end
return destination_path
end
def nightly_tarball_url(version)
params = "r=snapshots\&g=com.facebook.react\&a=react-native-artifacts\&c=hermes-ios-debug\&e=tar.gz\&v=#{version}-SNAPSHOT"
return resolve_url_redirects("http://oss.sonatype.org/service/local/artifact/maven/redirect\?#{params}")
end
def resolve_url_redirects(url)
return (`curl -Ls -o /dev/null -w %{url_effective} \"#{url}\"`)
end
# This function checks that Hermes artifact exists.
# As of now it should check it on the Maven repo.
#
# Parameters
# - version: the version of React Native
# - build_type: debug or release
def hermes_artifact_exists(tarball_url)
# -L is used to follow redirects, useful for the nightlies
# I also needed to wrap the url in quotes to avoid escaping & and ?.
return (`curl -o /dev/null --silent -Iw '%{http_code}' -L "#{tarball_url}"` == "200")
end
def hermes_log(message, level = :warning)
if !Object.const_defined?("Pod::UI")
return
end
hermes_log_messgae = '[Hermes] ' + message
case level
when :info
Pod::UI.puts hermes_log_messgae.green
when :error
Pod::UI.puts hermes_log_messgae.red
else
Pod::UI.puts hermes_log_messgae.yellow
end
end

View File

@@ -0,0 +1,216 @@
#!/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)
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 get_release_version {
use_env_var_or_ruby_prop "${RELEASE_VERSION}" "version"
}
function get_ios_deployment_target {
use_env_var_or_ruby_prop "${IOS_DEPLOYMENT_TARGET}" "deployment_target('ios')"
}
function get_mac_deployment_target {
use_env_var_or_ruby_prop "${MAC_DEPLOYMENT_TARGET}" "deployment_target('osx')"
}
# 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/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/Library/Frameworks/macosx" "destroot/bin" "destroot/Library/Frameworks/iphoneos" "destroot/Library/Frameworks/iphonesimulator" "destroot/Library/Frameworks/catalyst"
cp -R "./build_macosx/API/hermes/hermes.framework"* "destroot/Library/Frameworks/macosx"
cp -R "./build_iphoneos/API/hermes/hermes.framework"* "destroot/Library/Frameworks/iphoneos"
cp -R "./build_iphonesimulator/API/hermes/hermes.framework"* "destroot/Library/Frameworks/iphonesimulator"
cp -R "./build_catalyst/API/hermes/hermes.framework"* "destroot/Library/Frameworks/catalyst"
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/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"
local dSYM_path="$hermes_framework_path"
local dSYM_base_path="$HERMES_PATH/destroot/Library/Frameworks"
# If the dSYM rename has failed, the dSYM are generated as 0.dSYM
# (Apple default name) rather then hermes.framework.dSYM.
if [[ -e "$dSYM_base_path/${platform}/0.dSYM" ]]; then
dSYM_path="${platform}/0"
fi
args+="-framework $hermes_framework_path "
# Path to dSYM must be absolute
args+="-debug-symbols $dSYM_base_path/$dSYM_path.dSYM "
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
}

View File

@@ -0,0 +1,94 @@
#!/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
release_version="$1"; shift
hermesc_path="$1"; shift
jsi_path="$1"; shift
# Based on platform name returns the framework copy destination. Used later by `vendored_frameworks` in Podspec.
# Fallbacks to "ios" if platform is not recognized.
function get_platform_copy_destination {
if [[ $1 == "macosx" ]]; then
echo "macosx"
return
fi
echo "ios"
}
function get_deployment_target {
if [[ $1 == "macosx" ]]; then
echo ${MACOSX_DEPLOYMENT_TARGET}
return
fi
echo ${IPHONEOS_DEPLOYMENT_TARGET}
}
enable_debugger="false"
if [[ "$CONFIGURATION" == "Debug" ]]; then
enable_debugger="true"
fi
cmake_build_type=""
if [[ $CONFIGURATION == "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
deployment_target=$(get_deployment_target $PLATFORM_NAME)
xcode_15_flags=""
xcode_major_version=$(xcodebuild -version | grep -oE '[0-9]*' | head -n 1)
if [[ $xcode_major_version -ge 15 ]]; then
echo "########### Using LINKER:-ld_classic ###########"
xcode_15_flags="LINKER:-ld_classic"
fi
architectures=$( echo "$ARCHS" | tr " " ";" )
echo "Configure Apple framework"
"$CMAKE_BINARY" \
-S "${PODS_ROOT}/hermes-engine" \
-B "${PODS_ROOT}/hermes-engine/build/${PLATFORM_NAME}" \
-DHERMES_EXTRA_LINKER_FLAGS="$xcode_15_flags" \
-DHERMES_APPLE_TARGET_PLATFORM:STRING="$PLATFORM_NAME" \
-DCMAKE_OSX_ARCHITECTURES:STRING="$architectures" \
-DCMAKE_OSX_DEPLOYMENT_TARGET:STRING="$deployment_target" \
-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="${hermesc_path}" \
-DJSI_DIR="$jsi_path" \
-DHERMES_RELEASE_VERSION="for RN $release_version" \
-DCMAKE_BUILD_TYPE="$cmake_build_type"
echo "Build Apple framework"
"$CMAKE_BINARY" \
--build "${PODS_ROOT}/hermes-engine/build/${PLATFORM_NAME}" \
--target libhermes \
-j "$(sysctl -n hw.ncpu)"
echo "Copy Apple framework to destroot/Library/Frameworks"
platform_copy_destination=$(get_platform_copy_destination $PLATFORM_NAME)
cp -pfR \
"${PODS_ROOT}/hermes-engine/build/${PLATFORM_NAME}/API/hermes/hermes.framework" \
"${PODS_ROOT}/hermes-engine/destroot/Library/Frameworks/${platform_copy_destination}"

View File

@@ -0,0 +1,18 @@
#!/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 -e
hermesc_dir_path="$1"; shift
jsi_path="$1"
# This script is supposed to be executed from Xcode "run script" phase.
# Xcode sets up its build environment based on the build target (iphone, iphonesimulator, macodsx).
# We want to make sure that hermesc is built for mac.
# So we clean the environment with env -i, and explicitly set SDKROOT to macosx
SDKROOT=$(xcode-select -p)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
env -i SDKROOT="$SDKROOT" "$CMAKE_BINARY" -S "${PODS_ROOT}/hermes-engine" -B "$hermesc_dir_path" -DJSI_DIR="$jsi_path"
env -i SDKROOT="$SDKROOT" "$CMAKE_BINARY" --build "$hermesc_dir_path" --target hermesc -j "$(sysctl -n hw.ncpu)"

View File

@@ -0,0 +1,77 @@
#!/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.
if [ "$CI" ]; then
set -x
fi
set -e
# Given a specific target, retrieve the right architecture for it
# $1 the target you want to build. Allowed values: iphoneos, iphonesimulator, catalyst
function get_architecture {
if [[ $1 == "iphoneos" ]]; then
echo "arm64"
elif [[ $1 == "iphonesimulator" ]]; then
echo "x86_64;arm64"
elif [[ $1 == "catalyst" ]]; then
echo "x86_64;arm64"
else
echo "Error: unknown architecture passed $1"
exit 1
fi
}
# build a single framework
# $1 is the target to build
function build_framework {
if [ ! -d destroot/Library/Frameworks/universal/hermes.xcframework ]; then
ios_deployment_target=$(get_ios_deployment_target)
architecture=$(get_architecture "$1")
build_apple_framework "$1" "$architecture" "$ios_deployment_target"
else
echo "Skipping; Clean \"destroot\" to rebuild".
fi
}
# group the frameworks together to create a universal framework
function build_universal_framework {
if [ ! -d destroot/Library/Frameworks/universal/hermes.xcframework ]; then
create_universal_framework "iphoneos" "iphonesimulator" "catalyst"
else
echo "Skipping; Clean \"destroot\" to rebuild".
fi
}
# single function that builds sequentially iphoneos, iphonesimulator and catalyst
# this is used to preserve backward compatibility
function create_framework {
if [ ! -d destroot/Library/Frameworks/universal/hermes.xcframework ]; then
ios_deployment_target=$(get_ios_deployment_target)
build_framework "iphoneos"
build_framework "iphonesimulator"
build_framework "catalyst"
build_universal_framework
else
echo "Skipping; Clean \"destroot\" to rebuild".
fi
}
CURR_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
# shellcheck source=xplat/js/react-native-github/sdks/hermes-engine/utils/build-apple-framework.sh
. "${CURR_SCRIPT_DIR}/build-apple-framework.sh"
if [[ -z $1 ]]; then
create_framework
elif [[ $1 == "build_framework" ]]; then
build_universal_framework
else
build_framework "$1"
fi

View File

@@ -0,0 +1,22 @@
#!/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.
if [ "$CI" ]; then
set -x
fi
set -e
# shellcheck source=xplat/js/react-native-github/sdks/hermes-engine/utils/build-apple-framework.sh
CURR_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
. "${CURR_SCRIPT_DIR}/build-apple-framework.sh"
if [ ! -d destroot/Library/Frameworks/macosx/hermes.framework ]; then
mac_deployment_target=$(get_mac_deployment_target)
build_apple_framework "macosx" "x86_64;arm64" "$mac_deployment_target"
else
echo "Skipping; Clean \"destroot\" to rebuild".
fi

View File

@@ -0,0 +1,7 @@
#!/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.
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."

View File

@@ -0,0 +1,32 @@
#!/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
platforms=( "macosx" "ios" ) # Add other platforms here if needed
for platform in "${platforms[@]}"
do
mkdir -p "${platform}/hermes.framework"
clang dummy.c -dynamiclib -o "${platform}/hermes.framework/hermes"
done
rm dummy.c
popd > /dev/null || exit 1

View File

@@ -0,0 +1,106 @@
/**
* 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.
*
* @format
*/
'use strict';
const {execSync} = require('child_process');
const fs = require('fs');
const yargs = require('yargs');
const LAST_BUILD_FILENAME = '.last_build_configuration';
function validateBuildConfiguration(configuration) {
if (!['Debug', 'Release'].includes(configuration)) {
throw new Error(`Invalid configuration ${configuration}`);
}
}
function validateVersion(version) {
if (version == null || version === '') {
throw new Error('Version cannot be empty');
}
}
function shouldReplaceHermesConfiguration(configuration) {
const fileExists = fs.existsSync(LAST_BUILD_FILENAME);
if (fileExists) {
console.log(`Found ${LAST_BUILD_FILENAME} file`);
const oldConfiguration = fs.readFileSync(LAST_BUILD_FILENAME).toString();
if (oldConfiguration === configuration) {
console.log(
'Same config of the previous build. No need to replace Hermes engine',
);
return false;
}
}
// Assumption: if there is no stored last build, we assume that it was build for debug.
if (!fileExists && configuration === 'Debug') {
console.log(
'No previous build detected, but Debug Configuration. No need to replace Hermes engine',
);
return false;
}
return true;
}
function replaceHermesConfiguration(configuration, version, podsRoot) {
const tarballURLPath = `${podsRoot}/hermes-engine-artifacts/hermes-ios-${version.toLowerCase()}-${configuration.toLowerCase()}.tar.gz`;
const finalLocation = 'hermes-engine';
console.log('Preparing the final location');
fs.rmSync(finalLocation, {force: true, recursive: true});
fs.mkdirSync(finalLocation, {recursive: true});
console.log('Extracting the tarball');
execSync(`tar -xf ${tarballURLPath} -C ${finalLocation}`);
}
function updateLastBuildConfiguration(configuration) {
fs.writeFileSync(LAST_BUILD_FILENAME, configuration);
}
function main(configuration, version, podsRoot) {
validateBuildConfiguration(configuration);
validateVersion(version);
if (!shouldReplaceHermesConfiguration(configuration)) {
return;
}
replaceHermesConfiguration(configuration, version, podsRoot);
updateLastBuildConfiguration(configuration);
console.log('Done replacing hermes-engine');
}
// This script is executed in the Pods folder, which is usually not synched to Github, so it should be ok
const argv = yargs
.option('c', {
alias: 'configuration',
description:
'Configuration to use to download the right Hermes version. Allowed values are "Debug" and "Release".',
})
.option('r', {
alias: 'reactNativeVersion',
description:
'The Version of React Native associated with the Hermes tarball.',
})
.option('p', {
alias: 'podsRoot',
description: 'The path to the Pods root folder',
})
.usage('Usage: $0 -c Debug -r <version> -p <path/to/react-native>').argv;
const configuration = argv.configuration;
const version = argv.reactNativeVersion;
const podsRoot = argv.podsRoot;
main(configuration, version, podsRoot);

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,15 @@
#!/usr/bin/env python
# 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.
import os
import sys
# Make sure we can find the lit package.
sys.path.insert(0, os.path.join("/Users/distiller/react-native/packages/react-native/sdks/hermes/external/llvh", 'utils', 'lit'))
if __name__=='__main__':
from lit.main import main
main({})

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.