1#!/bin/bash 2# Copyright (c) 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. 14set -e 15 16script_path=$(cd $(dirname $0);pwd) 17code_dir=$(dirname ${script_path}) 18home_path=$HOME 19config_file="$script_path/prebuilts_config.json" 20 21 22# 处理命令行参数 23declare -A args 24parse_args(){ 25 while [[ $# -gt 0 ]]; do 26 case "$1" in 27 # 处理长参数(带等号) 28 --*=*) 29 key="${1%%=*}" # 提取参数名 30 value="${1#*=}" # 提取参数值 31 args["$key"]="$value" # 取最后的值 32 shift 33 ;; 34 # 处理长参数(不带等号) 35 --*) 36 key="$1" 37 shift 38 values=() 39 # 收集所有连续的非选项参数作为值 40 while [[ $# -gt 0 && "$1" != -* ]]; do 41 values+=("$1") 42 shift 43 done 44 if [[ ${#values[@]} -eq 0 ]]; then 45 args["$key"]="1" # 无值参数标记为1 46 else 47 args["$key"]="${values[*]}" # 合并为空格分隔的字符串 48 fi 49 ;; 50 # 处理短参数(带等号,如 -k=value) 51 -*=*) 52 key_part="${1%%=*}" # 提取短参数部分(如 -abc=value → -abc) 53 value="${1#*=}" # 提取值 54 chars="${key_part:1}" # 去掉前缀的短参数(如 abc) 55 # 处理除最后一个字符外的所有字符(作为无值参数) 56 while [[ ${#chars} -gt 1 ]]; do 57 args["-${chars:0:1}"]="1" 58 chars="${chars:1}" 59 done 60 # 最后一个字符作为带值参数 61 args["-${chars}"]="$value" 62 shift 63 ;; 64 # 处理短参数(不带等号) 65 -*) 66 chars="${1:1}" # 去掉短参数前缀(如 abc) 67 while [[ -n "$chars" ]]; do 68 key="-${chars:0:1}" 69 chars="${chars:1}" 70 # 如果还有剩余字符或后续参数是选项,视为无值参数 71 if [[ -n "$chars" ]] || [[ $# -gt 1 && "$2" == -* ]]; then 72 args["$key"]="1" 73 else 74 # 否则取下一个参数作为值 75 args["$key"]="$2" 76 shift 77 fi 78 done 79 shift 80 ;; 81 # 不处理其他参数 82 *) 83 shift 84 ;; 85 esac 86 done 87 88 for key in "${!args[@]}"; do 89 # 去除值首位的空格(因追加逻辑可能产生) 90 value="${args[$key]# }" 91 args[$key]=$value 92 done 93} 94 95parse_args "$@" 96 97case $(uname -s) in 98 Linux) 99 host_platform=linux 100 glibc_version=$(getconf GNU_LIBC_VERSION | grep -oE '[0-9].[0-9]{2}') 101 ;; 102 Darwin) 103 host_platform=darwin 104 ;; 105 *) 106 echo "Unsupported host platform: $(uname -s)" 107 exit 1 108esac 109 110case $(uname -m) in 111 arm64) 112 host_cpu=arm64 113 host_cpu_prefix=arm64 114 ;; 115 aarch64) 116 host_cpu=arm64 117 host_cpu_prefix=aarch64 118 ;; 119 *) 120 host_cpu=x86_64 121 host_cpu_prefix=x86 122esac 123 124if [[ "${glibc_version}" < "2.35" ]]; then 125 glibc_version="--glibc-version GLIBC2.27" 126else 127 glibc_version="--glibc-version GLIBC2.35" 128fi 129 130if [[ -v args["--pypi-url"] ]]; then 131 pypi_url=${args["--pypi_url"]} 132else 133 pypi_url='http://repo.huaweicloud.com/repository/pypi/simple' 134fi 135 136if [[ -v args["--trusted_host"] ]]; then 137 trusted_host=${args["--trusted_host"]} 138elif [ ! -z "$pypi_url" ];then 139 trusted_host=${pypi_url/#*:\/\//} # remove prefix part such as http:// https:// etc. 140 trusted_host=${trusted_host/%[:\/]*/} # remove suffix part including the port number 141else 142 trusted_host='repo.huaweicloud.com' 143fi 144 145 146if [[ -v args["--disable-rich"] ]]; then 147 disable_rich='--disable-rich' 148else 149 set +e 150 pip3 install --trusted-host $trusted_host -i $pypi_url rich; 151 if [ $? -eq 0 ];then 152 echo "rich installed successfully" 153 else 154 disable_rich='--disable-rich' 155 fi 156 set -e 157fi 158 159if [[ -v args["--part-names"] ]]; then 160 part_names="--part-names ${args["--part-names"]}" 161fi 162 163# 运行Python命令 164python3 "${script_path}/prebuilts_config.py" $glibc_version --config-file $config_file --host-platform $host_platform --host-cpu $host_cpu $disable_rich $part_names 165PYTHON_PATH=$(realpath $code_dir/prebuilts/python/${host_platform}-${host_cpu_prefix}/*/bin | tail -1) 166 167if [[ -v args["--download-sdk"] ]]; then 168 DOWNLOAD_SDK=YES 169fi 170 171if ! [[ -v args["--part-names"] ]]; then 172 if [[ "$DOWNLOAD_SDK" == "YES" ]] && [[ ! -d "${code_dir}/prebuilts/ohos-sdk/linux" ]]; then 173 $PYTHON_PATH/python3 ${code_dir}/build/scripts/download_sdk.py --branch master --product-name ohos-sdk-full-linux --api-version 20 174 fi 175fi 176 177 178 179if [[ "${target_os}" == "linux" ]]; then 180 sed -i "1s%.*%#!/usr/bin/env python3%" "${PYTHON_PATH}/pip3" 181elif [[ "${target_os}" == "darwin" ]]; then 182 sed -i "" "1s%.*%#!/usr/bin/env python3%" "${PYTHON_PATH}/pip3" 183fi 184 185# llvm_ndk is merged form llvm and libcxx-ndk for compiling the native of hap 186llvm_dir="${code_dir}/prebuilts/clang/ohos/linux-x86_64" 187llvm_dir_win="${code_dir}/prebuilts/clang/ohos/windows-x86_64" 188llvm_dir_mac_x86="${code_dir}/prebuilts/clang/ohos/darwin-x86_64" 189llvm_dir_mac_arm64="${code_dir}/prebuilts/clang/ohos/darwin-arm64" 190llvm_dir_list=($llvm_dir $llvm_dir_win $llvm_dir_mac_x86 $llvm_dir_mac_arm64) 191 192# copy libcxx-ndk library outside c++ 193function copy_inside_cxx(){ 194for i in ${llvm_dir_list[@]} 195do 196 libcxx_dir="${i}/libcxx-ndk/lib" 197 if [[ -d "${i}/libcxx-ndk" ]]; then 198 for file in $(ls ${libcxx_dir}) 199 do 200 if [ ! -d "${libcxx_dir}/${file}/c++" ];then 201 $(mkdir -p ${libcxx_dir}/c++) 202 $(cp -r ${libcxx_dir}/${file}/* ${libcxx_dir}/c++) 203 $(mv ${libcxx_dir}/c++ ${libcxx_dir}/${file}/c++) 204 fi 205 done 206 fi 207done 208} 209 210function update_llvm_ndk(){ 211if [[ -e "${llvm_dir}/llvm_ndk" ]];then 212 rm -rf "${llvm_dir}/llvm_ndk" 213fi 214mkdir -p "${llvm_dir}/llvm_ndk" 215cp -af "${llvm_dir}/llvm/include" "${llvm_dir}/llvm_ndk" 216cp -rfp "${llvm_dir}/libcxx-ndk/include" "${llvm_dir}/llvm_ndk" 217} 218 219function change_rustlib_name(){ 220rust_dir="${code_dir}/prebuilts/rustc/linux-x86_64/current/lib/rustlib/" 221for file in $(find "$rust_dir" -path "$rust_dir/x86_64-unknown-linux-gnu" -prune -o -name "lib*.*") 222do 223 dir_name=${file%/*} 224 file_name=${file##*/} 225 file_prefix=$(echo "$file_name" | awk '{split($1, arr, "."); print arr[1]}') 226 file_prefix=$(echo "$file_prefix" | awk '{split($1, arr, "-"); print arr[1]}') 227 file_suffix=$(echo "$file_name" | awk '{split($1, arr, "."); print arr[2]}') 228 if [[ "$file_suffix" != "rlib" && "$file_suffix" != "so" || "$file_prefix" == "librustc_demangle" || "$file_prefix" == "libcfg_if" || "$file_prefix" == "libunwind" ]] 229 then 230 continue 231 fi 232 if [[ "$file_suffix" == "rlib" ]] 233 then 234 if [[ "$file_prefix" == "libstd" || "$file_prefix" == "libtest" ]] 235 then 236 newfile_name="$file_prefix.dylib.rlib" 237 else 238 newfile_name="$file_prefix.rlib" 239 fi 240 fi 241 242 if [[ "$file_suffix" == "so" ]] 243 then 244 newfile_name="$file_prefix.dylib.so" 245 fi 246 if [[ "$file_name" == "$newfile_name" ]] 247 then 248 continue 249 fi 250 mv $file "$dir_name/$newfile_name" 251done 252} 253copy_inside_cxx 254echo "======copy inside cxx finished!======" 255echo -e "\033[0;33myou can use --skip-prebuilts to skip prebuilts_download step while using hb build command\033[0m" 256