diff --git a/.ci/before_install.sh b/.ci/before_install.sh
index e589294eb..d76cd9034 100644
--- a/.ci/before_install.sh
+++ b/.ci/before_install.sh
@@ -26,8 +26,8 @@ fi
pip install recommonmark || die
pip install sphinx_rtd_theme || die
}
- pip install PrettyTable || die
- pip install colorama || die
+ pip install embarc_cli || die
pip install configparser || die
pip install requests || die
+ pip install XlsxWriter || die
}
diff --git a/.ci/build.py b/.ci/build.py
index f8ed46ddc..601c64515 100644
--- a/.ci/build.py
+++ b/.ci/build.py
@@ -1,4 +1,5 @@
#! /usr/bin/env python
+from __future__ import print_function, unicode_literals
import json
import os
import sys
@@ -8,6 +9,14 @@
from configparser import ConfigParser
import copy
import argparse
+from xlsxwriter.workbook import Workbook
+from xlsxwriter.worksheet import Worksheet
+from xlsxwriter.worksheet import convert_cell_args
+from embarc_tools.download_manager import cd, delete_dir_files
+from embarc_tools.osp import osp
+from embarc_tools.builder import build
+import collections
+import operator
example = {
"arc_feature_cache": "example/baremetal/arc_feature/cache",
"arc_feature_timer_interrupt": "example/baremetal/arc_feature/timer_interrupt",
@@ -18,242 +27,226 @@
"graphic_u8glib": "example/baremetal/graphic_u8glib",
"kernel": "example/freertos/kernel"
}
-'''
-"bootloader":"baremetal/bootloader",
-"dma_spiflash":"baremetal/dma_spiflash",
-"openthread_cli":"baremetal/openthread/cli",
-"openthread_ncp":"baremetal/openthread/ncp",
-"iot_coap_coap_server":"freertos/iot/coap/coap_server",
-"iot_lwm2m_lwm2m_client":"freertos/iot/lwm2m/lwm2m_client",
-"iot_lwm2m_lwm2m_server":"freertos/iot/lwm2m/lwm2m_server",
-"kernel_secure":"freertos/kernel_secure",
-"net_httpserver":"freertos/net/httpserver"
-"net_ntshell":"freertos/net/ntshell",
-"secureshield_secret_normal":"baremetal/secureshield/secret_normal",
-"secureshield_secret_secure":"baremetal/secureshield/secret_secure",
-"secureshield_secret_secure_sid":"baremetal/secureshield/secret_secure_sid",
-"secureshield_test_case":"baremetal/secureshield/test_case",
-"sec_mbedtls_dtls_client":"freertos/sec/mbedtls/dtls/client",
-"sec_mbedtls_dtls_server":"freertos/sec/mbedtls/dtls/server",
-"sec_mbedtls_ssl_client2":"freertos/sec/mbedtls/ssl/client2",
-"sec_mbedtls_ssl_server2":"freertos/sec/mbedtls/ssl/server2"
-
-'''
-MakefileNames = ['Makefile', 'makefile', 'GNUMakefile']
-class TailRecurseException:
+MakefileNames = ['Makefile', 'makefile', 'GNUMakefile']
- def __init__(self, args, kwargs):
- self.args = args
- self.kwargs = kwargs
+def excel_string_width(str):
+ string_width = len(str)
+ if string_width == 0:
+ return 0
+ else:
+ return string_width * 1.1
-def tail_call_optimized(g):
- def func(*args, **kwargs):
- f = sys._getframe()
- if f.f_back and f.f_back.f_back and f.f_back.f_back.f_code == f.f_code:
- raise TailRecurseException(args, kwargs)
- else:
- while 1:
- try:
- return g(*args, **kwargs)
- except TailRecurseException as e:
- args = e.args
- kwargs = e.kwargs
- func.__doc__ = g.__doc__
- return func
+class MyWorksheet(Worksheet):
-def get_makefile(app_path):
- for makefile in MakefileNames:
- makefile_path = os.path.join(app_path, makefile)
- if os.path.exists(makefile_path) and os.path.isfile(makefile_path):
- return makefile_path
- return None
+ @convert_cell_args
+ def write_string(self, row, col, string, cell_format=None):
+ if self._check_dimensions(row, col):
+ return -1
+ min_width = 0
+ string_width = excel_string_width(string)
+ if string_width > min_width:
+ max_width = self.max_column_widths.get(col, min_width)
+ if string_width > max_width:
+ self.max_column_widths[col] = string_width
+ return super(MyWorksheet, self).write_string(row, col, string, cell_format)
-def is_embarc_makefile(makefile_path):
- with open(makefile_path) as f:
- embarc_root = False
- appl = False
- lines = f.read().splitlines()
- for line in lines:
- if "EMBARC_ROOT" in line:
- embarc_root = True
- if "APPL" in line:
- appl = True
- if embarc_root and appl:
- return True
- return False
+class MyWorkbook(Workbook):
+ def add_worksheet(self, name=None):
+ worksheet = super(MyWorkbook, self).add_worksheet(name, MyWorksheet)
+ worksheet.max_column_widths = {}
+ return worksheet
-def get_config(config):
- make_configs = dict()
- if type(config) == list:
- pass
- else:
- config = config.split(" ")
- for make_config in config:
- [config_name, value] = make_config.split("=")
- if value == "":
- value = None
- make_configs[config_name] = value
- return make_configs
+ def close(self):
+ for worksheet in self.worksheets():
+ for column, width in worksheet.max_column_widths.items():
+ worksheet.set_column(column, column, width)
+ return super(MyWorkbook, self).close()
-def board_version_config(osp_root, board, bd_version=None):
- board_path = os.path.join(osp_root, "board", board)
- bd_vers = dict()
- if os.path.exists(board_path):
- files = os.listdir(board_path)
- if "configs" in files:
- versions = os.listdir(os.path.join(board_path, "configs"))
- for version in versions:
- version_path = os.path.join(board_path, "configs", version)
- if os.path.isdir(version_path):
- bd_vers[version] = version_path
- else:
- versions = os.listdir(board_path)
- for version in versions:
- path = os.path.join(board_path, version)
- if os.path.isdir(path) and "configs" in os.listdir(path):
- version_path = os.path.join(board_path, version, "configs")
- bd_vers[version] = version_path
- if bd_version is not None:
- if bd_version in bd_vers:
- bd_ver = {bd_version: bd_vers[bd_version]}
- return bd_ver
- return bd_vers
-
-
-def get_tcf(osp_root, board, bd_version, cur_core):
- result = dict()
- tcf_name = cur_core + ".tcf"
- board_version_path_dict = copy.deepcopy(board_version_config(osp_root, board, bd_version))
- board_path = board_version_path_dict[bd_version]
-
- cur_core_file = cur_core + ".tcf"
- result[cur_core] = None
- if os.path.exists(board_path):
- for root, dirs, files in os.walk(board_path, topdown=True):
- if cur_core_file in files:
- result[tcf_name] = os.path.join(root, cur_core_file)
- return result
+def get_cache(osp_path):
+ cache = ".cache/result"
+ cache_path = os.path.join(osp_path, cache)
+ if not os.path.exists(cache_path):
+ os.makedirs(cache_path)
+ return cache_path
-def get_tcfs(osp_root, board, bd_version, cur_core=None):
- result = []
- board_version_path_dict = board_version_config(osp_root, board, bd_version)
- board_path = board_version_path_dict[bd_version]
- if os.path.exists(board_path):
- if cur_core:
- cur_core_file = cur_core + ".tcf"
- for root, dirs, files in os.walk(board_path, topdown=True):
- if cur_core_file in files:
- result.append(cur_core)
-
- else:
-
- for root, dirs, files in os.walk(board_path, topdown=True):
-
- for file in files:
- filename, filesuffix = os.path.splitext(file)
- if not filesuffix == ".tcf":
- continue
- result.append(filename)
+def generate_json_file(data, path):
+ with open(path, "w") as f:
+ json.dump(data, f, indent=4)
+ f.close()
- return result
+def result_json_artifacts(osp_path, result, file=None):
-def get_board_version(osp_root, board, bd_version=None):
- result = []
- board_path = "board/" + board
- ver_path = os.path.join(osp_root, board_path)
- if os.path.exists(ver_path):
- bd_vers_dict = board_version_config(osp_root, board, bd_version)
- result.extend(bd_vers_dict.keys())
- return result
+ if file:
+ job = file
+ else:
+ job = os.environ.get("CI_JOB_NAME")
+ if not job:
+ job = os.environ.get("NAME")
+ if not job:
+ job = os.environ.get("STAGE_NAME")
+ if job:
+
+ print(job)
+ cache_path = get_cache(osp_path)
+ file = job + ".json"
+ file_path = os.path.join(cache_path, file)
+ generate_json_file(result, file_path)
+
+
+def takeApp(elem):
+ return elem["app_path"]
+
+
+def dict_to_excel(datas):
+
+ print("Start to generate excel")
+ failed_summarize = dict()
+ for toolchain_config, results in datas.items():
+ results_board_config = dict()
+ filename = toolchain_config + ".xlsx"
+ workbook = MyWorkbook(filename)
+ sheet_dict = dict()
+ merge_format = workbook.add_format({'bold': True, "align": "center", "valign": "vcenter"})
+
+ for build_result in results:
+ config = build_result.get("config", None)
+ if config:
+ board_config = config["BOARD"] + "_" + config["BD_VER"]
+ if not results_board_config.get(board_config, None):
+ results_board_config[board_config] = [build_result]
+ else:
+ results_board_config[board_config].append(build_result)
+ for board_config in results_board_config:
+ worksheet = workbook.add_worksheet(board_config)
+ sheet_dict[board_config] = worksheet
+ for board_config, build_result in results_board_config.items():
+ build_result.sort(key=takeApp)
+ worksheet = sheet_dict[board_config]
+ worksheet.merge_range(0, 0, 1, 0, "APP", merge_format)
+ worksheet.set_column(0, 7, 10)
+ worksheet.merge_range(0, 1, 1, 1, "CORE", merge_format)
+ worksheet.merge_range(0, 2, 1, 2, "TIME (s)", merge_format)
+ worksheet.merge_range(0, 3, 1, 3, "GIT COMMIT SHA", merge_format)
+ worksheet.merge_range(0, 4, 0, 6, "SIZE (bytes)", merge_format)
+ worksheet.write(1, 4, "text", merge_format)
+ worksheet.write(1, 5, "data", merge_format)
+ worksheet.write(1, 6, "bss", merge_format)
+ worksheet.merge_range(0, 7, 1, 7, "CI JOB", merge_format)
+ worksheet.merge_range(0, 8, 1, 8, "PASS", merge_format)
+ worksheet.freeze_panes(1, 0)
+ worksheet.freeze_panes(2, 0)
+ row = 2
+
+ same_app = dict()
+ failed_count = dict()
+ same_app = collections.OrderedDict()
+ for app_build in build_result:
+ app_name = app_build["app_path"]
+ if same_app.get(app_name, None):
+ same_app[app_name] = same_app[app_name] + 1
+ else:
+ same_app[app_name] = 1
+ failed_count[app_name] = 0
-def get_boards(osp_root, board=None):
- result = []
- board_path = os.path.join(osp_root, "board")
- if os.path.exists(board_path):
- if board is not None:
- if board in os.listdir(board_path):
- result.append(board)
- return result
- for file in os.listdir(board_path):
- if os.path.isdir(os.path.join(board_path, file)):
- result.append(file)
- return result
+ cell_format = workbook.add_format({"align": "center", "valign": "vcenter"})
+ failed = "No"
+ if not app_build["code"]:
+ failed = "Yes"
+ else:
+ cell_format.set_bg_color("#FFC7CE")
+ failed_count[app_name] += 1
+ worksheet.write(row, 0, app_build["app_path"])
+ worksheet.write(row, 1, app_build["config"]["CUR_CORE"], cell_format)
+ worksheet.write(row, 2, round(app_build["time_cost"], 2), cell_format)
+ worksheet.write(row, 3, app_build["commit_sha"][0:8], cell_format)
+ worksheet.write(row, 4, str(app_build["size"].get("text", " ")), cell_format)
+ worksheet.write(row, 5, str(app_build["size"].get("data", " ")), cell_format)
+ worksheet.write(row, 6, str(app_build["size"].get("bss", " ")), cell_format)
+ worksheet.write(row, 7, app_build["JOB"], cell_format)
+ worksheet.write(row, 8, failed, cell_format)
+ row += 1
+ s = 2
+ for app, value in same_app.items():
+ merge_format_app = workbook.add_format({"align": "center", "valign": "vcenter"})
+ if value == failed_count[app]:
+ if not failed_summarize.get(toolchain_config, None):
+ failed_summarize[toolchain_config] = dict()
+ if not failed_summarize[toolchain_config].get(board_config, None):
+ failed_summarize[toolchain_config][board_config] = list()
+ failed_summarize[toolchain_config][board_config].append(app)
+ merge_format_app.set_font_color("red")
+ if value > 1:
+ worksheet.merge_range(s, 0, s + value - 1, 0, app, merge_format_app)
+ s += value
+ workbook.close()
+ return failed_summarize
+
+
+def result_excel_artifacts(osp_path):
+ cache_path = get_cache(osp_path)
+ files = os.listdir(cache_path)
+ datas = dict()
+ failed_summarize = None
+ for file in files:
+ filename, filesuffix = os.path.splitext(file)
+ if not filesuffix == ".json" or filename == "results":
+ continue
+ file_path = os.path.join(cache_path, file)
+ with open(file_path, "r") as f:
+ results = json.load(f)
+ for app, build_status in results.items():
+ for build_result in build_status:
+ config = build_result.get("config", None)
+ if config:
+ toolchain_config = config["TOOLCHAIN"] + "_" + config["TOOLCHAIN_VER"]
+ if not datas.get(toolchain_config, None):
+ datas[toolchain_config] = [build_result]
+ else:
+ datas[toolchain_config].append(build_result)
+ else:
+ continue
+ f.close()
+ result_json_artifacts(osp_path, datas, file="results")
+ with cd(cache_path):
+ failed_summarize = dict_to_excel(datas)
+ result_json_artifacts(osp_path, failed_summarize, file="failed_results")
-def build_makefile_project(app_path, config):
- result = dict()
- isMakeProject = False
- make_configs = copy.deepcopy(config)
- core_key = "CORE" if "CORE" in make_configs else "CUR_CORE"
+class TailRecurseException(Exception):
+ def __init__(self, args, kwargs):
+ self.args = args
+ self.kwargs = kwargs
- osp_root = make_configs.pop("OSP_ROOT")
- toolchain_ver = make_configs.pop("TOOLCHAIN_VER")
- parallel = make_configs.pop("PARALLEL")
-
- toolchain = make_configs["TOOLCHAIN"]
- board = make_configs["BOARD"]
- bd_ver = make_configs["BD_VER"]
- cur_core = make_configs[core_key]
-
- conf_key = board + "_" + bd_ver + "_" + cur_core
- tcf_name = cur_core + ".tcf"
- tcf_found = get_tcf(osp_root, board, bd_ver, cur_core)
- print "tcf_path:%s" % (tcf_found)
- build_conf_list = ["%s=%s" % (key, value) for (key, value) in make_configs.items()]
- build_conf = " ".join(build_conf_list)
-
- tcf_path = tcf_found[tcf_name]
- if tcf_path:
- makefile_found = get_makefile(app_path)
-
- if makefile_found:
- if is_embarc_makefile(makefile_found):
- isMakeProject = True
- # Record current folder
- cur_dir = os.getcwd()
- # Change to application makefile folder
- os.chdir(app_path)
- # Build application, clean it first
- print Fore.GREEN + "Build Application {} with Configuration {} {}".format(app_path, conf_key, config)
- print Style.RESET_ALL
- sys.stdout.flush()
- make_cmd = "make -j " + str(parallel) + " SILENT=1 " + build_conf
-
- cleancommand = make_cmd + " clean"
- os.system(cleancommand)
- buildcommand = make_cmd
- print Fore.GREEN + "{}".format(buildcommand)
- result["status"] = os.system(buildcommand)
- result["app"] = app_path
- result["conf"] = conf_key
- result["toolchain"] = toolchain
- result["toolchain_ver"] = toolchain_ver
- os.chdir(cur_dir)
- else:
- result["status"] = 1
- result["app"] = app_path
- result["conf"] = Fore.YELLOW + conf_key
- result["toolchain"] = toolchain
- result["toolchain_ver"] = toolchain_ver
- else:
- isMakeProject = False
- return isMakeProject, result
+def tail_call_optimized(g):
+ def func(*args, **kwargs):
+ f = sys._getframe()
+ if f.f_back and f.f_back.f_back and f.f_back.f_back.f_code == f.f_code:
+ raise TailRecurseException(args, kwargs)
+ else:
+ while 1:
+ try:
+ return g(*args, **kwargs)
+ except TailRecurseException as e:
+ args = e.args
+ kwargs = e.kwargs
+ func.__doc__ = g.__doc__
+ return func
-def build_project_configs(app_path, config):
+def parse_config(config):
make_configs = config
core_key = "CUR_CORE"
osp_root = None
@@ -263,22 +256,22 @@ def build_project_configs(app_path, config):
toolchain_ver = "2017.09"
bd_vers = dict()
cur_cores = dict()
- make_config = dict()
- results = []
toolchain = "gnu"
- build_count = 0
- status = True
expected_file = None
- expected_different = dict()
- expected_different[app_path] = []
parallel = ""
+ coverity = False
+ json_path = os.path.join(os.path.expanduser("~"), '.embarc_cli')
+ delete_dir_files(json_path, dir=True)
+ embarc_osp = osp.OSP()
core_key = "CORE" if "CORE" in make_configs else "CUR_CORE"
if "PARALLEL" in make_configs and make_configs["PARALLEL"] is not None:
parallel = make_configs["PARALLEL"]
if "EXPECTED" in make_configs and make_configs["EXPECTED"] is not None:
expected_file = make_configs["EXPECTED"]
-
+ if "COVERITY" in make_configs and make_configs["COVERITY"] is not None:
+ if make_configs["COVERITY"] == "true":
+ coverity = True
if "TOOLCHAIN_VER" in make_configs and make_configs["TOOLCHAIN_VER"] is not None:
toolchain_ver = make_configs["TOOLCHAIN_VER"]
@@ -288,55 +281,60 @@ def build_project_configs(app_path, config):
osp_root = make_configs["OSP_ROOT"]
if "BOARD" in make_configs and make_configs["BOARD"] is not None:
board_input = make_configs["BOARD"]
- boards = get_boards(osp_root, board_input)
+ support_boards = embarc_osp.supported_boards(osp_root)
+
+ boards = [board_input] if board_input in support_boards else support_boards
if "BD_VER" in make_configs and make_configs["BD_VER"] is not None:
bd_ver_input = make_configs["BD_VER"]
for board in boards:
- version = get_board_version(osp_root, board, bd_version=bd_ver_input)
+ version = embarc_osp.supported_bd_versions(osp_root, board, bd_version=bd_ver_input)
bd_vers[board] = version
if core_key in make_configs and make_configs[core_key] is not None:
cur_core_input = make_configs[core_key]
-
for (board, versions) in bd_vers.items():
cur_cores[board] = dict()
for version in versions:
- cores = get_tcfs(osp_root, board, version, cur_core=cur_core_input)
+ cores = embarc_osp.supported_cores(osp_root, board, version, cur_core=cur_core_input)
cur_cores[board][version] = cores
- for board in cur_cores:
- for bd_ver in cur_cores[board]:
- core_failed = 0
- core_num = len(cur_cores[board][bd_ver])
- may_compare = []
- for cur_core in cur_cores[board][bd_ver]:
- make_config["OSP_ROOT"] = osp_root
- make_config["BOARD"] = board
- make_config["BD_VER"] = bd_ver
- make_config[core_key] = cur_core
- make_config["TOOLCHAIN"] = toolchain
- make_config["TOOLCHAIN_VER"] = toolchain_ver
- make_config["PARALLEL"] = parallel
- isMakefileProject, result = build_makefile_project(app_path, make_config)
- if isMakefileProject is False:
- print "Application {} doesn't have makefile".format(app_path)
- else:
- build_count += 1
- if result["status"] != 0:
- status = False
- core_failed += 1
- results.append(result)
- may_compare.append(result)
-
- if core_failed == core_num:
- if expected_file is not None:
- expected_status = get_expected_result(expected_file, app_path, board, bd_ver)
- if not expected_status:
- print "This application compile failed, but the expected result is pass"
- expected_different[app_path].extend(may_compare)
- else:
- print "now not have expected file"
- expected_different[app_path].extend(may_compare)
- return status, results, build_count, expected_different
+ current_configs = dict()
+ current_configs["make_options"] = cur_cores
+ current_configs["core_key"] = core_key
+ current_configs["parallel"] = parallel
+ current_configs["osp_root"] = osp_root
+ current_configs["toolchain"] = {"name": toolchain, "version": toolchain_ver}
+ current_configs["EXPECTED"] = expected_file
+ current_configs["COVERITY"] = coverity
+ return current_configs
+
+
+def is_embarc_makefile(makefile_path):
+ with open(makefile_path) as f:
+ embarc_root = False
+ appl = False
+ lines = f.read().splitlines()
+ for line in lines:
+ if "EMBARC_ROOT" in line:
+ embarc_root = True
+ if "APPL" in line:
+ appl = True
+ if embarc_root and appl:
+ return True
+ return False
+
+
+def get_config(config):
+ make_configs = dict()
+ if type(config) == list:
+ pass
+ else:
+ config = config.split(" ")
+ for make_config in config:
+ [config_name, value] = make_config.split("=")
+ if value == "":
+ value = None
+ make_configs[config_name] = value
+ return make_configs
def get_expected_result(expected_file, app_path, board, bd_ver):
@@ -347,14 +345,8 @@ def get_expected_result(expected_file, app_path, board, bd_ver):
expected_result = json.load(f)
if app_path in expected_result:
if board in expected_result[app_path]:
- if bd_ver in expected_result[app_path][board]:
- result = False
- else:
+ if bd_ver not in expected_result[app_path][board]:
result = True
- else:
- result = False
- else:
- result = False
elif filesuffix == ".ini":
conf = ConfigParser()
@@ -364,14 +356,8 @@ def get_expected_result(expected_file, app_path, board, bd_ver):
options = conf.options(app_path)
if board in options:
items = conf.get(app_path, board)
- if bd_ver in items:
- result = False
- else:
+ if bd_ver not in items:
result = True
- else:
- result = False
- else:
- result = False
return result
@@ -380,26 +366,26 @@ def send_pull_request_comment(columns, results):
pr_number = os.environ.get("TRAVIS_PULL_REQUEST")
if all([job, pr_number]):
comment_job = "## " + job + "\n"
- if len(results)>0:
+ if len(results) > 0:
head = "|".join(columns) + "\n"
- table_format = "|".join(["---"]*len(columns)) + "\n"
- table_head =head +table_format
+ table_format = "|".join(["---"]*len(columns)) + "\n"
+ table_head = head + table_format
comments = ""
comment = ""
for result in results:
for k in result:
- comment += (k.replace(Fore.RED, "")).replace("\n", "
") +" |"
+ comment += (k.replace(Fore.RED, "")).replace("\n", "
") + " |"
comment = comment.rstrip("|") + "\n"
comments += comment
comment_on_pull_request(comment_job + table_head + comments)
+
else:
print("WARNING:Only send pull request comment in travis ci!")
-
pass
def show_results(results, expected=None):
- columns = ["TOOLCHAIN_VER", 'TOOLCHAIN', 'APP', 'CONF', 'PASS']
+ columns = ['TOOLCHAIN', "TOOLCHAIN_VER", 'APP', 'CONF', 'PASS']
failed_pt = PrettyTable(columns)
failed_results = []
success_results = []
@@ -420,7 +406,6 @@ def show_results(results, expected=None):
else:
result["PASS"] = "YES"
success_results.append([v for (k, v) in result.items()])
-
if expected is not None:
expected_results = failed_results
send_pull_request_comment(columns, expected_results)
@@ -428,49 +413,43 @@ def show_results(results, expected=None):
if len(result) > 0:
expected_pt.add_row(result)
if len(expected_results) > 0:
- print "these applications failed with some bd_ver: "
- print expected_pt
+ print("these applications failed with some bd_ver: ")
+ print(expected_pt)
sys.stdout.flush()
return
- else:
+ else:
for result in success_results:
if len(result) > 0:
success_pt.add_row(result)
- print Fore.GREEN + "Successfull results"
- print success_pt
-
-
- print Style.RESET_ALL
+ print(Fore.GREEN + "Successfull results")
+ print(success_pt)
+ print(Style.RESET_ALL)
sys.stdout.flush()
-
for result in failed_results:
if len(result) > 0:
list_key = range(len(result))
for i in list_key:
-
result[i] = Fore.RED + result[i]
-
failed_pt.add_row(result)
- print Fore.RED + "Failed result:"
- print failed_pt
-
- print Style.RESET_ALL
+ print(Fore.RED + "Failed result:")
+ print(failed_pt)
+ print(Style.RESET_ALL)
sys.stdout.flush()
@tail_call_optimized
def build_result_combine(results=None, formal_result=None):
+
first_result = results[0]
t = first_result.pop("conf") # first_result = results[0]
other_results = []
if formal_result is None:
formal_result = []
-
for result in results[1:]:
conf = result.pop("conf")
- if cmp(first_result, result) == 0:
+ if operator.eq(first_result, result):
t = t + "\n" + conf
else:
result["conf"] = conf
@@ -496,6 +475,7 @@ def get_apps(path):
def get_exampes_from_input(paths):
+
results = []
paths_list = paths.split(",")
for path in paths_list:
@@ -505,18 +485,6 @@ def get_exampes_from_input(paths):
return results
-def application_all_failed(results):
- count = len(results)
- i = 0
- for result in results:
- if result["status"] != 0:
- i += 1
- if i == count:
- return 1
- else:
- return 0
-
-
def build_result_combine_tail(results):
results_list = []
for (app_path, result) in results.items():
@@ -525,15 +493,8 @@ def build_result_combine_tail(results):
return results_list
-def build_makefiles_project(config):
- apps_results = {}
- apps_status = []
- count = 0
- app_count = 0
- results_list = []
- applications_failed = []
- diff_expected_differents = dict()
- expected_differents_list = []
+def get_applications(config):
+ app_paths = None
if "EXAMPLES" in config and config["EXAMPLES"]:
examples_path = config.pop("EXAMPLES")
app_paths_list = get_exampes_from_input(examples_path)
@@ -541,34 +502,107 @@ def build_makefiles_project(config):
app_paths = dict(zip(key_list, app_paths_list))
else:
app_paths = example
+ return app_paths
- for (app, app_path) in app_paths.items():
-
- status, results, build_count, expected_different = build_project_configs(app_path, config)
- application_failed = application_all_failed(results)
- if application_failed == 1:
- print Back.RED + "{} failed with all configurations".format(app_path)
- print Style.RESET_ALL
- applications_failed.append(application_failed)
- apps_results[app_path] = results
- apps_status.append(status)
- count += build_count
- app_count += 1
- if app_path in expected_different and len(expected_different[app_path]) > 0:
- diff_expected_differents[app_path] = copy.deepcopy(expected_different[app_path])
-
- print "There are {} projects, and they are compiled for {} times".format(app_count, count)
- results_list = copy.deepcopy(build_result_combine_tail(apps_results))
- show_results(results_list)
- expected_differents_list = build_result_combine_tail(diff_expected_differents)
- show_results(expected_differents_list, expected=True)
- return applications_failed, diff_expected_differents
+def startBuild(app, config, builder):
+
+ for opt in build.BUILD_OPTION_NAMES:
+ if opt in config:
+ builder.buildopts[opt] = config[opt]
+ CurrentBuildConfigString = ["%s=%s" % (key, value) for (key, value) in builder.buildopts.items()]
+
+ build_conf = str()
+ build_status = None
+ builder.make_options = " ".join(CurrentBuildConfigString)
+
+ # builder.build_target(app, target=str("clean"), parallel=config["PARALLEL"])
+ if os.environ.get("COVERITY", None) == "true":
+ build_status = builder.build_target(app, target=str("all"), parallel=config["PARALLEL"], coverity=True, silent=True)
+ else:
+ build_status = builder.get_build_size(app, parallel=config["PARALLEL"], silent=True)
+
+ board = builder.buildopts.get("BOARD")
+ bd_ver = builder.buildopts.get("BD_VER")
+ core = builder.buildopts.get("CUR_CORE")
+ build_conf = board + "_" + bd_ver + "_" + core
+
+ build_status["commit_sha"] = os.environ.get("CI_COMMIT_SHA") or os.environ.get("TRAVIS_COMMIT")
+ build_status["JOB"] = os.environ.get("CI_JOB_NAME") or os.environ.get("NAME")
+ build_status["status"] = 0 if build_status["result"] else 1
+ build_status["conf"] = build_conf
+ return build_status
+
+
+def BuildApp(app, config):
+
+ BuildOptions = config["make_options"]
+ core_key = config["core_key"]
+ toolchain = config["toolchain"]
+ parallel = config["parallel"]
+ osp_root = config["osp_root"]
+ app_build_status = dict()
+ app_build_results = list()
+ CurrentBuildConfig = dict()
+ expected_different = dict()
+ expected_different[app] = []
+ builder = build.embARC_Builder(osproot=osp_root)
+
+ if os.environ.get("COVERITY", None) == "true":
+ build_status = builder.configCoverity(toolchain["name"])
+ if not build_status["result"]:
+ print("Config Coverity failed")
+ for board in BuildOptions:
+ for bd_ver in BuildOptions[board]:
+ core_num = len(BuildOptions[board][bd_ver])
+ failed_count = 0
+ may_compare = []
+ for cur_core in BuildOptions[board][bd_ver]:
+ # CurrentBuildConfig["OSP_ROOT"] = osp_root
+ CurrentBuildConfig["BOARD"] = board
+ CurrentBuildConfig["BD_VER"] = bd_ver
+ CurrentBuildConfig[core_key] = cur_core
+ CurrentBuildConfig["TOOLCHAIN"] = toolchain["name"]
+ CurrentBuildConfig["TOOLCHAIN_VER"] = toolchain["version"]
+ CurrentBuildConfig["PARALLEL"] = None if parallel == "" else parallel
+
+ build_status = startBuild(app, CurrentBuildConfig, builder)
+ if not app_build_status.get(app, None):
+ app_build_status[app] = [build_status]
+
+ else:
+ app_build_status[app].append(build_status)
+ if build_status["status"] != 0:
+ failed_count += 1
+ current_result = dict()
+ current_result = collections.OrderedDict()
+ current_result["toolchain"] = toolchain["name"]
+ current_result["toolchain_ver"] = toolchain["version"]
+ current_result["app"] = app
+ current_result["conf"] = build_status["conf"]
+ current_result["status"] = build_status["status"]
+ app_build_results.append(current_result)
+ may_compare.append(current_result)
+
+ if failed_count == core_num:
+ expected_file = config.get("EXPECTED", None)
+ if expected_file is not None:
+ expected_status = get_expected_result(expected_file, app, board, bd_ver)
+ if not expected_status:
+ print("This application compile failed, but the expected result is pass")
+ expected_different[app].extend(may_compare)
+
+ else:
+ print("now not have expected file")
+ expected_different[app].extend(may_compare)
+
+ return app_build_results, expected_different, app_build_status
def comment_on_pull_request(comment):
+
pr_number = os.environ.get("TRAVIS_PULL_REQUEST")
- slug = os.environ.get("TRAVIS_REPO_SLUG")
+ slug = os.environ.get("TRAVIS_REPO_SLUG")
token = os.environ.get("GH_TOKEN")
request_config = [pr_number, slug, token, comment]
for i in range(len(request_config)):
@@ -589,8 +623,8 @@ def get_options_parser():
boardlist = ["emsk", "nsim", "axs", "hsdk"]
parser = argparse.ArgumentParser()
parser.add_argument("--osp_root", dest="osp_root", default=".", help=("the path of embarc_osp"), metavar="OSP_ROOT")
- parser.add_argument("--toolchain", dest="toolchain", default=None, help=("build using the given TOOLCHAIN (%s)" %', '.join(toolchainlist)), metavar="TOOLCHAIN")
- parser.add_argument("--board", dest="board", default=None, help=("build using the given BOARD (%s)" %', '.join(boardlist)), metavar="BOARD")
+ parser.add_argument("--toolchain", dest="toolchain", default=None, help=("build using the given TOOLCHAIN (%s)" % ', '.join(toolchainlist)), metavar="TOOLCHAIN")
+ parser.add_argument("--board", dest="board", default=None, help=("build using the given BOARD (%s)" % ', '.join(boardlist)), metavar="BOARD")
parser.add_argument("--bd_ver", dest="bd_ver", default=None, help=("build using the given BOARD VERSION"), metavar="BOARD VERSION")
parser.add_argument("--core", dest="cur_core", default=None, help=("build using the given core"), metavar="CUR_CORE")
parser.add_argument("--toolchain_ver", dest="toolchain_ver", default=None, help=("build using the given toolchian verion"), metavar="TOOLCHAIN_VER")
@@ -619,23 +653,55 @@ def get_options_parser():
return configs
+def main(config):
+
+ current_input_config = copy.deepcopy(config)
+ examples = get_applications(config)
+ BuildConfigs = parse_config(current_input_config)
+
+ if os.environ.get("CI_JOB_NAME") == "deploy_prod" or os.environ.get("STAGE_NAME") == "Deploy":
+ print("Build finish and generate excel")
+ result_excel_artifacts(BuildConfigs.get("OSP_ROOT", "."))
+ sys.exit(0)
+
+ apps_expected_different = dict()
+ all_results = dict()
+ apps_build_status = dict()
+ build_count = 0
+ for (app, app_path) in examples.items():
+ app_build_results, expected_different, app_build_status = BuildApp(app_path, BuildConfigs)
+ if all([i["status"] for i in app_build_results]):
+ print(Back.RED + "{} failed with all configurations".format(app_path))
+ print(Style.RESET_ALL)
+ build_count = build_count + len(app_build_results)
+ all_results[app_path] = app_build_results
+ apps_build_status.update(app_build_status)
+
+ if expected_different.get(app_path, False) and len(expected_different[app_path]) > 0:
+ apps_expected_different[app_path] = copy.deepcopy(expected_different[app_path])
+ print("There are {} projects, and they are compiled for {} times".format(len(examples), build_count))
+ all_results_list = copy.deepcopy(build_result_combine_tail(all_results))
+ show_results(all_results_list)
+ expected_differents_list = build_result_combine_tail(apps_expected_different)
+ show_results(expected_differents_list, expected=True)
+ print("Generate JSON for every job")
+ result_json_artifacts(BuildConfigs["osp_root"], apps_build_status)
+
+ if not len(apps_expected_different) > 0:
+ print("All the applications build as expected")
+ else:
+ print("these applications failed with some configuration: ")
+ print(apps_expected_different.keys())
+ comment = "applications failed with some configuration: \n" + "\n".join(apps_expected_different.keys())
+ comment_on_pull_request(comment)
+ sys.exit(1)
+
+
if __name__ == '__main__':
cwd_path = os.getcwd()
osp_path = os.path.dirname(cwd_path)
make_config = get_config(sys.argv[1:])
- sys.stdout.flush()
- os.chdir(osp_path)
- applications_failed, expected_differents = build_makefiles_project(make_config)
- os.chdir(cwd_path)
- if "embarc_applications" in os.listdir(os.getcwd()):
- os.chdir(os.path.dirname(cwd_path))
-
- if not len(expected_differents) > 0:
- print "All the applications build as expected"
- else:
- print "these applications failed with some configuration: "
- print expected_differents.keys()
- comment = "applications failed with some configuration: \n" + "\n".join(expected_differents.keys())
- comment_on_pull_request(comment)
- sys.exit(1)
+ with cd(osp_path):
+ main(make_config)
+ print("The end")
diff --git a/.ci/expected.ini b/.ci/expected.ini
index 86d73eee3..9a36a53c0 100644
--- a/.ci/expected.ini
+++ b/.ci/expected.ini
@@ -1,6 +1,3 @@
-[example/baremetal/dma_spiflash]
-emsk=23
-
[example/baremetal/arc_feature/udma]
axs=
@@ -8,35 +5,58 @@ axs=
nsim=
axs=
+[example/baremetal/dma_spiflash]
+emsk=23
+
+
+[example/baremetal/imu_mpu9250]
+nsim=
+
+[example/baremetal/ble_hm1x]
+nsim=
+
+[example/baremetal/graphic_u8glib]
+nsim=
+
+[example/baremetal/ble_rn4020]
+nsim=
+
+[example/baremetal/openthread/ncp]
+nsim=
+emsdp=
+iotdk=
+
[example/baremetal/secureshield/secret_secure_sid]
emsk=23
hsdk=
axs=
+emsdp=
[example/baremetal/secureshield/secret_secure]
emsk=23
hsdk=
axs=
+emsdp=
[example/baremetal/secureshield/secret_normal]
emsk=23
hsdk=
axs=
+emsdp=
+
[example/baremetal/secureshield/test_case]
emsk=23
hsdk=
axs=
+emsdp=
[example/baremetal/axs103]
emsk=
hsdk=
nsim=
-
-[example/freertos/kernel_secure]
-emsk=23
-hsdk=
-axs=
+emsdp=
+iotdk=
[example/baremetal/test/iotdk/adc_test]
emsk=
@@ -52,9 +72,58 @@ axs=
nsim=
iotdk=10
-[example/baremetal/test/iotdk/spiflash_test]
-emsk=
+[example/baremetal/bootloader]
+hsdk=
+axs=
+nsim=
+emsdp=
+
+[example/baremetal/openthread/cli]
+iotdk=
+nsim=
+emsdp=
+
+[example/freertos/kernel_secure]
+emsk=23
hsdk=
axs=
+emsdp=
+
+[example/freertos/sec/mbedtls/ssl/client2]
+iotdk=
+nsim=
+hsdk=
+
+[example/freertos/sec/mbedtls/ssl/server2]
+iotdk=
+nsim=
+hsdk=
+
+[example/freertos/sec/mbedtls/dtls/server]
+iotdk=
+nsim=
+hsdk=
+
+[example/freertos/sec/mbedtls/dtls/client]
+iotdk=
nsim=
-iotdk=10
\ No newline at end of file
+hsdk=
+
+[example/freertos/net/httpserver]
+nsim=
+
+[example/freertos/esp8266_wifi]
+nsim=
+
+[example/freertos/iot/coap/coap_server]
+nsim=
+
+[example/freertos/net/ntshell]
+nsim=
+
+[example/freertos/iot/lwm2m/lwm2m_client]
+nsim=
+
+[example/freertos/iot/lwm2m/lwm2m_server]
+nsim=
+
diff --git a/.ci/toolchain.py b/.ci/toolchain.py
index 707cc4af7..3c5bfc0f7 100644
--- a/.ci/toolchain.py
+++ b/.ci/toolchain.py
@@ -1,115 +1,55 @@
#! /usr/bin/env python
-import zipfile
-import tarfile
-import urllib
+
import os
-import sys
+import re
import shutil
-from colorama import Fore, Style
import argparse
+from embarc_tools.toolchain import gnu
-def download_file(url, path):
- try:
- urllib.urlretrieve(url, path)
- return 0
- except Exception as e:
- print e
- print "This file from %s can't be download" % (url)
- sys.stdout.flush()
- return 1
-
-
-def download_gnu(version="2017.09", path=None):
- baseurl = "https://github.com/foss-for-synopsys-dwc-arc-processors/toolchain/releases/download/"
- url = baseurl + "arc-" + version + "-release/arc_gnu_" + version + "_prebuilt_elf32_le_linux_install.tar.gz"
- gnu_tgz = "arc_gnu_" + version + "_prebuilt_elf32_le_linux_install.tar.gz"
- if path is not None:
- gnu_tgz_path = os.path.join(path, "arc_gnu_" + version + "_prebuilt_elf32_le_linux_install.tar.gz")
- else:
- path = os.getcwd()
- gnu_tgz_path = os.path.join(path, "arc_gnu_" + version + "_prebuilt_elf32_le_linux_install.tar.gz")
- if not os.path.exists(path):
- os.makedirs(path)
- if gnu_tgz in os.listdir(path):
- print Fore.BLUE + "toochain cache"
- print os.listdir(path)
- print Style.RESET_ALL
- sys.stdout.flush()
- else:
- result = download_file(url, gnu_tgz_path)
- if result:
- gnu_tgz_path = None
- return gnu_tgz_path
-
-
-def unzip(file, path):
- file_name = None
+def is_number(s):
try:
- pack = zipfile.ZipFile(file, "r")
- files = pack.namelist()
- file_name = files[0]
- pack.extractall(path)
- pack.close()
- return file_name
- except Exception:
- sys.exit(1)
+ float(s)
+ return True
+ except ValueError:
+ pass
-
-def untar(file, path):
- file_name = None
try:
- pack = tarfile.open(file, "r:gz")
- files = pack.getnames()
- file_name = files[0]
- for file in files:
- pack.extract(file, path)
- pack.close()
- return file_name
- except Exception as e:
- print e
-
-
-def extract_file(file, path):
- extract_file_name = None
- extract_file_path = None
- filename, filesuffix = os.path.splitext(file)
- if filesuffix == ".gz":
- extract_file_name = untar(file, path)
- elif filesuffix == ".zip":
- extract_file_name = unzip(file, path)
- else:
- print "This file {} can't be extracted".format(file)
- if extract_file_name is not None:
- extract_file_path = os.path.join(path, extract_file_name)
- return extract_file_path
-
-
-def store_gnu_toolchain(version, path=None):
- gnu_tgz_path = download_gnu(version, path)
+ import unicodedata
+ unicodedata.numeric(s)
+ return True
+ except (TypeError, ValueError):
+ pass
+
+ return False
+
+def store_gnu_toolchain(version, path):
+ gnu_version = version
+ if not is_number(version):
+ version = None
+ gnu_toolchain = gnu.Gnu()
+ gnu_tgz_path = gnu_toolchain.download(version, path)
gnu_root_path = None
gnu_file_path = None
if gnu_tgz_path is None:
print "Can't download gnu {} ".format(version)
- if version not in os.listdir(path):
- try:
- gnu_file_path = extract_file(gnu_tgz_path, path)
- except Exception as e:
- print e
- if gnu_file_path is not None:
- gnu_root_path = os.path.join(path, version)
- shutil.move(gnu_file_path, gnu_root_path)
+ new_path = os.path.join(path, gnu_version)
+ if gnu_version not in os.listdir(path):
+ gnu_file_path = gnu_toolchain.extract_file(gnu_tgz_path, path)
+ if gnu_file_path:
+ shutil.move(gnu_file_path, new_path)
def get_options_parser():
configs = dict()
parser = argparse.ArgumentParser()
- parser.add_argument("-v", "--gnu", dest="gnu", default="2017.09", help=("the version of gnu"), metavar="GNU_VERSION")
+ parser.add_argument("-v", "--gnu", dest="gnu", help=("the version of gnu"), metavar="GNU_VERSION")
parser.add_argument("-c", "--cache", dest="cache", default=".cache/toolchain", help=("the cache path"), metavar="TOOLCHAIN_CACHE_FOLDER")
options = parser.parse_args()
if options.gnu:
configs["gnu"] = options.gnu
+
if options.cache:
configs["cache"] = options.cache
diff --git a/.travis.yml b/.travis.yml
index 7398f9ef4..dd523e0e4 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -22,6 +22,9 @@ env:
--data @- << DATA\n{
"body": "$COMMENT"
}\nDATA'
+ - TOOLCHAIN_VER="latest"
+ - OSP_ROOT="."
+ - EXAMPLES="example/baremetal,example/freertos"
cache:
pip: true
@@ -56,42 +59,34 @@ matrix:
os: linux
compiler: gcc
- - env: NAME="baremetal-emsk-gnu-201709" TOOLCHAIN="gnu" BOARD="emsk" OSP_ROOT="." TOOLCHAIN_VER="2017.09" EXAMPLES="example/baremetal" EXPECTED=".ci/expected.ini"
+ - env: NAME="emsk-11-gnu-latest" TOOLCHAIN="gnu" BOARD="emsk" BD_VER="11" EXPECTED=".ci/expected.ini" PARALLEL=8
os: linux
compiler: gcc
- - env: NAME="baremetal-emsk-gnu-201803" TOOLCHAIN="gnu" BOARD="emsk" OSP_ROOT="." TOOLCHAIN_VER="2018.03" EXAMPLES="example/baremetal" EXPECTED=".ci/expected.ini"
+ - env: NAME="emsk-22-gnu-latest" TOOLCHAIN="gnu" BOARD="emsk" BD_VER="22" EXPECTED=".ci/expected.ini" PARALLEL=8
os: linux
compiler: gcc
- - env: NAME="freertos-emsk_11-gnu-201709" TOOLCHAIN="gnu" BOARD="emsk" BD_VER="11" OSP_ROOT="." TOOLCHAIN_VER="2017.09" EXAMPLES="example/freertos" EXPECTED=".ci/expected.ini"
+ - env: NAME="baremetal-emsk-23-gnu-latest" TOOLCHAIN="gnu" BOARD="emsk" BD_VER="23" EXPECTED=".ci/expected.ini" PARALLEL=8 EXAMPLES="example/baremetal"
os: linux
compiler: gcc
- - env: NAME="freertos-emsk_11-gnu-201803" TOOLCHAIN="gnu" BOARD="emsk" BD_VER="11" OSP_ROOT="." TOOLCHAIN_VER="2018.03" EXAMPLES="example/freertos" EXPECTED=".ci/expected.ini"
+ - env: NAME="freertos-emsk-23-gnu-latest" TOOLCHAIN="gnu" BOARD="emsk" BD_VER="23" EXPECTED=".ci/expected.ini" PARALLEL=8 EXAMPLES="example/freertos"
os: linux
compiler: gcc
- - env: NAME="freertos-emsk_22-gnu-201709" TOOLCHAIN="gnu" BOARD="emsk" BD_VER="22" OSP_ROOT="." TOOLCHAIN_VER="2017.09" EXAMPLES="example/freertos" EXPECTED=".ci/expected.ini"
+ - env: NAME="hsdk-gnu-latest" TOOLCHAIN="gnu" BOARD="hsdk" EXPECTED=".ci/expected.ini"
os: linux
compiler: gcc
- - env: NAME="freertos-emsk_22-gnu-201803" TOOLCHAIN="gnu" BOARD="emsk" BD_VER="22" OSP_ROOT="." TOOLCHAIN_VER="2018.03" EXAMPLES="example/freertos" EXPECTED=".ci/expected.ini"
+ - env: NAME="iotdk-gnu-latest" TOOLCHAIN="gnu" BOARD="iotdk" EXPECTED=".ci/expected.ini"
os: linux
compiler: gcc
- - env: NAME="freertos-emsk_23-gnu-201709" TOOLCHAIN="gnu" BOARD="emsk" BD_VER="23" OSP_ROOT="." TOOLCHAIN_VER="2017.09" EXAMPLES="example/freertos" EXPECTED=".ci/expected.ini" PARALLEL=8
+ - env: NAME="nsim-gnu-latest" TOOLCHAIN="gnu" BOARD="nsim" EXPECTED=".ci/expected.ini"
os: linux
compiler: gcc
- - env: NAME="freertos-emsk_23-gnu-201803" TOOLCHAIN="gnu" BOARD="emsk" BD_VER="23" OSP_ROOT="." TOOLCHAIN_VER="2018.03" EXAMPLES="example/freertos" EXPECTED=".ci/expected.ini" PARALLEL=8
- os: linux
- compiler: gcc
-
- - env: NAME="arc_feature-gnu-201709" TOOLCHAIN="gnu" OSP_ROOT="." TOOLCHAIN_VER="2017.09" EXAMPLES="example/baremetal/arc_feature" EXPECTED=".ci/expected.ini"
- os: linux
- compiler: gcc
-
- - env: NAME="arc_feature-gnu-201803" TOOLCHAIN="gnu" OSP_ROOT="." TOOLCHAIN_VER="2018.03" EXAMPLES="example/baremetal/arc_feature" EXPECTED=".ci/expected.ini"
+ - env: NAME="emsdp-gnu-latest" TOOLCHAIN="gnu" BOARD="emsdp" EXPECTED=".ci/expected.ini"
os: linux
compiler: gcc
diff --git a/board/iotdk/configs/core_configs.mk b/board/iotdk/configs/core_configs.mk
index adac1594b..eacf3efa5 100644
--- a/board/iotdk/configs/core_configs.mk
+++ b/board/iotdk/configs/core_configs.mk
@@ -2,6 +2,10 @@
CORE_TCF_DIR = $(BOARD_CORE_DIR)/tcf
CORE_CONFIG_MK = $(BOARD_CORE_DIR)/core_config.mk
+## Current Supported Core Configurations
+CORE_TCF_FILES = $(wildcard $(CORE_TCF_DIR)/*.tcf)
+SUPPORTED_CORES := $(basename $(notdir $(CORE_TCF_FILES)))
+
#### core_config.mk existed in sub version folder of the board
COMMON_COMPILE_PREREQUISITES += $(CORE_CONFIG_MK)
include $(CORE_CONFIG_MK)