mirror of
https://github.com/openharmony/kernel_linux_build.git
synced 2026-07-16 05:30:26 -04:00
kernel_build.py: update script
1. Add mask known warnings. 2. Set return value based on the compile result. Signed-off-by: Ma Feng <mafeng.ma@huawei.com>
This commit is contained in:
+196
-26
@@ -20,6 +20,139 @@ import subprocess
|
||||
import shlex
|
||||
import time
|
||||
|
||||
|
||||
ignores = [
|
||||
"include/trace/events/eas_sched.h: warning: format '%d' expects arguments of type 'int', but argument 9 has type 'long unsigned int' [-Wformat=]",
|
||||
"drivers/block/zram/zram_drv.c: warning: left shift count >= width of type",
|
||||
"include/trace/events/eas_sched.h: note: in expansion of macro",
|
||||
"include/trace/events/eas_sched.h: note: format string is defined here",
|
||||
"include/trace/trace_events.h: note: in expansion of macro",
|
||||
"mm/vmscan.c: warning: suggest parentheses around assignment used as truth value [-Wparentheses]",
|
||||
"lib/bitfiled_kunit.c: warning: the frame size of \d+ bytes is larger than \d+ bytes",
|
||||
]
|
||||
|
||||
|
||||
class Reporter:
|
||||
def __init__(self, arch, path):
|
||||
self.arch = arch
|
||||
self.path = path
|
||||
|
||||
|
||||
def normpath(self, filename):
|
||||
if re.search("^[\.]+[^/]", filename):
|
||||
filename = re.sub("^[\.]+", "", filename)
|
||||
return os.path.normpath(filename)
|
||||
|
||||
|
||||
def format_title(self, title):
|
||||
title = re.sub("\u2018", "'", title)
|
||||
title = re.sub("\u2019", "'", title)
|
||||
|
||||
return title.strip()
|
||||
|
||||
|
||||
def report_build_warning(self, filename, regex, details):
|
||||
if len(details) == 0 or filename is None:
|
||||
return None
|
||||
|
||||
if not os.path.exists(os.path.join(self.path, filename)):
|
||||
return None
|
||||
|
||||
line = details[0]
|
||||
try:
|
||||
warning = re.search(regex, line).group(0)
|
||||
except:
|
||||
print('Expect>>>', details)
|
||||
return
|
||||
|
||||
report = {
|
||||
'title': self.format_title("%s: %s" % (filename, warning)),
|
||||
'filename': filename,
|
||||
'report': '\n'.join(details),
|
||||
'nr': line.split(':')[1],
|
||||
}
|
||||
|
||||
return report
|
||||
|
||||
|
||||
def parse_build_warning(self, blocks, regex, title_regex):
|
||||
issues = {}
|
||||
reports = []
|
||||
details = []
|
||||
filename = None
|
||||
unused = False
|
||||
|
||||
for line in blocks:
|
||||
attrs = line.split(':')
|
||||
if len(attrs) < 5 and filename is None:
|
||||
continue
|
||||
if line.startswith(' ') or len(attrs) < 2:
|
||||
if unused is True:
|
||||
details.append(line)
|
||||
continue
|
||||
if not regex in line:
|
||||
unused = False
|
||||
continue
|
||||
unused = True
|
||||
newfile = self.normpath(attrs[0])
|
||||
if newfile != filename:
|
||||
if len(details) and filename:
|
||||
if filename in issues:
|
||||
issues[filename].extend(details)
|
||||
else:
|
||||
issues[filename] = details
|
||||
filename = newfile
|
||||
details = []
|
||||
|
||||
details.append(line)
|
||||
|
||||
if len(details) and filename:
|
||||
if filename in issues:
|
||||
issues[filename].extend(details)
|
||||
else:
|
||||
issues[filename] = details
|
||||
|
||||
for filename, details in issues.items():
|
||||
report = self.report_build_warning(filename, title_regex, details)
|
||||
if not report is None:
|
||||
reports.append(report)
|
||||
|
||||
|
||||
def parse(self, content):
|
||||
blocks = content.split('\n')
|
||||
reports = []
|
||||
|
||||
patterns = (
|
||||
('[-Wunused-but-set-variable]', 'warning: .* set but not used'),
|
||||
('[-Wunused-but-set-parameter]', 'warning: .* set but not used'),
|
||||
('[-Wunused-const-variable=]', 'warning: .* defined but not used'),
|
||||
('[-Wold-style-definition]', 'warning: .* definition'),
|
||||
('[-Wold-style-declaration]', 'warning: .* declaration'),
|
||||
('[-Wmaybe-uninitialized]', 'warning: .* uninitialized'),
|
||||
('[-Wtype-limits]', 'warning: .* always (false|true)'),
|
||||
('[-Wunused-function]', 'warning: .* defined but not used'),
|
||||
('[-Wsequence-point]', 'warning: .* may be undefined'),
|
||||
('[-Wformat=]', 'warning: format.*'),
|
||||
('[-Wunused-variable]', 'warning: [^\[]*'),
|
||||
('[-Wframe-larger-than=]', 'warning: the frame size [^\[]*'),
|
||||
('[-Wshift-count-overflow]', 'warning: left shift count >= width of type'),
|
||||
('definition or declaration', 'warning: .* declared inside parameter list will not be visible outside of this definition or declaration'),
|
||||
('character', 'warning: missing termination .* character'),
|
||||
('in expansion of macro', 'note: in expansion of macro'),
|
||||
('note: fromat string is defined here', 'note: format string is defined here'),
|
||||
('[-Wparentheses]', 'suggest parentheses around assignment used as truth value'),
|
||||
)
|
||||
|
||||
for regex, title_regex in patterns:
|
||||
items = self.parse_build_warning(blocks, regex, title_regex)
|
||||
if items is None:
|
||||
continue
|
||||
|
||||
reports.extend(items)
|
||||
|
||||
return reports
|
||||
|
||||
|
||||
def exec_cmd(command_list, shell=False, show_output=False, cwd=None):
|
||||
if isinstance(command_list, str):
|
||||
command_list = shlex.split(command_list)
|
||||
@@ -80,9 +213,9 @@ def make_cmd(cmd, arch, cross_compile, knl_path):
|
||||
outmsg, errmsg, ret = exec_cmd(make, cwd=knl_path)
|
||||
if ret:
|
||||
print(f'"{make}" errors --> \n {errmsg}')
|
||||
return False, f'"{make}" errors --> \n {errmsg}'
|
||||
return ret, f'"{make}" errors --> \n {errmsg}'
|
||||
|
||||
return True, f'"{make}" success!'
|
||||
return ret, f'"{make}" success!'
|
||||
|
||||
|
||||
def make_config(arch, config, corss_compile, knl_path):
|
||||
@@ -90,9 +223,9 @@ def make_config(arch, config, corss_compile, knl_path):
|
||||
outmsg, errmsg, ret = exec_cmd(make, cwd=knl_path)
|
||||
if ret:
|
||||
print(f'"{make}" errors --> \n {errmsg}')
|
||||
return False, f'"{make}" errors --> \n {errmsg}'
|
||||
return ret, f'"{make}" errors --> \n {errmsg}'
|
||||
|
||||
return True, f'"{make}" success!'
|
||||
return ret, f'"{make}" success!'
|
||||
|
||||
|
||||
def make_j(arch, cross_compile, knl_path):
|
||||
@@ -100,12 +233,30 @@ def make_j(arch, cross_compile, knl_path):
|
||||
outmsg, errmsg, ret = exec_cmd(make, cwd=knl_path)
|
||||
if ret:
|
||||
print(f'"{make}" errors --> \n {errmsg}')
|
||||
return False, f'"{make}" errors --> \n {errmsg}'
|
||||
elif len(errmsg) > 0:
|
||||
print(f'"{make}" warnings --> \n {errmsg}')
|
||||
return False, f'"{make}" warnings --> \n {errmsg}'
|
||||
result = "success"
|
||||
reporter = Reporter(arch, knl_path)
|
||||
known_issue = "\nKnown issue:\n"
|
||||
for report in reporter.parse(errmsg):
|
||||
if ignores and [i for i in ignores if re.match(i, report['title'])]:
|
||||
known_issue = known_issue + report['title'] + "\n"
|
||||
known_issue = known_issue + report['report'] + "\n"
|
||||
continue
|
||||
result = 'failed'
|
||||
|
||||
return True, f'"{make}" success!'
|
||||
print(known_issue)
|
||||
new_issue = "\nNew Issue:\n"
|
||||
if result == "failed":
|
||||
for report in reporter.parse(errmsg):
|
||||
if ignores and [i for i in ignores if re.match(i, report['title'])]:
|
||||
continue
|
||||
new_issue = new_issue + report['title'] + "\n"
|
||||
new_issue = new_issue + report['report'] + "\n"
|
||||
print(new_issue)
|
||||
return 2, f'"{make}" warning --> \n {errmsg}'
|
||||
|
||||
return ret, f'"{make}" warnings in ignores --> \n {errmsg}'
|
||||
|
||||
return ret, f'"{make}" success!'
|
||||
|
||||
|
||||
def cp_config(arch, config, config_path, knl_path):
|
||||
@@ -114,12 +265,12 @@ def cp_config(arch, config, config_path, knl_path):
|
||||
outmsg, errmsg, ret = exec_cmd(cp)
|
||||
if ret:
|
||||
print(f'"{cp}" errors --> \n {errmsg}')
|
||||
return False, f'"{cp}" errors --> \n {errmsg}'
|
||||
return ret, f'"{cp}" errors --> \n {errmsg}'
|
||||
else:
|
||||
print(f'"{config_path.format(arch, config)}" not exists!')
|
||||
return False, f'"{config_path.format(arch, config)}" not exists!'
|
||||
return ret, f'"{config_path.format(arch, config)}" not exists!'
|
||||
|
||||
return True, f'"{cp}" success!'
|
||||
return ret, f'"{cp}" success!'
|
||||
|
||||
|
||||
def get_logger(filename):
|
||||
@@ -137,53 +288,64 @@ def get_logger(filename):
|
||||
|
||||
def build(arch, config, config_path, cross_compile, knl_path, logger):
|
||||
ret, msg = make_cmd('make defconfig', arch, cross_compile, knl_path)
|
||||
if not ret:
|
||||
if ret:
|
||||
logger.error(msg)
|
||||
return ret, msg
|
||||
|
||||
ret, msg = make_cmd('make oldconfig', arch, cross_compile, knl_path)
|
||||
if not ret:
|
||||
if ret:
|
||||
logger.error(msg)
|
||||
return ret, msg
|
||||
|
||||
ret, msg = make_cmd('make clean', arch, cross_compile, knl_path)
|
||||
if not ret:
|
||||
if ret:
|
||||
logger.error(msg)
|
||||
return ret, msg
|
||||
|
||||
ret, msg = make_j(arch, cross_compile, knl_path)
|
||||
if not ret:
|
||||
if ret:
|
||||
logger.error(msg)
|
||||
return ret, msg
|
||||
|
||||
ret, msg = cp_config(arch, config, config_path, knl_path)
|
||||
if not ret:
|
||||
if ret:
|
||||
logger.error(msg)
|
||||
return ret, msg
|
||||
else:
|
||||
ret, msg = make_config(arch, config, cross_compile, knl_path)
|
||||
if not ret:
|
||||
if ret:
|
||||
logger.error(msg)
|
||||
return ret, msg
|
||||
|
||||
ret, msg = make_cmd('make clean', arch, cross_compile, knl_path)
|
||||
if not ret:
|
||||
if ret:
|
||||
logger.error(msg)
|
||||
return ret, msg
|
||||
|
||||
ret, msg = make_j(arch, cross_compile, knl_path)
|
||||
if not ret:
|
||||
if ret:
|
||||
logger.error(msg)
|
||||
return ret, msg
|
||||
|
||||
ret, msg = make_cmd('make allmodconfig', arch, cross_compile, knl_path)
|
||||
if not ret:
|
||||
if ret:
|
||||
logger.error(msg)
|
||||
return ret, msg
|
||||
|
||||
sed = f'sed -i s/^.*CONFIG_FRAME_WARN.*$/CONFIG_FRAME_WARN=2048/ .config'
|
||||
outmsg, errmsg, ret = exec_cmd(sed, cwd=knl_path)
|
||||
|
||||
ret, msg = make_cmd('make clean', arch, cross_compile, knl_path)
|
||||
if not ret:
|
||||
if ret:
|
||||
logger.error(msg)
|
||||
return ret, msg
|
||||
|
||||
ret, msg = make_j(arch, cross_compile, knl_path)
|
||||
if not ret:
|
||||
if ret:
|
||||
logger.error(msg)
|
||||
return ret, msg
|
||||
|
||||
return True, f'build success!'
|
||||
return 0, f'build success!'
|
||||
|
||||
|
||||
def main():
|
||||
@@ -197,12 +359,20 @@ def main():
|
||||
arch = 'arm'
|
||||
config = 'hispark_taurus_standard_defconfig'
|
||||
cross_compile = '../../../prebuilts/gcc/linux-x86/arm/gcc-linaro-7.5.0-arm-linux-gnueabi/bin/arm-linux-gnueabi-'
|
||||
build(arch, config, config_path, cross_compile, knl_path, logger)
|
||||
arm_ret, arm_msg = build(arch, config, config_path, cross_compile, knl_path, logger)
|
||||
|
||||
arch = 'arm64'
|
||||
config = 'rk3568_standard_defconfig'
|
||||
cross_compile = '../../../prebuilts/gcc/linux-x86/aarch64/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-'
|
||||
build(arch, config, config_path, cross_compile, knl_path, logger)
|
||||
arm64_ret, arm64_msg = build(arch, config, config_path, cross_compile, knl_path, logger)
|
||||
|
||||
print(f'arm_ret: {arm_ret}, arm64_ret: {arm64_ret}')
|
||||
if any([arm_ret, arm64_ret]):
|
||||
print('kernel build test failed!')
|
||||
exit(arm_ret or arm64_ret)
|
||||
|
||||
print('kernel build test success.')
|
||||
exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user