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