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