1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3# 4# Copyright (c) 2022 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 18from __future__ import print_function 19import errno 20import os 21import subprocess 22import sys 23 24USE_PTY = "linux" in sys.platform 25if USE_PTY: 26 import pty 27 28ARCHES = ["x64", "arm", "arm64"] 29DEFAULT_ARCHES = "x64" 30MODES = ["release", "debug"] 31DEFAULT_MODES = "release" 32TARGETS = ["ets_runtime", "ets_frontend", "default", "all"] 33DEFAULT_TARGETS = "default" 34TARGETS_TEST = ["-test262"] 35 36 37USER_ARGS_TEMPLATE = """\ 38is_standard_system = true 39%s 40""" 41 42OUTDIR = "out" 43 44 45Help_message = """ 46formot like python ark.py [arch].[mode] [options] [test] 47for example , python ark.py x64.release 48[arch] can be one of ["x64", "arm", "arm64"] 49[mode] can be one of ["release", "debug"] 50[options] 51 target: only support [ets_runtime | ets_frontend | default | all] now 52 clean: clear your data in output dir 53[test] 54 test262: run test262 55""" 56 57def PrintHelp(): 58 print(Help_message) 59 sys.exit(0) 60 61 62def _Call(cmd, silent=False): 63 if not silent: 64 print("# %s" % cmd) 65 return subprocess.call(cmd, shell=True) 66 67 68def _Write(filename, content, mode): 69 with open(filename, mode) as f: 70 f.write(content) 71 72 73def get_path(arch, mode): 74 subdir = "%s.%s" % (arch, mode) 75 return os.path.join(OUTDIR, subdir) 76 77 78def call_with_output(cmd, file): 79 host, guest = pty.openpty() 80 h = subprocess.Popen(cmd, shell=True, stdin=guest, stdout=guest, stderr=guest) 81 os.close(guest) 82 output_data = [] 83 while True: 84 try: 85 build_data = os.read(host, 512).decode('utf-8') 86 except OSError as error: 87 if error == errno.ENOENT: 88 print("no such file") 89 elif error == errno.EPERM: 90 print("permission denied") 91 break 92 else: 93 if not build_data: 94 break 95 print(build_data) 96 sys.stdout.flush() 97 _Write(file, build_data, "a") 98 os.close(host) 99 h.wait() 100 return h.returncode 101 102 103def get_args(argvs): 104 args_list = argvs 105 args_len = len(args_list) 106 if args_len < 1: 107 print("Wrong usage") 108 PrintHelp() 109 elif args_len == 1: 110 args_out = args_list 111 if "-help" in args_out: 112 PrintHelp() 113 else : 114 args_out = args_list 115 return get_templete(args_out) 116 117 118def get_templete(args_list): 119 global_arche = DEFAULT_ARCHES 120 global_mode = DEFAULT_MODES 121 global_target = DEFAULT_TARGETS 122 global_test = '' 123 global_clean = False 124 for args in args_list: 125 parameter = args.split(".") 126 for part in parameter: 127 if part in ARCHES: 128 global_arche = part 129 elif part in MODES: 130 global_mode = part 131 elif part in TARGETS: 132 global_target = part 133 elif part == "clean": 134 global_clean = True 135 elif part in TARGETS_TEST: 136 global_test = part 137 else: 138 print("\033[34mUnkown word: %s\033[0m" % part) 139 PrintHelp() 140 sys.exit(1) 141# Determine the target CPU 142 if global_arche in ("arm", "arm64"): 143 ark_cpu = global_arche 144 else: 145 ark_cpu = "x64" 146 target_cpu = "target_cpu = \"%s\"" % ark_cpu 147# Determine the target OS,Only ohos for now 148 ark_os = "ohos" 149 target_os = "target_os = \"%s\"" % ark_os 150 if global_mode == "debug": 151 is_debug = "is_debug = true" 152 else: 153 is_debug = "is_debug = false" 154 all_part = (is_debug + "\n" + target_os + "\n" + target_cpu) 155 return [global_arche, global_mode, global_target, global_clean, USER_ARGS_TEMPLATE % (all_part), global_test] 156 157 158def Build(template): 159 arch = template[0] 160 mode = template[1] 161 target = template[2] 162 clean = template[3] 163 template_part = template[4] 164 path = get_path(arch, mode) 165 if not os.path.exists(path): 166 print("# mkdir -p %s" % path) 167 os.makedirs(path) 168 if clean: 169 print("=== start clean ===") 170 code = _Call("./prebuilts/build-tools/linux-x86/bin/gn clean %s" % path) 171 code += _Call("./prebuilts/build-tools/linux-x86/bin/ninja -C %s -t clean" % path) 172 if code != 0: 173 return code 174 print("=== clean success! ===") 175 exit(0) 176 build_log = os.path.join(path, "build.log") 177 if not os.path.exists("args.gn"): 178 args_gn = os.path.join(path, "args.gn") 179 _Write(args_gn, template_part, "w") 180 if not os.path.exists("build.ninja"): 181 build_ninja = os.path.join(path, "build.ninja") 182 code = _Call("./prebuilts/build-tools/linux-x86/bin/gn gen %s" % path) 183 print("=== gn success! ===") 184 if code != 0: 185 return code 186 pass_code = call_with_output("./prebuilts/build-tools/linux-x86/bin/ninja -C %s %s" % 187 (path, target), build_log) 188 if pass_code == 0: 189 print("=== ninja success! ===") 190 return pass_code 191 192 193def run_test(template): 194 arch = template[0] 195 mode = template[1] 196 test = template[5] 197 test_dir = arch + "." + mode 198 test262_code = '''cd ets_frontend 199 python3 test262/run_test262.py --es2021 all --timeout 180000 --libs-dir ../out/%s:../prebuilts/clang/ohos/linux-x86_64/llvm/lib --ark-tool=../out/%s/arkcompiler/ets_runtime/ark_js_vm --ark-frontend-binary=../out/%s/clang_x64/arkcompiler/ets_frontend/es2abc --merge-abc-binary=../out/%s/clang_x64/arkcompiler/ets_frontend/merge_abc --ark-frontend=es2panda 200 ''' % (test_dir, test_dir, test_dir, test_dir) 201 if ("-test262" == test): 202 print("=== come to test ===") 203 return _Call(test262_code) 204 else: 205 print("=== nothing to test ===") 206 return 0 207 208 209def Main(argvs): 210 pass_code = 0 211 templete = get_args(argvs) 212 pass_code += Build(templete) 213 if pass_code == 0: 214 pass_code += run_test(templete) 215 if pass_code == 0: 216 print('\033[32mDone!\033[0m', '\033[32mARK_{} compilation finished successfully.\033[0m'.format(argvs[0].split('.')[0])) 217 else: 218 print('\033[31mError!\033[0m', '\033[31mARK_{} compilation finished with errors.\033[0m'.format(argvs[0].split('.')[0])) 219 return pass_code 220 221 222if __name__ == "__main__": 223 sys.exit(Main(sys.argv[1:])) 224