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, 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["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 get_test262_cmd(gn_args, out_path, x64_out_path, run_pgo, enable_litecg, args_to_test262_cmd, 313 timeout): 314 315 print("running test262 in AsmMode\n") 316 if any('target_cpu="arm64"' in arg for arg in gn_args): 317 test262_cmd = "cd arkcompiler/ets_frontend && python3 test262/run_test262.py {0} --timeout {3}" \ 318 " --libs-dir ../../{1}/arkcompiler/ets_runtime:../../{1}/thirdparty/icu:" \ 319 "../../{1}/thirdparty/zlib:../../prebuilts/clang/ohos/linux-x86_64/llvm/lib" \ 320 " --ark-arch aarch64" \ 321 " --ark-arch-root=../../{1}/common/common/libc/" \ 322 " --ark-tool=../../{1}/arkcompiler/ets_runtime/ark_js_vm" \ 323 " --ark-frontend-binary=../../{2}/arkcompiler/ets_frontend/es2abc" \ 324 " --merge-abc-binary=../../{2}/arkcompiler/ets_frontend/merge_abc" \ 325 " --ark-frontend=es2panda".format(args_to_test262_cmd, out_path, x64_out_path) 326 else: 327 test262_cmd = "cd arkcompiler/ets_frontend && python3 test262/run_test262.py {0} --timeout {2}" \ 328 " --libs-dir ../../prebuilts/clang/ohos/linux-x86_64/llvm/lib" \ 329 " --ark-tool=../../{1}/arkcompiler/ets_runtime/ark_js_vm" \ 330 " --ark-frontend-binary=../../{1}/arkcompiler/ets_frontend/es2abc" \ 331 " --merge-abc-binary=../../{1}/arkcompiler/ets_frontend/merge_abc" \ 332 " --ark-frontend=es2panda".format(args_to_test262_cmd, out_path, timeout) 333 return test262_cmd 334 335 @staticmethod 336 def get_test262_aot_cmd(gn_args, out_path, x64_out_path, run_pgo, enable_litecg, args_to_test262_cmd, 337 timeout): 338 print("running test262 in AotMode\n") 339 if any('target_cpu="arm64"' in arg for arg in gn_args): 340 if run_pgo: 341 test262_cmd = "cd arkcompiler/ets_frontend && python3 test262/run_test262.py {0} --timeout {4}" \ 342 " --libs-dir ../../{1}/arkcompiler/ets_runtime:../../{1}/thirdparty/icu:" \ 343 "../../{1}/thirdparty/zlib:../../prebuilts/clang/ohos/linux-x86_64/llvm/lib" \ 344 " --ark-arch aarch64" \ 345 " --ark-arch-root=../../{1}/common/common/libc/" \ 346 " --ark-tool=../../{1}/arkcompiler/ets_runtime/ark_js_vm" \ 347 " --ark-aot-tool=../../{1}/arkcompiler/ets_runtime/ark_aot_compiler" \ 348 " --ark-frontend-binary=../../{2}/arkcompiler/ets_frontend/es2abc" \ 349 " --merge-abc-binary=../../{2}/arkcompiler/ets_frontend/merge_abc" \ 350 " --ark-aot" \ 351 " --ark-frontend=es2panda"\ 352 "{3}".format(args_to_test262_cmd, out_path, x64_out_path, " --run-pgo", timeout) 353 else: 354 test262_cmd = "cd arkcompiler/ets_frontend && python3 test262/run_test262.py {0} --timeout {3}" \ 355 " --libs-dir ../../prebuilts/clang/ohos/linux-x86_64/llvm/lib:../../{2}/thirdparty/icu/" \ 356 " --ark-arch aarch64" \ 357 " --ark-arch-root=../../{1}/common/common/libc/" \ 358 " --ark-aot" \ 359 " --ark-aot-tool=../../{2}/arkcompiler/ets_runtime/ark_aot_compiler" \ 360 " --ark-tool=../../{1}/arkcompiler/ets_runtime/ark_js_vm" \ 361 " --ark-frontend-binary=../../{2}/arkcompiler/ets_frontend/es2abc" \ 362 " --merge-abc-binary=../../{2}/arkcompiler/ets_frontend/merge_abc" \ 363 " --ark-frontend=es2panda".format(args_to_test262_cmd, out_path, x64_out_path, timeout) 364 else: 365 test262_cmd = "cd arkcompiler/ets_frontend && python3 test262/run_test262.py {0} --timeout {3}" \ 366 " --libs-dir ../../{1}/arkcompiler/ets_runtime:../../{1}/thirdparty/icu" \ 367 ":../../{1}/thirdparty/zlib:../../prebuilts/clang/ohos/linux-x86_64/llvm/lib" \ 368 " --ark-tool=../../{1}/arkcompiler/ets_runtime/ark_js_vm" \ 369 " --ark-aot-tool=../../{1}/arkcompiler/ets_runtime/ark_aot_compiler" \ 370 " --ark-frontend-binary=../../{1}/arkcompiler/ets_frontend/es2abc" \ 371 " --merge-abc-binary=../../{1}/arkcompiler/ets_frontend/merge_abc" \ 372 " --ark-aot" \ 373 " --ark-frontend=es2panda"\ 374 "{2}".format(args_to_test262_cmd, out_path, " --run-pgo" if run_pgo else "", timeout) 375 if enable_litecg: 376 test262_cmd = test262_cmd + " --enable-litecg" 377 return test262_cmd 378 379 @staticmethod 380 def get_test262_jit_cmd(gn_args, out_path, x64_out_path, args_to_test262_cmd, timeout): 381 print("running test262 in JIT mode\n") 382 if any('target_cpu="arm64"' in arg for arg in gn_args): 383 test262_cmd = "cd arkcompiler/ets_frontend && python3 test262/run_test262.py {0} --timeout {3}" \ 384 " --libs-dir ../../prebuilts/clang/ohos/linux-x86_64/llvm/lib:../../{1}/thirdparty/icu/" \ 385 ":../../{1}/thirdparty/bounds_checking_function" \ 386 ":../../{1}/arkcompiler/ets_runtime:" \ 387 " --ark-arch aarch64" \ 388 " --run-jit" \ 389 " --ark-arch-root=../../{1}/common/common/libc/" \ 390 " --ark-aot-tool=../../{2}/arkcompiler/ets_runtime/ark_aot_compiler" \ 391 " --ark-tool=../../{1}/arkcompiler/ets_runtime/ark_js_vm" \ 392 " --ark-frontend-binary=../../{2}/arkcompiler/ets_frontend/es2abc" \ 393 " --merge-abc-binary=../../{2}/arkcompiler/ets_frontend/merge_abc" \ 394 " --ark-frontend=es2panda".format(args_to_test262_cmd, out_path, x64_out_path, timeout) 395 else: 396 test262_cmd = "cd arkcompiler/ets_frontend && python3 test262/run_test262.py {0} --timeout {3}" \ 397 " --libs-dir ../../{1}/arkcompiler/ets_runtime:../../{1}/thirdparty/icu" \ 398 ":../../{1}/thirdparty/zlib:../../prebuilts/clang/ohos/linux-x86_64/llvm/lib" \ 399 " --run-jit" \ 400 " --ark-tool=../../{1}/arkcompiler/ets_runtime/ark_js_vm" \ 401 " --ark-frontend-binary=../../{1}/arkcompiler/ets_frontend/es2abc" \ 402 " --merge-abc-binary=../../{1}/arkcompiler/ets_frontend/merge_abc" \ 403 " --ark-frontend=es2panda"\ 404 "{2}".format(args_to_test262_cmd, out_path, x64_out_path, timeout) 405 return test262_cmd 406 407 @staticmethod 408 def get_test262_baseline_jit_cmd(gn_args, out_path, x64_out_path, args_to_test262_cmd, timeout): 409 print("running test262 in baseline JIT mode\n") 410 if any('target_cpu="arm64"' in arg for arg in gn_args): 411 test262_cmd = "cd arkcompiler/ets_frontend && python3 test262/run_test262.py {0} --timeout {3}" \ 412 " --libs-dir ../../prebuilts/clang/ohos/linux-x86_64/llvm/lib" \ 413 ":../../{1}/thirdparty/icu" \ 414 ":../../prebuilts/clang/ohos/linux-x86_64/llvm/lib/aarch64-linux-ohos" \ 415 ":../../{1}/thirdparty/bounds_checking_function" \ 416 ":../../{1}/arkcompiler/ets_runtime" \ 417 ":../../{1}/common/common/libc/lib" \ 418 " --ark-arch aarch64" \ 419 " --run-baseline-jit" \ 420 " --ark-arch-root=../../{1}/common/common/libc/" \ 421 " --ark-aot-tool=../../{2}/arkcompiler/ets_runtime/ark_aot_compiler" \ 422 " --ark-tool=../../{1}/arkcompiler/ets_runtime/ark_js_vm" \ 423 " --ark-frontend-binary=../../{2}/arkcompiler/ets_frontend/es2abc" \ 424 " --merge-abc-binary=../../{2}/arkcompiler/ets_frontend/merge_abc" \ 425 " --ark-frontend=es2panda".format(args_to_test262_cmd, out_path, x64_out_path, timeout) 426 else: 427 test262_cmd = "cd arkcompiler/ets_frontend && python3 test262/run_test262.py {0} --timeout {3}" \ 428 " --libs-dir ../../{1}/lib.unstripped/arkcompiler/ets_runtime" \ 429 ":../../{1}/lib.unstripped/thirdparty/icu" \ 430 ":../../prebuilts/clang/ohos/linux-x86_64/llvm/lib" \ 431 ":../../{1}/lib.unstripped/thirdparty/bounds_checking_function/" \ 432 " --run-baseline-jit" \ 433 " --ark-tool=../../{1}/arkcompiler/ets_runtime/ark_js_vm" \ 434 " --ark-frontend-binary=../../{1}/arkcompiler/ets_frontend/es2abc" \ 435 " --merge-abc-binary=../../{1}/arkcompiler/ets_frontend/merge_abc" \ 436 " --ark-frontend=es2panda"\ 437 "{2}".format(args_to_test262_cmd, out_path, x64_out_path, timeout) 438 return test262_cmd 439 440 @staticmethod 441 def build_args_to_test262_cmd(arg_list): 442 args_to_test262_cmd = [] 443 444 disable_force_gc = [arg for arg in arg_list if "disable-force-gc" in arg] 445 if disable_force_gc: 446 args_to_test262_cmd.append("--disable-force-gc") 447 arg_list.remove(disable_force_gc[0]) 448 449 threads_name = "--threads" 450 threads_value, arg_list = ArkPy.parse_option(arg_list, option_name=threads_name, default_value=None) 451 if threads_value: 452 args_to_test262_cmd.extend([threads_name, threads_value]) 453 454 if len(arg_list) == 0: 455 args_to_test262_cmd.append("--es2021 all") 456 elif len(arg_list) == 1: 457 arg = arg_list[0] 458 if ".js" in arg: 459 args_to_test262_cmd.append("--file test262/data/test_es2021/{}".format(arg)) 460 else: 461 args_to_test262_cmd.append("--dir test262/data/test_es2021/{}".format(arg)) 462 else: 463 print("\033[92m\"test262\" not support multiple additional arguments.\033[0m\n".format()) 464 sys.exit(0) 465 466 return " ".join(args_to_test262_cmd) 467 468 @staticmethod 469 def build_args_to_regress_cmd(arg_list): 470 args_to_regress_cmd = [] 471 472 processes_name = "--processes" 473 processes_value, arg_list = ArkPy.parse_option(arg_list, option_name=processes_name, default_value=1) 474 args_to_regress_cmd.extend([processes_name, processes_value]) 475 476 test_list_name = "--test-list" 477 test_list_value, arg_list = ArkPy.parse_option(arg_list, option_name=test_list_name, default_value=None) 478 if test_list_value is not None: 479 args_to_regress_cmd.extend([test_list_name, test_list_value]) 480 481 if len(arg_list) == 1: 482 arg = arg_list[0] 483 if ".js" in arg: 484 args_to_regress_cmd.append(f"--test-file {arg}") 485 else: 486 args_to_regress_cmd.append(f"--test-dir {arg}") 487 elif len(arg_list) > 1: 488 print("\033[92m\"regresstest\" not support multiple additional arguments.\033[0m\n".format()) 489 sys.exit(0) 490 491 return " ".join([str(arg) for arg in args_to_regress_cmd]) 492 493 @staticmethod 494 def parse_option(arg_list: List[str], option_name: str, default_value: Optional[Union[str, int]]) \ 495 -> Tuple[Optional[Union[str, int]], List[str]]: 496 option_value, arg_list = ArkPy.__parse_option_with_space(arg_list, option_name) 497 if option_value is None: 498 option_value, arg_list = ArkPy.__parse_option_with_equal(arg_list, option_name) 499 if option_value is None and default_value is not None: 500 option_value = default_value 501 return option_value, arg_list 502 503 @staticmethod 504 def __is_option_value_int(value: Optional[Union[str, int]]) -> Tuple[bool, Optional[int]]: 505 if isinstance(value, int): 506 return True, int(value) 507 else: 508 return False, None 509 510 @staticmethod 511 def __is_option_value_str(value: Optional[Union[str, int]]) -> Tuple[bool, Optional[str]]: 512 if isinstance(value, str): 513 return True, str(value) 514 else: 515 return False, None 516 517 @staticmethod 518 def __get_option_value(option_name: str, value: Optional[Union[str, int]]) -> Union[str, int]: 519 result, res_value = ArkPy.__is_option_value_int(value) 520 if result: 521 return res_value 522 result, res_value = ArkPy.__is_option_value_str(value) 523 if result: 524 return res_value 525 print(f"Invalid '{option_name}' value.") 526 sys.exit(1) 527 528 @staticmethod 529 def __parse_option_with_space(arg_list: List[str], option_name: str) \ 530 -> Tuple[Optional[Union[str, int]], List[str]]: 531 if option_name in arg_list: 532 option_index = arg_list.index(option_name) 533 if len(arg_list) > option_index + 1: 534 option_value = ArkPy.__get_option_value(option_name, arg_list[option_index + 1]) 535 arg_list = arg_list[:option_index] + arg_list[option_index + 2:] 536 else: 537 print(f"Missing {option_name} value.") 538 sys.exit(1) 539 540 return option_value, arg_list 541 return None, arg_list 542 543 @staticmethod 544 def __parse_option_with_equal(arg_list: List[str], option_name: str) \ 545 -> Tuple[Optional[Union[str, int]], List[str]]: 546 for index, arg in enumerate(arg_list): 547 local_option_name = f"{option_name}=" 548 if arg.startswith(local_option_name): 549 option_value = arg[len(local_option_name):] 550 if option_value: 551 option_value = ArkPy.__get_option_value(option_name, option_value) 552 arg_list = arg_list[:index] + arg_list[index + 1:] 553 return option_value, arg_list 554 else: 555 print(f"Missing {option_name} value.") 556 sys.exit(1) 557 return None, arg_list 558 559 def get_binaries(self): 560 host_os = sys.platform 561 host_cpu = platform.machine() 562 try: 563 with open(self.PREBUILTS_DOWNLOAD_CONFIG_FILE_PATH) as file_prebuilts_download_config: 564 prebuilts_download_config_dict = json.load(file_prebuilts_download_config) 565 file_prebuilts_download_config.close() 566 for element in prebuilts_download_config_dict[host_os][host_cpu]["copy_config"]: 567 if element["unzip_filename"] == "gn": 568 self.gn_binary_path = os.path.join(element["unzip_dir"], element["unzip_filename"]) 569 elif element["unzip_filename"] == "ninja": 570 self.ninja_binary_path = os.path.join(element["unzip_dir"], element["unzip_filename"]) 571 except Exception as error: 572 print("\nLogic of getting gn binary or ninja binary does not match logic of prebuilts_download." \ 573 "\nCheck func \033[92m{0} of class {1} in file {2}\033[0m against file {3} if the name of this " \ 574 "file had not changed!\n".format( 575 sys._getframe().f_code.co_name, self.__class__.__name__, CURRENT_FILENAME, 576 self.PREBUILTS_DOWNLOAD_CONFIG_FILE_PATH)) 577 raise error 578 if self.gn_binary_path == "" or self.ninja_binary_path == "": 579 print("\nLogic of prebuilts_download may be wrong." \ 580 "\nCheck \033[92mdata in file {0}\033[0m against func {1} of class {2} in file {3}!\n".format( 581 self.PREBUILTS_DOWNLOAD_CONFIG_FILE_PATH, sys._getframe().f_code.co_name, self.__class__.__name__, 582 CURRENT_FILENAME)) 583 sys.exit(0) 584 if not os.path.isfile(self.gn_binary_path) or not os.path.isfile(self.ninja_binary_path): 585 print("\nStep for prebuilts_download may be ommited. (\033[92m./prebuilts_download.sh\033[0m)" \ 586 "\nCheck \033[92mwhether gn binary and ninja binary are under directory prebuilts\033[0m!\n".format()) 587 sys.exit(0) 588 return 589 590 def which_dict_flags_match_arg(self, dict_including_dicts_to_match: dict, arg_to_match: str) -> str: 591 for key in dict_including_dicts_to_match.keys(): 592 if self.is_dict_flags_match_arg(dict_including_dicts_to_match[key], arg_to_match): 593 return key 594 return "" 595 596 def dict_in_os_cpu_mode_match_arg(self, arg: str) -> [bool, str, str]: 597 os_cpu_part = "" 598 mode_part = "" 599 match_success = True 600 key_to_dict_in_os_cpu_matched_arg = "" 601 key_to_dict_in_mode_matched_arg = "" 602 arg_to_list = arg.split(self.DELIMITER_BETWEEN_OS_CPU_MODE_FOR_COMMAND) 603 if len(arg_to_list) == 1: 604 os_cpu_part = arg_to_list[0] 605 mode_part = "release" 606 key_to_dict_in_os_cpu_matched_arg = self.which_dict_flags_match_arg(self.ARG_DICT["os_cpu"], os_cpu_part) 607 key_to_dict_in_mode_matched_arg = self.which_dict_flags_match_arg(self.ARG_DICT["mode"], mode_part) 608 elif len(arg_to_list) == 2: 609 os_cpu_part = arg_to_list[0] 610 mode_part = arg_to_list[1] 611 key_to_dict_in_os_cpu_matched_arg = self.which_dict_flags_match_arg(self.ARG_DICT["os_cpu"], os_cpu_part) 612 key_to_dict_in_mode_matched_arg = self.which_dict_flags_match_arg(self.ARG_DICT["mode"], mode_part) 613 else: 614 print("\"\033[92m{0}\033[0m\" combined with more than 2 flags is not supported.".format(arg)) 615 if (key_to_dict_in_os_cpu_matched_arg == "") | (key_to_dict_in_mode_matched_arg == ""): 616 match_success = False 617 return [match_success, key_to_dict_in_os_cpu_matched_arg, key_to_dict_in_mode_matched_arg] 618 619 def get_help_msg_of_dict(self, dict_in: dict, indentation_str_current: str, indentation_str_per_level: str) -> str: 620 help_msg = "".format() 621 for key in dict_in.keys(): 622 if isinstance(dict_in[key], dict): 623 help_msg += "{0}{1}:\n".format(indentation_str_current, key) 624 help_msg += self.get_help_msg_of_dict( 625 dict_in[key], indentation_str_current + indentation_str_per_level, indentation_str_per_level) 626 elif key == "flags": 627 help_msg += "{0}{1}: \033[92m{2}\033[0m\n".format(indentation_str_current, key, " ".join(dict_in[key])) 628 elif key == "description": 629 help_msg += "{0}{1}: {2}\n".format(indentation_str_current, key, dict_in[key]) 630 return help_msg 631 632 def get_help_msg_of_all(self) -> str: 633 help_msg = "".format() 634 # Command template 635 help_msg += "\033[32mCommand template:\033[0m\n{}\n\n".format( 636 " python3 ark.py \033[92m[os_cpu].[mode] [gn_target] [option]\033[0m\n" 637 " python3 ark.py \033[92m[os_cpu].[mode] [test262] [none or --aot] " \ 638 "[none or --pgo] [none or --litecg] [none, file or dir] [none or --threads=X] [option]\033[0m\n" 639 " python3 ark.py \033[92m[os_cpu].[mode] [test262] [none or --jit] [none or --threads=X]\033[0m\n" 640 " python3 ark.py \033[92m[os_cpu].[mode] [test262] [none or --baseline-jit] [none or --threads=X]\033[0m\n" 641 " python3 ark.py \033[92m[os_cpu].[mode] [unittest] [option]\033[0m\n" 642 " python3 ark.py \033[92m[os_cpu].[mode] [regresstest] [none, file or dir] " \ 643 "[none or --processes X and/or --test-list TEST_LIST_NAME]\033[0m\n") 644 # Command examples 645 help_msg += "\033[32mCommand examples:\033[0m\n{}\n\n".format( 646 " python3 ark.py \033[92mx64.release\033[0m\n" 647 " python3 ark.py \033[92mx64.release ets_runtime\033[0m\n" 648 " python3 ark.py \033[92mx64.release ark_js_vm es2panda\033[0m\n" 649 " python3 ark.py \033[92mx64.release ark_js_vm es2panda --clean\033[0m\n" 650 " python3 ark.py \033[92mx64.release test262\033[0m\n" 651 " python3 ark.py \033[92mx64.release test262 --threads=16\033[0m\n" 652 " python3 ark.py \033[92mx64.release test262 --aot --pgo --litecg\033[0m\n" 653 " python3 ark.py \033[92mx64.release test262 --aot --pgo --litecg --threads=8\033[0m\n" 654 " python3 ark.py \033[92mx64.release test262 --jit\033[0m\n" 655 " python3 ark.py \033[92mx64.release test262 --baseline-jit\033[0m\n" 656 " python3 ark.py \033[92mx64.release test262 built-ins/Array\033[0m\n" 657 " python3 ark.py \033[92mx64.release test262 built-ins/Array/name.js\033[0m\n" 658 " python3 ark.py \033[92mx64.release unittest\033[0m\n" 659 " python3 ark.py \033[92mx64.release regresstest\033[0m\n" 660 " python3 ark.py \033[92mx64.release regresstest --processes=4\033[0m\n" 661 " python3 ark.py \033[92mx64.release workload\033[0m\n" 662 " python3 ark.py \033[92mx64.release workload report\033[0m\n" 663 " python3 ark.py \033[92mx64.release workload report dev\033[0m\n" 664 " python3 ark.py \033[92mx64.release workload report dev -20\033[0m\n" 665 " python3 ark.py \033[92mx64.release workload report dev -20 10\033[0m\n" 666 " python3 ark.py \033[92mx64.release workload report dev -20 10 weekly_workload\033[0m\n") 667 # Arguments 668 help_msg += "\033[32mArguments:\033[0m\n{}".format( 669 self.get_help_msg_of_dict( 670 self.ARG_DICT, self.INDENTATION_STRING_PER_LEVEL, self.INDENTATION_STRING_PER_LEVEL)) 671 return help_msg 672 673 def clean(self, out_path: str): 674 if not os.path.exists(out_path): 675 print("Path \"{}\" does not exist! No need to clean it.".format(out_path)) 676 else: 677 print("=== clean start ===") 678 code = _call("{0} clean {1}".format(self.gn_binary_path, out_path)) 679 if code != 0: 680 print("=== clean failed! ===\n") 681 sys.exit(code) 682 print("=== clean success! ===\n") 683 return 684 685 def build_for_gn_target(self, out_path: str, gn_args: list, arg_list: list, log_file_name: str): 686 # prepare log file 687 build_log_path = os.path.join(out_path, log_file_name) 688 backup(build_log_path, "w") 689 str_to_build_log = "================================\nbuild_time: {0}\nbuild_target: {1}\n\n".format( 690 str_of_time_now(), " ".join(arg_list)) 691 _write(build_log_path, str_to_build_log, "a") 692 # gn command 693 print("=== gn gen start ===") 694 code = call_with_output( 695 "{0} gen {1} --args=\"{2}\"".format( 696 self.gn_binary_path, out_path, " ".join(gn_args).replace("\"", "\\\"")), 697 build_log_path) 698 if code != 0: 699 print("=== gn gen failed! ===\n") 700 sys.exit(code) 701 else: 702 print("=== gn gen success! ===\n") 703 # ninja command 704 # Always add " -d keeprsp" to ninja command to keep response file("*.rsp"), thus we could get shared libraries 705 # of an excutable from its response file. 706 ninja_cmd = \ 707 self.ninja_binary_path + \ 708 (" -v" if self.enable_verbose else "") + \ 709 (" -d keepdepfile" if self.enable_keepdepfile else "") + \ 710 " -d keeprsp" + \ 711 " -C {}".format(out_path) + \ 712 " {}".format(" ".join(arg_list)) + \ 713 " -k {}".format(self.ignore_errors) 714 print(ninja_cmd) 715 code = call_with_output(ninja_cmd, build_log_path) 716 if code != 0: 717 print("=== ninja failed! ===\n") 718 sys.exit(code) 719 else: 720 print("=== ninja success! ===\n") 721 return 722 723 def build_for_test262(self, out_path, timeout, gn_args: list, arg_list: list, log_file_name: str, 724 aot_mode: bool, run_pgo=False, enable_litecg=False, run_jit=False, 725 run_baseline_jit=False): 726 args_to_test262_cmd = self.build_args_to_test262_cmd(arg_list) 727 x64_out_path = "" 728 if any('target_cpu="arm64"' in arg for arg in gn_args): 729 if 'release' in out_path: 730 x64_out_path = 'out/x64.release' 731 if 'debug' in out_path: 732 x64_out_path = 'out/x64.debug' 733 gn_args.append("so_dir_for_qemu=\"../../{0}/common/common/libc/\"".format(out_path)) 734 gn_args.append("run_with_qemu=true".format(out_path)) 735 if not os.path.exists(x64_out_path): 736 os.makedirs(x64_out_path) 737 self.build_for_gn_target( 738 x64_out_path, ['target_os="linux"', 'target_cpu="x64"', 'is_debug=false'], 739 self.ARG_DICT["target"]["test262"]["gn_targets_depend_on"], log_file_name) 740 self.build_for_gn_target( 741 out_path, gn_args, self.ARG_DICT["target"]["test262"]["arm64_gn_targets_depend_on"], log_file_name) 742 else: 743 self.build_for_gn_target( 744 out_path, gn_args, self.ARG_DICT["target"]["test262"]["gn_targets_depend_on"], log_file_name) 745 if run_jit: 746 test262_cmd = self.get_test262_jit_cmd(gn_args, out_path, x64_out_path, args_to_test262_cmd, timeout) 747 elif run_baseline_jit: 748 test262_cmd = self.get_test262_baseline_jit_cmd(gn_args, out_path, x64_out_path, 749 args_to_test262_cmd, timeout) 750 elif aot_mode: 751 test262_cmd = self.get_test262_aot_cmd(gn_args, out_path, x64_out_path, run_pgo, enable_litecg, args_to_test262_cmd, 752 timeout) 753 else: 754 test262_cmd = self.get_test262_cmd(gn_args, out_path, x64_out_path, run_pgo, 755 enable_litecg, args_to_test262_cmd, timeout) 756 test262_log_path = os.path.join(out_path, log_file_name) 757 str_to_test262_log = "================================\ntest262_time: {0}\ntest262_target: {1}\n\n".format( 758 str_of_time_now(), args_to_test262_cmd) 759 _write(test262_log_path, str_to_test262_log, "a") 760 print("=== test262 start ===") 761 code = call_with_output(test262_cmd, test262_log_path) 762 if code != 0: 763 print("=== test262 fail! ===\n") 764 sys.exit(code) 765 print("=== test262 success! ===\n") 766 767 def build_for_unittest(self, out_path: str, gn_args: list, log_file_name:str): 768 self.build_for_gn_target( 769 out_path, gn_args, self.ARG_DICT["target"]["unittest"]["gn_targets_depend_on"], 770 log_file_name) 771 return 772 773 def build_for_regress_test(self, out_path, gn_args: list, arg_list: list, log_file_name: str, timeout): 774 args_to_regress_test_cmd = self.build_args_to_regress_cmd(arg_list) 775 self.build_for_gn_target( 776 out_path, gn_args, self.ARG_DICT["target"]["regresstest"]["gn_targets_depend_on"], log_file_name) 777 regress_test_cmd = "python3 arkcompiler/ets_runtime/test/regresstest/run_regress_test.py --timeout {2}" \ 778 " --ark-tool ./{0}/arkcompiler/ets_runtime/ark_js_vm" \ 779 " --ark-frontend-binary ./{0}/arkcompiler/ets_frontend/es2abc" \ 780 " --LD_LIBRARY_PATH ./{0}/arkcompiler/ets_runtime:./{0}/thirdparty/icu:" \ 781 "./prebuilts/clang/ohos/linux-x86_64/llvm/lib" \ 782 " --out-dir ./{0}/ {1}".format(out_path, args_to_regress_test_cmd, timeout) 783 regress_test_log_path = os.path.join(out_path, log_file_name) 784 str_to_test_log = "============\n regresstest_time: {0}\nregresstest_target: {1}\n\n".format( 785 str_of_time_now(), regress_test_cmd) 786 _write(regress_test_log_path, str_to_test_log, "a") 787 print("=== regresstest start ===") 788 code = call_with_output(regress_test_cmd, regress_test_log_path) 789 if code != 0: 790 print("=== regresstest fail! ===\n") 791 sys.exit(code) 792 print("=== regresstest success! ===\n") 793 return 794 795 def build(self, out_path: str, gn_args: list, arg_list: list): 796 if not os.path.exists(out_path): 797 print("# mkdir -p {}".format(out_path)) 798 os.makedirs(out_path) 799 if len(arg_list) == 0: 800 self.build_for_gn_target(out_path, gn_args, ["default"], self.GN_TARGET_LOG_FILE_NAME) 801 elif self.is_dict_flags_match_arg(self.ARG_DICT["target"]["workload"], arg_list[0]): 802 self.build_for_workload(arg_list, out_path, gn_args, 'workload.log') 803 elif self.is_dict_flags_match_arg(self.ARG_DICT["target"]["test262"], arg_list[0]): 804 timeout, arg_list = self.parse_timeout(arg_list) 805 run_aot_mode = len(arg_list) >= 2 and arg_list[1] == "--aot" 806 run_aot_pgo_litecg = len(arg_list) >= 4 and ((arg_list[2] == "--pgo" and arg_list[3] == "--litecg") or 807 (arg_list[3] == "--pgo" and arg_list[2] == "--litecg")) 808 run_aot_pgo = len(arg_list) >= 3 and arg_list[2] == "--pgo" 809 run_aot_litecg = len(arg_list) >= 3 and arg_list[2] == "--litecg" 810 run_jit = len(arg_list) >= 2 and arg_list[1] == "--jit" 811 run_baseline_jit = len(arg_list) >= 2 and arg_list[1] == "--baseline-jit" 812 if run_aot_mode: 813 if run_aot_pgo_litecg: 814 self.build_for_test262(out_path, timeout, gn_args, arg_list[4:], self.TEST262_LOG_FILE_NAME, True, 815 True, True) 816 elif run_aot_litecg: 817 self.build_for_test262(out_path, timeout, gn_args, arg_list[3:], self.TEST262_LOG_FILE_NAME, True, 818 False, True) 819 elif run_aot_pgo: 820 self.build_for_test262(out_path, timeout, gn_args, arg_list[3:], 821 self.TEST262_LOG_FILE_NAME, True, True) 822 else: 823 self.build_for_test262(out_path, timeout, gn_args, arg_list[2:], self.TEST262_LOG_FILE_NAME, True) 824 elif run_jit: 825 self.build_for_test262(out_path, timeout, gn_args, arg_list[2:], 826 self.TEST262_LOG_FILE_NAME, False, False, 827 False, True) 828 elif run_baseline_jit: 829 self.build_for_test262(out_path, timeout, gn_args, arg_list[2:], 830 self.TEST262_LOG_FILE_NAME, False, False, 831 False, False, True) 832 else: 833 self.build_for_test262(out_path, timeout, gn_args, arg_list[1:], self.TEST262_LOG_FILE_NAME, False) 834 elif self.is_dict_flags_match_arg(self.ARG_DICT["target"]["unittest"], arg_list[0]): 835 if len(arg_list) > 1: 836 print("\033[92m\"unittest\" not support additional arguments.\033[0m\n".format()) 837 sys.exit(0) 838 self.build_for_unittest(out_path, gn_args, self.UNITTEST_LOG_FILE_NAME) 839 elif self.is_dict_flags_match_arg(self.ARG_DICT["target"]["regresstest"], arg_list[0]): 840 timeout, arg_list = self.parse_option(arg_list, option_name="--timeout", default_value=200) 841 self.build_for_regress_test(out_path, gn_args, arg_list[1:], self.REGRESS_TEST_LOG_FILE_NAME, timeout) 842 else: 843 self.build_for_gn_target(out_path, gn_args, arg_list, self.GN_TARGET_LOG_FILE_NAME) 844 return 845 846 def parse_timeout(self, arg_list) -> Tuple[Optional[Union[str, int]], List[str]]: 847 return self.parse_option(arg_list, option_name="--timeout", default_value=400000) 848 849 def match_options(self, arg_list: list, out_path: str) -> [list, list]: 850 arg_list_ret = [] 851 gn_args_ret = [] 852 for arg in arg_list: 853 # match [option][clean] flag 854 if self.is_dict_flags_match_arg(self.ARG_DICT["option"]["clean"], arg): 855 self.clean(out_path) 856 sys.exit(0) 857 # match [option][clean-continue] flag 858 elif self.is_dict_flags_match_arg(self.ARG_DICT["option"]["clean-continue"], arg): 859 if not self.has_cleaned: 860 self.clean(out_path) 861 self.has_cleaned = True 862 # match [option][gn-args] flag 863 elif self.is_dict_flags_match_arg(self.ARG_DICT["option"]["gn-args"], arg): 864 gn_args_ret.append(arg[(arg.find("=") + 1):]) 865 # match [option][keepdepfile] flag 866 elif self.is_dict_flags_match_arg(self.ARG_DICT["option"]["keepdepfile"], arg): 867 if not self.enable_keepdepfile: 868 self.enable_keepdepfile = True 869 # match [option][verbose] flag 870 elif self.is_dict_flags_match_arg(self.ARG_DICT["option"]["verbose"], arg): 871 if not self.enable_verbose: 872 self.enable_verbose = True 873 # match [option][keep-going] flag 874 elif self.is_dict_flags_match_arg(self.ARG_DICT["option"]["keep-going"], arg): 875 if self.ignore_errors == 1: 876 input_value = arg[(arg.find("=") + 1):] 877 try: 878 self.ignore_errors = int(input_value) 879 except Exception as _: 880 print("\033[92mIllegal value \"{}\" for \"--keep-going\" argument.\033[0m\n".format( 881 input_value 882 )) 883 sys.exit(0) 884 # make a new list with flag that do not match any flag in [option] 885 else: 886 arg_list_ret.append(arg) 887 return [arg_list_ret, gn_args_ret] 888 889 def build_for_workload(self, arg_list, out_path, gn_args, log_file_name): 890 root_dir = os.path.dirname(os.path.abspath(__file__)) 891 report = False 892 tools = 'dev' 893 boundary_value = '-10' 894 run_count = '10' 895 code_v = '' 896 run_interpreter = False 897 if len(arg_list) >= 2 and arg_list[1] == 'report': 898 report = True 899 if len(arg_list) >= 3 and arg_list[2]: 900 tools = arg_list[2] 901 if len(arg_list) >= 4 and arg_list[3]: 902 boundary_value = arg_list[3] 903 if len(arg_list) >= 5 and arg_list[4]: 904 run_count = arg_list[4] 905 if len(arg_list) >= 6 and arg_list[5]: 906 code_v = arg_list[5] 907 if len(arg_list) >= 7 and arg_list[6] == '--run-interpreter': 908 run_interpreter = True 909 self.build_for_gn_target(out_path, gn_args, ["default"], self.GN_TARGET_LOG_FILE_NAME) 910 workload_cmd = "cd arkcompiler/ets_runtime/test/workloadtest/ && python3 work_load.py" \ 911 " --code-path {0}" \ 912 " --report {1}" \ 913 " --tools-type {2}" \ 914 " --boundary-value {3}" \ 915 " --run-count {4}" \ 916 " --code-v {5}" \ 917 .format(root_dir, report, tools, boundary_value, run_count, code_v) 918 if run_interpreter: 919 workload_cmd += " --run-interpreter true" 920 workload_log_path = os.path.join(out_path, log_file_name) 921 str_to_workload_log = "================================\nwokload_time: {0}\nwokload_target: {1}\n\n".format( 922 str_of_time_now(), 'file') 923 _write(workload_log_path, str_to_workload_log, "a") 924 print("=== workload start ===") 925 code = call_with_output(workload_cmd, workload_log_path) 926 if code != 0: 927 print("=== workload fail! ===\n") 928 sys.exit(code) 929 print("=== workload success! ===\n") 930 return 931 932 def start_for_matched_os_cpu_mode(self, os_cpu_key: str, mode_key: str, arg_list: list): 933 # get binary gn and ninja 934 self.get_binaries() 935 # get out_path 936 name_of_out_dir_of_second_level = \ 937 self.ARG_DICT["os_cpu"][os_cpu_key]["prefix_of_name_of_out_dir_of_second_level"] + \ 938 self.DELIMITER_FOR_SECOND_OUT_DIR_NAME + \ 939 self.ARG_DICT["mode"][mode_key]["suffix_of_name_of_out_dir_of_second_level"] 940 out_path = os.path.join(self.NAME_OF_OUT_DIR_OF_FIRST_LEVEL, name_of_out_dir_of_second_level) 941 # match [option] flag 942 [arg_list, gn_args] = self.match_options(arg_list, out_path) 943 # get expression which would be written to args.gn file 944 gn_args.extend(self.ARG_DICT["os_cpu"][os_cpu_key]["gn_args"]) 945 gn_args.extend(self.ARG_DICT["mode"][mode_key]["gn_args"]) 946 # start to build 947 self.build(out_path, gn_args, arg_list) 948 return 949 950 951 952if __name__ == "__main__": 953 ark_py = ArkPy() 954 ark_py.__main__(sys.argv[1:]) 955