diff --git a/tools/build_api.py b/tools/build_api.py index fcbbad3c62..1c9b0a2c45 100644 --- a/tools/build_api.py +++ b/tools/build_api.py @@ -207,9 +207,9 @@ def build_project(src_path, build_path, target, toolchain_name, resources.objects.extend(objects) # Link Program - res, needed_update = toolchain.link_program(resources, build_path, name) + res, _ = toolchain.link_program(resources, build_path, name) - if report != None and needed_update: + if report != None: end = time() cur_result["elapsed_time"] = end - start cur_result["output"] = toolchain.get_output() @@ -234,8 +234,6 @@ def build_project(src_path, build_path, target, toolchain_name, if toolchain_output: cur_result["output"] += toolchain_output - cur_result["output"] += str(e) - add_result_to_report(report, cur_result) # Let Exception propagate @@ -360,11 +358,9 @@ def build_library(src_paths, build_path, target, toolchain_name, resources.objects.extend(objects) if archive: - needed_update = toolchain.build_library(resources.objects, build_path, name) - else: - needed_update = True + toolchain.build_library(objects, build_path, name) - if report != None and needed_update: + if report != None: end = time() cur_result["elapsed_time"] = end - start cur_result["output"] = toolchain.get_output() @@ -511,12 +507,12 @@ def build_mbed_libs(target, toolchain_name, options=None, verbose=False, clean=F for o in separate_objects: objects.remove(o) - needed_update = toolchain.build_library(objects, BUILD_TOOLCHAIN, "mbed") + toolchain.build_library(objects, BUILD_TOOLCHAIN, "mbed") for o in separate_objects: toolchain.copy_files(o, BUILD_TOOLCHAIN) - if report != None and needed_update: + if report != None: end = time() cur_result["elapsed_time"] = end - start cur_result["output"] = toolchain.get_output() diff --git a/tools/test.py b/tools/test.py index 1956cfec56..a9c7775f94 100644 --- a/tools/test.py +++ b/tools/test.py @@ -66,6 +66,9 @@ if __name__ == '__main__': parser.add_option("-f", "--format", type="choice", dest="format", choices=format_choices, default=format_default_choice, help=format_help) + parser.add_option("--continue-on-build-fail", action="store_true", dest="continue_on_build_fail", + default=None, help="Continue trying to build all tests if a build failure occurs") + parser.add_option("-n", "--names", dest="names", default=None, help="Limit the tests to a comma separated list of names") @@ -157,7 +160,8 @@ if __name__ == '__main__': properties=build_properties, macros=options.macros, verbose=options.verbose, - jobs=options.jobs) + jobs=options.jobs, + continue_on_build_fail=options.continue_on_build_fail) # If a path to a test spec is provided, write it to a file if options.test_spec: @@ -181,7 +185,10 @@ if __name__ == '__main__': report_exporter = ReportExporter(ResultExporterType.JUNIT, package="build") report_exporter.report_to_file(build_report, options.build_report_junit, test_suite_properties=build_properties) - if library_build_success and test_build_success: + print_report_exporter = ReportExporter(ResultExporterType.PRINT, package="build") + status = print_report_exporter.report(build_report) + + if status: sys.exit(0) else: sys.exit(1) diff --git a/tools/test_api.py b/tools/test_api.py index b7d88c8492..9cdedf9dc9 100644 --- a/tools/test_api.py +++ b/tools/test_api.py @@ -2042,7 +2042,8 @@ def print_tests(tests, format="list"): def build_tests(tests, base_source_paths, build_path, target, toolchain_name, options=None, clean=False, notify=None, verbose=False, jobs=1, - macros=None, silent=False, report=None, properties=None): + macros=None, silent=False, report=None, properties=None, + continue_on_build_fail=False): """Given the data structure from 'find_tests' and the typical build parameters, build all the tests @@ -2077,7 +2078,11 @@ def build_tests(tests, base_source_paths, build_path, target, toolchain_name, except Exception, e: result = False - continue + + if continue_on_build_fail: + continue + else: + break # If a clean build was carried out last time, disable it for the next build. # Otherwise the previously built test will be deleted. diff --git a/tools/test_exporters.py b/tools/test_exporters.py index a65fd29fb1..857a6bfcd3 100644 --- a/tools/test_exporters.py +++ b/tools/test_exporters.py @@ -20,7 +20,6 @@ Author: Przemyslaw Wirkus from tools.utils import construct_enum, mkdir import os - ResultExporterType = construct_enum(HTML='Html_Exporter', JUNIT='JUnit_Exporter', JUNIT_OPER='JUnit_Exporter_Interoperability', @@ -73,7 +72,8 @@ class ReportExporter(): self.result_exporter_type = result_exporter_type self.package = package - def report(self, test_summary_ext, test_suite_properties=None): + def report(self, test_summary_ext, test_suite_properties=None, + print_log_for_failures=True): """ Invokes report depending on exporter_type set in constructor """ if self.result_exporter_type == ResultExporterType.HTML: @@ -87,7 +87,7 @@ class ReportExporter(): return self.exporter_junit_ioper(test_summary_ext, test_suite_properties) elif self.result_exporter_type == ResultExporterType.PRINT: # JUNIT exporter for interoperability test - return self.exporter_print(test_summary_ext) + return self.exporter_print(test_summary_ext, print_log_for_failures=print_log_for_failures) return None def report_to_file(self, test_summary_ext, file_name, test_suite_properties=None): @@ -297,11 +297,15 @@ class ReportExporter(): test_suites.append(ts) return TestSuite.to_xml_string(test_suites) - def exporter_print_helper(self, array): + def exporter_print_helper(self, array, print_log=False): for item in array: print " * %s::%s::%s" % (item["target_name"], item["toolchain_name"], item["id"]) + if print_log: + log_lines = item["output"].split("\n") + for log_line in log_lines: + print " %s" % log_line - def exporter_print(self, test_result_ext): + def exporter_print(self, test_result_ext, print_log_for_failures=False): """ Export test results in print format. """ failures = [] @@ -340,7 +344,7 @@ class ReportExporter(): if failures: print "\n\nBuild failures:" - self.exporter_print_helper(failures) + self.exporter_print_helper(failures, print_log=print_log_for_failures) return False else: return True diff --git a/tools/toolchains/gcc.py b/tools/toolchains/gcc.py index 0a0b91f410..e1313ef474 100644 --- a/tools/toolchains/gcc.py +++ b/tools/toolchains/gcc.py @@ -28,7 +28,7 @@ class GCC(mbedToolchain): STD_LIB_NAME = "lib%s.a" CIRCULAR_DEPENDENCIES = True - DIAGNOSTIC_PATTERN = re.compile('((?P\d+):)(\d+:)? (?Pwarning|error): (?P.+)') + DIAGNOSTIC_PATTERN = re.compile('((?P[^:]+):(?P\d+):)(\d+:)? (?Pwarning|error): (?P.+)') def __init__(self, target, options=None, notify=None, macros=None, silent=False, tool_path="", extra_verbose=False): mbedToolchain.__init__(self, target, options, notify, macros, silent, extra_verbose=extra_verbose) @@ -138,27 +138,16 @@ class GCC(mbedToolchain): ) continue - # Each line should start with the file information: "filepath: ..." - # i should point past the file path ^ - # avoid the first column in Windows (C:\) - i = line.find(':', 2) - if i == -1: continue - - if state == WHERE: - file = line[:i] - message = line[i+1:].strip() + ' ' - state = WHAT - - elif state == WHAT: - match = GCC.DIAGNOSTIC_PATTERN.match(line[i+1:]) - if match is None: - state = WHERE - continue + match = GCC.DIAGNOSTIC_PATTERN.match(line) + if match is not None: self.cc_info( - match.group('severity'), - file, match.group('line'), - message + match.group('message') + match.group('severity').lower(), + match.group('file'), + match.group('line'), + match.group('message'), + target_name=self.target.name, + toolchain_name=self.name ) def get_dep_option(self, object):