1#!/usr/bin/env bash 2# Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15set -e 16 17MSG_PREFIX="[ARK THIRD PARTY]" 18SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)" 19ARK_ROOT=$SCRIPT_DIR/.. 20ARK_THIRD_PARTY_DIR=$ARK_ROOT/third_party 21ARK_THIRD_PARTY_FORCE_CLONE=no 22ARK_INSTALL_NODE=no 23NUM_CLONE_ATTEMPTS=5 24 25MIRROR_ARK_THIRD_PARTY_MANIFEST="$SCRIPT_DIR/extras/third-party-lists/mirror" 26PUBLIC_ARK_THIRD_PARTY_MANIFEST="$SCRIPT_DIR/third-party-lists/public" 27if [ -f "${MIRROR_ARK_THIRD_PARTY_MANIFEST}" ]; then 28 ARK_THIRD_PARTY_MANIFEST="${MIRROR_ARK_THIRD_PARTY_MANIFEST}" 29else 30 ARK_THIRD_PARTY_MANIFEST="${PUBLIC_ARK_THIRD_PARTY_MANIFEST}" 31fi 32 33function print_help() { 34 HELP_MESSAGE=" 35 This script installs build-time third party dependencies for ARK Runtime. 36 37 SYNOPSIS 38 39 $0 [OPTIONS] 40 41 OPTIONS 42 43 --help, -h Show this message and exit. 44 45 --manifest=FILE Path to the manifest. Default: $ARK_THIRD_PARTY_MANIFEST 46 47 --force-clone Remove local repositories and re-clone everything anew 48 49 --clone-attempts=N Try to clone N times. Default: $NUM_CLONE_ATTEMPTS 50 51 --node Install node js to third-party 52 53 --repo-name=repo install specific repo 54 55 CAVEAT 56 * Manifest file format is documented in the default manifest. 57 " 58 59 echo "$HELP_MESSAGE" 60} 61 62declare -a REPOS=() 63 64for opt in "$@"; do 65 case $opt in 66 -h|--help) 67 print_help 68 exit 0 69 ;; 70 --manifest=*) 71 ARK_THIRD_PARTY_MANIFEST=${opt//[-a-zA-Z0-9]*=/} 72 ;; 73 --force-clone) 74 ARK_THIRD_PARTY_FORCE_CLONE=yes 75 ;; 76 --clone-attempts=*) 77 NUM_CLONE_ATTEMPTS=${opt//[-a-zA-Z0-9]*=/} 78 ;; 79 --node) 80 ARK_INSTALL_NODE=yes 81 ;; 82 --repo-name=*) 83 REPOS+=("${opt#*=}") 84 ;; 85 *) 86 echo "Error: Unsupported flag $opt" >&2 87 exit 1 88 ;; 89 esac 90done 91 92 93mapfile -t REPOS< <(for r in "${REPOS[@]}"; do echo "$r"; done | sort -u) 94readonly -a REPOS 95 96function requested_repo() { 97 for one_repo in "${REPOS[@]}" 98 do 99 if [[ "${one_repo}" == "$1" ]] 100 then 101 return 0 102 fi 103 done 104 return 1 105} 106 107function clone_repository_branch() { 108 local lib_repo="$1" 109 local lib_dir="$2" 110 local commit_id="$3" # branch or tag name, the syntax is the same 111 112 for i in `seq 1 $NUM_CLONE_ATTEMPTS` 113 do 114 echo "$MSG_PREFIX Cloning $lib_dir, attempt $i / $NUM_CLONE_ATTEMPTS" 115 116 GIT_SSL_NO_VERIFY=true git clone --verbose --depth=1 --branch "$commit_id" \ 117 "$lib_repo" "$lib_dir" || continue 118 119 return 120 done 121 122 echo "$MSG_PREFIX Failed to clone $lib_dir" 123 exit 1 124} 125 126function clone_repository() { 127 local lib_repo="$1" 128 local lib_dir="$2" 129 130 for i in `seq 1 $NUM_CLONE_ATTEMPTS` 131 do 132 echo "$MSG_PREFIX Cloning $lib_dir, attempt $i / $NUM_CLONE_ATTEMPTS" 133 GIT_SSL_NO_VERIFY=true git clone --verbose "$lib_repo" "$lib_dir" || continue 134 135 pushd "$lib_dir" 136 git checkout "$commit_id" 137 popd 138 return 139 done 140 141 echo "$MSG_PREFIX Failed to clone $lib_dir" 142 exit 1 143} 144 145function apply_patches() { 146 local lib_name="$1" 147 local lib_dir="$2" 148 149 local patch_dir="$ARK_ROOT/patches/$lib_name" 150 if [[ ! -d "$patch_dir" ]] ; then 151 echo "$MSG_PREFIX No patch directory $patch_dir for $lib_name" 152 exit 1 153 fi 154 155 pushd "$lib_dir" 156 readarray -t patches <<< "$(find "$patch_dir" -name '*.patch' | sort)" 157 for patch in "${patches[@]}" 158 do 159 git apply --ignore-space-change --check "$patch" 160 git am --ignore-space-change "$patch" 161 done 162 popd 163} 164 165function process_manifest() { 166 local manifest="$1" 167 168 while read -r component 169 do 170 component=$(echo "$component" | perl -lane 'chomp; s/^\s+//; s/\s+$//; print $_') 171 172 if [[ "$component" == "" || "$component" =~ ^# ]] ; then 173 continue 174 fi 175 176 IFS=',' read -r -a info <<< "$component" 177 local lib_name="${info[0]}" 178 local lib_repo="${info[1]}" 179 local commit_type="${info[2]}" 180 local commit_id="${info[3]}" 181 local patch_mode="${info[4]}" 182 local submodule_mode="${info[5]}" 183 if [[ ${#REPOS[@]} -ne 0 ]] && ! requested_repo "${lib_name}" ; then 184 continue 185 fi 186 187 local lib_dir="$ARK_THIRD_PARTY_DIR/$lib_name" 188 189 if [[ -d "$lib_dir" && ${#REPOS[@]} -eq 0 ]] ; then 190 echo "$MSG_PREFIX $lib_dir already exists. Skip download." 191 continue 192 fi; 193 194 if [[ "$commit_type" == "branch" || "$commit_type" == "tag" ]] ; then 195 clone_repository_branch "$lib_repo" "$lib_dir" "$commit_id" 196 elif [[ "$commit_type" == "commit" ]] ; then 197 clone_repository "$lib_repo" "$lib_dir" 198 else 199 echo "$MSG_PREFIX Invalid commit type for $lib_name: $commit_type" 200 exit 1 201 fi 202 203 if [[ "$patch_mode" == "with_patches" ]] ; then 204 apply_patches "$lib_name" "$lib_dir" 205 elif [[ "$patch_mode" != "no_patches" ]] ; then 206 echo "$MSG_PREFIX Invalid patch mode for $lib_name: $patch_mode" 207 exit 1 208 fi 209 210 if [[ "$submodule_mode" =~ ^with_submodules: ]] ; then 211 # Split by delimiter and remove "with_submodules" keyword: 212 IFS=':' read -r -a submodules <<< "$submodule_mode" 213 submodules=("${submodules[@]:1}") 214 pushd "$lib_dir" 215 for submodule in "${submodules[@]}" 216 do 217 git submodule update --init "$submodule" 218 done 219 popd 220 elif [[ "$submodule_mode" != "no_submodules" ]] ; then 221 echo "$MSG_PREFIX Invalid submodule mode for $lib_name: $submodule_mode" 222 exit 1 223 fi 224 225 done < "$manifest" 226} 227 228if [[ "$ARK_INSTALL_NODE" == "yes" ]] ; then 229 NODE_VERSION="v18.13.0" 230 DISTRO="linux-x64" 231 if [ -f "$SCRIPT_DIR/extras/install_nodejs.sh" ]; then 232 bash $SCRIPT_DIR/extras/install_nodejs.sh --node-version=${NODE_VERSION} --distro=${DISTRO} 233 else 234 if [ ! -d "${ARK_THIRD_PARTY_DIR}/nodejs" ] 235 then 236 echo "-- Downloading nodejs for interop tests" 237 ARCHIVE_NAME=node-${NODE_VERSION}-${DISTRO}.tar.xz 238 wget -q -P ${ARK_THIRD_PARTY_DIR}/nodejs https://nodejs.org/dist/${NODE_VERSION}/${ARCHIVE_NAME} 239 tar -xJf ${ARK_THIRD_PARTY_DIR}/nodejs/${ARCHIVE_NAME} -C ${ARK_THIRD_PARTY_DIR}/nodejs 240 rm ${ARK_THIRD_PARTY_DIR}/nodejs/${ARCHIVE_NAME} 241 fi 242 fi 243 244 exit 0 245fi 246 247if [[ "$ARK_THIRD_PARTY_FORCE_CLONE" == "yes" ]] ; then 248 if [[ -L "$ARK_THIRD_PARTY_DIR/arkcompiler/toolchain" ]] ; then 249 # remove all folders in third_party except arkcompiler if arkcompiler/toolchain is symlink 250 cd "$ARK_THIRD_PARTY_DIR" && rm -rf `ls | grep -v arkcompiler` 251 else 252 rm -rf "$ARK_THIRD_PARTY_DIR" 253 fi 254fi 255 256if [[ -d "$ARK_THIRD_PARTY_DIR" && ${#REPOS[@]} -eq 0 ]] ; then 257 echo "$MSG_PREFIX Third-party dependencies are found in $ARK_THIRD_PARTY_DIR" 258 echo "$MSG_PREFIX If you need to update all, restart this script with --force-clone" 259fi 260 261if [[ ${#REPOS[@]} -ne 0 ]] ; then 262 for third_party_repo in "${REPOS[@]}" 263 do 264 rm -rf "$ARK_THIRD_PARTY_DIR/${third_party_repo}" 265 done 266fi 267 268echo "$MSG_PREFIX Third-party dependencies are not found in $ARK_THIRD_PARTY_DIR" 269 270if [[ ! -f "$ARK_THIRD_PARTY_MANIFEST" ]] ; then 271 echo "$MSG_PREFIX Invalid manifest file '$ARK_THIRD_PARTY_MANIFEST'" 272 exit 1 273fi 274 275echo "$MSG_PREFIX Using manifest $ARK_THIRD_PARTY_MANIFEST" 276process_manifest "$ARK_THIRD_PARTY_MANIFEST" 277 278echo "$MSG_PREFIX Third-party dependencies installed" 279exit 0 280 281