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 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 [ -d ${ROOT_PATH}/prebuilts/ohos-sdk/linux/12 ]; then 186 mkdir -p ${ohos_sdk_path} 187 mv -n ${ROOT_PATH}/prebuilts/ohos-sdk/linux/12 ${ohos_sdk_path} 188 pushd ${ohos_sdk_path} 189 sdk_version=$(grep version 12/toolchains/oh-uni-package.json | awk '{print $2}' | sed -r 's/\",?//g') 190 mkdir -p ets 191 ln -nsf ../12/ets ets/$sdk_version 192 mkdir -p js 193 ln -nsf ../12/js js/$sdk_version 194 mkdir -p toolchains 195 ln -nsf ../12/toolchains toolchains/$sdk_version 196 mkdir -p native 197 ln -nsf ../12/native native/$sdk_version 198 mkdir -p previewer 199 ln -nsf ../12/previewer previewer/$sdk_version 200 popd 201fi 202if [ -d ${ROOT_PATH}/prebuilts/ohos-sdk/linux/14 ]; then 203 mkdir -p ${ohos_sdk_path} 204 mv -n ${ROOT_PATH}/prebuilts/ohos-sdk/linux/14 ${ohos_sdk_path} 205 pushd ${ohos_sdk_path} 206 sdk_version=$(grep version 14/toolchains/oh-uni-package.json | awk '{print $2}' | sed -r 's/\",?//g') 207 mkdir -p ets 208 ln -nsf ../14/ets ets/$sdk_version 209 mkdir -p js 210 ln -nsf ../14/js js/$sdk_version 211 mkdir -p toolchains 212 ln -nsf ../14/toolchains toolchains/$sdk_version 213 mkdir -p native 214 ln -nsf ../14/native native/$sdk_version 215 mkdir -p previewer 216 ln -nsf ../14/previewer previewer/$sdk_version 217 popd 218fi 219if [ -d ${ROOT_PATH}/prebuilts/ohos-sdk/linux/18 ]; then 220 mkdir -p ${ohos_sdk_path} 221 mv -n ${ROOT_PATH}/prebuilts/ohos-sdk/linux/18 ${ohos_sdk_path} 222 pushd ${ohos_sdk_path} 223 sdk_version=$(grep version 18/toolchains/oh-uni-package.json | awk '{print $2}' | sed -r 's/\",?//g') 224 mkdir -p ets 225 ln -nsf ../18/ets ets/$sdk_version 226 mkdir -p js 227 ln -nsf ../18/js js/$sdk_version 228 mkdir -p toolchains 229 ln -nsf ../18/toolchains toolchains/$sdk_version 230 mkdir -p native 231 ln -nsf ../18/native native/$sdk_version 232 mkdir -p previewer 233 ln -nsf ../18/previewer previewer/$sdk_version 234 popd 235fi 236if [ -d ${ROOT_PATH}/prebuilts/ohos-sdk/linux/19 ]; then 237 mkdir -p ${ohos_sdk_path} 238 mv -n ${ROOT_PATH}/prebuilts/ohos-sdk/linux/19 ${ohos_sdk_path} 239 pushd ${ohos_sdk_path} 240 sdk_version=$(grep version 19/toolchains/oh-uni-package.json | awk '{print $2}' | sed -r 's/\",?//g') 241 mkdir -p ets 242 ln -nsf ../19/ets ets/$sdk_version 243 mkdir -p js 244 ln -nsf ../19/js js/$sdk_version 245 mkdir -p toolchains 246 ln -nsf ../19/toolchains toolchains/$sdk_version 247 mkdir -p native 248 ln -nsf ../19/native native/$sdk_version 249 mkdir -p previewer 250 ln -nsf ../19/previewer previewer/$sdk_version 251 popd 252fi 253if [ -d ${ROOT_PATH}/prebuilts/ohos-sdk/linux/20 ]; then 254 mkdir -p ${ohos_sdk_path} 255 mv -n ${ROOT_PATH}/prebuilts/ohos-sdk/linux/20 ${ohos_sdk_path} 256 pushd ${ohos_sdk_path} 257 sdk_version=$(grep version 20/toolchains/oh-uni-package.json | awk '{print $2}' | sed -r 's/\",?//g') 258 mkdir -p ets 259 ln -nsf ../20/ets ets/$sdk_version 260 mkdir -p js 261 ln -nsf ../20/js js/$sdk_version 262 mkdir -p toolchains 263 ln -nsf ../20/toolchains toolchains/$sdk_version 264 mkdir -p native 265 ln -nsf ../20/native native/$sdk_version 266 mkdir -p previewer 267 ln -nsf ../20/previewer previewer/$sdk_version 268 popd 269fi 270if [ "${arg_project}" == "" -a "${arg_url}" == "" ]; then 271 echo "--project or --url is not null" 272 exit 1; 273fi 274 275 276if [ ! -d "${arg_project}" ]; then 277 echo "${arg_project} is not dir" 278 exit 1; 279fi 280 281 282if [[ ${arg_project} = */ ]]; then 283 arg_project=${arg_project%/} 284fi 285 286 287if [[ ${arg_sign_tool} = */ ]]; then 288 arg_sign_tool=${arg_sign_tool%/} 289fi 290 291if [[ ${arg_p7b} = "" ]]; then 292 arg_p7b=$(find ${arg_project} -name *.p7b | head -n 1) 293 if [[ ${arg_p7b} = "" ]]; then 294 arg_p7b=openharmony_sx.p7b 295 fi 296fi 297 298clear_dir ${arg_out_path} 299 300 301if [ "${arg_url}" != "" ]; then 302 if [ "${arg_branch}" == "" ]; then 303 echo "branch is not null" 304 exit 1 305 fi 306 project_name=${arg_url##*/} 307 project_name=${project_name%%.git*} 308 if test -d ${BASE_PATH}/projects/${project_name} 309 then 310 echo "${project_name} exists,ready for update..." 311 cd ${BASE_PATH}/projects/${project_name} 312 git fetch origin ${arg_branch} 313 git reset --hard origin/${arg_branch} 314 git pull 315 else 316 echo "${project_name} dose not exist,ready to download..." 317 cd ${BASE_PATH}/projects 318 git clone -b ${arg_branch} ${arg_url} ${project_name} 319 fi 320 arg_project=${BASE_PATH}/projects/${project_name} 321fi 322 323 324if ! is_project_root ${arg_project}; then 325 echo "${arg_project} is not OpenHarmony Project" 326 exit 1; 327fi 328 329if [ "${arg_sdk_path}" != "" ]; then 330 export OHOS_SDK_HOME=${arg_sdk_path} 331fi 332export OHOS_BASE_SDK_HOME=${OHOS_SDK_HOME} 333 334echo "start build hap..." 335cd ${arg_project} 336echo "sdk.dir=${OHOS_SDK_HOME}" > ./local.properties 337echo "nodejs.dir=${NODE_HOME}" >> ./local.properties 338 339echo "use sdk:"${OHOS_SDK_HOME} 340 341is_ohpm=true 342package_json_name="oh-package.json5" 343if [ ! -f ${arg_project}/${package_json_name} ]; then 344 is_ohpm=false 345 package_json_name="package.json" 346fi 347 348if ${is_ohpm}; then 349 if [ "${arg_ohpm}" == "" ]; then 350 arg_ohpm="@ohos:registry https://ohpm.openharmony.cn/ohpm/" 351 fi 352 echo "ohpm config set ${arg_ohpm}" 353 ohpm config set ${arg_ohpm} 354else 355 if [ "${arg_npm}" == "" ]; then 356 arg_npm="@ohos:registry=https://repo.harmonyos.com/npm/" 357 fi 358 echo "npm config set ${arg_npm}" 359 npm config set ${arg_npm} 360fi 361 362module_list=() 363module_name=() 364out_module=() 365bundle_name="" 366 367 368function del_module_name(){ 369 name=${1} 370 for i in "${!module_name[@]}" 371 do 372 if [[ "${module_name[i]}" == "${name}" ]]; then 373 unset module_name[i] 374 echo "移除"${name}" , 剩余 : "${module_name[@]} 375 return 0 376 fi 377 done 378 return 1 379} 380 381 382function load_dep(){ 383 local cur_m_n=${1} 384 local cur_module 385 for cur_module in ${module_list[@]} 386 do 387 if [[ "${cur_module}" =~ "${cur_m_n}" ]]; then 388 del_module_name ${cur_m_n} 389 for m_n_1 in ${module_name[@]} 390 do 391 rr=$(cat ${cur_module}"/${package_json_name}" | grep "${m_n_1}" || true) 392 if [[ "${rr}" != "" ]]; then 393 load_dep ${m_n_1} 394 fi 395 done 396 cd ${cur_module} 397 echo ${cur_module}" 执行npm/ohpm install" 398 if ${is_ohpm}; then 399 ohpm install 400 else 401 npm i 402 fi 403 404 fi 405 done 406} 407 408 409while read line 410do 411 if [[ ${line} =~ "srcPath" ]]; then 412 pa=${line%\"*} 413 pa=${pa##*\".} 414 module_list[${#module_list[*]}]=${arg_project}${pa} 415 module_name[${#module_name[*]}]=${pa} 416 if [ -d "${arg_project}/AppScope" ]; then 417 cur_bundle_line=`cat ${arg_project}/AppScope/app.json5 | grep "\"bundleName\""` 418 bundle_name=${cur_bundle_line%\"*} 419 bundle_name=${bundle_name##*\"} 420 # echo "bundleName : "${bundle_name} 421 is_entry=`cat ${arg_project}${pa}/src/main/module.json5 | sed 's/ //g' | grep "\"type\":\"entry\"" || true` 422 is_feature=`cat ${arg_project}${pa}/src/main/module.json5 | sed 's/ //g' | grep "\"type\":\"feature\"" || true` 423 if [[ "${is_entry}" != "" || "${is_feature}" != "" ]]; then 424 echo "hap输出module: "${arg_project}${pa} 425 out_module[${#out_module[*]}]=${arg_project}${pa} 426 fi 427 else 428 cur_bundle_line=`cat ${arg_project}${pa}/src/main/config.json | grep "\"bundleName\""` 429 bundle_name=${cur_bundle_line%\"*} 430 bundle_name=${bundle_name##*\"} 431 # echo "bundleName : "${bundle_name} 432 is_entry=`cat ${arg_project}${pa}/src/main/config.json | sed 's/ //g' | grep "\"moduleType\":\"entry\"" || true` 433 is_feature=`cat ${arg_project}${pa}/src/main/config.json | sed 's/ //g' | grep "\"moduleType\":\"feature\"" || true` 434 if [[ "${is_entry}" != "" || "${is_feature}" != "" ]]; then 435 echo "hap输出module: "${arg_project}${pa} 436 out_module[${#out_module[*]}]=${arg_project}${pa} 437 fi 438 fi 439 fi 440done < ${arg_project}"/build-profile.json5" 441 442 443for module in ${module_list[@]} 444do 445 if del_module_name ${module##${arg_project}}; then 446 for m_n in ${module_name[@]} 447 do 448 rr=$(cat ${module}"/${package_json_name}" | grep "${m_n}" || true) 449 if [[ "${rr}" != "" ]]; then 450 load_dep ${m_n} 451 fi 452 done 453 cd ${module} 454 echo ${module}" 执行npm/ohpm install" 455 if ${is_ohpm}; then 456 ohpm install 457 else 458 npm i 459 fi 460 fi 461done 462 463 464cd ${arg_project} 465echo ${arg_project}" 执行npm/ohpm install" 466if ${is_ohpm}; then 467 ohpm install 468 if [ ! -f "hvigorw" ]; then 469 hvigorw clean --no-daemon 470 hvigorw assembleHap --mode module -p product=default -p debuggable=false --no-daemon 471 else 472 chmod +x hvigorw 473 # Historical reasons need to be compatible with NODE_HOME path issue 474 if grep -q "\${NODE_HOME}/bin/node" hvigorw ; then 475 # node home path include "bin" 476 if [ ! -x "${NODE_HOME}/bin/node" ];then 477 export NODE_HOME=$(dirname ${NODE_HOME}) 478 fi 479 else 480 # node home path does not include "bin" 481 if [ -x "${NODE_HOME}/bin/node" ];then 482 export NODE_HOME=${NODE_HOME}/bin 483 fi 484 fi 485 ./hvigorw clean --no-daemon 486 ./hvigorw assembleHap --mode module -p product=default -p debuggable=false --no-daemon 487 fi 488else 489 npm install 490 node ./node_modules/@ohos/hvigor/bin/hvigor.js clean 491 node ./node_modules/@ohos/hvigor/bin/hvigor.js --mode module clean assembleHap -p debuggable=false 492fi 493 494 495 496for module in ${out_module[@]} 497do 498 cur_out_module_name=${module##*/} 499 is_sign=false 500 echo "module = ${module} , cur_out_module_name=${cur_out_module_name}" 501 if [ ! -d ${module}/build/default/outputs/default/ ]; then 502 echo "module = ${module}, assembleHap error !!!" 503 continue 504 fi 505 for out_file in `ls ${module}/build/default/outputs/default/` 506 do 507 if [[ "${out_file}" =~ "-signed.hap" ]]; then 508 is_sign=true 509 echo "发现signed包 : "${out_file}",直接归档" 510 cp ${module}/build/default/outputs/default/${out_file} ${arg_out_path}/ 511 break 512 fi 513 done 514 if test ${is_sign} = false 515 then 516 hap_name=${arg_project##*/} 517 # echo "${hap_name},skip sign 'hap'. Invalid signingConfig is configured for 'default' product." 518 for out_file in `ls ${module}/build/default/outputs/default/` 519 do 520 if [[ "${out_file}" =~ "-unsigned.hap" ]]; then 521 echo "发现unsigned包 : "${out_file}",开始使用签名工具签名" 522 nosign_hap_path=${module}/build/default/outputs/default/${out_file} 523 sign_hap_path=${module}/build/default/outputs/default/${out_file/unsigned/signed} 524 cp -r ${arg_sign_tool} ${arg_project}/ 525 cd ${arg_project}/dist 526 if [ ! -e ${arg_profile} ]; then 527 echo "${arg_profile} not exist! ! !" 528 exit 1 529 fi 530 if [ "${arg_bundle_name}" != "" ]; then 531 sed -i "s/\"com.OpenHarmony.app.test\"/\"${arg_bundle_name}\"/g" ${arg_profile} 532 else 533 sed -i "s/\"com.OpenHarmony.app.test\"/\"${bundle_name}\"/g" ${arg_profile} 534 fi 535 sed -i "s/\"normal\"/\"${arg_apl}\"/g" ${arg_profile} 536 sed -i "s/\"system_basic\"/\"${arg_apl}\"/g" ${arg_profile} 537 sed -i "s/\"system_core\"/\"${arg_apl}\"/g" ${arg_profile} 538 sed -i "s/\"hos_normal_app\"/\"${arg_feature}\"/g" ${arg_profile} 539 sed -i "s/\"hos_system_app\"/\"${arg_feature}\"/g" ${arg_profile} 540 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" 541 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" 542 cp ${sign_hap_path} ${arg_out_path}/ 543 is_sign=true 544 fi 545 done 546 if test ${is_sign} = false 547 then 548 echo "${module} assembleHap error !!!" 549 rm -rf ${arg_project}/sign_helper 550 exit 1 551 fi 552 fi 553done 554rm -rf ${arg_project}/sign_helper 555 556# backup sourceMaps.json files for DFR 557cd ${arg_project} 558find . -name "sourceMaps.json" -type f | while read file; do 559 sourceMaps_path=$(echo ${file} | sed 's/^\.\///;s/\/sourceMaps.json$//') 560 mkdir -p ${arg_out_path}/${sourceMaps_path} 561 cp ${file} ${arg_out_path}/${sourceMaps_path}/ 562done 563 564exit 0 565