1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3 4# 5# Copyright (c) 2023 Huawei Device Co., Ltd. 6# Licensed under the Apache License, Version 2.0 (the "License"); 7# you may not use this file except in compliance with the License. 8# You may obtain a copy of the License at 9# 10# http://www.apache.org/licenses/LICENSE-2.0 11# 12# Unless required by applicable law or agreed to in writing, software 13# distributed under the License is distributed on an "AS IS" BASIS, 14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15# See the License for the specific language governing permissions and 16# limitations under the License. 17# 18 19import os 20import re 21import sys 22import stat 23import subprocess 24import csv 25 26from datetime import datetime 27from distutils.spawn import find_executable 28from containers.arg import Arg 29from containers.status import throw_exception 30from exceptions.ohos_exception import OHOSException 31from modules.interface.build_module_interface import BuildModuleInterface 32from resources.config import Config 33from resources.global_var import CURRENT_OHOS_ROOT, DEFAULT_BUILD_ARGS 34from resolver.interface.args_resolver_interface import ArgsResolverInterface 35from util.type_check_util import TypeCheckUtil 36from util.io_util import IoUtil 37from util.log_util import LogUtil 38from util.system_util import SystemUtil 39from util.type_check_util import TypeCheckUtil 40from util.component_util import ComponentUtil 41from util.product_util import ProductUtil 42from util.prebuild.patch_process import Patch 43from util.post_build.part_rom_statistics import output_part_rom_status 44from util.post_gn.check_compilation_parameters import check_compilation_parameters 45 46 47class BuildArgsResolver(ArgsResolverInterface): 48 49 def __init__(self, args_dict: dict): 50 super().__init__(args_dict) 51 52 @staticmethod 53 def resolve_product(target_arg: Arg, build_module: BuildModuleInterface): 54 """resolve '--product-name' arg. 55 :param target_arg: arg object which is used to get arg value. 56 :param build_module [maybe unused]: build module object which is used to get other services. 57 :phase: prebuild. 58 """ 59 config = Config() 60 target_generator = build_module.target_generator 61 target_generator.regist_arg('product_name', config.product) 62 target_generator.regist_arg('product_path', config.product_path) 63 target_generator.regist_arg( 64 'product_config_path', config.product_config_path) 65 66 target_generator.regist_arg('device_name', config.board) 67 target_generator.regist_arg('device_path', config.device_path) 68 target_generator.regist_arg('device_company', config.device_company) 69 target_generator.regist_arg( 70 'device_config_path', config.device_config_path) 71 72 target_generator.regist_arg('target_cpu', config.target_cpu) 73 target_generator.regist_arg( 74 'is_{}_system'.format(config.os_level), True) 75 76 target_generator.regist_arg('ohos_kernel_type', config.kernel) 77 target_generator.regist_arg('ohos_build_compiler_specified', 78 ProductUtil.get_compiler(config.device_path)) 79 80 target_generator.regist_arg('ohos_build_time', 81 SystemUtil.get_current_time(time_type='timestamp')) 82 target_generator.regist_arg('ohos_build_datetime', 83 SystemUtil.get_current_time(time_type='datetime')) 84 85 features_dict = ProductUtil.get_features_dict(config.product_json) 86 for key, value in features_dict.items(): 87 target_generator.regist_arg(key, value) 88 89 if ProductUtil.get_compiler(config.device_path) == 'clang': 90 target_generator.regist_arg( 91 'ohos_build_compiler_dir', config.clang_path) 92 93 if target_arg.arg_value == 'ohos-sdk': 94 target_generator = build_module.target_generator 95 target_generator.regist_arg('build_ohos_sdk', True) 96 target_generator.regist_arg('build_ohos_ndk', True) 97 if len(build_module.args_dict['build_target'].arg_value) == 0: 98 build_module.args_dict['build_target'].arg_value = [ 99 'build_ohos_sdk'] 100 build_module.args_dict['target_cpu'].arg_value = 'arm64' 101 elif target_arg.arg_value == 'arkui-x': 102 target_generator = build_module.target_generator 103 target_generator.regist_arg('is_arkui_x', True) 104 target_generator.regist_arg('enable_ng_build', True) 105 target_generator.regist_arg('is_component_build', False) 106 target_generator.regist_arg('use_musl', False) 107 target_generator.regist_arg('is_use_check_deps', False) 108 if len(build_module.args_dict['build_target'].arg_value) == 0: 109 build_module.args_dict['build_target'].arg_value = [ 110 'arkui_targets'] 111 112 @staticmethod 113 def resolve_target_cpu(target_arg: Arg, build_module: BuildModuleInterface): 114 """resolve '--target-cpu' arg. 115 :param target_arg: arg object which is used to get arg value. 116 :param build_module [maybe unused]: build module object which is used to get other services. 117 :phase: prebuild. 118 """ 119 config = Config() 120 default_build_args = IoUtil.read_json_file(DEFAULT_BUILD_ARGS) 121 if config.target_cpu == "": 122 config.target_cpu = target_arg.arg_value 123 elif target_arg.arg_value != default_build_args.get("target_cpu").get("argDefault"): 124 config.target_cpu = target_arg.arg_value 125 126 @staticmethod 127 def resolve_target_os(target_arg: Arg, build_module: BuildModuleInterface): 128 """resolve '--target-os' arg. 129 :param target_arg: arg object which is used to get arg value. 130 :param build_module [maybe unused]: build module object which is used to get other services. 131 :phase: prebuild. 132 """ 133 config = Config() 134 default_build_args = IoUtil.read_json_file(DEFAULT_BUILD_ARGS) 135 if config.target_os == "": 136 config.target_os = target_arg.arg_value 137 elif target_arg.arg_value != default_build_args.get("target_os").get("argDefault"): 138 config.target_os = target_arg.arg_value 139 140 @staticmethod 141 def get_tdd_repository(input_file): 142 if not os.path.isfile(input_file): 143 raise OHOSException(f'{input_file} not found') 144 145 target_set = set() 146 with open(input_file, 'r') as input_f: 147 data = csv.DictReader(input_f) 148 tdd_col_name = "dayu200_tdd" 149 for col_name in data.fieldnames: 150 if col_name.startswith(tdd_col_name): 151 tdd_col_name = col_name 152 break 153 for csv_row in data: 154 if csv_row[tdd_col_name] == 'Y': 155 target_set.add(csv_row['repoistory']) 156 return target_set 157 158 @staticmethod 159 def get_tdd_build_target(build_target_arg, build_module: BuildModuleInterface): 160 parts_file = os.path.join(CURRENT_OHOS_ROOT, 'test/testfwk/developer_test/precise_compilation/part_tdd.json') 161 tdd_manifest_file = os.path.join(CURRENT_OHOS_ROOT, '.repo/manifests/matrix_product.csv') 162 parts_data = IoUtil.read_json_file(parts_file) 163 repository_set = BuildArgsResolver.get_tdd_repository(tdd_manifest_file) 164 config = Config() 165 prefix = 'out/{}/build_configs/'.format(config.product) 166 target_name = build_target_arg[len('TDD'):] 167 build_targets = [] 168 for target in target_name.split(','): 169 if target not in repository_set: 170 print('{} not find in csv!'.format(target)) 171 continue 172 for item in parts_data: 173 if item['name'] == target: 174 new_targets = [prefix + test_target for test_target in item['buildTarget'].split(',')] 175 build_targets.extend(new_targets) 176 break 177 else: 178 build_targets = ['build/ohos/packages:build_all_test_pkg'] 179 target_generator = build_module.target_generator 180 target_generator.regist_arg('use_thin_lto', False) 181 break 182 return build_targets 183 184 @staticmethod 185 @throw_exception 186 def resolve_build_target(target_arg: Arg, build_module: BuildModuleInterface): 187 """resolve '--build-target' arg. 188 :param target_arg: arg object which is used to get arg value. 189 :param build_module [maybe unused]: build module object which is used to get other services. 190 :phase: prebuild. 191 :raise OHOSException: when build target not exist in compiling product. 192 """ 193 config = Config() 194 build_executor = build_module.target_compiler 195 target_list = [] 196 test_target_list = ['build_all_test_pkg', 'package_testcase', 'package_testcase_mlf'] 197 if len(target_arg.arg_value): 198 for target_name in target_arg.arg_value: 199 if target_name.endswith('make_test') or target_name.split(':')[-1] in test_target_list: 200 target_generator = build_module.target_generator 201 target_generator.regist_arg('use_thin_lto', False) 202 target_list.append(target_name) 203 elif target_name.startswith('TDD'): 204 target_list.extend(BuildArgsResolver.get_tdd_build_target(target_name, build_module)) 205 else: 206 target_list.append(target_name) 207 else: 208 if os.getcwd() == CURRENT_OHOS_ROOT: 209 target_list = ['images'] 210 elif ComponentUtil.is_in_component_dir(os.getcwd()) and \ 211 ComponentUtil.is_component_in_product( 212 ComponentUtil.get_component_name(os.getcwd()), Config().product): 213 component_name = ComponentUtil.get_component_name(os.getcwd()) 214 LogUtil.write_log(Config().log_path, 'In the component "{}" directory,' 215 'this compilation will compile only this component'.format( 216 component_name), 217 'warning') 218 target_list.append(component_name) 219 target_list.append(component_name + '_test') 220 else: 221 component_name = ComponentUtil.get_component_name(os.getcwd()) 222 component_name = os.path.basename( 223 os.getcwd()) if component_name == '' else component_name 224 raise OHOSException('There is no target component "{}" for the current product "{}"' 225 .format(component_name, Config().product), "4001") 226 build_executor.regist_arg('build_target', target_list) 227 228 @staticmethod 229 def resolve_rename_last_log(target_arg: Arg, build_module: BuildModuleInterface): 230 """resolve '--rename-last-log' arg 231 :param target_arg: arg object which is used to get arg value. 232 :param build_module [maybe unused]: build module object which is used to get other services. 233 :phase: prebuild. 234 """ 235 if target_arg.arg_value: 236 config = Config() 237 out_path = config.out_path 238 logfile = os.path.join(out_path, 'build.log') 239 if os.path.exists(logfile): 240 mtime = os.stat(logfile).st_mtime 241 os.rename(logfile, '{}/build.{}.log'.format(out_path, mtime)) 242 243 @staticmethod 244 def resolve_log_mode(target_arg: Arg, build_module: BuildModuleInterface): 245 """resolve '--log-mode' arg 246 :param target_arg: arg object which is used to get arg value. 247 :param build_module: build module object which is used to get other services. 248 :phase: prebuild. 249 """ 250 if target_arg.arg_value: 251 config = Config() 252 config.log_mode = target_arg.arg_value 253 254 @staticmethod 255 def resolve_ccache(target_arg: Arg, build_module: BuildModuleInterface): 256 """resolve '--ccache' arg 257 :param target_arg: arg object which is used to get arg value. 258 :param build_module [maybe unused]: build module object which is used to get other services. 259 :phase: prebuild. 260 """ 261 if target_arg.arg_value: 262 config = Config() 263 ccache_path = find_executable('ccache') 264 if ccache_path is None: 265 LogUtil.hb_warning('Failed to find ccache, ccache disabled.') 266 return 267 else: 268 target_generator = build_module.target_generator 269 target_generator.regist_arg( 270 'ohos_build_enable_ccache', target_arg.arg_value) 271 272 ccache_local_dir = os.environ.get('CCACHE_LOCAL_DIR') 273 ccache_base = os.environ.get('CCACHE_BASE') 274 if not ccache_local_dir: 275 ccache_local_dir = '.ccache' 276 if not ccache_base: 277 ccache_base = os.environ.get('HOME') 278 ccache_base = os.path.join(ccache_base, ccache_local_dir) 279 if not os.path.exists(ccache_base): 280 os.makedirs(ccache_base, exist_ok=True) 281 282 ccache_log_suffix = os.environ.get('CCACHE_LOG_SUFFIX') 283 if ccache_log_suffix: 284 logfile = os.path.join( 285 ccache_base, "ccache.{}.log".format(ccache_log_suffix)) 286 else: 287 logfile = os.path.join(ccache_base, "ccache.log") 288 if os.path.exists(logfile): 289 oldfile = os.path.join(ccache_base, '{}.old'.format(logfile)) 290 if os.path.exists(oldfile): 291 os.unlink(oldfile) 292 os.rename(logfile, oldfile) 293 294 os.environ['CCACHE_EXEC'] = ccache_path 295 os.environ['CCACHE_LOGFILE'] = logfile 296 os.environ['USE_CCACHE'] = '1' 297 os.environ['CCACHE_DIR'] = ccache_base 298 os.environ['CCACHE_UMASK'] = '002' 299 os.environ['CCACHE_BASEDIR'] = config.root_path 300 ccache_max_size = os.environ.get('CCACHE_MAXSIZE') 301 if not ccache_max_size: 302 ccache_max_size = '100G' 303 304 cmd = ['ccache', '-M', ccache_max_size] 305 306 SystemUtil.exec_command(cmd, log_path=config.log_path) 307 308 @staticmethod 309 def resolve_pycache(target_arg: Arg, build_module: BuildModuleInterface): 310 """resolve '--enable-pycache' arg 311 :param target_arg: arg object which is used to get arg value. 312 :param build_module [maybe unused]: build module object which is used to get other services. 313 :phase: prebuild. 314 """ 315 if target_arg.arg_value: 316 config = Config() 317 pycache_dir = os.environ.get('CCACHE_BASE') 318 # The default value is HOME for local users 319 if not pycache_dir: 320 pycache_dir = os.environ.get('HOME') 321 pycache_dir = os.path.join(pycache_dir, '.pycache') 322 os.environ['PYCACHE_DIR'] = pycache_dir 323 pyd_start_cmd = [ 324 'python3', 325 '{}/build/scripts/util/pyd.py'.format(config.root_path), 326 '--root', 327 pycache_dir, 328 '--start', 329 ] 330 cmd = ['/bin/bash', '-c', ' '.join(pyd_start_cmd), '&'] 331 subprocess.Popen(cmd) 332 333 @staticmethod 334 def resolve_full_compilation(target_arg: Arg, build_module: BuildModuleInterface): 335 """resolve '--full-compilation' arg 336 :param target_arg: arg object which is used to get arg value. 337 :param build_module [maybe unused]: build module object which is used to get other services. 338 :phase: prebuild. 339 """ 340 if target_arg.arg_value: 341 build_executor = build_module.target_compiler 342 target_list = build_executor.args_dict.get('build_target', None) 343 if isinstance(target_list, list): 344 target_list.append('make_all') 345 target_list.append('make_test') 346 else: 347 build_executor.regist_arg( 348 'build_target', ['make_all', 'make_test']) 349 target_generator = build_module.target_generator 350 target_generator.regist_arg('use_thin_lto', False) 351 352 @staticmethod 353 @throw_exception 354 def resolve_gn_args(target_arg: Arg, build_module: BuildModuleInterface): 355 """resolve '--gn-args' arg 356 :param target_arg: arg object which is used to get arg value. 357 :param build_module [maybe unused]: build module object which is used to get other services. 358 :phase: prebuild. 359 :raise OHOSException: when some gn_arg is not in 'key=value' format. 360 """ 361 target_generator = build_module.target_generator 362 target_generator.regist_arg( 363 'device_type', build_module.args_dict['device_type'].arg_value) 364 target_generator.regist_arg( 365 'build_variant', build_module.args_dict['build_variant'].arg_value) 366 for gn_args in target_arg.arg_value: 367 try: 368 gn_args_list = gn_args.split() 369 for gn_arg in gn_args_list: 370 variable, value = gn_arg.split('=') 371 if TypeCheckUtil.is_bool_type(value): 372 if str(value).lower() == 'false': 373 convert_value = False 374 elif str(value).lower() == 'true': 375 convert_value = True 376 elif TypeCheckUtil.is_int_type(value): 377 convert_value = int(value) 378 elif isinstance(value, list): 379 convert_value = list(value) 380 else: 381 convert_value = str(value).strip('"') 382 target_generator.regist_arg(variable, convert_value) 383 except ValueError: 384 raise OHOSException(f'Invalid gn args: {gn_arg}', "0001") 385 386 @staticmethod 387 @throw_exception 388 def resolve_gn_flags(target_arg: Arg, build_module: BuildModuleInterface): 389 """resolve '--gn-flags' arg 390 :param target_arg: arg object which is used to get arg value. 391 :param build_module [maybe unused]: build module object which is used to get other services. 392 :phase: targetGenerate. 393 :raise OHOSException: when some gn_arg is not in 'key=value' format. 394 """ 395 target_generator = build_module.target_generator 396 gn_flags_list = [] 397 for gn_flags in target_arg.arg_value: 398 gn_flags = re.sub("'", "", gn_flags) 399 gn_flags_list.append(gn_flags) 400 target_generator.regist_flag('gn_flags', gn_flags_list) 401 402 @staticmethod 403 @throw_exception 404 def resolve_ninja_args(target_arg: Arg, build_module: BuildModuleInterface): 405 """resolve '--ninja-args' arg 406 :param target_arg: arg object which is used to get arg value. 407 :param build_module [maybe unused]: build module object which is used to get other services. 408 :phase: prebuild. 409 :raise OHOSException: when the value of the ninja parameter does not use quotation marks. 410 """ 411 build_executor = build_module.target_compiler 412 ninja_args_list = [] 413 for ninja_arg in target_arg.arg_value: 414 ninja_arg = re.sub("'", "", ninja_arg) 415 ninja_args_list.append(ninja_arg) 416 build_executor.regist_arg('ninja_args', ninja_args_list) 417 418 @staticmethod 419 @throw_exception 420 def resolve_strict_mode(target_arg: Arg, build_module: BuildModuleInterface): 421 """resolve '--strict-mode' arg. 422 :param target_arg: arg object which is used to get arg value. 423 :param build_module [maybe unused]: build module object which is used to get other services. 424 :phase: load. 425 :raise OHOSException: when preloader or loader results not correct 426 """ 427 if target_arg.arg_value: 428 preloader = build_module.preloader 429 loader = build_module.loader 430 if not preloader.outputs.check_outputs(): 431 raise OHOSException('Preloader result not correct', "1001") 432 if not loader.outputs.check_outputs(): 433 raise OHOSException('Loader result not correct ', "2001") 434 435 @staticmethod 436 def resolve_scalable_build(target_arg: Arg, build_module: BuildModuleInterface): 437 """resolve '--scalable-build' arg. 438 :param target_arg: arg object which is used to get arg value. 439 :param build_module [maybe unused]: build module object which is used to get other services. 440 :phase: load. 441 """ 442 loader = build_module.loader 443 loader.regist_arg("scalable_build", target_arg.arg_value) 444 445 @staticmethod 446 def resolve_build_example(target_arg: Arg, build_module: BuildModuleInterface): 447 """resolve '--build-example' arg. 448 :param target_arg: arg object which is used to get arg value. 449 :param build_module [maybe unused]: build module object which is used to get other services. 450 :phase: load. 451 """ 452 loader = build_module.loader 453 loader.regist_arg("build_example", target_arg.arg_value) 454 455 @staticmethod 456 def resolve_build_platform_name(target_arg: Arg, build_module: BuildModuleInterface): 457 """resolve '---build-platform-name' arg 458 :param target_arg: arg object which is used to get arg value. 459 :param build_module [maybe unused]: build module object which is used to get other services. 460 :phase: load. 461 """ 462 loader = build_module.loader 463 loader.regist_arg("build_platform_name", target_arg.arg_value) 464 465 @staticmethod 466 def resolve_build_xts(target_arg: Arg, build_module: BuildModuleInterface): 467 """resolve '--build-xts' arg 468 :param target_arg: arg object which is used to get arg value. 469 :param build_module [maybe unused]: build module object which is used to get other services. 470 :phase: load. 471 """ 472 loader = build_module.loader 473 for gn_arg in build_module.args_dict['gn_args'].arg_value: 474 if 'build_xts' in gn_arg: 475 variable, value = gn_arg.split('=') 476 if str(value).lower() == 'false': 477 value = False 478 elif str(value).lower() == 'true': 479 value = True 480 loader.regist_arg(variable, value) 481 return 482 loader.regist_arg("build_xts", target_arg.arg_value) 483 484 @staticmethod 485 def resolve_ignore_api_check(target_arg: Arg, build_module: BuildModuleInterface): 486 """resolve '--ignore-api-check' arg 487 :param target_arg: arg object which is used to get arg value. 488 :param build_module [maybe unused]: build module object which is used to get other services. 489 :phase: load. 490 """ 491 loader = build_module.loader 492 if len(target_arg.arg_value): 493 loader.regist_arg("ignore_api_check", target_arg.arg_value) 494 else: 495 loader.regist_arg("ignore_api_check", [ 496 'xts', 'common', 'testfwk']) 497 498 @staticmethod 499 def resolve_load_test_config(target_arg: Arg, build_module: BuildModuleInterface): 500 """resolve '--load-test-config' arg 501 :param target_arg: arg object which is used to get arg value. 502 :param build_module [maybe unused]: build module object which is used to get other services. 503 :phase: load. 504 """ 505 loader = build_module.loader 506 loader.regist_arg("load_test_config", target_arg.arg_value) 507 508 @staticmethod 509 @throw_exception 510 def resolve_export_para(target_arg: Arg, build_module: BuildModuleInterface): 511 """resolve '--export-para' arg 512 :param target_arg: arg object which is used to get arg value. 513 :param build_module [maybe unused]: build module object which is used to get other services. 514 :phase: targetGenerate. 515 """ 516 target_generator = build_module.target_generator 517 for gn_arg in target_arg.arg_value: 518 try: 519 variable, value = gn_arg.split(':') 520 if TypeCheckUtil.is_bool_type(value): 521 if str(value).lower() == 'false': 522 value = False 523 elif str(value).lower() == 'true': 524 value = True 525 elif TypeCheckUtil.is_int_type(value): 526 value = int(value) 527 else: 528 value = str(value) 529 target_generator.regist_arg(variable, value) 530 except ValueError: 531 raise OHOSException(f'Invalid gn args: {gn_arg}', "0001") 532 533 @staticmethod 534 def resolve_log_level(target_arg: Arg, build_module: BuildModuleInterface): 535 """resolve '--log-level' arg. 536 :param target_arg: arg object which is used to get arg value. 537 :param build_module [maybe unused]: build module object which is used to get other services. 538 :phase: targetGenerate. 539 """ 540 if target_arg.arg_value == 'debug': 541 target_generator = build_module.target_generator 542 target_compiler = build_module.target_compiler 543 target_generator.regist_flag('-v', ''), 544 target_generator.regist_flag( 545 '--tracelog', '{}/gn_trace.log'.format(Config().out_path)) 546 target_generator.regist_flag('--ide', 'json') 547 target_compiler.regist_arg('-v', '') 548 549 @staticmethod 550 @throw_exception 551 def resolve_test(target_arg: Arg, build_module: BuildModuleInterface): 552 """resolve '--test' arg 553 :param target_arg: arg object which is used to get arg value. 554 :param build_module [maybe unused]: build module object which is used to get other services. 555 :phase: targetGenerate. 556 """ 557 if len(target_arg.arg_value) > 1: 558 target_generator = build_module.target_generator 559 # TODO: Ask sternly why the xts subsystem passes parameters in this way? 560 if 'notest' in target_arg.arg_value: 561 target_generator.regist_arg('ohos_test_args', 'notest') 562 elif 'xts' in target_arg.arg_value: 563 test_target_index = 1 564 if target_arg.arg_value.index('xts') == 1: 565 test_target_index = 0 566 target_generator.regist_arg( 567 'ohos_xts_test_args', target_arg.arg_value[test_target_index]) 568 else: 569 raise OHOSException('Test type value "{}" is not support' 570 .format(target_arg.arg_value), "0002") 571 572 @staticmethod 573 def resolve_build_type(target_arg: Arg, build_module: BuildModuleInterface): 574 """resolve '--build-type' arg 575 :param target_arg: arg object which is used to get arg value. 576 :param build_module [maybe unused]: build module object which is used to get other services. 577 :phase: targetGenerate. 578 """ 579 target_generator = build_module.target_generator 580 if target_arg.arg_value == 'debug': 581 target_generator.regist_arg('is_debug', True) 582 elif target_arg.arg_value == 'profile': 583 target_generator.regist_arg('is_profile', True) 584 # For historical reasons, this value must be debug 585 target_generator.regist_arg('ohos_build_type', 'debug') 586 587 @staticmethod 588 def resolve_root_perf_main(target_arg: Arg, build_module: BuildModuleInterface): 589 """resolve '--root-perf-main' arg 590 :param target_arg: arg object which is used to get arg value. 591 :param build_module [maybe unused]: build module object which is used to get other services. 592 :phase: targetGenerate. 593 """ 594 target_generator = build_module.target_generator 595 target_generator.regist_arg('root_perf_main', target_arg.arg_value) 596 597 @staticmethod 598 def resolve_runtime_mode(target_arg: Arg, build_module: BuildModuleInterface): 599 """resolve '--runtime-mode' arg 600 :param target_arg: arg object which is used to get arg value. 601 :param build_module [maybe unused]: build module object which is used to get other services. 602 :phase: targetGenerate. 603 """ 604 target_generator = build_module.target_generator 605 target_generator.regist_arg('runtime_mode', target_arg.arg_value) 606 607 @staticmethod 608 def resolve_check_compilation_parameters(target_arg: Arg, build_module: BuildModuleInterface): 609 """resolve '--check-compilation-parameters' arg 610 :param target_arg: arg object which is used to get arg value. 611 :param build_module [maybe unused]: build module object which is used to get other services. 612 :phase: postTargetGenerate. 613 """ 614 if target_arg.arg_value: 615 check_compilation_parameters(CURRENT_OHOS_ROOT) 616 617 @staticmethod 618 def resolve_keep_ninja_going(target_arg: Arg, build_module: BuildModuleInterface): 619 """resolve '--keep-ninja-going' arg 620 :param target_arg: arg object which is used to get arg value. 621 :param build_module [maybe unused]: build module object which is used to get other services. 622 :phase: targetCompilation. 623 """ 624 if target_arg.arg_value: 625 target_compiler = build_module.target_compiler 626 target_compiler.regist_arg('-k1000000', '') 627 628 @staticmethod 629 def resolve_build_variant(target_arg: Arg, build_module: BuildModuleInterface): 630 """resolve '--build-variant' arg 631 :param target_arg: arg object which is used to get arg value. 632 :param build_module [maybe unused]: build module object which is used to get other services. 633 :phase: postTargetCompilation. 634 """ 635 pass 636 637 @staticmethod 638 def resolve_device_type(target_arg: Arg, build_module: BuildModuleInterface): 639 """resolve '--device-type' arg 640 :param target_arg: arg object which is used to get arg value. 641 :param build_module [maybe unused]: build module object which is used to get other services. 642 :phase: postTargetCompilation. 643 """ 644 config = Config() 645 ohos_para_data = [] 646 ohos_para_file_path = os.path.join( 647 config.out_path, 'packages/phone/system/etc/param/ohos.para') 648 if target_arg.arg_value != 'default': 649 with os.fdopen(os.open(ohos_para_file_path, 650 os.O_RDWR | os.O_CREAT, stat.S_IWUSR | stat.S_IRUSR), 651 'r', encoding='utf-8') as ohos_para_file: 652 for line in ohos_para_file: 653 ohos_para_data.append(line) 654 for i, line in enumerate(ohos_para_data): 655 if ohos_para_data[i].__contains__('const.build.characteristics'): 656 ohos_para_data[i] = 'const.build.characteristics=' + \ 657 target_arg.arg_value + '\n' 658 break 659 data = '' 660 for line in ohos_para_data: 661 data += line 662 with os.fdopen(os.open(ohos_para_file_path, 663 os.O_RDWR | os.O_CREAT, stat.S_IWUSR | stat.S_IRUSR), 664 'w', encoding='utf-8') as ohos_para_file: 665 ohos_para_file.write(data) 666 667 @staticmethod 668 def resolve_archive_image(target_arg: Arg, build_module: BuildModuleInterface): 669 """resolve '--archive-image' arg 670 :param target_arg: arg object which is used to get arg value. 671 :param build_module [maybe unused]: build module object which is used to get other services. 672 :phase: postTargetCompilation 673 """ 674 if target_arg.arg_value: 675 config = Config() 676 image_path = os.path.join( 677 config.out_path, 'packages', 'phone', 'images') 678 if os.path.exists(image_path): 679 packaged_file_path = os.path.join( 680 config.out_path, 'images.tar.gz') 681 cmd = ['tar', '-zcvf', packaged_file_path, image_path] 682 SystemUtil.exec_command(cmd, log_path=config.out_path) 683 else: 684 LogUtil.hb_info( 685 '"--archive-image" option not work, cause the currently compiled product is not a standard product') 686 687 @staticmethod 688 def resolve_patch(target_arg: Arg, build_module: BuildModuleInterface): 689 """resolve '--patch' arg 690 :param target_arg: arg object which is used to get arg value. 691 :param build_module [maybe unused]: build module object which is used to get other services. 692 :phase: postTargetCompilation 693 """ 694 if target_arg.arg_value: 695 patch_obj = Patch() 696 patch_obj.patch_make() 697 698 @staticmethod 699 def resolve_rom_size_statistics(target_arg: Arg, build_module: BuildModuleInterface): 700 """resolve '--rom-size-statistics' arg 701 :param target_arg: arg object which is used to get arg value. 702 :param build_module [maybe unused]: build module object which is used to get other services. 703 :phase: postTargetCompilation 704 """ 705 if target_arg.arg_value: 706 output_part_rom_status(CURRENT_OHOS_ROOT) 707 708 @staticmethod 709 def resolve_stat_ccache(target_arg: Arg, build_module: BuildModuleInterface): 710 """resolve "--stat-ccache' arg 711 :param target_arg: arg object which is used to get arg value. 712 :param build_module [maybe unused]: build module object which is used to get other services. 713 :phase: postTargetCompilation 714 """ 715 if target_arg.arg_value: 716 config = Config() 717 ccache_path = find_executable('ccache') 718 if ccache_path is None: 719 LogUtil.hb_warning('Failed to find ccache, ccache disabled.') 720 return 721 ccache_log_suffix = os.environ.get('CCACHE_LOG_SUFFIX') 722 if ccache_log_suffix: 723 logfile = "ccache.{}.log".format(ccache_log_suffix) 724 else: 725 logfile = "ccache.log" 726 ccache_local_dir = os.environ.get('CCACHE_LOCAL_DIR') 727 if not ccache_local_dir: 728 ccache_local_dir = '.ccache' 729 ccache_base = os.environ.get('CCACHE_BASE') 730 731 # The default value is HOME for local users 732 if not ccache_base: 733 ccache_base = os.environ.get('HOME') 734 ccache_base = os.path.join(ccache_base, ccache_local_dir) 735 cmd = [ 736 'python3', '{}/build/scripts/summary_ccache_hitrate.py'.format( 737 config.root_path), '{}/{}'.format(ccache_base, logfile) 738 ] 739 SystemUtil.exec_command(cmd, log_path=config.log_path) 740 741 @staticmethod 742 def resolve_get_warning_list(target_arg: Arg, build_module: BuildModuleInterface): 743 """resolve "--get-warning-list' arg 744 :param target_arg: arg object which is used to get arg value. 745 :param build_module [maybe unused]: build module object which is used to get other services. 746 :phase: postTargetCompilation 747 """ 748 if target_arg.arg_value: 749 config = Config() 750 cmd = [ 751 'python3', 752 '{}/build/scripts/get_warnings.py'.format(config.root_path), 753 '--build-log-file', 754 '{}/build.log'.format(config.out_path), 755 '--warning-out-file', 756 '{}/packages/WarningList.txt'.format(config.out_path), 757 ] 758 SystemUtil.exec_command(cmd, log_path=config.log_path) 759 760 @staticmethod 761 def resolve_generate_ninja_trace(target_arg: Arg, build_module: BuildModuleInterface): 762 """resolve "--generate-ninja-trace' arg 763 :param target_arg: arg object which is used to get arg value. 764 :param build_module [maybe unused]: build module object which is used to get other services. 765 :phase: postTargetCompilation 766 """ 767 if target_arg.arg_value: 768 config = Config() 769 epoch = datetime.utcfromtimestamp(0) 770 unixtime = '%f' % ( 771 (build_module.target_compiler._start_time - epoch).total_seconds() * 10**9) 772 cmd = [ 773 'python3', 774 '{}/build/scripts/ninja2trace.py'.format(config.root_path), 775 '--ninja-log', 776 '{}/.ninja_log'.format(config.out_path), 777 "--trace-file", 778 "{}/build.trace".format(config.out_path), 779 "--ninja-start-time", 780 str(unixtime), 781 "--duration-file", 782 "{}/sorted_action_duration.txt".format(config.out_path), 783 ] 784 SystemUtil.exec_command(cmd, log_path=config.log_path) 785 786 @staticmethod 787 def resolve_compute_overlap_rate(target_arg: Arg, build_module: BuildModuleInterface): 788 """resolve "--compute-overlap-rate' arg 789 :param target_arg: arg object which is used to get arg value. 790 :param build_module [maybe unused]: build module object which is used to get other services. 791 :phase: postTargetCompilation 792 """ 793 if target_arg.arg_value: 794 config = Config() 795 subsystem_config_overlay_path = os.path.join(config.product_path, 796 'subsystem_config_overlay.json') 797 if os.path.isfile(subsystem_config_overlay_path): 798 cmd = [ 799 'python3', 800 '{}/build/ohos/statistics/build_overlap_statistics.py'.format( 801 config.root_path), "--build-out-dir", config.out_path, 802 "--subsystem-config-file", 803 "{}/build/subsystem_config.json".format(config.root_path), 804 "--subsystem-config-overlay-file", 805 "{}/subsystem_config_overlay.json".format( 806 config.product_path), 807 "--root-source-dir", config.root_path 808 ] 809 else: 810 cmd = [ 811 'python3', 812 '{}/build/ohos/statistics/build_overlap_statistics.py'.format( 813 config.root_path), "--build-out-dir", config.out_path, 814 "--subsystem-config-file", 815 "{}/build/subsystem_config.json".format(config.root_path), 816 "--root-source-dir", config.root_path 817 ] 818 SystemUtil.exec_command(cmd, log_path=config.log_path) 819 820 @staticmethod 821 def resolve_deps_guard(target_arg: Arg, build_module: BuildModuleInterface): 822 """resolve '--deps-guard' arg 823 :param target_arg: arg object which is used to get arg value. 824 :param build_module [maybe unused]: build module object which is used to get other services. 825 :phase: postbuild 826 """ 827 if target_arg.arg_value: 828 config = Config() 829 if config.os_level == "standard": 830 sys.path.append(os.path.join( 831 config.root_path, "developtools/integration_verification/tools/deps_guard")) 832 from deps_guard import deps_guard 833 deps_guard(config.out_path) 834 835 @staticmethod 836 def resolve_skip_partlist_check(target_arg: Arg, build_module: BuildModuleInterface): 837 """resolve '--skip-partlist-check' arg 838 :param target_arg: arg object which is used to get arg value. 839 :param build_module [maybe unused]: build module object which is used to get other services. 840 :phase: load. 841 """ 842 loader = build_module.loader 843 loader.regist_arg("skip_partlist_check", target_arg.arg_value) 844 845 @staticmethod 846 def resolve_clean_args(target_arg: Arg, build_module: BuildModuleInterface): 847 """resolve '--clean-args' arg 848 :param target_arg: arg object which is used to get arg value. 849 :param build_module [maybe unused]: build module object which is used to get other services. 850 :phase: postbuild 851 """ 852 if target_arg.arg_value: 853 Arg.clean_args_file() 854 855 # PlaceHolder 856 @staticmethod 857 def resolve_compiler(target_arg: Arg, build_module: BuildModuleInterface): 858 return 859 860 # PlaceHolder 861 @staticmethod 862 def resolve_jobs(target_arg: Arg, build_module: BuildModuleInterface): 863 return 864 865 # PlaceHolder 866 @staticmethod 867 def resolve_disable_part_of_post_build(target_arg: Arg, build_module: BuildModuleInterface): 868 return 869 870 # PlaceHolder 871 @staticmethod 872 def resolve_disable_package_image(target_arg: Arg, build_module: BuildModuleInterface): 873 return 874 875 # PlaceHolder 876 @staticmethod 877 def resolve_disable_post_build(target_arg: Arg, build_module: BuildModuleInterface): 878 return 879 880 # PlaceHolder 881 @staticmethod 882 def resolve_build_only_load(target_arg: Arg, build_module: BuildModuleInterface): 883 return 884 885 # PlaceHolder 886 @staticmethod 887 def resolve_build_only_gn(target_arg: Arg, build_module: BuildModuleInterface): 888 return 889 890 # PlaceHolder 891 @staticmethod 892 def resolve_fast_rebuild(target_arg: Arg, build_module: BuildModuleInterface): 893 return 894