import os
import sys
import subprocess
import argparse
import traceback
import csv
from argparse import Namespace
from collections import namedtuple
from datetime import datetime, timezone
from functools import partial
from itertools import chain
from typing import Dict, Iterator, List, Set, Tuple, TextIO
import shutil
from common.py.utils import pkg_utils
from common.py.filelist import (
FileItem, FileList, check_filelist, create_file_item, generate_filelist,
get_transform_nested_path_func,
)
from common.py.packer import (
PackageName, create_makeself_pkg_params_factory, create_run_package_command, exec_pack_cmd
)
from common.py.pkg_parser import (
ParseOption, XmlConfig, parse_xml_config, get_cann_version_info, get_target_name
)
from common.py.utils.pkg_utils import (
CONFIG_SCRIPT_PATH, CompressError, ContainAsteriskError, DELIVERY_PATH, FAIL,
FilelistError, GenerateFilelistError, PackageNameEmptyError, SUCC, TOP_DIR,
UnknownOperateTypeError, path_join
)
from common.py.utils.funcbase import invoke, pipe
from common.py.utils.comm_log import CommLog
def get_comments(package_name: PackageName) -> str:
"""获取run包注释。"""
comments = '_'.join(
[package_name.chip_name.upper(), package_name.func_name.upper(), 'RUN_PACKAGE']
)
return f'"{comments}"'
def get_compress_cmd(delivery_dir: str,
pkg_args: Namespace,
xml_config: XmlConfig) -> str:
"""获取makeself压缩命令"""
suffix = xml_config.package_attr.get('suffix')
if suffix == "run":
package_name = PackageName(xml_config.package_attr, pkg_args, xml_config.version)
factory = create_makeself_pkg_params_factory(
pkg_args.pkg_output_dir, package_name.getvalue(), get_comments(package_name)
)
params = factory(pkg_args.makeself_dir, xml_config.package_attr, pkg_args.independent_pkg)
pack_cmd, err_msg = create_run_package_command(params)
if err_msg:
CommLog.cilog_error(err_msg)
CommLog.cilog_error("create_run_command failed!")
raise CompressError(package_name.getvalue())
if pkg_args.independent_pkg:
exec_pack_cmd(delivery_dir, pack_cmd, package_name.getvalue())
else:
CommLog.cilog_error("the repack type '%s' is not support!", suffix)
sys.exit(FAIL)
try:
makeself_dir = os.path.join(TOP_DIR, "build/makeself.txt")
with open(makeself_dir, 'w') as f:
f.write(pack_cmd)
except Exception as exception:
CommLog.cilog_error(f"save makeself.txt failed!{str(exception)}")
sys.exit(FAIL)
return package_name.getvalue()
def make_parse_option(args_: argparse.Namespace) -> ParseOption:
"""创建解析参数。"""
return ParseOption(
args_.os_arch, args_.pkg_version,
args_.build_type,
args_.package_check,
args_.ext_name
)
PrivatePackageOption = namedtuple(
'PrivatePackageOption',
[
'os_arch', 'package_suffix', 'not_in_name', 'pkg_version', 'ext_name',
'chip_name', 'func_name', 'version_dir', 'disable_multi_version', 'suffix'
]
)
class PackageOption(PrivatePackageOption):
"""打包配置参数。"""
__slots__ = ()
def __new__(cls, *package_option_args, **kwargs):
return super().__new__(cls, *package_option_args, **kwargs)
def do_copy(target_conf=None,
delivery_dir='',
release_dir='',
package_name=None):
'''
功能描述:根据拷贝类型来执行文件或目录拷贝
返回值:SUCC/FAIL
'''
if target_conf is None:
target_conf = {}
target_name = get_target_name(target_conf)
dst_path = os.path.join(release_dir, target_conf.get('dst_path', ''))
dst_fullpath = os.path.join(dst_path, target_name)
pkg_softlink = target_conf.get('pkg_softlink')
if pkg_softlink:
rets = [
create_softlink(dst_fullpath, os.path.join(release_dir, link))
for link in pkg_softlink
]
if not all(rets):
return FAIL
return SUCC
def do_chmod(target_conf=None, release_dir=''):
"""打包时设置权限 。"""
if target_conf is None:
target_conf = {}
target_name = get_target_name(target_conf)
dst_path = os.path.join(release_dir, target_conf.get('dst_path', ''))
dst_fullpath = os.path.join(dst_path, target_name)
pkg_mod = target_conf.get('pkg_mod', '')
if pkg_mod:
cmd_list = ['chmod', '-R', pkg_mod, dst_fullpath]
try:
result = subprocess.run(cmd_list, capture_output=True, text=True, check=False)
status = result.returncode
output = result.stdout + result.stderr
if status != 0:
CommLog.cilog_error("chmod failed! Command: %s", " ".join(cmd_list))
CommLog.cilog_info("%s", output)
return FAIL
except Exception as e:
CommLog.cilog_error("Execute chmod exception: %s", str(e))
return FAIL
return SUCC
def create_softlink(source, target) -> bool:
'''
功能描述:创建软连接
参数:source, target
返回值:成功或失败
'''
source = os.path.abspath(source.strip())
target = os.path.abspath(target.strip())
link_target_path = os.path.dirname(target)
link_target_name = os.path.basename(target)
relative_path = os.path.relpath(source, link_target_path)
if os.path.isfile(target):
cmd_list = ['rm', '-f', target]
try:
result = subprocess.run(cmd_list, capture_output=True, text=True, check=False)
status = result.returncode
output = result.stdout + result.stderr
if status != 0:
CommLog.cilog_error("Error: rm -f %s failed, %s", target, output)
return False
except Exception as e:
CommLog.cilog_error("Execute rm exception: %s", str(e))
return False
if os.path.isdir(target):
CommLog.cilog_warning("Warning: %s is already a directory, skipping soft link creation.", target)
return True
if not os.path.exists(link_target_path):
os.makedirs(link_target_path)
tmp_dir = os.getcwd()
os.chdir(link_target_path)
os.symlink(relative_path, link_target_name)
os.chdir(tmp_dir)
return True
def generate_info_content(target_conf, ext_name) -> List[str]:
"""生成info内容。"""
def toolchain_llvm_config() -> Iterator[Tuple[str, str]]:
if 'llvm' in ext_name:
yield 'toolchain', 'llvm'
content_list = [
f'{key}={value}'
for key, value in chain(
target_conf['content'].items(), toolchain_llvm_config()
)
]
return content_list
def generate_version_header_content(target_conf) -> Iterator[str]:
"""生成version_header内容。"""
guard_name = target_conf['value'].replace('.', '_').upper()
yield f'#ifndef {guard_name}'
yield f'#define {guard_name}'
yield ''
for name, value in target_conf['content'].items():
if name.endswith('_VERSION'):
version_infos = get_cann_version_info(name, value)
for version_name, version_value in version_infos:
yield f'#define {version_name} {version_value}'
else:
yield f'#define {name} {value}'
yield ''
yield f'#endif /* {guard_name} */'
yield ''
def generate_customized_file(target_conf, ext_name):
filepath = os.path.join(TOP_DIR, "build", target_conf.get('value'))
generator = target_conf.get('generator', 'info')
if generator == 'version_header':
content_list = generate_version_header_content(target_conf)
else:
content_list = generate_info_content(target_conf, ext_name)
file_content = '\n'.join(content_list)
try:
with open(filepath, 'w') as file:
file.write(file_content)
except Exception as ex:
CommLog.cilog_error(f"generate customized file {filepath} failed: {ex}!")
return FAIL
return SUCC
def get_module(target_config) -> str:
"""获取配置模块。"""
module = target_config.get('module', 'NA')
return module if module else 'NA'
def get_operation(operation, target_config) -> str:
"""获取操作类型。"""
if operation in ('copy', 'move') and target_config.get('entity') == 'true':
return 'copy_entity'
return operation
def get_permission(target_config) -> str:
"""获取配置权限。"""
return target_config.get('install_mod', 'NA')
def get_owner_group(target_config) -> str:
"""获取配置属主。"""
return target_config.get('install_own', 'NA').replace('$', '\\\\$')
def get_install_type(target_config) -> str:
"""获取安装类型。"""
return target_config.get('install_type', 'NA')
def get_softlink(target_config) -> List[str]:
"""获取配置软链。"""
softlink_str = target_config.get('install_softlink')
if not softlink_str:
return []
return softlink_str.split(';')
def get_feature(target_config) -> Set[str]:
"""获取配置特性。"""
return target_config['feature']
def get_chip(target_config) -> Set[str]:
"""获取配置芯片。"""
return target_config['chip']
def get_configurable(target_config) -> str:
"""获取配置是否为配置文件。"""
return target_config.get('configurable', 'FALSE')
def get_hash_value(target_config) -> str:
"""获取配置哈希值。"""
return target_config.get('hash', 'NA')
def get_block(target_config) -> str:
"""获取配置块信息。"""
return target_config.get('name', 'NA')
def get_pkg_inner_softlink(target_config) -> List[str]:
"""获取配置包内软链。"""
softlink_str = target_config.get('pkg_inner_softlink')
if not softlink_str:
return []
return softlink_str.split(';')
def validate_path_consistency(target_config, target_name):
"""验证 dst_path 和 install_path 一致性,不一致则抛出异常。"""
dst_path_val = target_config.get('dst_path', '')
install_path_val = target_config.get('install_path', '')
if dst_path_val != install_path_val:
value_path = target_config.get('value', 'unknown')
CommLog.cilog_error(
f"Configuration Error: 'dst_path' MUST be equal to 'install_path'.\n"
f" - Current dst_path: {dst_path_val}\n"
f" - Current install_path: {install_path_val}\n"
)
raise GenerateFilelistError(
f"dst_path ({dst_path_val}) does not match install_path ({install_path_val})"
)
def parse_install_info(infos: List, operate_type, filter_key) -> Iterator[FileItem]:
"""根据配置解析生成安装信息。"""
for target_config in infos:
target_name = get_target_name(target_config)
if target_config.get("optional") == 'true' and operate_type in ('copy', 'move'):
path = os.path.join(TOP_DIR, DELIVERY_PATH, target_config.get('dst_path'))
vaule = os.path.join(TOP_DIR, DELIVERY_PATH, target_config.get('dst_path'), target_name)
if not os.path.exists(path):
continue
if not os.path.exists(vaule):
continue
if operate_type in ('copy', 'move'):
relative_path_in_pkg = os.path.join(target_config.get('dst_path'), target_name)
relative_install_path = path_join(target_config.get('install_path'), target_name)
is_dir = target_config.get('is_dir', False)
validate_path_consistency(target_config, target_name)
elif operate_type == 'mkdir':
relative_path_in_pkg = 'NA'
relative_install_path = target_config.get('value')
is_dir = False
elif operate_type == 'del':
relative_path_in_pkg = 'NA'
relative_install_path = path_join(target_config.get('install_path'), target_name)
is_dir = False
else:
raise UnknownOperateTypeError(f"unknown operate type {operate_type}")
if relative_install_path is None:
continue
install_type = get_install_type(target_config)
if any(key in install_type for key in filter_key):
is_in_docker = 'TRUE'
else:
is_in_docker = 'FALSE'
file_item = create_file_item(
get_module(target_config), get_operation(operate_type, target_config),
relative_path_in_pkg, relative_install_path,
is_in_docker, get_permission(target_config),
get_owner_group(target_config), install_type,
get_softlink(target_config), get_feature(target_config), 'N',
get_configurable(target_config), get_hash_value(target_config),
get_block(target_config), get_pkg_inner_softlink(target_config),
get_chip(target_config), is_dir,
)
yield file_item
def execute_repack_process(xmlconfig: XmlConfig,
delivery_dir: str,
pkg_args: Namespace,
package_name: PackageName = None,
package_option: PackageOption = None):
"""
功能描述: 执行打包流程(拷贝--->签名--->打包)
返回值: SUCC/FAIL
"""
status = SUCC
release_dir = delivery_dir
for item in xmlconfig.generate_infos:
if generate_customized_file(item, package_option.ext_name):
return FAIL
for item in chain(xmlconfig.package_content_list, xmlconfig.move_content_list):
if do_copy(item,
delivery_dir,
release_dir,
package_name):
status = FAIL
continue
if status != SUCC:
return FAIL
if pkg_args.check_size == "True":
limit_list, tag = processing_csv_file(
release_dir, package_name.func_name, package_name.chip_name, pkg_args.build_type
)
if not tag:
return FAIL
if limit_list:
abspath = os.path.abspath(release_dir)
replace_path = abspath + "/"
result = check_add_dir(replace_path, abspath, limit_list)
if not result:
return FAIL
try:
package_name = get_compress_cmd(pkg_args.pkg_output_dir, pkg_args, xmlconfig)
except CompressError:
return FAIL
CommLog.cilog_info("package %s generate filelist.csv and makeself cmd successfully!",
package_name)
return SUCC
def check_path_is_conflict(xml_config):
"""
功能描述: 检查打包时安装路径与软连接路径是否冲突
参数: xml_config
返回值: SUCC/FAIL
"""
install_path_list = set()
pkg_softlink_list = set()
for item in xml_config.package_content_list:
value_list = item.get('value').split('/')
target_name = value_list[-1] if value_list[-1] else value_list[-2]
if item.get('install_path'):
install_path_list.add(
os.path.join(item['install_path'], target_name)
)
if item.get('pkg_inner_softlink'):
pkg_softlink = item.get('pkg_inner_softlink')
pkg_softlink_list.add(pkg_softlink)
if install_path_list & pkg_softlink_list:
CommLog.cilog_info('intersection:{}'.format(install_path_list & pkg_softlink_list))
CommLog.cilog_info('path conflicting: pkg_inner_softlink dir equals install_path!!')
return FAIL
return SUCC
def checksum_value(limit_value, release_dir):
"""
功能描叙: 校验传入的文件或目录大小是否合格
参数:
limit_value: limit.csv中的一行数据如[compiler/bin, 3976, 110%]
返回值: True/False
"""
path = os.path.join(release_dir, limit_value[1])
if len(limit_value) >= 7:
try:
max_value = int(limit_value[4])
except ValueError:
CommLog.cilog_error("{0} configuration is not standard., Please check limit.csv.".format(path))
return True
else:
CommLog.cilog_error("{0} configuration is less than four, Please check limit.csv.".format(path))
return True
if not os.path.exists(path):
CommLog.cilog_warning("{0} doesn't exist, Please check limit.csv.".format(path))
return True
size = 0
for root, dirs, files in os.walk(path):
size += os.path.getsize(root)
for f in files:
filepath = os.path.join(root, f)
if os.path.islink(filepath):
continue
if not os.path.exists(filepath):
continue
size += os.path.getsize(os.path.join(root, f))
if size == 0:
size = os.path.getsize(path)
if size > max_value * 1024:
CommLog.cilog_error(f"\n{path} size {size} bytes exceeds maximum {max_value * 1024} bytes")
return False
return True
def processing_csv_file(release_dir, package_name, chip_name, build_type):
"""
功能描叙: 处理limit.csv文件数据
返回值: [],True/[],False
"""
ret = True
limit_list = []
product = os.path.basename(os.path.dirname(release_dir))
limit_path = os.path.join(pkg_utils.TOP_SOURCE_DIR, CONFIG_SCRIPT_PATH, "common/limit.csv")
if not os.path.exists(limit_path):
CommLog.cilog_warning("{0} doesn't exist.".format(limit_path))
return limit_list, ret
with open(limit_path, "r") as file:
reader = csv.reader(file)
next(reader)
for data in reader:
if not data:
CommLog.cilog_warning("The limit.csv file contains empty lines.")
continue
if is_match_line(package_name, chip_name, product, build_type, data):
if data[1][-1] == "/":
limit_list.append(data[1][:-1])
else:
limit_list.append(data[1])
res = checksum_value(data, release_dir)
if not res:
ret = False
return limit_list, ret
def is_match_line(package_name, chip_name, product, build_type, data):
return package_name == data[0] and chip_name == data[5] and product == data[6] and build_type == data[7].lower()
def check_add_dir(package_path, dirs, limit_list, ret=True):
"""
功能描述: 校验新增目录
参数: path, limit_list
返回值: False/True
"""
for limit_path in limit_list:
if dirs == os.path.join(os.path.split(dirs)[0], limit_path):
return ret
for dir_file in os.listdir(dirs):
path = os.path.join(dirs, dir_file)
relative_path = path.replace(package_path, "")
if os.path.isfile(path) and relative_path not in limit_list:
CommLog.cilog_error("{0} is not in limit.csv file and is newly added.".format(path))
ret = False
elif os.path.isdir(path) and relative_path not in limit_list:
ret = check_add_dir(package_path, path, limit_list, ret)
return ret
def gen_file_install_list(xml_config: XmlConfig,
filter_key) -> Tuple[FileList, FileList]:
"""生成filelist列表。"""
file_install_list = []
dir_filelist = parse_install_info(
xml_config.dir_install_list, 'mkdir', filter_key
)
move_filelist = parse_install_info(
xml_config.move_content_list, 'move', filter_key
)
pkg_filelist = parse_install_info(
xml_config.package_content_list, 'copy', filter_key
)
gen_filelist = parse_install_info(
xml_config.generate_infos, 'copy', filter_key
)
del_filelist = parse_install_info(
xml_config.expand_content_list, 'del', filter_key
)
collect_filelist = list(chain(dir_filelist, move_filelist, pkg_filelist, gen_filelist))
collect_filelist = list(xml_config.packer_config.fill_is_common_path(collect_filelist))
all_filelist = list(chain(collect_filelist, del_filelist))
for file_item in all_filelist:
file_install_list.append(file_item)
return file_install_list, []
def generate_filelist_file_by_xml_config(xml_config: XmlConfig,
filter_key: List[str],
package_check: bool):
"""生成文件列表文件。"""
check_move = xml_config.package_attr.get('use_move', False)
transform_nested_path_func = get_transform_nested_path_func(
xml_config.package_attr.get('parallel') or check_move
)
check_features = xml_config.package_attr.get('check_features', False)
file_install_list, [] = invoke(
pipe(
gen_file_install_list,
partial(map, transform_nested_path_func),
tuple,
),
xml_config, filter_key
)
generate_filelist(file_install_list, 'filelist.csv')
check_filelist(file_install_list, check_features, check_move)
def get_pkg_xml_relative_path(pkg_args: Namespace) -> str:
"""获取包配置文件相对路径。"""
def parts():
yield CONFIG_SCRIPT_PATH
yield pkg_args.pkg_name
if pkg_args.chip_scenes:
yield pkg_args.chip_scenes
if pkg_args.xml_file:
yield pkg_args.xml_file
else:
yield f'{pkg_args.pkg_name}.xml'
return os.path.join(*parts())
def write_config_inc_var(name: str, package_attr: Dict, file: TextIO):
"""向config.inc文件写入变量。"""
if name in package_attr:
value = str(package_attr[name]).lower()
file.write(f"{name.upper()}={value}\n")
def generate_config_inc(package_attr: Dict):
"""生成config.inc文件。"""
if 'parallel' not in package_attr and 'parallel_limit' not in package_attr and 'use_move' not in package_attr:
return
year = datetime.now(timezone.utc).year
config_inc = os.path.join(TOP_DIR, "build", 'config.inc')
header = [
'#!/bin/sh\n',
'#----------------------------------------------------------------------------\n',
f'# Copyright Huawei Technologies Co., Ltd. 2023-{year}. All rights reserved.\n',
'#----------------------------------------------------------------------------\n',
'\n',
]
if os.path.isfile(config_inc):
os.chmod(config_inc, 0o700)
with open(config_inc, 'w', encoding='utf-8') as file:
file.writelines(header)
write_config_inc_var('parallel', package_attr, file)
write_config_inc_var('parallel_limit', package_attr, file)
write_config_inc_var('use_move', package_attr, file)
os.chmod(config_inc, 0o500)
def execute_packaging_process(xml_config, main_args, delivery_dir):
"""
执行打包的后续流程:
1. 处理 independent_pkg 的文件拷贝
2. 创建配置对象
3. 检查路径冲突
4. 执行最终打包
"""
if main_args.independent_pkg:
src_file_path = os.path.join(TOP_DIR, "build", "filelist.csv")
dst_dir = os.path.join(main_args.pkg_output_dir, "share", "info", main_args.pkg_name, "script")
dst_file_path = os.path.join(dst_dir, "filelist.csv")
if os.path.exists(dst_file_path):
try:
os.remove(dst_file_path)
except PermissionError:
CommLog.cilog_error("Failed to delete old file: %s, please check directory permissions", dst_file_path)
os.makedirs(dst_dir, exist_ok=True)
shutil.copy(src_file_path, dst_file_path)
package_option = PackageOption(
main_args.os_arch, main_args.package_suffix, main_args.not_in_name,
main_args.pkg_version, main_args.ext_name,
chip_name=main_args.chip_name, func_name=main_args.func_name,
version_dir=main_args.version_dir,
disable_multi_version=main_args.disable_multi_version,
suffix=main_args.suffix
)
package_name = PackageName(xml_config.package_attr, main_args, xml_config.version)
if check_path_is_conflict(xml_config) == FAIL:
return FAIL
return execute_repack_process(
xml_config, delivery_dir, main_args,
package_name=package_name,
package_option=package_option
)
def main(pkg_name='', xml_file='', main_args=None):
"""
功能描述:执行打包流程 (解析配置--->生成文件列表--->执行拷贝/打包动作)
参数:pkg_name, os_arch, type
返回值:SUCC/FAIL
"""
delivery_dir = os.path.join(TOP_DIR, DELIVERY_PATH)
if not os.path.exists(delivery_dir):
return FAIL
config_relative_path = get_pkg_xml_relative_path(main_args)
pkg_xml_file = os.path.join(pkg_utils.TOP_SOURCE_DIR, config_relative_path)
parse_option = make_parse_option(main_args)
try:
xml_config = parse_xml_config(
pkg_xml_file, delivery_dir, parse_option, main_args
)
except ContainAsteriskError as ex:
CommLog.cilog_error(f"Value contain '*' in {config_relative_path}. value is '{ex.value}'.")
return FAIL
if pkg_name in ['driver', 'firmware']:
filter_key = ['all', 'docker']
elif pkg_name in ['aicpu_kernels_device', 'aicpu_kernels_host']:
filter_key = []
else:
filter_key = ['all', 'run']
try:
generate_filelist_file_by_xml_config(
xml_config, filter_key,
main_args.package_check or xml_config.package_attr.get('package_check')
)
except PackageNameEmptyError:
CommLog.cilog_error(f'package name is empty in {xml_file}, please check it')
return FAIL
except GenerateFilelistError as ex:
CommLog.cilog_error(f'generate filelist {ex.filename} failed!', )
return FAIL
except FilelistError as ex:
CommLog.cilog_error('check filelist error! %s', str(ex))
return FAIL
generate_config_inc(xml_config.package_attr)
return execute_packaging_process(xml_config, main_args, delivery_dir)
def args_parse():
"""
功能描述 : 脚本入参解析
参数 : 调用脚本的传参
返回值 : 解析后的参数值
"""
parser = argparse.ArgumentParser(
description='This script is for package repack processing.')
parser.add_argument('-c', '--chip_scenes', metavar='chip_scenes', required=False, dest='chip_scenes', nargs='?',
const='',
default='', help='This parameter define chip id for package.')
parser.add_argument('-n', '--pkg_name', metavar='pkg_name', required=False,
help='This parameter define pkg_name for config_xml.')
parser.add_argument('-o', '--os_arch', metavar='os_arch', required=False, dest='os_arch', nargs='?', const='',
default=None, help="This parameter define the package's os_arch")
parser.add_argument('-t', '--type', metavar='type', required=False, dest='type', nargs='?', const='',
default='repack', help="This parameter define this script's function")
parser.add_argument('-i', '--not_in_name', metavar='not_in_name', required=False, dest='not_in_name', nargs='?',
const='',
default='', help="This parameter define the package's name not contain the element")
parser.add_argument('-v', '--pkg_version', metavar='pkg_version', required=False, dest='pkg_version', nargs='?',
const='',
default='', help="This parameter define the version for package.")
parser.add_argument('-e', '--ext_name', metavar='ext_name', required=False, dest='ext_name', nargs='?', const='',
default='', help="This parameter define the package's ext_name")
parser.add_argument('--package_suffix', nargs='?', const='none',
default='none', help="This parameter define the package suffix, debug or none")
parser.add_argument('--suffix', metavar='suffix', required=False, dest='suffix', nargs='?', const='',
default=None, help="This parameter define the package suffix, for example such as tar.gz")
parser.add_argument('-b', '--build_type', metavar='build_type', required=False, dest='build_type', nargs='?',
const='',
default='debug', help="This parameter define release type of package")
parser.add_argument('-x', '--xml', metavar='xml_file', required=False, dest='xml_file', nargs='?', const='',
default='', help="This parameter define xml file")
parser.add_argument('--chip_name', metavar='chip_name', required=False, dest='chip_name', nargs='?', const=None,
default=None,
help="This parameter define package chip name, has higher priority than chip name in xml")
parser.add_argument('--func_name', metavar='func_name', required=False, dest='func_name', nargs='?', const=None,
default=None,
help="This parameter define package func name, has higher priority than func name in xml")
parser.add_argument('--source_root', metavar='source_root', required=False, dest='source_root', nargs='?', const='',
help='source root dir.')
parser.add_argument('--makeself_dir', metavar='makeself_dir', required=False, dest='makeself_dir',
nargs='?', const='', help='makeself dir.')
parser.add_argument('--independent_pkg', action='store_true', help='Independent pkg.')
parser.add_argument('--pkg-output-dir', default='', help='Package dirpath.')
parser.add_argument('--version_dir', nargs='?', const='', default='', help='Set version dir.')
parser.add_argument('--tag', metavar='tag', nargs='?', const='', default='')
parser.add_argument('--disable-multi-version', action='store_true', help='Disable multi version.')
parser.add_argument('--package-check', action='store_true', help='check package config.')
parser.add_argument('--check_size', nargs='?', const='', default='', help="Check the size of a file or directory.")
parser.add_argument('--pkg-name-style', metavar='pkg_name_style', default='common', help='Package name style.')
return parser.parse_args()
if __name__ == "__main__":
CommLog.cilog_info("%s", " ".join(sys.argv))
args = args_parse()
try:
if args.source_root:
pkg_utils.TOP_SOURCE_DIR = args.source_root
if args.build_type == '':
args.build_type = 'debug'
else:
args.build_type = args.build_type.lower()
status = main(args.pkg_name, args.xml_file, main_args=args)
except Exception as e:
CommLog.cilog_error("exception is occurred (%s)!", e)
CommLog.cilog_info("%s", traceback.format_exc())
status = FAIL
sys.exit(status)