提交 cfd7c5a7 编写于 作者: P pilipala195 提交者: gzyang

hb add patch framework for product customization

上级 72308c77
......@@ -39,6 +39,7 @@ CONFIG_STRUCT = {
"kernel": None,
"product": None,
"product_path": None,
"device_path": None
"device_path": None,
"patch_cache": None
}
VERSION = '0.3.10'
VERSION = '0.4.0'
......@@ -49,6 +49,8 @@ def add_options(parser):
action='store_true')
parser.add_argument('-shs', '--sign_haps_by_server',
help='sign haps by server', action='store_true')
parser.add_argument('--patch', help='apply product patch before compiling',
action='store_true')
def exec_command(args):
......@@ -96,4 +98,4 @@ def exec_command(args):
'true',
quota=False)
return build.build(args.full, cmd_args=cmd_args)
return build.build(args.full, patch=args.patch, cmd_args=cmd_args)
......@@ -31,6 +31,7 @@ from hb.cts.cts import CTS
from hb.common.device import Device
from hb.common.product import Product
from hb.build.fs_process import Packer
from hb.build.patch_process import Patch
class Build():
......@@ -61,9 +62,9 @@ class Build():
for subsystem_cls in cts:
for cname, component_cls in subsystem_cls:
if cname == component:
if component_cls.adapted_board is None or\
if not len(component_cls.adapted_board) or\
self.config.board in component_cls.adapted_board:
if component_cls.adapted_kernel is None or\
if not len(component_cls.adapted_kernel) or\
self.config.kernel in component_cls.adapted_kernel:
self._target = component_cls.targets
self.register_args('ohos_build_target',
......@@ -113,8 +114,8 @@ class Build():
if args_name == 'ohos_build_target' and len(args_value):
self.config.fs_attr = None
def build(self, full_compile, ninja=True, cmd_args=None):
cmd_list = self.get_cmd(full_compile, ninja)
def build(self, full_compile, patch=False, ninja=True, cmd_args=None):
cmd_list = self.get_cmd(full_compile, patch, ninja)
if cmd_args is None:
cmd_args = defaultdict(list)
......@@ -124,7 +125,7 @@ class Build():
hb_info(f'{os.path.basename(self.config.out_path)} build success')
return 0
def get_cmd(self, full_compile, ninja):
def get_cmd(self, full_compile, patch, ninja):
if not ninja:
self.register_args('ohos_full_compile', 'true', quota=False)
return [self.gn_build]
......@@ -145,6 +146,10 @@ class Build():
self.register_args('ohos_full_compile', 'false', quota=False)
cmd_list = [self.ninja_build]
if patch:
patch = Patch()
cmd_list = [patch.patch_make] + cmd_list
if self.config.fs_attr is not None:
packer = Packer()
cmd_list.append(packer.fs_make)
......
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2020 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 os
from hb.common.utils import OHOSException
from hb.common.utils import exec_command
from hb.common.utils import read_yaml_file
from hb.common.config import Config
class Patch():
"""Patch class for hb build --patch parameter
Install the patch based on the configuration file.
"""
def __init__(self):
self.config = Config()
# Patch configuration file path
self.patch_cfg = os.path.join(self.config.product_path, 'patch.yml')
def patch_make(self, cmd_args=None, reverse=False):
"""Patch installation entry function
Args:
reverse (bool, optional): True if the patch is rolled back,
else False. Defaults to False.
Raises:
OHOSException: if configuration file does not exist.
"""
patch_cfg = self.config.patch_cache
# Check whether the rollback is in progress
if not reverse:
# Try to update patch cache and check whether rollback is required
self.patch_cache_update()
patch_cfg = self.patch_cfg
if not os.path.isfile(patch_cfg):
raise OHOSException(f'{patch_cfg} not found, '
'which "--patch" parameter needs')
patch_cfg_dict = read_yaml_file(patch_cfg)
for src_path, patch_list in patch_cfg_dict.items():
self.patch_apply(src_path, patch_list, reverse)
def patch_apply(self, src_path, patch_list, reverse=False):
"""Run the patch installation command.
Args:
src_path (string): Path to which the patch needs to be installed
patch_list (list): List of paths for storing patches
reverse (bool, optional): True if the patch is rolled back,
else False. Defaults to False.
Raises:
OHOSException: src_path or patch_path is invalid,
or the command fails to be executed.
"""
src_path = os.path.join(self.config.root_path, src_path)
if not os.path.exists(src_path):
raise OHOSException(f'{src_path} not exist, stop applying patch')
cmd = ''
for patch in patch_list:
patch_path = os.path.join(self.config.root_path, patch)
if not os.path.isfile(patch_path):
patch_path = os.path.join(self.config.root_path,
src_path, patch)
if not os.path.isfile(patch_path):
raise OHOSException(f'patch {patch} not exist for '
f'{src_path}, stop applying patch')
if reverse:
cmd = f'patch -p1 -R < {patch_path}'
else:
cmd = f'patch -p1 < {patch_path}'
try:
exec_command(cmd, log_path=self.config.log_path,
cwd=src_path, shell=True)
except OHOSException as ohos_exeception:
# Failed to roll back the patch, clear patch cache
self.config.patch_cache = None
raise ohos_exeception
def patch_cache_update(self):
"""Try to update patch cache and Check whether rollback is required
If patch_cache is None, no rollback is required,
otherwise roll back patch.
"""
# patch_cache stores the configuration file of the last patch.
if self.config.patch_cache is not None:
self.patch_make(reverse=True)
# Update patch cache to current path configuration file path
self.config.patch_cache = self.patch_cfg
if __name__ == "__main__":
patch = Patch()
patch.patch_make()
......@@ -38,6 +38,7 @@ class Config(metaclass=Singleton):
self._product = config_content.get('product', None)
self._product_path = config_content.get('product_path', None)
self._device_path = config_content.get('device_path', None)
self._patch_cache = config_content.get('patch_cache', None)
self._out_path = None
self.fs_attr = set()
......@@ -217,6 +218,15 @@ class Config(metaclass=Singleton):
raise OHOSException('clang not found, install it please')
@property
def patch_cache(self):
return self._patch_cache
@patch_cache.setter
def patch_cache(self, value):
self._patch_cache = value
self.config_update('patch_cache', self._patch_cache)
def config_create(self, config_path):
dump_json_file(config_path, CONFIG_STRUCT)
self.config_json = config_path
......
......@@ -126,7 +126,7 @@ def exec_command(cmd, log_path='out/build.log', **kwargs):
cmd = ' '.join(cmd)
raise OHOSException(f'command: "{cmd}" failed\n'
f'return code: {ret_code}\n'
f'execution path: {os.getcwd()}')
f'execution path: {kwargs.get("cwd", os.getcwd())}')
def get_failed_log(log_path):
......
......@@ -242,8 +242,8 @@ class Component():
def _init_comp(self, component_json):
self.dirs = component_json.get('dirs', [])
self.targets = component_json.get('targets', [])
self.adapted_board = component_json.get('adapted_board', None)
self.adapted_kernel = component_json.get('adapted_kernel', None)
self.adapted_board = component_json.get('adapted_board', [])
self.adapted_kernel = component_json.get('adapted_kernel', [])
self.features = component_json.get('features', None)
deps = component_json.get('deps', {})
......@@ -258,7 +258,7 @@ class Component():
return False
def is_board_in_comp(self, board):
if self.adapted_board is None:
if not len(self.adapted_board):
return True
if board in self.adapted_board:
return True
......@@ -266,7 +266,7 @@ class Component():
return False
def is_kernel_in_comp(self, kernel):
if self.adapted_kernel is None:
if not len(self.adapted_kernel):
return True
if kernel in self.adapted_kernel:
return True
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册