#!/bin/bash
if [ -z "$DEVECO_SDK_HOME" ]; then
echo "Environment variable DEVECO_SDK_HOME is not defined"
exit 1
fi
ENABLE_DEBUGGER=${HERMES_ENABLE_DEBUGGER:-false}
HERMES_V1_ENABLED=${HERMES_V1_ENABLED:-true}
HERMES_REPO_URL="https://github.com/facebook/hermes.git"
REACT_NATIVE_VERSION="0.84.1"
HERMES_TAG="hermes-v0.15.1"
HERMES_V1_BRANCH="250829098.0.0-stable"
HERMES_V1_COMMIT="7f41c52586c320ef8341fa3a7ba10c6c3212bc6f"
HERMES_V1_VERSION="250829098.0.9"
SCRIPT_PATH=$(realpath "$0")
SCRIPT_DIR=$(dirname "$SCRIPT_PATH")
THIRD_PARTY_DIR="$SCRIPT_DIR/../../tester/harmony/react_native_openharmony/src/main/cpp/third-party"
OUTPUT_DIR="$SCRIPT_DIR/out"
HERMES_SRC_DIR="$OUTPUT_DIR/hermes"
HERMES_RELEASE_VERSION="for RN $REACT_NATIVE_VERSION"
if [ -d "$HERMES_SRC_DIR" ]; then
echo "Removing existing Hermes sources at $HERMES_SRC_DIR"
rm -rf "$HERMES_SRC_DIR"
fi
echo "Cloning hermes"
if [ "$HERMES_V1_ENABLED" = "true" ]; then
HERMES_RELEASE_VERSION="$HERMES_V1_VERSION"
git clone --branch "$HERMES_V1_BRANCH" --single-branch "$HERMES_REPO_URL" "$HERMES_SRC_DIR"
if [ -n "$HERMES_V1_COMMIT" ]; then
(cd "$HERMES_SRC_DIR" && git checkout "$HERMES_V1_COMMIT")
fi
else
git clone -b "$HERMES_TAG" --depth 1 "$HERMES_REPO_URL" "$HERMES_SRC_DIR"
fi
echo
echo "Applying CMakeLists.txt patch to hermes"
if [ "$HERMES_V1_ENABLED" = "true" ]; then
(cd "$HERMES_SRC_DIR" && git apply "$SCRIPT_DIR/hermesv1_cmakelists.patch")
else
(cd "$HERMES_SRC_DIR" && git apply "$SCRIPT_DIR/hermes_cmakelists.patch")
fi
if [ $? -ne 0 ]; then
echo "FAILED to apply patch."
echo "Fix the CMakeLists.txt file yourself and generate a new patch for this version of hermes before running the build script again."
echo "See the 'git apply' output for details"
exit 1
fi
echo
if [ "$HERMES_V1_ENABLED" = "true" ]; then
ARCHITECTURES=("arm64-v8a" "x86_64")
else
ARCHITECTURES=("armeabi-v7a" "arm64-v8a" "x86_64")
fi
OHOS_SDK_NATIVE_DIR=$DEVECO_SDK_HOME/default/openharmony/native
BUILD_HERMESC_DIR=$OUTPUT_DIR/hermesc
JSI_DIR=$(realpath "$THIRD_PARTY_DIR/rn/ReactCommon/jsi")
echo "############# ENABLE_DEBUGGER ${ENABLE_DEBUGGER}"
if [ "$ENABLE_DEBUGGER" = "true" ]; then
CMAKE_BUILD_TYPE_FLAG="Release"
BUILD_TYPE_FLAG="debug"
HERMES_ENABLE_DEBUGGER=True
CFLAGS="-g"
CXXFLAGS="-g"
else
BUILD_TYPE_FLAG="release"
CMAKE_BUILD_TYPE_FLAG="MinSizeRel"
HERMES_ENABLE_DEBUGGER=False
CFLAGS="-O3 -DNDEBUG"
CXXFLAGS="-O3 -DNDEBUG"
fi
$OHOS_SDK_NATIVE_DIR/build-tools/cmake/bin/cmake \
-S$HERMES_SRC_DIR \
-B$BUILD_HERMESC_DIR \
-DJSI_DIR=$JSI_DIR \
-DCMAKE_BUILD_TYPE=Release
$OHOS_SDK_NATIVE_DIR/build-tools/cmake/bin/cmake \
--build $BUILD_HERMESC_DIR \
--target hermesc -j 4
for ARCHITECTURE in "${ARCHITECTURES[@]}"; do
echo "Building Hermes@$ARCHITECTURE"
BUILD_TARGET_DIRECTORY="$OUTPUT_DIR/${BUILD_TYPE_FLAG}/${ARCHITECTURE}-output"
BUILD_LIBRARY_DIRECTORY="$OUTPUT_DIR/${BUILD_TYPE_FLAG}/${ARCHITECTURE}-lib"
$OHOS_SDK_NATIVE_DIR/build-tools/cmake/bin/cmake \
-H$HERMES_SRC_DIR \
-B$BUILD_TARGET_DIRECTORY \
-GNinja \
-DCMAKE_SYSTEM_NAME=OHOS \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DCMAKE_SYSTEM_VERSION=1 \
-DOHOS_ARCH=$ARCHITECTURE \
-DOHOS_STL=c++_shared \
-DCMAKE_TOOLCHAIN_FILE=$OHOS_SDK_NATIVE_DIR/build/cmake/ohos.toolchain.cmake \
-DCMAKE_MAKE_PROGRAM=$OHOS_SDK_NATIVE_DIR/build-tools/cmake/bin/ninja \
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=$BUILD_LIBRARY_DIRECTORY \
-DIMPORT_HOST_COMPILERS=$BUILD_HERMESC_DIR/ImportHostCompilers.cmake \
-DJSI_DIR=$JSI_DIR \
-DHERMES_IS_ANDROID=True \
-DHERMES_SLOW_DEBUG=False \
-DHERMES_BUILD_SHARED_JSI=True \
-DHERMES_RELEASE_VERSION="$HERMES_RELEASE_VERSION" \
-DHERMES_ENABLE_INTL=False \
-DHERMES_ENABLE_DEBUGGER=${HERMES_ENABLE_DEBUGGER} \
-DCMAKE_BUILD_WITH_INSTALL_RPATH=On \
-DHERMES_ENABLE_TEST_SUITE=False \
-DHERMES_UNICODE_LITE=True \
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE_FLAG} \
-DCMAKE_C_FLAGS="${CFLAGS}" \
-DCMAKE_CXX_FLAGS="${CXXFLAGS}" \
-DCMAKE_SHARED_LINKER_FLAGS_RELEASE="-Wl,--build-id" \
-DHERMESVM_HEAP_HV_MODE=HEAP_HV_PREFER32
if [ $? -ne 0 ]; then
echo "FAILED to configure Hermes@$ARCHITECTURE."
exit 1
fi
$OHOS_SDK_NATIVE_DIR/build-tools/cmake/bin/ninja \
-C \
$BUILD_TARGET_DIRECTORY \
hermesvm
if [ $? -ne 0 ]; then
echo "FAILED to build Hermes@$ARCHITECTURE."
exit 1
fi
done
strip_and_separate_debug() {
local INPUT_FILE="$1"
local OUTPUT_DIR="$2"
local BASENAME=$(basename "$INPUT_FILE")
if [ ! -f "$INPUT_FILE" ]; then
echo "Warning: $INPUT_FILE not found, skipping strip"
return 1
fi
echo "Extracting debug symbols from $BASENAME..."
local OBJ_COPY=llvm-objcopy
if command -v $OHOS_SDK_NATIVE_DIR/llvm/bin/llvm-objcopy &> /dev/null; then
OBJ_COPY=$OHOS_SDK_NATIVE_DIR/llvm/bin/llvm-objcopy
elif command -v objcopy &> /dev/null; then
OBJ_COPY=objcopy
else
echo "Warning: Neither llvm-objcopy nor objcopy found, skipping debug extraction"
exit 1
fi
$OBJ_COPY --only-keep-debug "$INPUT_FILE" "$OUTPUT_DIR/${BASENAME}.sym"
local SYM_TXT_NAME="$OUTPUT_DIR/${BASENAME}.debug.txt"
echo "Build ID: $(readelf -n "$INPUT_FILE" 2>/dev/null | grep 'Build ID' | head -1)" > $SYM_TXT_NAME
echo "Architecture: $ARCHITECTURE" >> $SYM_TXT_NAME
echo "Build Type: $BUILD_TYPE_FLAG" >> $SYM_TXT_NAME
echo "Timestamp: $(date -u +"%Y-%m-%d %H:%M:%S UTC")" >> $SYM_TXT_NAME
$OBJ_COPY --strip-debug "$INPUT_FILE"
$OBJ_COPY --add-gnu-debuglink="$OUTPUT_DIR/${BASENAME}.sym" "$INPUT_FILE"
echo "Debug symbols separated to: $OUTPUT_DIR/${BASENAME}.sym"
echo "Debug info file: $SYM_TXT_NAME"
return 0
}
for ARCHITECTURE in "${ARCHITECTURES[@]}"; do
mkdir -p "$THIRD_PARTY_DIR/prebuilt/${BUILD_TYPE_FLAG}/$ARCHITECTURE"
if [ "$HERMES_V1_ENABLED" = "true" ]; then
INPUT_SO="$OUTPUT_DIR/${BUILD_TYPE_FLAG}/${ARCHITECTURE}-lib/libhermesvm.so"
else
INPUT_SO="$OUTPUT_DIR/${BUILD_TYPE_FLAG}/${ARCHITECTURE}-output/lib/libhermesvm.so"
fi
OUTPUT_DIR_PREBUILT="$THIRD_PARTY_DIR/prebuilt/${BUILD_TYPE_FLAG}/$ARCHITECTURE"
echo "Copying $INPUT_SO to $OUTPUT_DIR_PREBUILT/libhermesvm.so"
echo ""
echo "Separating debug symbols for release build..."
strip_and_separate_debug "$INPUT_SO" "$OUTPUT_DIR_PREBUILT"
cp -f "$INPUT_SO" "$OUTPUT_DIR_PREBUILT/libhermesvm.so"
echo "Done: $ARCHITECTURE"
echo ""
done