• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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