306 lines
11 KiB
Python
306 lines
11 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
# -*- coding: utf-8 -*-
|
||
|
|
|
||
|
|
#
|
||
|
|
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
|
# you may not use this file except in compliance with the License.
|
||
|
|
# You may obtain a copy of the License at
|
||
|
|
#
|
||
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||
|
|
#
|
||
|
|
# Unless required by applicable law or agreed to in writing, software
|
||
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
|
# See the License for the specific language governing permissions and
|
||
|
|
# limitations under the License.
|
||
|
|
#
|
||
|
|
|
||
|
|
|
||
|
|
import sys
|
||
|
|
import os
|
||
|
|
from enum import Enum
|
||
|
|
|
||
|
|
from containers.status import throw_exception
|
||
|
|
from exceptions.ohos_exception import OHOSException
|
||
|
|
from services.interface.build_file_generator_interface import BuildFileGeneratorInterface
|
||
|
|
from resources.config import Config
|
||
|
|
from containers.arg import Arg, ModuleType
|
||
|
|
from util.system_util import SystemUtil
|
||
|
|
from util.io_util import IoUtil
|
||
|
|
from util.log_util import LogUtil
|
||
|
|
|
||
|
|
|
||
|
|
class CMDTYPE(Enum):
|
||
|
|
GEN = 1
|
||
|
|
PATH = 2
|
||
|
|
DESC = 3
|
||
|
|
LS = 4
|
||
|
|
REFS = 5
|
||
|
|
FORMAT = 6
|
||
|
|
CLEAN = 7
|
||
|
|
|
||
|
|
|
||
|
|
class Gn(BuildFileGeneratorInterface):
|
||
|
|
|
||
|
|
def __init__(self):
|
||
|
|
super().__init__()
|
||
|
|
self.config = Config()
|
||
|
|
self._regist_gn_path()
|
||
|
|
|
||
|
|
def run(self):
|
||
|
|
self.execute_gn_cmd(CMDTYPE.GEN)
|
||
|
|
|
||
|
|
@throw_exception
|
||
|
|
def execute_gn_cmd(self, cmd_type: int, **kwargs):
|
||
|
|
if cmd_type == CMDTYPE.GEN:
|
||
|
|
return self._execute_gn_gen_cmd()
|
||
|
|
elif cmd_type == CMDTYPE.PATH:
|
||
|
|
return self._execute_gn_path_cmd(**kwargs)
|
||
|
|
elif cmd_type == CMDTYPE.DESC:
|
||
|
|
return self._execute_gn_desc_cmd(**kwargs)
|
||
|
|
elif cmd_type == CMDTYPE.LS:
|
||
|
|
return self._execute_gn_ls_cmd(**kwargs)
|
||
|
|
elif cmd_type == CMDTYPE.REFS:
|
||
|
|
return self._execute_gn_refs_cmd(**kwargs)
|
||
|
|
elif cmd_type == CMDTYPE.FORMAT:
|
||
|
|
return self._execute_gn_format_cmd(**kwargs)
|
||
|
|
elif cmd_type == CMDTYPE.CLEAN:
|
||
|
|
return self._execute_gn_clean_cmd(**kwargs)
|
||
|
|
else:
|
||
|
|
raise OHOSException(
|
||
|
|
'You are tring to use an unsupported gn cmd type "{}"'.format(cmd_type), '3001')
|
||
|
|
|
||
|
|
'''Description: Get gn excutable path and regist it
|
||
|
|
@parameter: none
|
||
|
|
@return: Status
|
||
|
|
'''
|
||
|
|
|
||
|
|
@throw_exception
|
||
|
|
def _regist_gn_path(self):
|
||
|
|
gn_path = os.path.join(self.config.root_path, 'prebuilts/build-tools/{}-x86/bin/gn'
|
||
|
|
.format(sys.platform))
|
||
|
|
if os.path.exists(gn_path):
|
||
|
|
self.exec = gn_path
|
||
|
|
else:
|
||
|
|
raise OHOSException(
|
||
|
|
'There is no gn executable file at {}'.format(gn_path), '0001')
|
||
|
|
|
||
|
|
'''Description: Convert all registed args into a list
|
||
|
|
@parameter: none
|
||
|
|
@return: list of all registed args
|
||
|
|
'''
|
||
|
|
|
||
|
|
def _convert_args(self) -> list:
|
||
|
|
args_list = []
|
||
|
|
|
||
|
|
for key, value in self.args_dict.items():
|
||
|
|
if isinstance(value, bool):
|
||
|
|
args_list.append('{}={}'.format(key, str(value).lower()))
|
||
|
|
|
||
|
|
elif isinstance(value, str):
|
||
|
|
args_list.append('{}="{}"'.format(key, value))
|
||
|
|
|
||
|
|
elif isinstance(value, int):
|
||
|
|
args_list.append('{}={}'.format(key, value))
|
||
|
|
|
||
|
|
elif isinstance(value, list):
|
||
|
|
args_list.append('{}="{}"'.format(key, "&&".join(value)))
|
||
|
|
|
||
|
|
return args_list
|
||
|
|
|
||
|
|
'''Description: Convert all registed flags into a list
|
||
|
|
@parameter: none
|
||
|
|
@return: list of all registed flags
|
||
|
|
'''
|
||
|
|
|
||
|
|
def _convert_flags(self) -> list:
|
||
|
|
flags_list = []
|
||
|
|
|
||
|
|
for key, value in self.flags_dict.items():
|
||
|
|
if key == 'gn_flags' and isinstance(value, list):
|
||
|
|
flags_list += value
|
||
|
|
elif value == '':
|
||
|
|
flags_list.append('{}'.format(key))
|
||
|
|
else:
|
||
|
|
flags_list.append('{}={}'.format(key, str(value)).lower())
|
||
|
|
|
||
|
|
return flags_list
|
||
|
|
|
||
|
|
'''Description: Option validity check
|
||
|
|
@parameter: "option": Option to be checked
|
||
|
|
"args_file": Option config file
|
||
|
|
@return: Inspection result(True|False)
|
||
|
|
'''
|
||
|
|
|
||
|
|
def _check_options_validity(self, option: str, args_file: dict):
|
||
|
|
support_sub_options = args_file.get(
|
||
|
|
"arg_attribute").get("support_sub_options")
|
||
|
|
option_name = option.lstrip('-')
|
||
|
|
option_value = ""
|
||
|
|
if '=' in option:
|
||
|
|
option_name, option_value = option.lstrip('-').split('=')
|
||
|
|
if option_name in support_sub_options:
|
||
|
|
sub_optional_list = support_sub_options.get(
|
||
|
|
option_name).get("arg_attribute").get("optional")
|
||
|
|
if sub_optional_list and option_value not in sub_optional_list:
|
||
|
|
if not len(option_value):
|
||
|
|
raise OHOSException('ERROR argument "--{}": Invalid choice "{}". '
|
||
|
|
'choose from {}'.format(option_name, option_value, sub_optional_list), '3006')
|
||
|
|
else:
|
||
|
|
raise OHOSException('ERROR argument "--{}": Invalid choice "{}". '
|
||
|
|
'choose from {}'.format(option_name, option_value, sub_optional_list), '3003')
|
||
|
|
else:
|
||
|
|
raise OHOSException('ERROR argument "{}": Invalid choice "{}". '
|
||
|
|
'choose from {}'.format(args_file.get("arg_name"),
|
||
|
|
option, list(support_sub_options.keys())), '3003')
|
||
|
|
|
||
|
|
'''Description: Execute 'gn gen' command using registed args
|
||
|
|
@parameter: kwargs TBD
|
||
|
|
@return: None
|
||
|
|
'''
|
||
|
|
|
||
|
|
@throw_exception
|
||
|
|
def _execute_gn_gen_cmd(self, **kwargs):
|
||
|
|
gn_gen_cmd = [self.exec, 'gen',
|
||
|
|
'--args={}'.format(' '.join(self._convert_args())),
|
||
|
|
self.config.out_path] + self._convert_flags()
|
||
|
|
if self.config.os_level == 'mini' or self.config.os_level == 'small':
|
||
|
|
gn_gen_cmd.append(f'--script-executable={sys.executable}')
|
||
|
|
try:
|
||
|
|
LogUtil.write_log(self.config.log_path, 'Excuting gn command: {} {} --args="{}" {}'.format(
|
||
|
|
self.exec, 'gen',
|
||
|
|
' '.join(self._convert_args()).replace('"', "\\\""),
|
||
|
|
' '.join(gn_gen_cmd[3:])),
|
||
|
|
'info')
|
||
|
|
SystemUtil.exec_command(gn_gen_cmd, self.config.log_path)
|
||
|
|
except OHOSException:
|
||
|
|
raise OHOSException('GN phase failed', '3000')
|
||
|
|
|
||
|
|
'''Description: Execute 'gn path' command using registed args
|
||
|
|
@parameter: kwargs TBD
|
||
|
|
@return: None
|
||
|
|
'''
|
||
|
|
|
||
|
|
@throw_exception
|
||
|
|
def _execute_gn_path_cmd(self, **kwargs):
|
||
|
|
out_dir = kwargs.get("out_dir")
|
||
|
|
default_options = ['--all']
|
||
|
|
args_file = Arg.read_args_file(ModuleType.TOOL)['path']
|
||
|
|
if (os.path.exists(os.path.join(out_dir, "args.gn"))):
|
||
|
|
gn_path_cmd = [self.exec, 'path', out_dir]
|
||
|
|
for arg in kwargs.get('args_list'):
|
||
|
|
if arg.startswith('-'):
|
||
|
|
self._check_options_validity(arg, args_file)
|
||
|
|
gn_path_cmd.append(arg)
|
||
|
|
gn_path_cmd.extend(default_options)
|
||
|
|
sort_index = gn_path_cmd.index
|
||
|
|
gn_path_cmd = list(set(gn_path_cmd))
|
||
|
|
gn_path_cmd.sort(key=sort_index)
|
||
|
|
SystemUtil.exec_command(gn_path_cmd)
|
||
|
|
else:
|
||
|
|
raise OHOSException(
|
||
|
|
'"{}" Not a build directory.'.format(out_dir), '3004')
|
||
|
|
|
||
|
|
'''Description: Execute 'gn desc' command using registed args
|
||
|
|
@parameter: kwargs TBD
|
||
|
|
@return: None
|
||
|
|
'''
|
||
|
|
|
||
|
|
@throw_exception
|
||
|
|
def _execute_gn_desc_cmd(self, **kwargs):
|
||
|
|
out_dir = kwargs.get("out_dir")
|
||
|
|
default_options = ['--tree', '--blame']
|
||
|
|
args_file = Arg.read_args_file(ModuleType.TOOL)['desc']
|
||
|
|
if (os.path.exists(os.path.join(out_dir, "args.gn"))):
|
||
|
|
gn_desc_cmd = [self.exec, 'desc', out_dir]
|
||
|
|
for arg in kwargs.get('args_list'):
|
||
|
|
if arg.startswith('-'):
|
||
|
|
self._check_options_validity(arg, args_file)
|
||
|
|
gn_desc_cmd.append(arg)
|
||
|
|
gn_desc_cmd.extend(default_options)
|
||
|
|
sort_index = gn_desc_cmd.index
|
||
|
|
gn_desc_cmd = list(set(gn_desc_cmd))
|
||
|
|
gn_desc_cmd.sort(key=sort_index)
|
||
|
|
SystemUtil.exec_command(gn_desc_cmd)
|
||
|
|
else:
|
||
|
|
raise OHOSException(
|
||
|
|
'"{}" Not a build directory.'.format(out_dir), '3004')
|
||
|
|
|
||
|
|
'''Description: Execute 'gn ls' command using registed args
|
||
|
|
@parameter: kwargs TBD
|
||
|
|
@return: None
|
||
|
|
'''
|
||
|
|
|
||
|
|
@throw_exception
|
||
|
|
def _execute_gn_ls_cmd(self, **kwargs):
|
||
|
|
out_dir = kwargs.get("out_dir")
|
||
|
|
args_file = Arg.read_args_file(ModuleType.TOOL)['ls']
|
||
|
|
if (os.path.exists(os.path.join(out_dir, "args.gn"))):
|
||
|
|
gn_ls_cmd = [self.exec, 'ls', out_dir]
|
||
|
|
for arg in kwargs.get('args_list'):
|
||
|
|
if arg.startswith('-'):
|
||
|
|
self._check_options_validity(arg, args_file)
|
||
|
|
gn_ls_cmd.append(arg)
|
||
|
|
SystemUtil.exec_command(gn_ls_cmd)
|
||
|
|
else:
|
||
|
|
raise OHOSException(
|
||
|
|
'"{}" Not a build directory.'.format(out_dir), '3004')
|
||
|
|
|
||
|
|
'''Description: Execute 'gn refs' command using registed args
|
||
|
|
@parameter: kwargs TBD
|
||
|
|
@return: None
|
||
|
|
'''
|
||
|
|
|
||
|
|
@throw_exception
|
||
|
|
def _execute_gn_refs_cmd(self, **kwargs):
|
||
|
|
out_dir = kwargs.get("out_dir")
|
||
|
|
args_file = Arg.read_args_file(ModuleType.TOOL)['refs']
|
||
|
|
if (os.path.exists(os.path.join(out_dir, "args.gn"))):
|
||
|
|
gn_refs_cmd = [self.exec, 'refs', out_dir]
|
||
|
|
for arg in kwargs.get('args_list'):
|
||
|
|
if arg.startswith('-'):
|
||
|
|
self._check_options_validity(arg, args_file)
|
||
|
|
gn_refs_cmd.append(arg)
|
||
|
|
SystemUtil.exec_command(gn_refs_cmd)
|
||
|
|
else:
|
||
|
|
raise OHOSException(
|
||
|
|
'"{}" Not a build directory.'.format(out_dir), '3004')
|
||
|
|
|
||
|
|
'''Description: Execute 'gn format' command using registed args
|
||
|
|
@parameter: kwargs TBD
|
||
|
|
@return: None
|
||
|
|
'''
|
||
|
|
|
||
|
|
@throw_exception
|
||
|
|
def _execute_gn_format_cmd(self, **kwargs):
|
||
|
|
gn_format_cmd = [self.exec, 'format']
|
||
|
|
args_file = Arg.read_args_file(ModuleType.TOOL)['format']
|
||
|
|
for arg in kwargs.get("args_list"):
|
||
|
|
if (arg.endswith('.gn')):
|
||
|
|
if (os.path.exists(arg)):
|
||
|
|
gn_format_cmd.append(arg)
|
||
|
|
else:
|
||
|
|
raise OHOSException(
|
||
|
|
"ERROR Couldn't read '{}'".format(arg), '3005')
|
||
|
|
else:
|
||
|
|
if arg.startswith('-'):
|
||
|
|
self._check_options_validity(arg, args_file)
|
||
|
|
gn_format_cmd.append(arg)
|
||
|
|
SystemUtil.exec_command(gn_format_cmd)
|
||
|
|
|
||
|
|
'''Description: Execute 'gn clean' command using registed args
|
||
|
|
@parameter: kwargs TBD
|
||
|
|
@return: None
|
||
|
|
'''
|
||
|
|
|
||
|
|
@throw_exception
|
||
|
|
def _execute_gn_clean_cmd(self, **kwargs):
|
||
|
|
out_dir = kwargs.get("out_dir")
|
||
|
|
if (os.path.exists(os.path.join(out_dir, "args.gn"))):
|
||
|
|
gn_clean_cmd = [self.exec, 'clean', out_dir]
|
||
|
|
SystemUtil.exec_command(gn_clean_cmd)
|
||
|
|
else:
|
||
|
|
raise OHOSException('"{}" Not a build directory.'
|
||
|
|
'Usage: "gn clean <out_dir>"'.format(out_dir), '3004')
|