1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3# 4# Copyright (c) 2024 Huawei Device Co., Ltd. 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16# 17 18import os 19import sys 20import subprocess 21import shutil 22import logging 23 24logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') 25logging.basicConfig(level=logging.ERROR, format='%(asctime)s - %(levelname)s - %(message)s') 26 27usage_info = """ 28USAGE 29 ./build.sh [suite=BUILD_TARGET] [target_os=TARGET_OS] [target_arch=TARGET_ARCH] [variant=BUILD_VARIANT] [target_subsystem=TARGET_SUBSYSTEM] [xts_suitetype=SUITE_TYPE_LIST] 30 suite : BUILD_TARGET acts, hats, dcts 31 target_arch : TARGET_ARCH arm64 or arm, default value is arm 32 variant : BUILD_VARIANT release or debug, default value is debug 33 target_subsystem : TARGET_SUBSYSTEM the target subsystem to build 34 system_size : SYSTEM_SIZE standard 35 product_name : PRODUCT_NAME the name of product. such as Hi3516DV300, and so on. 36 xts_suitetype : SUITE_TYPE_LIST {bin, hap_dynamic, hap_static, hap_interop}. eg. xts_suitetype=bin,hap_dynamic 37""" 38 39 40class XtsBuild: 41 42 def __init__(self, commandline): 43 self._xts_root_dir = os.path.dirname(os.path.realpath(__file__)) 44 self._code_root_dir = os.path.realpath(os.path.join(self._xts_root_dir, '../../..')) 45 self._change_list_file = "{}/change_info.json".format(self._code_root_dir) 46 self._python_path = "{}/prebuilts/python/linux-x86/3.11.4/bin".format(self._code_root_dir) 47 os.environ['PATH'] = "{}:{}".format(self._python_path, os.environ['PATH']) 48 self._commandline = commandline 49 self._args = {} 50 self._gn_args = {} 51 self._other_args = {} 52 self._build_target = [] 53 self._arkts_static = False 54 55 def usage(self): 56 print(usage_info) 57 58 def parse_cmdline(self): 59 cmdline_args = [ 60 'suite', 'target_arch', 'use_musl', 'target_subsystem', 'system_size', 'product_name', 'pr_path_list', 61 'cache_type', 'make_osp', 'target_app_dir', "xts_suitetype" 62 ] 63 cmdline = {'use_musl': 'false', 'system_size': 'standard', 'target_arch': 'arm'} 64 for p in self._commandline: 65 if p.find('=') == -1: 66 self.usage() 67 return -1 68 69 [option, param] = p.split('=') 70 if option in cmdline_args: 71 cmdline[option] = param 72 else: 73 self.usage() 74 return -1 75 if cmdline.get('target_subsystem'): 76 os.environ['target_subsystem'] = cmdline.get('target_subsystem') 77 if cmdline.get('xts_suitetype'): 78 os.environ['XTS_SUITETYPE'] = cmdline.get('xts_suitetype') 79 else: 80 os.environ['XTS_SUITETYPE'] = "bin,hap_dynamic" 81 _suitetype_list = os.environ['XTS_SUITETYPE'].split(',') 82 if "hap_static" in _suitetype_list: 83 self._arkts_static = True 84 85 self._gn_args['build_xts'] = 'true' 86 if cmdline.get('system_size') == 'standard': 87 build_target = cmdline['suite'] if cmdline.get('suite') else "test/xts/acts:xts_acts" 88 self._args['product-name'] = cmdline['product_name'] if cmdline.get('product_name') else "Hi3516DV300" 89 if self._args['product-name'] == 'm40' and cmdline.get('use_musl') == 'false': 90 self._gn_args['use_musl'] = 'false' 91 self._gn_args['use_custom_libcxx'] = 'true' 92 self._gn_args['use_custom_clang'] = 'true' 93 94 if cmdline.get('cache_type') == 'xcache': 95 self._args['ccache'] = 'false' 96 self._args['xcache'] = 'true' 97 98 if cmdline.get('pr_path_list'): 99 self._gn_args['pr_path_list'] = cmdline.get('pr_path_list') 100 101 if cmdline.get('make_osp'): 102 self._gn_args['make_osp'] = cmdline.get('make_osp') 103 104 if cmdline.get('target_app_dir'): 105 self._gn_args['target_app_dir'] = cmdline.get('target_app_dir') 106 107 self._args['target-cpu'] = cmdline.get('target_arch') 108 self._other_args['get-warning-list'] = 'false' 109 self._other_args['stat-ccache'] = 'true' 110 self._other_args['compute-overlap-rate'] = 'false' 111 self._other_args['ninja-args'] = '-v' 112 self._args['deps-guard'] = 'false' 113 self._gn_args['skip_generate_module_list_file'] = 'true' 114 self._gn_args['is_standard_system'] = 'true' 115 else: 116 build_target = cmdline['suite'] if cmdline.get('suite') else "acts acts_ivi acts_intellitv acts_wearable" 117 self._args['product-name'] = cmdline['product_name'] if cmdline.get('product_name') else "arm64" 118 119 self._build_target = build_target.replace(',', ' ').split() 120 121 return 0 122 123 def standard_check(self): 124 self._hvigor_check_file = "{}/test/xts/tools/standard_check/check_hvigor.py".format(self._code_root_dir) 125 check_command = "{}/python3 -B {} {}".format(self._python_path, self._hvigor_check_file, self._xts_root_dir) 126 ret = subprocess.run(check_command.split()) 127 return ret.returncode 128 129 def get_accurate_targets(self): 130 accurate_dir = "{}/test/xts/tools/ci".format(self._code_root_dir) 131 sys.path.append(accurate_dir) 132 import generate_accurate_targets as gat 133 retcode, accurate_target = gat.generate(self._xts_root_dir, self._change_list_file, self._build_target) 134 if retcode: 135 sys.exit(-1) 136 return accurate_target 137 138 def do_make(self): 139 os.environ['XTS_SUITENAME'] = 'acts' 140 # 精准编译重新计算要编译的目标 141 self._build_target = self.get_accurate_targets() 142 if len(self._build_target) == 0: 143 logging.info("Info: accurate targets list is null, no need to compile") 144 return 0 145 logging.info(f"_build_target = {self._build_target}") 146 self._build_target.append('deploy_testtools') 147 148 autogen_apiobjs_dir = "{}/test/xts/autogen_apiobjs".format(self._code_root_dir) 149 if os.path.exists(autogen_apiobjs_dir): 150 shutil.rmtree(autogen_apiobjs_dir) 151 152 # 拼接编译命令 153 build_command = "./build.sh" 154 for i in self._args: 155 build_command = "{} --{} {}".format(build_command, i, self._args.get(i)) 156 for i in self._gn_args: 157 build_command = "{} --gn-args {}={}".format(build_command, i, self._gn_args.get(i)) 158 for i in self._build_target: 159 build_command = "{} --build-target {}".format(build_command, i) 160 for i in self._other_args: 161 build_command = "{} --{}={}".format(build_command, i, self._other_args.get(i)) 162 if self._arkts_static: 163 build_command = "{} {}".format(build_command, "--prebuilts-sdk-gn-args sdk_build_arkts=true") 164 logging.info("build_command: {}".format(build_command)) 165 166 # 执行编译命令 167 os.chdir(self._code_root_dir) 168 ret = subprocess.run(build_command.split()) 169 if ret.returncode: 170 logging.info("subprocess.run ret={}".format(ret)) 171 172 if os.path.exists(autogen_apiobjs_dir): 173 shutil.rmtree(autogen_apiobjs_dir) 174 175 return ret.returncode 176 177 def build(self): 178 func_list = [ 179 self.parse_cmdline, 180 # self.standard_check, 181 self.do_make 182 ] 183 for i in func_list: 184 retcode = i() 185 if retcode: 186 return retcode 187 return 0 188 189 190def main(): 191 logging.info(">>> Execute command: {}".format(" ".join(sys.argv))) 192 obj = XtsBuild(sys.argv[1:]) 193 194 retcode = obj.build() 195 196 return retcode 197 198 199if __name__ == "__main__": 200 sys.exit(main()) 201