1#!/bin/bash 2 3# Copyright (c) 2022 Huawei Device Co., Ltd. 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16set -e 17 18CUR_PATH=$(cd $(dirname ${BASH_SOURCE[0]}) && pwd) 19BASE_PATH=$(dirname ${CUR_PATH}) 20ROOT_PATH=$(cd ${CUR_PATH}/../../.. && pwd) && cd - 21 22arg_project="" 23arg_sdk_path="" 24arg_build_sdk="false" 25arg_help="0" 26arg_url="" 27arg_branch="" 28arg_npm="" 29arg_ohpm="" 30arg_out_path="${ROOT_PATH}/out/hap" 31arg_sign_tool="${ROOT_PATH}/developtools/hapsigner/dist" 32arg_p7b="" 33arg_apl="normal" 34arg_feature="hos_normal_app" 35arg_profile="UnsgnedReleasedProfileTemplate.json" 36arg_bundle_name="" 37 38ohos_sdk_path="${ROOT_PATH}/out/sdk/packages/ohos-sdk/linux" 39 40function print_help() { 41 cat <<EOF 42 use assembleHap [options] <mainclass> [args...] 43 44EOF 45} 46 47 48function clear_dir(){ 49 if [ ! -d "$1" ]; then 50 mkdir -p $1 51 fi 52} 53 54 55function is_project_root(){ 56 if [ -f $1"/build-profile.json5" ]; then 57 return 0 58 else 59 return 1 60 fi 61} 62 63function build_sdk() { 64 if [ -d ${ohos_sdk_path} ]; then 65 echo "ohos-sdk exists." 66 return 0 67 fi 68 SDK_PREBUILTS_PATH=${ROOT_PATH}/out/sdk/packages/ohos-sdk 69 pushd ${ROOT_PATH} 70 echo "building the latest ohos-sdk..." 71 ./build.py --product-name ohos-sdk --load-test-config=false --get-warning-list=false --stat-ccache=false --compute-overlap-rate=false --deps-guard=false --generate-ninja-trace=false --gn-args skip_generate_module_list_file=true sdk_platform=linux ndk_platform=linux use_cfi=false use_thin_lto=false enable_lto_O0=true sdk_check_flag=false enable_ndk_doxygen=false archive_ndk=false sdk_for_hap_build=true 72 if [[ "$?" -ne 0 ]]; then 73 echo "ohos-sdk build failed! You can try to use '--no-prebuilt-sdk' to skip the build of ohos-sdk." 74 exit 1 75 fi 76 if [ -d "${SDK_PREBUILTS_PATH}/linux" ]; then 77 rm -rf ${SDK_PREBUILTS_PATH}/linux 78 fi 79 mkdir -p ${SDK_PREBUILTS_PATH} 80 mv ${ROOT_PATH}/out/sdk/ohos-sdk/linux ${SDK_PREBUILTS_PATH}/ 81 mkdir -p ${SDK_PREBUILTS_PATH}/linux/native 82 mv ${ROOT_PATH}/out/sdk/sdk-native/os-irrelevant/* ${SDK_PREBUILTS_PATH}/linux/native/ 83 mv ${ROOT_PATH}/out/sdk/sdk-native/os-specific/linux/* ${SDK_PREBUILTS_PATH}/linux/native/ 84 pushd ${SDK_PREBUILTS_PATH}/linux 85 api_version=$(grep apiVersion toolchains/oh-uni-package.json | awk '{print $2}' | sed -r 's/\",?//g') || api_version="11" 86 mkdir -p $api_version 87 for i in */; do 88 if [ -d "$i" ] && [ "$i" != "$api_version/" ]; then 89 mv $i $api_version 90 fi 91 done 92 popd 93 popd 94} 95 96function parse_arguments() { 97 local helperKey=""; 98 local helperValue=""; 99 local current=""; 100 101 while [ "$1" != "" ]; do 102 current=$1; 103 helperKey=${current#*--}; 104 helperKey=${helperKey%%=*}; 105 helperKey=$(echo "$helperKey" | tr '-' '_'); 106 helperValue=${current#*=}; 107 if [ "$helperValue" == "$current" ]; then 108 helperValue="1"; 109 fi 110 #echo "eval arg_$helperKey=\"$helperValue\""; 111 112 eval "arg_$helperKey=\"$helperValue\""; 113 shift 114 done 115} 116 117 118parse_arguments "${@}"; 119 120if [ "$arg_help" != "0" ]; then 121 print_help; 122 exit 1; 123fi 124 125# Called in the warm-up process to ensure that the docker is the latest SDK every day 126# Called like this: ./build.sh --build_sdk 127if [ "$arg_build_sdk" == "1" ]; then 128 rm -rf ${ohos_sdk_path} 129 build_sdk 130 exit 0; 131fi 132 133if [ "$arg_build_sdk" == "true" ]; then 134 echo "start build sdk" 135 build_sdk 136 if [[ "$?" -ne 0 ]]; then 137 echo "ohos-sdk build failed! You can try to use '--no-prebuilt-sdk' to skip the build of ohos-sdk." 138 exit 1 139 fi 140 export OHOS_SDK_HOME=${ohos_sdk_path} 141 echo "set OHOS_SDK_HOME to" ${OHOS_SDK_HOME} 142fi 143 144 145export PATH=/home/tools/command-line-tools/ohpm/bin:$PATH 146npm config set registry https://repo.huaweicloud.com/repository/npm/ 147npm config set @ohos:registry https://repo.harmonyos.com/npm/ 148npm config set strict-ssl false 149npm config set lockfile false 150cat $HOME/.npmrc | grep 'lockfile=false' || echo 'lockfile=false' >> $HOME/.npmrc 151if [ -d ${ROOT_PATH}/prebuilts/ohos-sdk/linux/10 ]; then 152 mkdir -p ${ohos_sdk_path} 153 mv -n ${ROOT_PATH}/prebuilts/ohos-sdk/linux/10 ${ohos_sdk_path} 154 pushd ${ohos_sdk_path} 155 sdk_version=$(grep version 10/toolchains/oh-uni-package.json | awk '{print $2}' | sed -r 's/\",?//g') 156 mkdir -p ets 157 ln -nsf ../10/ets ets/$sdk_version 158 mkdir -p js 159 ln -nsf ../10/js js/$sdk_version 160 mkdir -p toolchains 161 ln -nsf ../10/toolchains toolchains/$sdk_version 162 mkdir -p native 163 ln -nsf ../10/native native/$sdk_version 164 mkdir -p previewer 165 ln -nsf ../10/previewer previewer/$sdk_version 166 popd 167fi 168if [ -d ${ROOT_PATH}/prebuilts/ohos-sdk/linux/11 ]; then 169 mkdir -p ${ohos_sdk_path} 170 mv -n ${ROOT_PATH}/prebuilts/ohos-sdk/linux/11 ${ohos_sdk_path} 171 pushd ${ohos_sdk_path} 172 sdk_version=$(grep version 11/toolchains/oh-uni-package.json | awk '{print $2}' | sed -r 's/\",?//g') 173 mkdir -p ets 174 ln -nsf ../11/ets ets/$sdk_version 175 mkdir -p js 176 ln -nsf ../11/js js/$sdk_version 177 mkdir -p toolchains 178 ln -nsf ../11/toolchains toolchains/$sdk_version 179 mkdir -p native 180 ln -nsf ../11/native native/$sdk_version 181 mkdir -p previewer 182 ln -nsf ../11/previewer previewer/$sdk_version 183 popd 184fi 185if [ "${arg_project}" == "" -a "${arg_url}" == "" ]; then 186 echo "--project or --url is not null" 187 exit 1; 188fi 189 190 191if [ ! -d "${arg_project}" ]; then 192 echo "${arg_project} is not dir" 193 exit 1; 194fi 195 196 197if [[ ${arg_project} = */ ]]; then 198 arg_project=${arg_project%/} 199fi 200 201 202if [[ ${arg_sign_tool} = */ ]]; then 203 arg_sign_tool=${arg_sign_tool%/} 204fi 205 206if [[ ${arg_p7b} = "" ]]; then 207 arg_p7b=$(find ${arg_project} -name *.p7b | head -n 1) 208 if [[ ${arg_p7b} = "" ]]; then 209 arg_p7b=openharmony_sx.p7b 210 fi 211fi 212 213clear_dir ${arg_out_path} 214 215 216if [ "${arg_url}" != "" ]; then 217 if [ "${arg_branch}" == "" ]; then 218 echo "branch is not null" 219 exit 1 220 fi 221 project_name=${arg_url##*/} 222 project_name=${project_name%%.git*} 223 if test -d ${BASE_PATH}/projects/${project_name} 224 then 225 echo "${project_name} exists,ready for update..." 226 cd ${BASE_PATH}/projects/${project_name} 227 git fetch origin ${arg_branch} 228 git reset --hard origin/${arg_branch} 229 git pull 230 else 231 echo "${project_name} dose not exist,ready to download..." 232 cd ${BASE_PATH}/projects 233 git clone -b ${arg_branch} ${arg_url} ${project_name} 234 fi 235 arg_project=${BASE_PATH}/projects/${project_name} 236fi 237 238 239if ! is_project_root ${arg_project}; then 240 echo "${arg_project} is not OpenHarmony Project" 241 exit 1; 242fi 243 244if [ "${arg_sdk_path}" != "" ]; then 245 export OHOS_SDK_HOME=${arg_sdk_path} 246fi 247export OHOS_BASE_SDK_HOME=${OHOS_SDK_HOME} 248 249echo "start build hap..." 250cd ${arg_project} 251echo "sdk.dir=${OHOS_SDK_HOME}" > ./local.properties 252echo "nodejs.dir=${NODE_HOME}" >> ./local.properties 253 254echo "use sdk:"${OHOS_SDK_HOME} 255 256is_ohpm=true 257package_json_name="oh-package.json5" 258if [ ! -f ${arg_project}/${package_json_name} ]; then 259 is_ohpm=false 260 package_json_name="package.json" 261fi 262 263if ${is_ohpm}; then 264 if [ "${arg_ohpm}" == "" ]; then 265 arg_ohpm="@ohos:registry https://ohpm.openharmony.cn/ohpm/" 266 fi 267 echo "ohpm config set ${arg_ohpm}" 268 ohpm config set ${arg_ohpm} 269else 270 if [ "${arg_npm}" == "" ]; then 271 arg_npm="@ohos:registry=https://repo.harmonyos.com/npm/" 272 fi 273 echo "npm config set ${arg_npm}" 274 npm config set ${arg_npm} 275fi 276 277module_list=() 278module_name=() 279out_module=() 280bundle_name="" 281 282 283function del_module_name(){ 284 name=${1} 285 for i in "${!module_name[@]}" 286 do 287 if [[ "${module_name[i]}" == "${name}" ]]; then 288 unset module_name[i] 289 echo "移除"${name}" , 剩余 : "${module_name[@]} 290 return 0 291 fi 292 done 293 return 1 294} 295 296 297function load_dep(){ 298 local cur_m_n=${1} 299 local cur_module 300 for cur_module in ${module_list[@]} 301 do 302 if [[ "${cur_module}" =~ "${cur_m_n}" ]]; then 303 del_module_name ${cur_m_n} 304 for m_n_1 in ${module_name[@]} 305 do 306 rr=$(cat ${cur_module}"/${package_json_name}" | grep "${m_n_1}" || true) 307 if [[ "${rr}" != "" ]]; then 308 load_dep ${m_n_1} 309 fi 310 done 311 cd ${cur_module} 312 echo ${cur_module}" 执行npm/ohpm install" 313 if ${is_ohpm}; then 314 ohpm install 315 else 316 npm i 317 fi 318 319 fi 320 done 321} 322 323 324while read line 325do 326 if [[ ${line} =~ "srcPath" ]]; then 327 pa=${line%\"*} 328 pa=${pa##*\".} 329 module_list[${#module_list[*]}]=${arg_project}${pa} 330 module_name[${#module_name[*]}]=${pa} 331 if [ -d "${arg_project}/AppScope" ]; then 332 cur_bundle_line=`cat ${arg_project}/AppScope/app.json5 | grep "\"bundleName\""` 333 bundle_name=${cur_bundle_line%\"*} 334 bundle_name=${bundle_name##*\"} 335 # echo "bundleName : "${bundle_name} 336 is_entry=`cat ${arg_project}${pa}/src/main/module.json5 | sed 's/ //g' | grep "\"type\":\"entry\"" || true` 337 is_feature=`cat ${arg_project}${pa}/src/main/module.json5 | sed 's/ //g' | grep "\"type\":\"feature\"" || true` 338 if [[ "${is_entry}" != "" || "${is_feature}" != "" ]]; then 339 echo "hap输出module: "${arg_project}${pa} 340 out_module[${#out_module[*]}]=${arg_project}${pa} 341 fi 342 else 343 cur_bundle_line=`cat ${arg_project}${pa}/src/main/config.json | grep "\"bundleName\""` 344 bundle_name=${cur_bundle_line%\"*} 345 bundle_name=${bundle_name##*\"} 346 # echo "bundleName : "${bundle_name} 347 is_entry=`cat ${arg_project}${pa}/src/main/config.json | sed 's/ //g' | grep "\"moduleType\":\"entry\"" || true` 348 is_feature=`cat ${arg_project}${pa}/src/main/config.json | sed 's/ //g' | grep "\"moduleType\":\"feature\"" || true` 349 if [[ "${is_entry}" != "" || "${is_feature}" != "" ]]; then 350 echo "hap输出module: "${arg_project}${pa} 351 out_module[${#out_module[*]}]=${arg_project}${pa} 352 fi 353 fi 354 fi 355done < ${arg_project}"/build-profile.json5" 356 357 358for module in ${module_list[@]} 359do 360 if del_module_name ${module##${arg_project}}; then 361 for m_n in ${module_name[@]} 362 do 363 rr=$(cat ${module}"/${package_json_name}" | grep "${m_n}" || true) 364 if [[ "${rr}" != "" ]]; then 365 load_dep ${m_n} 366 fi 367 done 368 cd ${module} 369 echo ${module}" 执行npm/ohpm install" 370 if ${is_ohpm}; then 371 ohpm install 372 else 373 npm i 374 fi 375 fi 376done 377 378 379cd ${arg_project} 380echo ${arg_project}" 执行npm/ohpm install" 381if ${is_ohpm}; then 382 ohpm install 383 chmod +x hvigorw 384 # Historical reasons need to be compatible with NODE_HOME path issue 385 if grep -q "\${NODE_HOME}/bin/node" hvigorw ; then 386 # node home path include "bin" 387 if [ ! -x "${NODE_HOME}/bin/node" ];then 388 export NODE_HOME=$(dirname ${NODE_HOME}) 389 fi 390 else 391 # node home path does not include "bin" 392 if [ -x "${NODE_HOME}/bin/node" ];then 393 export NODE_HOME=${NODE_HOME}/bin 394 fi 395 fi 396 ./hvigorw clean --no-daemon 397 ./hvigorw assembleHap --mode module -p product=default -p debuggable=false --no-daemon 398else 399 npm install 400 node ./node_modules/@ohos/hvigor/bin/hvigor.js clean 401 node ./node_modules/@ohos/hvigor/bin/hvigor.js --mode module clean assembleHap -p debuggable=false 402fi 403 404 405 406for module in ${out_module[@]} 407do 408 cur_out_module_name=${module##*/} 409 is_sign=false 410 echo "module = ${module} , cur_out_module_name=${cur_out_module_name}" 411 if [ ! -d ${module}/build/default/outputs/default/ ]; then 412 echo "module = ${module}, assembleHap error !!!" 413 continue 414 fi 415 for out_file in `ls ${module}/build/default/outputs/default/` 416 do 417 if [[ "${out_file}" =~ "-signed.hap" ]]; then 418 is_sign=true 419 echo "发现signed包 : "${out_file}",直接归档" 420 cp ${module}/build/default/outputs/default/${out_file} ${arg_out_path}/ 421 break 422 fi 423 done 424 if test ${is_sign} = false 425 then 426 hap_name=${arg_project##*/} 427 # echo "${hap_name},skip sign 'hap'. Invalid signingConfig is configured for 'default' product." 428 for out_file in `ls ${module}/build/default/outputs/default/` 429 do 430 if [[ "${out_file}" =~ "-unsigned.hap" ]]; then 431 echo "发现unsigned包 : "${out_file}",开始使用签名工具签名" 432 nosign_hap_path=${module}/build/default/outputs/default/${out_file} 433 sign_hap_path=${module}/build/default/outputs/default/${out_file/unsigned/signed} 434 cp -r ${arg_sign_tool} ${arg_project}/ 435 cd ${arg_project}/dist 436 if [ ! -e ${arg_profile} ]; then 437 echo "${arg_profile} not exist! ! !" 438 exit 1 439 fi 440 if [ "${arg_bundle_name}" != "" ]; then 441 sed -i "s/\"com.OpenHarmony.app.test\"/\"${arg_bundle_name}\"/g" ${arg_profile} 442 else 443 sed -i "s/\"com.OpenHarmony.app.test\"/\"${bundle_name}\"/g" ${arg_profile} 444 fi 445 sed -i "s/\"normal\"/\"${arg_apl}\"/g" ${arg_profile} 446 sed -i "s/\"system_basic\"/\"${arg_apl}\"/g" ${arg_profile} 447 sed -i "s/\"system_core\"/\"${arg_apl}\"/g" ${arg_profile} 448 sed -i "s/\"hos_normal_app\"/\"${arg_feature}\"/g" ${arg_profile} 449 sed -i "s/\"hos_system_app\"/\"${arg_feature}\"/g" ${arg_profile} 450 java -jar hap-sign-tool.jar sign-profile -keyAlias "openharmony application profile release" -signAlg "SHA256withECDSA" -mode "localSign" -profileCertFile "OpenHarmonyProfileRelease.pem" -inFile "${arg_profile}" -keystoreFile "OpenHarmony.p12" -outFile "openharmony_sx.p7b" -keyPwd "123456" -keystorePwd "123456" 451 java -jar hap-sign-tool.jar sign-app -keyAlias "openharmony application release" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "OpenHarmonyApplication.pem" -profileFile "${arg_p7b}" -inFile "${nosign_hap_path}" -keystoreFile "OpenHarmony.p12" -outFile "${sign_hap_path}" -keyPwd "123456" -keystorePwd "123456" 452 cp ${sign_hap_path} ${arg_out_path}/ 453 is_sign=true 454 fi 455 done 456 if test ${is_sign} = false 457 then 458 echo "${module} assembleHap error !!!" 459 rm -rf ${arg_project}/sign_helper 460 exit 1 461 fi 462 fi 463done 464rm -rf ${arg_project}/sign_helper 465 466# backup sourceMaps.json files for DFR 467cd ${arg_project} 468find . -name "sourceMaps.json" -type f | while read file; do 469 sourceMaps_path=$(echo ${file} | sed 's/^\.\///;s/\/sourceMaps.json$//') 470 mkdir -p ${arg_out_path}/${sourceMaps_path} 471 cp ${file} ${arg_out_path}/${sourceMaps_path}/ 472done 473 474exit 0 475