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 23logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') 24logging.basicConfig(level=logging.ERROR, format='%(asctime)s - %(levelname)s - %(message)s') 25 26usage_info = """ 27USAGE 28 ./build.sh [suite=BUILD_TARGET] [target_os=TARGET_OS] [target_arch=TARGET_ARCH] [variant=BUILD_VARIANT] [target_subsystem=TARGET_SUBSYSTEM] 29 suite : BUILD_TARGET acts, hats, dcts 30 target_arch : TARGET_ARCH arm64 or arm, default value is arm 31 variant : BUILD_VARIANT release or debug, default value is debug 32 target_subsystem : TARGET_SUBSYSTEM the target subsystem to build 33 system_size : SYSTEM_SIZE standard 34 product_name : PRODUCT_NAME the name of product. such as Hi3516DV300, and so on. 35 36""" 37 38 39class XtsBuild: 40 41 def __init__(self, commandline): 42 self._xts_root_dir = os.path.dirname(os.path.realpath(__file__)) 43 self._code_root_dir = os.path.realpath(os.path.join(self._xts_root_dir, '../../..')) 44 self._change_list_file = "{}/change_info.json".format(self._code_root_dir) 45 self._python_path = "{}/prebuilts/python/linux-x86/3.11.4/bin".format(self._code_root_dir) 46 os.environ['PATH'] = "{}:{}".format(self._python_path, os.environ['PATH']) 47 self._commandline = commandline 48 self._args = {} 49 self._gn_args = {} 50 self._other_args = {} 51 self._build_target = [] 52 53 def usage(self): 54 print(usage_info) 55 56 def parse_cmdline(self): 57 cmdline_args = [ 58 'suite', 'target_arch', 'use_musl', 'target_subsystem', 'system_size', 'product_name', 'pr_path_list', 59 'cache_type', 'make_osp', 'target_app_dir' 60 ] 61 cmdline = {'use_musl': 'false', 'system_size': 'standard', 'target_arch': 'arm'} 62 for p in self._commandline: 63 if p.find('=') == -1: 64 self.usage() 65 return -1 66 67 [option, param] = p.split('=') 68 if option in cmdline_args: 69 cmdline[option] = param 70 else: 71 self.usage() 72 return -1 73 if cmdline.get('target_subsystem'): 74 os.environ['target_subsystem'] = cmdline.get('target_subsystem') 75 76 # print("args_dict = {}".format(cmdline)) 77 self._gn_args['build_xts'] = 'true' 78 if cmdline.get('system_size') == 'standard': 79 build_target = cmdline['suite'] if cmdline.get('suite') else "test/xts/dcts:xts_dcts" 80 self._args['product-name'] = cmdline['product_name'] if cmdline.get('product_name') else "Hi3516DV300" 81 if self._args['product-name'] == 'm40' and cmdline.get('use_musl') == 'false': 82 self._gn_args['use_musl'] = 'false' 83 self._gn_args['use_custom_libcxx'] = 'true' 84 self._gn_args['use_custom_clang'] = 'true' 85 86 if cmdline.get('cache_type') == 'xcache': 87 self._args['ccache'] = 'false' 88 self._args['xcache'] = 'true' 89 90 if cmdline.get('pr_path_list'): 91 self._gn_args['pr_path_list'] = cmdline.get('pr_path_list') 92 93 if cmdline.get('make_osp'): 94 self._gn_args['make_osp'] = cmdline.get('make_osp') 95 96 if cmdline.get('target_app_dir'): 97 self._gn_args['target_app_dir'] = cmdline.get('target_app_dir') 98 99 self._args['target-cpu'] = cmdline.get('target_arch') 100 self._other_args['get-warning-list'] = 'false' 101 self._other_args['stat-ccache'] = 'true' 102 self._other_args['compute-overlap-rate'] = 'false' 103 self._args['deps-guard'] = 'false' 104 self._gn_args['skip_generate_module_list_file'] = 'true' 105 self._gn_args['is_standard_system'] = 'true' 106 else: 107 build_target = cmdline['suite'] if cmdline.get('suite') else "dcts dcts_ivi dcts_intellitv dcts_wearable" 108 self._args['product-name'] = cmdline['product_name'] if cmdline.get('product_name') else "arm64" 109 110 self._build_target = build_target.replace(',', ' ').split() 111 112 return 0 113 114 def standard_check(self): 115 self._hvigor_check_file = "{}/test/xts/tools/standard_check/check_hvigor.py".format(self._code_root_dir) 116 check_command = "{}/python3 -B {} {}".format(self._python_path, self._hvigor_check_file, self._xts_root_dir) 117 ret = subprocess.run(check_command.split()) 118 return ret.returncode 119 120 def get_accurate_targets(self): 121 accurate_dir = "{}/test/xts/tools/ci".format(self._code_root_dir) 122 sys.path.append(accurate_dir) 123 import generate_accurate_targets as gat 124 retcode, accurate_target = gat.generate(self._xts_root_dir, self._change_list_file, self._build_target) 125 if retcode: 126 sys.exit(-1) 127 return accurate_target 128 129 def do_make(self): 130 os.environ['XTS_SUITENAME'] = 'dcts' 131 # 精准编译重新计算要编译的目标 132 self._build_target = self.get_accurate_targets() 133 if len(self._build_target) == 0: 134 logging.info("Info: accurate targets list is null, no need to compile") 135 return 0 136 logging.info(f"_build_target = {self._build_target}") 137 self._build_target.append('deploy_testtools') 138 139 autogen_apiobjs_dir = "{}/test/xts/autogen_apiobjs".format(self._code_root_dir) 140 if os.path.exists(autogen_apiobjs_dir): 141 shutil.rmtree(autogen_apiobjs_dir) 142 143 # 拼接编译命令 144 build_command = "./build.sh" 145 for i in self._args: 146 build_command = "{} --{} {}".format(build_command, i, self._args.get(i)) 147 for i in self._gn_args: 148 build_command = "{} --gn-args {}={}".format(build_command, i, self._gn_args.get(i)) 149 for i in self._build_target: 150 build_command = "{} --build-target {}".format(build_command, i) 151 for i in self._other_args: 152 build_command = "{} --{}={}".format(build_command, i, self._other_args.get(i)) 153 logging.info("build_command: {}".format(build_command)) 154 155 # 执行编译命令 156 os.chdir(self._code_root_dir) 157 ret = subprocess.run(build_command.split()) 158 if ret.returncode: 159 logging.info("subprocess.run ret={}".format(ret)) 160 161 if os.path.exists(autogen_apiobjs_dir): 162 shutil.rmtree(autogen_apiobjs_dir) 163 164 return ret.returncode 165 166 def build(self): 167 func_list = [self.parse_cmdline, self.standard_check, self.do_make] 168 for i in func_list: 169 retcode = i() 170 if retcode: 171 return retcode 172 return 0 173 174 175def main(): 176 logging.info(">>> Execute command: {}".format(" ".join(sys.argv))) 177 obj = XtsBuild(sys.argv[1:]) 178 179 retcode = obj.build() 180 181 return retcode 182 183if __name__ == "__main__": 184 sys.exit(main()) 185