1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3# 4# Copyright (c) 2022-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 18from __future__ import print_function 19from datetime import datetime 20from fnmatch import fnmatch 21import errno 22import json 23import os 24import platform 25import subprocess 26import sys 27from typing import List, Any, Tuple, Union, Optional 28 29CURRENT_FILENAME = os.path.basename(__file__) 30 31 32def str_of_time_now() -> str: 33 return datetime.now().strftime("%Y-%m-%d-%H-%M-%S-%f")[:-3] 34 35 36def _call(cmd: str): 37 print("# %s" % cmd) 38 return subprocess.call(cmd, shell=True) 39 40 41def _write(filename: str, content: str, mode: str): 42 with open(filename, mode) as f: 43 f.write(content) 44 45 46def call_with_output(cmd: str, file: str): 47 print("# %s" % cmd) 48 host = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) 49 while True: 50 try: 51 build_data = host.stdout.readline().decode('utf-8') 52 sys.stdout.flush() 53 print(build_data) 54 _write(file, build_data, "a") 55 except OSError as error: 56 if error == errno.ENOENT: 57 print("no such file") 58 elif error == errno.EPERM: 59 print("permission denied") 60 break 61 if not build_data: 62 break 63 host.wait() 64 return host.returncode 65 66 67def enable_ccache(): 68 try: 69 ccache_path = subprocess.check_output(['which', 'ccache']).strip().decode() 70 except subprocess.CalledProcessError: 71 print("Error: ccache not found.") 72 return 73 os.environ['CCACHE_EXEC'] = ccache_path 74 os.environ['USE_CCACHE'] = "1" 75 76 77def backup(file: str, mode: str): 78 if os.path.exists(file): 79 with open(file, 'r+') as src_file: 80 src_content = src_file.read() 81 src_file.seek(0) 82 src_file.truncate() 83 84 with open(file[:-4] + "_last.log", mode) as dst_file: 85 dst_file.write(src_content) 86 87 88class ArkPy: 89 # constants determined by designer of this class 90 NAME_OF_OUT_DIR_OF_FIRST_LEVEL = "out" 91 DELIMITER_BETWEEN_OS_CPU_MODE_FOR_COMMAND = "." 92 DELIMITER_FOR_SECOND_OUT_DIR_NAME = "." 93 GN_TARGET_LOG_FILE_NAME = "build.log" 94 UNITTEST_LOG_FILE_NAME = "unittest.log" 95 TEST262_LOG_FILE_NAME = "test262.log" 96 REGRESS_TEST_LOG_FILE_NAME = "regresstest.log" 97 PREBUILTS_DOWNLOAD_CONFIG_FILE_PATH = \ 98 "./arkcompiler/toolchain/build/prebuilts_download/prebuilts_download_config.json" 99 INDENTATION_STRING_PER_LEVEL = " " # for help message 100 # In ARG_DICT, "flags" and "description" are must-keys for the leaf-dicts in it. 101 # (Future designer need know.) 102 ARG_DICT = { 103 "os_cpu": { 104 "linux_x64": { 105 "flags": ["linux_x64", "x64"], 106 "description": 107 "Build for arkcompiler target of target-operating-system linux and " 108 "target-central-processing-unit x64.", 109 "gn_args": ["target_os=\"linux\"", "target_cpu=\"x64\""], 110 "prefix_of_name_of_out_dir_of_second_level": "x64", 111 }, 112 "linux_x86": { 113 "flags": ["linux_x86", "x86"], 114 "description": 115 "Build for arkcompiler target of target-operating-system linux and " 116 "target-central-processing-unit x86.", 117 "gn_args": ["target_os=\"linux\"", "target_cpu=\"x86\""], 118 "prefix_of_name_of_out_dir_of_second_level": "x86", 119 }, 120 "ohos_arm": { 121 "flags": ["ohos_arm", "arm"], 122 "description": 123 "Build for arkcompiler target of target-operating-system ohos and " 124 "target-central-processing-unit arm.", 125 "gn_args": ["target_os=\"ohos\"", "target_cpu=\"arm\""], 126 "prefix_of_name_of_out_dir_of_second_level": "arm", 127 }, 128 "ohos_arm64": { 129 "flags": ["ohos_arm64", "arm64"], 130 "description": 131 "Build for arkcompiler target of target-operating-system ohos and " 132 "target-central-processing-unit arm64.", 133 "gn_args": ["target_os=\"ohos\"", "target_cpu=\"arm64\""], 134 "prefix_of_name_of_out_dir_of_second_level": "arm64", 135 }, 136 "android_arm64": { 137 "flags": ["android_arm64"], 138 "description": 139 "Build for arkcompiler target of target-operating-system android and " 140 "target-central-processing-unit arm64.", 141 "gn_args": ["target_os=\"android\"", "target_cpu=\"arm64\""], 142 "prefix_of_name_of_out_dir_of_second_level": "android_arm64", 143 }, 144 "mingw_x86_64": { 145 "flags": ["mingw_x86_64"], 146 "description": 147 "Build for arkcompiler target of target-operating-system MinGW(Minimalist GNU on Windows) and " 148 "target-central-processing-unit x86_64.", 149 "gn_args": ["target_os=\"mingw\"", "target_cpu=\"x86_64\""], 150 "prefix_of_name_of_out_dir_of_second_level": "mingw_x86_64", 151 }, 152 "ohos_mipsel": { 153 "flags": ["ohos_mipsel", "mipsel"], 154 "description": 155 "Build for arkcompiler target of target-operating-system ohos and " 156 "target-central-processing-unit mipsel(32-bit little-endian mips).", 157 "gn_args": ["target_os=\"ohos\"", "target_cpu=\"mipsel\""], 158 "prefix_of_name_of_out_dir_of_second_level": "mipsel", 159 }, 160 "mac_arm64": { 161 "flags": ["mac_arm64", "arm64"], 162 "description": 163 "Build for arkcompiler target of target-operating-system linux and " 164 "target-central-processing-unit arm64.", 165 "gn_args": ["target_os=\"mac\"", "target_cpu=\"arm64\""], 166 "prefix_of_name_of_out_dir_of_second_level": "mac_arm64", 167 }, 168 "mac_x86": { 169 "flags": ["mac_x86", "x86"], 170 "description": 171 "Build for arkcompiler target of target-operating-system mac and " 172 "target-central-processing-unit x86.", 173 "gn_args": ["target_os=\"mac\"", "target_cpu=\"x86\""], 174 "prefix_of_name_of_out_dir_of_second_level": "mac_x86", 175 }, 176 }, 177 "mode": { 178 "release": { 179 "flags": ["release", "r"], 180 "description": "Build for arkcompiler target(executables and libraries) for distribution.", 181 "gn_args": ["is_debug=false"], 182 "suffix_of_name_of_out_dir_of_second_level": "release", 183 }, 184 "debug": { 185 "flags": ["debug", "d"], 186 "description": "Build for arkcompiler target(executables and libraries) for debugging.", 187 "gn_args": ["is_debug=true"], 188 "suffix_of_name_of_out_dir_of_second_level": "debug", 189 }, 190 "fastverify": { 191 "flags": ["fastverify", "fv"], 192 "description": "Build for arkcompiler target(executables and libraries) for fastverify.", 193 "gn_args": ["is_debug=true is_fastverify=true"], 194 "suffix_of_name_of_out_dir_of_second_level": "fastverify", 195 }, 196 }, 197 "target": { 198 "test262": { 199 "flags": ["test262", "test-262", "test_262", "262test", "262-test", "262_test", "262"], 200 "description": "Compile arkcompiler target and run test262 with arkcompiler target.", 201 "gn_targets_depend_on": ["default"], 202 "arm64_gn_targets_depend_on": ["ark_js_packages"], 203 }, 204 "unittest": { 205 "flags": ["unittest", "ut"], 206 "description": 207 "Compile and run unittest of arkcompiler target. " 208 "Add --keep-going=N to keep running unittest when errors occured less than N. " 209 "Add --gn-args=\"run_with_qemu=true\" timeout=\"1200\"\ 210 \"disable_force_gc=true\" to command when running unittest of non-host type with qemu.", 211 "gn_targets_depend_on": ["unittest_packages"], 212 }, 213 "workload": { 214 "flags": ["workload", "work-load", "work_load"], 215 "description": "Compile arkcompiler target and run workload with arkcompiler target.", 216 "gn_targets_depend_on": ["default"], 217 }, 218 "regresstest": { 219 "flags": ["regresstest", "regress_test", "regress", "testregress", "test_regress"], 220 "description": "Compile arkcompiler target and run regresstest with arkcompiler target.", 221 "gn_targets_depend_on": ["default"], 222 }, 223 "gn_target": { 224 "flags": ["<name of target in \"*.gn*\" file>"], # any other flags 225 "description": 226 "Build for arkcompiler target assigned by user. Targets include group(ets_runtime), " 227 "ohos_executable(ark_js_vm), ohos_shared_library(libark_jsruntime), " 228 "ohos_static_library(static_icuuc), ohos_source_set(libark_jsruntime_set), " 229 "ohos_unittest(EcmaVm_001_Test), action(EcmaVm_001_TestAction) and other target of user-defined " 230 "template type in \"*.gn*\" file.", 231 "gn_targets_depend_on": [], # not need, depend on deps of itself in "*.gn*" file 232 }, 233 }, 234 "option": { 235 "clean": { 236 "flags": ["--clean", "-clean"], 237 "description": 238 "Clean the root-out-dir(x64.release-->out/x64.release) execept for file args.gn. " 239 "Then exit.", 240 }, 241 "clean-continue": { 242 "flags": ["--clean-continue", "-clean-continue"], 243 "description": 244 "Clean the root-out-dir(x64.release-->out/x64.release) execept for file args.gn. " 245 "Then continue to build.", 246 }, 247 "gn-args": { 248 "flags": ["--gn-args=*", "-gn-args=*"], 249 "description": 250 "Pass args(*) to gn command. Example: python3 ark.py x64.release " 251 "--gn-args=\"bool_declared_in_src_gn=true string_declared_in_src_gn=\\\"abcd\\\" " 252 "list_declared_in_src_gn=[ \\\"element0\\\", \\\"element1\\\" ] print(list_declared_in_src_gn) " 253 "exec_script(\\\"script_in_src\\\", [ \\\"arg_to_script\\\" ])\" .", 254 }, 255 "keepdepfile": { 256 "flags": ["--keepdepfile", "-keepdepfile"], 257 "description": 258 "Keep depfile(\"*.o.d\") generated by commands(CXX, CC ...) called by ninja during compilation.", 259 }, 260 "verbose": { 261 "flags": ["--verbose", "-verbose"], 262 "description": "Print full commands(CXX, CC, LINK ...) called by ninja during compilation.", 263 }, 264 "keep-going": { 265 "flags": ["--keep-going=*", "-keep-going=*"], 266 "description": "Keep running unittest etc. until errors occured less than N times" 267 " (use 0 to ignore all errors).", 268 }, 269 }, 270 "help": { 271 "flags": ["help", "--help", "--h", "-help", "-h"], 272 "description": "Show the usage of ark.py.", 273 }, 274 } 275 276 # variables which would change with the change of host_os or host_cpu 277 gn_binary_path = "" 278 ninja_binary_path = "" 279 280 # variables which would change with the change of ark.py command 281 has_cleaned = False 282 enable_verbose = False 283 enable_keepdepfile = False 284 ignore_errors = 1 285 286 def __main__(self, arg_list: list): 287 enable_ccache() 288 # delete duplicate arg in arg_list 289 arg_list = list(dict.fromkeys(arg_list)) 290 # match [help] flag 291 if len(arg_list) == 0 or ( 292 True in [self.is_dict_flags_match_arg(self.ARG_DICT.get("help"), arg) for arg in arg_list]): 293 print(self.get_help_msg_of_all()) 294 return 295 # match [[os_cpu].[mode]] flag 296 [match_success, key_to_dict_in_os_cpu, key_to_dict_in_mode] = self.dict_in_os_cpu_mode_match_arg(arg_list[0]) 297 if match_success: 298 self.start_for_matched_os_cpu_mode(key_to_dict_in_os_cpu, key_to_dict_in_mode, arg_list[1:]) 299 else: 300 print("\033[92mThe command is not supported! Help message shows below.\033[0m\n{}".format( 301 self.get_help_msg_of_all())) 302 return 303 304 @staticmethod 305 def is_dict_flags_match_arg(dict_to_match: dict, arg_to_match: str) -> bool: 306 for flag in dict_to_match["flags"]: 307 if fnmatch(arg_to_match, flag): 308 return True 309 return False 310 311 @staticmethod 312 def libs_dir(is_arm, is_aot, is_pgo, out_dir, x64_out_dir) -> str: 313 if is_arm and is_aot and is_pgo: 314 return (f"--libs-dir ../../{out_dir}/arkcompiler/ets_runtime:" 315 f"../../{out_dir}/thirdparty/icu:" 316 f"../../{out_dir}/third_party/icu:" 317 f"../../thirdparty/zlib:" 318 f"../../prebuilts/clang/ohos/linux-x86_64/llvm/lib") 319 if is_arm and is_aot and not is_pgo: 320 return ("--libs-dir ../../prebuilts/clang/ohos/linux-x86_64/llvm/lib" 321 f":../../{x64_out_dir}/thirdparty/icu/") 322 if not is_arm and is_aot: 323 return (f"--libs-dir ../../{out_dir}/arkcompiler/ets_runtime" 324 f":../../{out_dir}/thirdparty/icu:" 325 f"../../{out_dir}/third_party/icu:" 326 f"../../thirdparty/zlib:" 327 f"../../prebuilts/clang/ohos/linux-x86_64/llvm/lib") 328 # not is_arm and not is_aot 329 return " --libs-dir ../../prebuilts/clang/ohos/linux-x86_64/llvm/lib" 330 331 @staticmethod 332 def get_cmd(test_suite, test_script_name, test_script_path, gn_args, out_path, x64_out_path, aot_mode, run_pgo, 333 enable_litecg, args_to_cmd, timeout, ignore_list: Optional[str] = None): 334 cmd = [ 335 f"cd {test_script_path}", 336 f"&& python3 {test_script_name} {args_to_cmd}", 337 f"--timeout {timeout}", 338 f"--ark-tool=../../{out_path}/arkcompiler/ets_runtime/ark_js_vm", 339 "--ark-frontend=es2panda" 340 ] 341 is_arm = any('target_cpu="arm64"' in arg for arg in gn_args) 342 if is_arm: 343 cmd.append("--ark-arch aarch64") 344 cmd.append(f"--ark-arch-root=../../{out_path}/common/common/libc/") 345 cmd.append(f"--ark-frontend-binary=../../{x64_out_path}/arkcompiler/ets_frontend/es2abc") 346 cmd.append(f"--merge-abc-binary=../../{x64_out_path}/arkcompiler/ets_frontend/merge_abc") 347 if aot_mode: 348 cmd.append(f"--ark-aot-tool=../../{out_path}/arkcompiler/ets_runtime/ark_aot_compiler") 349 if test_suite == "regresstest": 350 cmd.append(f"--stub-path=../../{out_path}/gen/arkcompiler/ets_runtime/stub.an") 351 else: 352 cmd.append(f"--ark-frontend-binary=../../{out_path}/arkcompiler/ets_frontend/es2abc") 353 cmd.append(f"--merge-abc-binary=../../{out_path}/arkcompiler/ets_frontend/merge_abc") 354 if aot_mode: 355 cmd.append(f"--ark-aot-tool=../../{out_path}/arkcompiler/ets_runtime/ark_aot_compiler") 356 if test_suite == "regresstest": 357 cmd.append(f"--stub-path=../../{out_path}/gen/arkcompiler/ets_runtime/stub.an") 358 359 cmd.append(ArkPy.libs_dir( 360 is_arm=is_arm, 361 is_aot=aot_mode, 362 is_pgo=run_pgo, 363 out_dir=out_path, 364 x64_out_dir=x64_out_path 365 )) 366 367 if aot_mode: 368 cmd.append("--ark-aot") 369 mode = ["AOT"] 370 if run_pgo: 371 cmd.append("--run-pgo") 372 mode.append("PGO") 373 if enable_litecg: 374 cmd.append("--enable-litecg") 375 mode.append("LiteCG") 376 mode_str = " ".join(mode) 377 print(f"Running {test_suite} in {mode_str} Mode\n") 378 379 if test_suite == "regresstest" and ignore_list: 380 cmd.append(f"--ignore-list {ignore_list}") 381 382 if test_suite == "regresstest": 383 cmd.append(f"--out-dir ../../{out_path}") 384 385 return " ".join(cmd) 386 387 @staticmethod 388 def get_test262_aot_cmd(gn_args, out_path, x64_out_path, run_pgo, enable_litecg, args_to_test262_cmd, 389 timeout): 390 print("running test262 in AotMode\n") 391 if any('target_cpu="arm64"' in arg for arg in gn_args): 392 if run_pgo: 393 test262_cmd = f"cd arkcompiler/ets_frontend && python3 test262/run_test262.py {args_to_test262_cmd}" \ 394 f" --timeout {timeout}" \ 395 f" --libs-dir ../../{out_path}/arkcompiler/ets_runtime:../../{out_path}/thirdparty/icu:" \ 396 f"../../{out_path}/thirdparty/zlib:../../prebuilts/clang/ohos/linux-x86_64/llvm/lib" \ 397 " --ark-arch aarch64" \ 398 f" --ark-arch-root=../../{out_path}/common/common/libc/" \ 399 f" --ark-tool=../../{out_path}/arkcompiler/ets_runtime/ark_js_vm" \ 400 f" --ark-aot-tool=../../{out_path}/arkcompiler/ets_runtime/ark_aot_compiler" \ 401 f" --ark-frontend-binary=../../{x64_out_path}/arkcompiler/ets_frontend/es2abc" \ 402 f" --merge-abc-binary=../../{x64_out_path}/arkcompiler/ets_frontend/merge_abc" \ 403 " --ark-aot" \ 404 " --ark-frontend=es2panda" \ 405 " --run-pgo" 406 else: 407 test262_cmd = "cd arkcompiler/ets_frontend && python3 test262/run_test262.py {0} --timeout {3}" \ 408 " --libs-dir ../../prebuilts/clang/ohos/linux-x86_64/llvm/lib:../../{2}/thirdparty/icu/" \ 409 " --ark-arch aarch64" \ 410 " --ark-arch-root=../../{1}/common/common/libc/" \ 411 " --ark-aot" \ 412 " --ark-aot-tool=../../{2}/arkcompiler/ets_runtime/ark_aot_compiler" \ 413 " --ark-tool=../../{1}/arkcompiler/ets_runtime/ark_js_vm" \ 414 " --ark-frontend-binary=../../{2}/arkcompiler/ets_frontend/es2abc" \ 415 " --merge-abc-binary=../../{2}/arkcompiler/ets_frontend/merge_abc" \ 416 " --ark-frontend=es2panda".format(args_to_test262_cmd, out_path, x64_out_path, timeout) 417 else: 418 run_pgo_arg = " --run-pgo" if run_pgo else "" 419 test262_cmd = f"cd arkcompiler/ets_frontend && python3 test262/run_test262.py {args_to_test262_cmd}" \ 420 f" --timeout {timeout}" \ 421 f" --libs-dir ../../{out_path}/arkcompiler/ets_runtime:../../{out_path}/thirdparty/icu" \ 422 f":../../{out_path}/thirdparty/zlib:../../prebuilts/clang/ohos/linux-x86_64/llvm/lib" \ 423 f" --ark-tool=../../{out_path}/arkcompiler/ets_runtime/ark_js_vm" \ 424 f" --ark-aot-tool=../../{out_path}/arkcompiler/ets_runtime/ark_aot_compiler" \ 425 f" --ark-frontend-binary=../../{out_path}/arkcompiler/ets_frontend/es2abc" \ 426 f" --merge-abc-binary=../../{out_path}/arkcompiler/ets_frontend/merge_abc" \ 427 " --ark-aot" \ 428 " --ark-frontend=es2panda" \ 429 f" {run_pgo_arg}" 430 if enable_litecg: 431 test262_cmd = test262_cmd + " --enable-litecg" 432 return test262_cmd 433 434 @staticmethod 435 def get_jit_cmd(test_suite, test_script_name, test_script_path, gn_args, out_path, x64_out_path, args_to_cmd, 436 timeout): 437 print(f"running {test_suite} in JIT mode\n") 438 if any('target_cpu="arm64"' in arg for arg in gn_args): 439 cmd = f"cd {test_script_path} && python3 {test_script_name} {args_to_cmd} --timeout {timeout}" \ 440 f" --libs-dir ../../prebuilts/clang/ohos/linux-x86_64/llvm/lib:../../{out_path}/thirdparty/icu/" \ 441 f":../../{out_path}/thirdparty/bounds_checking_function" \ 442 f":../../{out_path}/arkcompiler/ets_runtime:" \ 443 " --ark-arch aarch64" \ 444 " --run-jit" \ 445 f" --ark-arch-root=../../{out_path}/common/common/libc/" \ 446 f" --ark-aot-tool=../../{x64_out_path}/arkcompiler/ets_runtime/ark_aot_compiler" \ 447 f" --ark-tool=../../{out_path}/arkcompiler/ets_runtime/ark_js_vm" \ 448 f" --ark-frontend-binary=../../{x64_out_path}/arkcompiler/ets_frontend/es2abc" \ 449 f" --merge-abc-binary=../../{x64_out_path}/arkcompiler/ets_frontend/merge_abc" \ 450 " --ark-frontend=es2panda" 451 else: 452 cmd = f"cd arkcompiler/ets_frontend && python3 {test_script_name} {args_to_cmd} --timeout {timeout}" \ 453 f" --libs-dir ../../{out_path}/arkcompiler/ets_runtime:../../{out_path}/thirdparty/icu" \ 454 f":../../{out_path}/thirdparty/zlib:../../prebuilts/clang/ohos/linux-x86_64/llvm/lib" \ 455 " --run-jit" \ 456 f" --ark-tool=../../{out_path}/arkcompiler/ets_runtime/ark_js_vm" \ 457 f" --ark-frontend-binary=../../{out_path}/arkcompiler/ets_frontend/es2abc" \ 458 f" --merge-abc-binary=../../{out_path}/arkcompiler/ets_frontend/merge_abc" \ 459 " --ark-frontend=es2panda" 460 return cmd 461 462 @staticmethod 463 def get_baseline_jit_cmd(test_suite, test_script_name, test_script_path, gn_args, out_path, x64_out_path, 464 args_to_test262_cmd, timeout): 465 print(f"running {test_suite} in baseline JIT mode\n") 466 if any('target_cpu="arm64"' in arg for arg in gn_args): 467 cmd = f"cd {test_script_path} && python3 {test_script_name} {args_to_test262_cmd} --timeout {timeout}" \ 468 f" --libs-dir ../../prebuilts/clang/ohos/linux-x86_64/llvm/lib" \ 469 f":../../{out_path}/thirdparty/icu" \ 470 f":../../prebuilts/clang/ohos/linux-x86_64/llvm/lib/aarch64-linux-ohos" \ 471 f":../../{out_path}/thirdparty/bounds_checking_function" \ 472 f":../../{out_path}/arkcompiler/ets_runtime" \ 473 f":../../{out_path}/common/common/libc/lib" \ 474 " --ark-arch aarch64" \ 475 " --run-baseline-jit" \ 476 f" --ark-arch-root=../../{out_path}/common/common/libc/" \ 477 f" --ark-aot-tool=../../{x64_out_path}/arkcompiler/ets_runtime/ark_aot_compiler" \ 478 f" --ark-tool=../../{out_path}/arkcompiler/ets_runtime/ark_js_vm" \ 479 f" --ark-frontend-binary=../../{x64_out_path}/arkcompiler/ets_frontend/es2abc" \ 480 f" --merge-abc-binary=../../{x64_out_path}/arkcompiler/ets_frontend/merge_abc" \ 481 " --ark-frontend=es2panda" 482 else: 483 cmd = f"cd {test_script_path} && python3 {test_script_name} {args_to_test262_cmd} --timeout {timeout}" \ 484 f" --libs-dir ../../{out_path}/lib.unstripped/arkcompiler/ets_runtime" \ 485 f":../../{out_path}/thirdparty/icu" \ 486 ":../../prebuilts/clang/ohos/linux-x86_64/llvm/lib" \ 487 f":../../{out_path}/thirdparty/bounds_checking_function/" \ 488 " --run-baseline-jit" \ 489 f" --ark-tool=../../{out_path}/arkcompiler/ets_runtime/ark_js_vm" \ 490 f" --ark-frontend-binary=../../{out_path}/arkcompiler/ets_frontend/es2abc" \ 491 f" --merge-abc-binary=../../{out_path}/arkcompiler/ets_frontend/merge_abc" \ 492 " --ark-frontend=es2panda" 493 return cmd 494 495 @staticmethod 496 def build_args_to_test262_cmd(arg_list): 497 args_to_test262_cmd = [] 498 499 disable_force_gc_name = "--disable-force-gc" 500 disable_force_gc_value, arg_list = ArkPy.parse_bool_option( 501 arg_list, option_name=disable_force_gc_name, default_value=False 502 ) 503 if disable_force_gc_value: 504 args_to_test262_cmd.extend([disable_force_gc_name]) 505 506 threads_name = "--threads" 507 threads_value, arg_list = ArkPy.parse_option(arg_list, option_name=threads_name, default_value=None) 508 if threads_value: 509 args_to_test262_cmd.extend([threads_name, threads_value]) 510 511 test_list_name = "--test-list" 512 test_list_value, arg_list = ArkPy.parse_option(arg_list, option_name=test_list_name, default_value=None) 513 if test_list_value is not None: 514 args_to_test262_cmd.extend([test_list_name, test_list_value]) 515 516 enable_rm = [arg for arg in arg_list if "enable-rm" in arg] 517 if enable_rm: 518 args_to_test262_cmd.append("--enable-rm") 519 arg_list.remove(enable_rm[0]) 520 521 skip_list_name = "--skip-list" 522 skip_list_value, arg_list = ArkPy.parse_option(arg_list, option_name=skip_list_name, default_value=None) 523 if skip_list_value is not None: 524 args_to_test262_cmd.extend([skip_list_name, skip_list_value]) 525 526 if len(arg_list) == 0: 527 args_to_test262_cmd.append("--es2021 all") 528 elif len(arg_list) == 1: 529 arg = arg_list[0] 530 if arg == "sendable": 531 args_to_test262_cmd.append("--sendable sendable") 532 elif ".js" in arg: 533 args_to_test262_cmd.append("--file test262/data/test_es2021/{}".format(arg)) 534 else: 535 args_to_test262_cmd.append("--dir test262/data/test_es2021/{}".format(arg)) 536 else: 537 print("\033[92m\"test262\" not support multiple additional arguments.\033[0m\n".format()) 538 sys.exit(0) 539 540 return " ".join(args_to_test262_cmd) 541 542 @staticmethod 543 def build_args_to_regress_cmd(arg_list): 544 args_to_regress_cmd = [] 545 546 disable_force_gc_name = "--disable-force-gc" 547 disable_force_gc_value, arg_list = ArkPy.parse_bool_option( 548 arg_list, option_name=disable_force_gc_name, default_value=False 549 ) 550 if disable_force_gc_value: 551 args_to_regress_cmd.extend([disable_force_gc_name]) 552 553 processes_name = "--processes" 554 processes_value, arg_list = ArkPy.parse_option(arg_list, option_name=processes_name, default_value=1) 555 args_to_regress_cmd.extend([processes_name, processes_value]) 556 557 test_list_name = "--test-list" 558 test_list_value, arg_list = ArkPy.parse_option(arg_list, option_name=test_list_name, default_value=None) 559 if test_list_value is not None: 560 args_to_regress_cmd.extend([test_list_name, test_list_value]) 561 562 if len(arg_list) == 1: 563 arg = arg_list[0] 564 if ".js" in arg: 565 args_to_regress_cmd.append(f"--test-file {arg}") 566 else: 567 args_to_regress_cmd.append(f"--test-dir {arg}") 568 elif len(arg_list) > 1: 569 print("\033[92m\"regresstest\" not support multiple additional arguments.\033[0m\n".format()) 570 sys.exit(0) 571 572 return " ".join([str(arg) for arg in args_to_regress_cmd]) 573 574 @staticmethod 575 def parse_option(arg_list: List[str], option_name: str, default_value: Optional[Union[str, int]]) \ 576 -> Tuple[Optional[Union[str, int]], List[str]]: 577 option_value, arg_list = ArkPy.__parse_option_with_space(arg_list, option_name) 578 if option_value is None: 579 option_value, arg_list = ArkPy.__parse_option_with_equal(arg_list, option_name) 580 if option_value is None and default_value is not None: 581 option_value = default_value 582 return option_value, arg_list 583 584 @staticmethod 585 def parse_bool_option(arg_list: List[str], option_name: str, default_value: bool) \ 586 -> Tuple[bool, List[str]]: 587 if option_name in arg_list: 588 option_index = arg_list.index(option_name) 589 option_value = not default_value 590 arg_list = arg_list[:option_index] + arg_list[option_index + 1:] 591 else: 592 option_value = default_value 593 594 return option_value, arg_list 595 596 @staticmethod 597 def __is_option_value_int(value: Optional[Union[str, int]]) -> Tuple[bool, Optional[int]]: 598 if isinstance(value, int): 599 return True, int(value) 600 else: 601 return False, None 602 603 @staticmethod 604 def __is_option_value_str(value: Optional[Union[str, int]]) -> Tuple[bool, Optional[str]]: 605 if isinstance(value, str): 606 return True, str(value) 607 else: 608 return False, None 609 610 @staticmethod 611 def __get_option_value(option_name: str, value: Optional[Union[str, int]]) -> Union[str, int]: 612 result, res_value = ArkPy.__is_option_value_int(value) 613 if result: 614 return res_value 615 result, res_value = ArkPy.__is_option_value_str(value) 616 if result: 617 return res_value 618 print(f"Invalid '{option_name}' value.") 619 sys.exit(1) 620 621 @staticmethod 622 def __parse_option_with_space(arg_list: List[str], option_name: str) \ 623 -> Tuple[Optional[Union[str, int]], List[str]]: 624 if option_name in arg_list: 625 option_index = arg_list.index(option_name) 626 if len(arg_list) > option_index + 1: 627 option_value = ArkPy.__get_option_value(option_name, arg_list[option_index + 1]) 628 arg_list = arg_list[:option_index] + arg_list[option_index + 2:] 629 else: 630 print(f"Missing {option_name} value.") 631 sys.exit(1) 632 633 return option_value, arg_list 634 return None, arg_list 635 636 @staticmethod 637 def __parse_option_with_equal(arg_list: List[str], option_name: str) \ 638 -> Tuple[Optional[Union[str, int]], List[str]]: 639 for index, arg in enumerate(arg_list): 640 local_option_name = f"{option_name}=" 641 if arg.startswith(local_option_name): 642 option_value = arg[len(local_option_name):] 643 if option_value: 644 option_value = ArkPy.__get_option_value(option_name, option_value) 645 arg_list = arg_list[:index] + arg_list[index + 1:] 646 return option_value, arg_list 647 else: 648 print(f"Missing {option_name} value.") 649 sys.exit(1) 650 return None, arg_list 651 652 @staticmethod 653 def __get_x64_out_path(out_path) -> str: 654 if 'release' in out_path: 655 return 'out/x64.release' 656 if 'debug' in out_path: 657 return 'out/x64.debug' 658 if 'fastverify' in out_path: 659 return 'out/x64.fastverify' 660 return "" 661 662 def get_binaries(self): 663 host_os = sys.platform 664 host_cpu = platform.machine() 665 try: 666 with open(self.PREBUILTS_DOWNLOAD_CONFIG_FILE_PATH) as file_prebuilts_download_config: 667 prebuilts_download_config_dict = json.load(file_prebuilts_download_config) 668 file_prebuilts_download_config.close() 669 for element in prebuilts_download_config_dict[host_os][host_cpu]["copy_config"]: 670 if element["unzip_filename"] == "gn": 671 self.gn_binary_path = os.path.join(element["unzip_dir"], element["unzip_filename"]) 672 elif element["unzip_filename"] == "ninja": 673 self.ninja_binary_path = os.path.join(element["unzip_dir"], element["unzip_filename"]) 674 except Exception as error: 675 print("\nLogic of getting gn binary or ninja binary does not match logic of prebuilts_download." \ 676 "\nCheck func \033[92m{0} of class {1} in file {2}\033[0m against file {3} if the name of this " \ 677 "file had not changed!\n".format( 678 sys._getframe().f_code.co_name, self.__class__.__name__, CURRENT_FILENAME, 679 self.PREBUILTS_DOWNLOAD_CONFIG_FILE_PATH)) 680 raise error 681 if self.gn_binary_path == "" or self.ninja_binary_path == "": 682 print("\nLogic of prebuilts_download may be wrong." \ 683 "\nCheck \033[92mdata in file {0}\033[0m against func {1} of class {2} in file {3}!\n".format( 684 self.PREBUILTS_DOWNLOAD_CONFIG_FILE_PATH, sys._getframe().f_code.co_name, self.__class__.__name__, 685 CURRENT_FILENAME)) 686 sys.exit(0) 687 if not os.path.isfile(self.gn_binary_path) or not os.path.isfile(self.ninja_binary_path): 688 print("\nStep for prebuilts_download may be ommited. (\033[92m./prebuilts_download.sh\033[0m)" \ 689 "\nCheck \033[92mwhether gn binary and ninja binary are under directory prebuilts\033[0m!\n".format()) 690 sys.exit(0) 691 return 692 693 def which_dict_flags_match_arg(self, dict_including_dicts_to_match: dict, arg_to_match: str) -> str: 694 for key in dict_including_dicts_to_match.keys(): 695 if self.is_dict_flags_match_arg(dict_including_dicts_to_match[key], arg_to_match): 696 return key 697 return "" 698 699 def dict_in_os_cpu_mode_match_arg(self, arg: str) -> [bool, str, str]: 700 os_cpu_part = "" 701 mode_part = "" 702 match_success = True 703 key_to_dict_in_os_cpu_matched_arg = "" 704 key_to_dict_in_mode_matched_arg = "" 705 arg_to_list = arg.split(self.DELIMITER_BETWEEN_OS_CPU_MODE_FOR_COMMAND) 706 if len(arg_to_list) == 1: 707 os_cpu_part = arg_to_list[0] 708 mode_part = "release" 709 key_to_dict_in_os_cpu_matched_arg = self.which_dict_flags_match_arg(self.ARG_DICT.get("os_cpu"), os_cpu_part) 710 key_to_dict_in_mode_matched_arg = self.which_dict_flags_match_arg(self.ARG_DICT.get("mode"), mode_part) 711 elif len(arg_to_list) == 2: 712 os_cpu_part = arg_to_list[0] 713 mode_part = arg_to_list[1] 714 key_to_dict_in_os_cpu_matched_arg = self.which_dict_flags_match_arg(self.ARG_DICT.get("os_cpu"), os_cpu_part) 715 key_to_dict_in_mode_matched_arg = self.which_dict_flags_match_arg(self.ARG_DICT.get("mode"), mode_part) 716 else: 717 print("\"\033[92m{0}\033[0m\" combined with more than 2 flags is not supported.".format(arg)) 718 if (key_to_dict_in_os_cpu_matched_arg == "") | (key_to_dict_in_mode_matched_arg == ""): 719 match_success = False 720 return [match_success, key_to_dict_in_os_cpu_matched_arg, key_to_dict_in_mode_matched_arg] 721 722 def get_help_msg_of_dict(self, dict_in: dict, indentation_str_current: str, indentation_str_per_level: str) -> str: 723 help_msg = "".format() 724 for key in dict_in.keys(): 725 if isinstance(dict_in[key], dict): 726 help_msg += "{0}{1}:\n".format(indentation_str_current, key) 727 help_msg += self.get_help_msg_of_dict( 728 dict_in[key], indentation_str_current + indentation_str_per_level, indentation_str_per_level) 729 elif key == "flags": 730 help_msg += "{0}{1}: \033[92m{2}\033[0m\n".format(indentation_str_current, key, " ".join(dict_in[key])) 731 elif key == "description": 732 help_msg += "{0}{1}: {2}\n".format(indentation_str_current, key, dict_in[key]) 733 return help_msg 734 735 def get_help_msg_of_all(self) -> str: 736 help_msg = "".format() 737 # Command template 738 help_msg += "\033[32mCommand template:\033[0m\n{}\n\n".format( 739 " python3 ark.py \033[92m[os_cpu].[mode] [gn_target] [option]\033[0m\n" 740 " python3 ark.py \033[92m[os_cpu].[mode] [test262] [none or --aot] " \ 741 "[none or --pgo] [none or --litecg] [none, file or dir] [none or --threads=X] [option]\033[0m\n" 742 " python3 ark.py \033[92m[os_cpu].[mode] [test262] [none or --jit] [none or --threads=X]\033[0m\n" 743 " python3 ark.py \033[92m[os_cpu].[mode] [test262] [none or --baseline-jit] [none or --enable-rm] " \ 744 "[none or --threads=X and/or --test-list TEST_LIST_NAME]\033[0m\n" 745 " python3 ark.py \033[92m[os_cpu].[mode] [unittest] [option]\033[0m\n" 746 " python3 ark.py \033[92m[os_cpu].[mode] [regresstest] [none, file or dir] " \ 747 "[none or --processes X and/or --test-list TEST_LIST_NAME]\033[0m\n") 748 # Command examples 749 help_msg += "\033[32mCommand examples:\033[0m\n{}\n\n".format( 750 " python3 ark.py \033[92mx64.release\033[0m\n" 751 " python3 ark.py \033[92mx64.release ets_runtime\033[0m\n" 752 " python3 ark.py \033[92mx64.release ark_js_vm es2panda\033[0m\n" 753 " python3 ark.py \033[92mx64.release ark_js_vm es2panda --clean\033[0m\n" 754 " python3 ark.py \033[92mx64.release test262\033[0m\n" 755 " python3 ark.py \033[92mx64.release test262 --threads=16\033[0m\n" 756 " python3 ark.py \033[92mx64.release test262 --aot --pgo --litecg\033[0m\n" 757 " python3 ark.py \033[92mx64.release test262 --aot --pgo --litecg --threads=8\033[0m\n" 758 " python3 ark.py \033[92mx64.release test262 --jit --enable-rm\033[0m\n" 759 " python3 ark.py \033[92mx64.release test262 --baseline-jit\033[0m\n" 760 " python3 ark.py \033[92mx64.release test262 built-ins/Array\033[0m\n" 761 " python3 ark.py \033[92mx64.release test262 built-ins/Array/name.js\033[0m\n" 762 " python3 ark.py \033[92mx64.release unittest\033[0m\n" 763 " python3 ark.py \033[92mx64.release regresstest\033[0m\n" 764 " python3 ark.py \033[92mx64.release regresstest --processes=4\033[0m\n" 765 " python3 ark.py \033[92mx64.release workload\033[0m\n" 766 " python3 ark.py \033[92mx64.release workload report\033[0m\n" 767 " python3 ark.py \033[92mx64.release workload report dev\033[0m\n" 768 " python3 ark.py \033[92mx64.release workload report dev -20\033[0m\n" 769 " python3 ark.py \033[92mx64.release workload report dev -20 10\033[0m\n" 770 " python3 ark.py \033[92mx64.release workload report dev -20 10 weekly_workload\033[0m\n") 771 # Arguments 772 help_msg += "\033[32mArguments:\033[0m\n{}".format( 773 self.get_help_msg_of_dict( 774 self.ARG_DICT, self.INDENTATION_STRING_PER_LEVEL, self.INDENTATION_STRING_PER_LEVEL)) 775 return help_msg 776 777 def clean(self, out_path: str): 778 if not os.path.exists(out_path): 779 print("Path \"{}\" does not exist! No need to clean it.".format(out_path)) 780 else: 781 print("=== clean start ===") 782 code = _call("{0} clean {1}".format(self.gn_binary_path, out_path)) 783 if code != 0: 784 print("=== clean failed! ===\n") 785 sys.exit(code) 786 print("=== clean success! ===\n") 787 return 788 789 def build_for_gn_target(self, out_path: str, gn_args: list, arg_list: list, log_file_name: str): 790 # prepare log file 791 build_log_path = os.path.join(out_path, log_file_name) 792 backup(build_log_path, "w") 793 if arg_list is not None: 794 build_target = " ".join([str(arg).strip() for arg in arg_list 795 if arg is not None or len(str(arg).strip()) > 0]) 796 else: 797 build_target = "" 798 str_to_build_log = "================================\nbuild_time: {0}\nbuild_target: {1}\n\n".format( 799 str_of_time_now(), build_target) 800 _write(build_log_path, str_to_build_log, "a") 801 # gn command 802 print("=== gn gen start ===") 803 code = call_with_output( 804 "{0} gen {1} --args=\"{2}\" --export-compile-commands".format( 805 self.gn_binary_path, out_path, " ".join(gn_args).replace("\"", "\\\"")), 806 build_log_path) 807 if code != 0: 808 print("=== gn gen failed! ===\n") 809 sys.exit(code) 810 else: 811 print("=== gn gen success! ===\n") 812 # ninja command 813 # Always add " -d keeprsp" to ninja command to keep response file("*.rsp"), thus we could get shared libraries 814 # of an excutable from its response file. 815 ninja_cmd = \ 816 self.ninja_binary_path + \ 817 (" -v" if self.enable_verbose else "") + \ 818 (" -d keepdepfile" if self.enable_keepdepfile else "") + \ 819 " -d keeprsp" + \ 820 " -C {}".format(out_path) + \ 821 " {}".format(" ".join(arg_list if arg_list else [])) + \ 822 " -k {}".format(self.ignore_errors) 823 print(ninja_cmd) 824 code = call_with_output(ninja_cmd, build_log_path) 825 if code != 0: 826 print("=== ninja failed! ===\n") 827 sys.exit(code) 828 else: 829 print("=== ninja success! ===\n") 830 return 831 832 def call_build_gn_target(self, gn_args, out_path, x64_out_path, test_suite, log_file_name): 833 if any('target_cpu="arm64"' in arg for arg in gn_args): 834 gn_args.append("so_dir_for_qemu=\"../../{0}/common/common/libc/\"".format(out_path)) 835 gn_args.append("run_with_qemu=true".format(out_path)) 836 if not os.path.exists(x64_out_path): 837 os.makedirs(x64_out_path) 838 self.build_for_gn_target( 839 x64_out_path, 840 ['target_os="linux"', 'target_cpu="x64"', 'is_debug=false'], 841 self.ARG_DICT.get("target").get(test_suite).get("gn_targets_depend_on"), 842 log_file_name) 843 self.build_for_gn_target( 844 out_path, 845 gn_args, 846 self.ARG_DICT.get("target").get(test_suite).get("arm64_gn_targets_depend_on"), 847 log_file_name) 848 else: 849 self.build_for_gn_target( 850 out_path, 851 gn_args, 852 self.ARG_DICT.get("target").get(test_suite).get("gn_targets_depend_on"), 853 log_file_name) 854 855 def get_build_cmd(self, *, test_suite, test_script_name, test_script_path, 856 out_path, x64_out_path, gn_args: list, args_to_cmd: str, timeout, 857 run_jit: bool = False, run_baseline_jit: bool = False, aot_mode: bool = False, 858 run_pgo: bool = False, enable_litecg: bool = False, ignore_list: Optional[str] = None) -> str: 859 if run_jit: 860 cmd = self.get_jit_cmd(test_suite, test_script_name, test_script_path, 861 gn_args, out_path, x64_out_path, args_to_cmd, timeout) 862 elif run_baseline_jit: 863 cmd = self.get_baseline_jit_cmd(test_suite, test_script_name, test_script_path, 864 gn_args, out_path, x64_out_path, args_to_cmd, timeout) 865 elif aot_mode and test_suite == "test262": 866 cmd = self.get_test262_aot_cmd(gn_args, out_path, x64_out_path, run_pgo, 867 enable_litecg, args_to_cmd, timeout) 868 else: 869 cmd = self.get_cmd(test_suite, test_script_name, test_script_path, 870 gn_args, out_path, x64_out_path, aot_mode, run_pgo, 871 enable_litecg, args_to_cmd, timeout, ignore_list) 872 return cmd 873 874 def build_for_suite(self, *, test_suite, test_script_name, test_script_path, 875 out_path, gn_args: list, log_file_name, args_to_cmd: str, timeout, 876 run_jit: bool = False, run_baseline_jit: bool = False, aot_mode: bool = False, 877 run_pgo: bool = False, enable_litecg: bool = False, ignore_list: Optional[str] = None): 878 x64_out_path = self.__get_x64_out_path(out_path) 879 self.call_build_gn_target(gn_args, out_path, x64_out_path, test_suite, log_file_name) 880 cmd = self.get_build_cmd( 881 test_suite=test_suite, 882 test_script_name=test_script_name, 883 test_script_path=test_script_path, 884 out_path=out_path, 885 x64_out_path=x64_out_path, 886 gn_args=gn_args, 887 args_to_cmd=args_to_cmd, 888 timeout=timeout, 889 run_jit=run_jit, 890 run_baseline_jit=run_baseline_jit, 891 aot_mode=aot_mode, run_pgo=run_pgo, enable_litecg=enable_litecg, ignore_list=ignore_list) 892 log_path = str(os.path.join(out_path, log_file_name)) 893 str_to_log = "================================\n{2}_time: {0}\n{2}_target: {1}\n\n".format( 894 str_of_time_now(), args_to_cmd, test_suite) 895 _write(log_path, str_to_log, "a") 896 print(f"=== {test_suite} start ===") 897 code = call_with_output(cmd, log_path) 898 if code != 0: 899 print(f"=== {test_suite} fail! ===\n") 900 sys.exit(code) 901 print(f"=== {test_suite} success! ===\n") 902 903 def build_for_test262(self, out_path, gn_args: list, arg_list: list): 904 timeout, arg_list = self.parse_timeout(arg_list) 905 arg_list = arg_list[1:] 906 907 is_aot_mode, arg_list = self.__purge_arg_list("--aot", arg_list) 908 is_pgo, arg_list = self.__purge_arg_list("--pgo", arg_list) 909 is_litecg, arg_list = self.__purge_arg_list("--litecg", arg_list) 910 is_jit, arg_list = self.__purge_arg_list("--jit", arg_list) 911 is_baseline_jit, arg_list = self.__purge_arg_list("--baseline-jit", arg_list) 912 print(f"Test262: arg_list = {arg_list}") 913 914 args_to_test262_cmd = self.build_args_to_test262_cmd(arg_list) 915 self.build_for_suite( 916 test_suite="test262", 917 test_script_name="test262/run_test262.py", 918 test_script_path="arkcompiler/ets_frontend", 919 out_path=out_path, 920 gn_args=gn_args, 921 log_file_name=self.TEST262_LOG_FILE_NAME, 922 args_to_cmd=args_to_test262_cmd, 923 timeout=timeout, 924 run_jit=is_jit, 925 run_pgo=is_pgo, 926 run_baseline_jit=is_baseline_jit, 927 aot_mode=is_aot_mode, 928 enable_litecg=is_litecg 929 ) 930 931 def build_for_unittest(self, out_path: str, gn_args: list, log_file_name: str): 932 self.build_for_gn_target( 933 out_path, gn_args, self.ARG_DICT.get("target").get("unittest").get("gn_targets_depend_on"), 934 log_file_name) 935 return 936 937 def build_for_regress_test(self, out_path, gn_args: list, arg_list: list): 938 timeout, arg_list = self.parse_option(arg_list, option_name="--timeout", default_value=200) 939 ignore_list, arg_list = self.parse_option(arg_list, option_name="--ignore-list", default_value=None) 940 941 arg_list = arg_list[1:] 942 943 is_aot, arg_list = self.__purge_arg_list("--aot", arg_list) 944 is_pgo, arg_list = self.__purge_arg_list("--pgo", arg_list) 945 is_litecg, arg_list = self.__purge_arg_list("--litecg", arg_list) 946 is_jit, arg_list = self.__purge_arg_list("--jit", arg_list) 947 is_baseline_jit, arg_list = self.__purge_arg_list("--baseline-jit", arg_list) 948 print(f"Regress: arg_list = {arg_list}") 949 950 args_to_regress_test_cmd = self.build_args_to_regress_cmd(arg_list) 951 self.build_for_suite( 952 test_suite="regresstest", 953 test_script_name="test/regresstest/run_regress_test.py", 954 test_script_path="arkcompiler/ets_runtime", 955 out_path=out_path, 956 gn_args=gn_args, 957 log_file_name=self.REGRESS_TEST_LOG_FILE_NAME, 958 args_to_cmd=args_to_regress_test_cmd, 959 timeout=timeout, 960 run_jit=is_jit, 961 run_pgo=is_pgo, 962 run_baseline_jit=is_baseline_jit, 963 aot_mode=is_aot, 964 enable_litecg=is_litecg, 965 ignore_list=ignore_list 966 ) 967 968 def build(self, out_path: str, gn_args: list, arg_list: list): 969 if not os.path.exists(out_path): 970 print("# mkdir -p {}".format(out_path)) 971 os.makedirs(out_path) 972 if len(arg_list) == 0: 973 self.build_for_gn_target(out_path, gn_args, ["default"], self.GN_TARGET_LOG_FILE_NAME) 974 elif self.is_dict_flags_match_arg(self.ARG_DICT.get("target").get("workload"), arg_list[0]): 975 self.build_for_workload(arg_list, out_path, gn_args, 'workload.log') 976 elif self.is_dict_flags_match_arg(self.ARG_DICT.get("target").get("test262"), arg_list[0]): 977 self.build_for_test262(out_path, gn_args, arg_list) 978 elif self.is_dict_flags_match_arg(self.ARG_DICT.get("target").get("unittest"), arg_list[0]): 979 if len(arg_list) > 1: 980 print("\033[92m\"unittest\" not support additional arguments.\033[0m\n".format()) 981 sys.exit(0) 982 self.build_for_unittest(out_path, gn_args, self.UNITTEST_LOG_FILE_NAME) 983 elif self.is_dict_flags_match_arg(self.ARG_DICT.get("target").get("regresstest"), arg_list[0]): 984 self.build_for_regress_test(out_path, gn_args, arg_list) 985 else: 986 self.build_for_gn_target(out_path, gn_args, arg_list, self.GN_TARGET_LOG_FILE_NAME) 987 return 988 989 def parse_timeout(self, arg_list) -> Tuple[Optional[Union[str, int]], List[str]]: 990 return self.parse_option(arg_list, option_name="--timeout", default_value=400000) 991 992 def match_options(self, arg_list: list, out_path: str) -> [list, list]: 993 arg_list_ret = [] 994 gn_args_ret = [] 995 for arg in arg_list: 996 # match [option][clean] flag 997 if self.is_dict_flags_match_arg(self.ARG_DICT.get("option").get("clean"), arg): 998 self.clean(out_path) 999 sys.exit(0) 1000 # match [option][clean-continue] flag 1001 elif self.is_dict_flags_match_arg(self.ARG_DICT.get("option").get("clean-continue"), arg): 1002 if not self.has_cleaned: 1003 self.clean(out_path) 1004 self.has_cleaned = True 1005 # match [option][gn-args] flag 1006 elif self.is_dict_flags_match_arg(self.ARG_DICT.get("option").get("gn-args"), arg): 1007 gn_args_ret.append(arg[(arg.find("=") + 1):]) 1008 # match [option][keepdepfile] flag 1009 elif self.is_dict_flags_match_arg(self.ARG_DICT.get("option").get("keepdepfile"), arg): 1010 if not self.enable_keepdepfile: 1011 self.enable_keepdepfile = True 1012 # match [option][verbose] flag 1013 elif self.is_dict_flags_match_arg(self.ARG_DICT.get("option").get("verbose"), arg): 1014 if not self.enable_verbose: 1015 self.enable_verbose = True 1016 # match [option][keep-going] flag 1017 elif self.is_dict_flags_match_arg(self.ARG_DICT.get("option").get("keep-going"), arg): 1018 if self.ignore_errors == 1: 1019 input_value = arg[(arg.find("=") + 1):] 1020 try: 1021 self.ignore_errors = int(input_value) 1022 except Exception as _: 1023 print("\033[92mIllegal value \"{}\" for \"--keep-going\" argument.\033[0m\n".format( 1024 input_value 1025 )) 1026 sys.exit(0) 1027 # make a new list with flag that do not match any flag in [option] 1028 else: 1029 arg_list_ret.append(arg) 1030 return [arg_list_ret, gn_args_ret] 1031 1032 def build_for_workload(self, arg_list, out_path, gn_args, log_file_name): 1033 root_dir = os.path.dirname(os.path.abspath(__file__)) 1034 report = False 1035 tools = 'dev' 1036 boundary_value = '-10' 1037 run_count = '10' 1038 code_v = '' 1039 run_interpreter = False 1040 if len(arg_list) >= 2 and arg_list[1] == 'report': 1041 report = True 1042 if len(arg_list) >= 3 and arg_list[2]: 1043 tools = arg_list[2] 1044 if len(arg_list) >= 4 and arg_list[3]: 1045 boundary_value = arg_list[3] 1046 if len(arg_list) >= 5 and arg_list[4]: 1047 run_count = arg_list[4] 1048 if len(arg_list) >= 6 and arg_list[5]: 1049 code_v = arg_list[5] 1050 if len(arg_list) >= 7 and arg_list[6] == '--run-interpreter': 1051 run_interpreter = True 1052 self.build_for_gn_target(out_path, gn_args, ["default"], self.GN_TARGET_LOG_FILE_NAME) 1053 workload_cmd = "cd arkcompiler/ets_runtime/test/workloadtest/ && python3 work_load.py" \ 1054 " --code-path {0}" \ 1055 " --report {1}" \ 1056 " --tools-type {2}" \ 1057 " --boundary-value {3}" \ 1058 " --run-count {4}" \ 1059 " --code-v {5}" \ 1060 .format(root_dir, report, tools, boundary_value, run_count, code_v) 1061 if run_interpreter: 1062 workload_cmd += " --run-interpreter true" 1063 workload_log_path = os.path.join(out_path, log_file_name) 1064 str_to_workload_log = "================================\nwokload_time: {0}\nwokload_target: {1}\n\n".format( 1065 str_of_time_now(), 'file') 1066 _write(workload_log_path, str_to_workload_log, "a") 1067 print("=== workload start ===") 1068 code = call_with_output(workload_cmd, workload_log_path) 1069 if code != 0: 1070 print("=== workload fail! ===\n") 1071 sys.exit(code) 1072 print("=== workload success! ===\n") 1073 return 1074 1075 def start_for_matched_os_cpu_mode(self, os_cpu_key: str, mode_key: str, arg_list: list): 1076 # get binary gn and ninja 1077 self.get_binaries() 1078 # get out_path 1079 name_of_out_dir_of_second_level = \ 1080 self.ARG_DICT.get("os_cpu").get(os_cpu_key).get("prefix_of_name_of_out_dir_of_second_level") + \ 1081 self.DELIMITER_FOR_SECOND_OUT_DIR_NAME + \ 1082 self.ARG_DICT.get("mode").get(mode_key).get("suffix_of_name_of_out_dir_of_second_level") 1083 out_path = os.path.join(self.NAME_OF_OUT_DIR_OF_FIRST_LEVEL, name_of_out_dir_of_second_level) 1084 # match [option] flag 1085 [arg_list, gn_args] = self.match_options(arg_list, out_path) 1086 # get expression which would be written to args.gn file 1087 gn_args.extend(self.ARG_DICT.get("os_cpu").get(os_cpu_key).get("gn_args")) 1088 gn_args.extend(self.ARG_DICT.get("mode").get(mode_key).get("gn_args")) 1089 # start to build 1090 self.build(out_path, gn_args, arg_list) 1091 return 1092 1093 def __purge_arg_list(self, option_name: str, arg_list: List[Any]) -> Tuple[bool, List[Any]]: 1094 if option_name in arg_list: 1095 arg_list.remove(option_name) 1096 return True, arg_list 1097 return False, arg_list 1098 1099 1100if __name__ == "__main__": 1101 ark_py = ArkPy() 1102 ark_py.__main__(sys.argv[1:]) 1103