Clone of official tools
test/export/build_test.py@25:aef6536015e3, 2016-08-01 (annotated)
- Committer:
- screamer
- Date:
- Mon Aug 01 09:10:34 2016 +0100
- Revision:
- 25:aef6536015e3
- Child:
- 31:8ea194f6145b
Add missing files
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
screamer | 25:aef6536015e3 | 1 | #!/usr/bin/env python |
screamer | 25:aef6536015e3 | 2 | """ |
screamer | 25:aef6536015e3 | 3 | mbed SDK |
screamer | 25:aef6536015e3 | 4 | Copyright (c) 2011-2013 ARM Limited |
screamer | 25:aef6536015e3 | 5 | |
screamer | 25:aef6536015e3 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); |
screamer | 25:aef6536015e3 | 7 | you may not use this file except in compliance with the License. |
screamer | 25:aef6536015e3 | 8 | You may obtain a copy of the License at |
screamer | 25:aef6536015e3 | 9 | |
screamer | 25:aef6536015e3 | 10 | http://www.apache.org/licenses/LICENSE-2.0 |
screamer | 25:aef6536015e3 | 11 | |
screamer | 25:aef6536015e3 | 12 | Unless required by applicable law or agreed to in writing, software |
screamer | 25:aef6536015e3 | 13 | distributed under the License is distributed on an "AS IS" BASIS, |
screamer | 25:aef6536015e3 | 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
screamer | 25:aef6536015e3 | 15 | See the License for the specific language governing permissions and |
screamer | 25:aef6536015e3 | 16 | limitations under the License. |
screamer | 25:aef6536015e3 | 17 | """ |
screamer | 25:aef6536015e3 | 18 | |
screamer | 25:aef6536015e3 | 19 | |
screamer | 25:aef6536015e3 | 20 | import sys |
screamer | 25:aef6536015e3 | 21 | import argparse |
screamer | 25:aef6536015e3 | 22 | import os |
screamer | 25:aef6536015e3 | 23 | import shutil |
screamer | 25:aef6536015e3 | 24 | from os.path import join, abspath, dirname, exists, basename |
screamer | 25:aef6536015e3 | 25 | r=dirname(__file__) |
screamer | 25:aef6536015e3 | 26 | ROOT = abspath(join(r, "..","..","..")) |
screamer | 25:aef6536015e3 | 27 | sys.path.insert(0, ROOT) |
screamer | 25:aef6536015e3 | 28 | |
screamer | 25:aef6536015e3 | 29 | from tools.export import EXPORTERS |
screamer | 25:aef6536015e3 | 30 | from tools.targets import TARGET_NAMES, TARGET_MAP |
screamer | 25:aef6536015e3 | 31 | from tools.project_api import setup_project, perform_export, print_results, get_test_from_name, get_lib_symbols |
screamer | 25:aef6536015e3 | 32 | from project_generator_definitions.definitions import ProGenDef |
screamer | 25:aef6536015e3 | 33 | from tools.utils import args_error |
screamer | 25:aef6536015e3 | 34 | |
screamer | 25:aef6536015e3 | 35 | |
screamer | 25:aef6536015e3 | 36 | class ProgenBuildTest(): |
screamer | 25:aef6536015e3 | 37 | def __init__(self, desired_ides, targets): |
screamer | 25:aef6536015e3 | 38 | #map of targets and the ides that can build programs for them |
screamer | 25:aef6536015e3 | 39 | self.target_ides = {} |
screamer | 25:aef6536015e3 | 40 | for target in targets: |
screamer | 25:aef6536015e3 | 41 | self.target_ides[target] =[] |
screamer | 25:aef6536015e3 | 42 | for ide in desired_ides: |
screamer | 25:aef6536015e3 | 43 | if target in EXPORTERS[ide].TARGETS: |
screamer | 25:aef6536015e3 | 44 | #target is supported by ide |
screamer | 25:aef6536015e3 | 45 | self.target_ides[target].append(ide) |
screamer | 25:aef6536015e3 | 46 | if len(self.target_ides[target]) == 0: |
screamer | 25:aef6536015e3 | 47 | del self.target_ides[target] |
screamer | 25:aef6536015e3 | 48 | |
screamer | 25:aef6536015e3 | 49 | |
screamer | 25:aef6536015e3 | 50 | @staticmethod |
screamer | 25:aef6536015e3 | 51 | def get_pgen_targets(ides): |
screamer | 25:aef6536015e3 | 52 | #targets supported by pgen and desired ides for tests |
screamer | 25:aef6536015e3 | 53 | targs = [] |
screamer | 25:aef6536015e3 | 54 | for ide in ides: |
screamer | 25:aef6536015e3 | 55 | for target in TARGET_NAMES: |
screamer | 25:aef6536015e3 | 56 | if target not in targs and hasattr(TARGET_MAP[target],'progen') \ |
screamer | 25:aef6536015e3 | 57 | and ProGenDef(ide).is_supported(TARGET_MAP[target].progen['target']): |
screamer | 25:aef6536015e3 | 58 | targs.append(target) |
screamer | 25:aef6536015e3 | 59 | return targs |
screamer | 25:aef6536015e3 | 60 | |
screamer | 25:aef6536015e3 | 61 | @staticmethod |
screamer | 25:aef6536015e3 | 62 | def handle_project_files(project_dir, mcu, test, tool, clean=False): |
screamer | 25:aef6536015e3 | 63 | log = '' |
screamer | 25:aef6536015e3 | 64 | if tool == 'uvision' or tool == 'uvision5': |
screamer | 25:aef6536015e3 | 65 | log = os.path.join(project_dir,"build","build_log.txt") |
screamer | 25:aef6536015e3 | 66 | elif tool == 'iar': |
screamer | 25:aef6536015e3 | 67 | log = os.path.join(project_dir, 'build_log.txt') |
screamer | 25:aef6536015e3 | 68 | try: |
screamer | 25:aef6536015e3 | 69 | with open(log, 'r') as f: |
screamer | 25:aef6536015e3 | 70 | print f.read() |
screamer | 25:aef6536015e3 | 71 | except: |
screamer | 25:aef6536015e3 | 72 | return |
screamer | 25:aef6536015e3 | 73 | |
screamer | 25:aef6536015e3 | 74 | prefix = "_".join([test, mcu, tool]) |
screamer | 25:aef6536015e3 | 75 | log_name = os.path.join(os.path.dirname(project_dir), prefix+"_log.txt") |
screamer | 25:aef6536015e3 | 76 | |
screamer | 25:aef6536015e3 | 77 | #check if a log already exists for this platform+test+ide |
screamer | 25:aef6536015e3 | 78 | if os.path.exists(log_name): |
screamer | 25:aef6536015e3 | 79 | #delete it if so |
screamer | 25:aef6536015e3 | 80 | os.remove(log_name) |
screamer | 25:aef6536015e3 | 81 | os.rename(log, log_name) |
screamer | 25:aef6536015e3 | 82 | |
screamer | 25:aef6536015e3 | 83 | if clean: |
screamer | 25:aef6536015e3 | 84 | shutil.rmtree(project_dir, ignore_errors=True) |
screamer | 25:aef6536015e3 | 85 | return |
screamer | 25:aef6536015e3 | 86 | |
screamer | 25:aef6536015e3 | 87 | def generate_and_build(self, tests, clean=False): |
screamer | 25:aef6536015e3 | 88 | |
screamer | 25:aef6536015e3 | 89 | #build results |
screamer | 25:aef6536015e3 | 90 | successes = [] |
screamer | 25:aef6536015e3 | 91 | failures = [] |
screamer | 25:aef6536015e3 | 92 | skips = [] |
screamer | 25:aef6536015e3 | 93 | for mcu, ides in self.target_ides.items(): |
screamer | 25:aef6536015e3 | 94 | for test in tests: |
screamer | 25:aef6536015e3 | 95 | #resolve name alias |
screamer | 25:aef6536015e3 | 96 | test = get_test_from_name(test) |
screamer | 25:aef6536015e3 | 97 | for ide in ides: |
screamer | 25:aef6536015e3 | 98 | lib_symbols = get_lib_symbols(None, None, test) |
screamer | 25:aef6536015e3 | 99 | project_dir, project_name, project_temp = setup_project(mcu, ide, test) |
screamer | 25:aef6536015e3 | 100 | |
screamer | 25:aef6536015e3 | 101 | dest_dir = os.path.dirname(project_temp) |
screamer | 25:aef6536015e3 | 102 | destination = os.path.join(dest_dir,"_".join([project_name, mcu, ide])) |
screamer | 25:aef6536015e3 | 103 | |
screamer | 25:aef6536015e3 | 104 | tmp_path, report = perform_export(project_dir, project_name, ide, mcu, destination, |
screamer | 25:aef6536015e3 | 105 | lib_symbols=lib_symbols, progen_build = True) |
screamer | 25:aef6536015e3 | 106 | |
screamer | 25:aef6536015e3 | 107 | if report['success']: |
screamer | 25:aef6536015e3 | 108 | successes.append("build for %s::%s\t%s" % (mcu, ide, project_name)) |
screamer | 25:aef6536015e3 | 109 | elif report['skip']: |
screamer | 25:aef6536015e3 | 110 | skips.append("%s::%s\t%s" % (mcu, ide, project_name)) |
screamer | 25:aef6536015e3 | 111 | else: |
screamer | 25:aef6536015e3 | 112 | failures.append("%s::%s\t%s for %s" % (mcu, ide, report['errormsg'], project_name)) |
screamer | 25:aef6536015e3 | 113 | |
screamer | 25:aef6536015e3 | 114 | ProgenBuildTest.handle_project_files(destination, mcu, project_name, ide, clean) |
screamer | 25:aef6536015e3 | 115 | return successes, failures, skips |
screamer | 25:aef6536015e3 | 116 | |
screamer | 25:aef6536015e3 | 117 | |
screamer | 25:aef6536015e3 | 118 | if __name__ == '__main__': |
screamer | 25:aef6536015e3 | 119 | accepted_ides = ["iar", "uvision", "uvision5"] |
screamer | 25:aef6536015e3 | 120 | accepted_targets = sorted(ProgenBuildTest.get_pgen_targets(accepted_ides)) |
screamer | 25:aef6536015e3 | 121 | default_tests = ["MBED_BLINKY"] |
screamer | 25:aef6536015e3 | 122 | |
screamer | 25:aef6536015e3 | 123 | parser = argparse.ArgumentParser(description = "Test progen builders. Leave any flag off to run with all possible options.") |
screamer | 25:aef6536015e3 | 124 | parser.add_argument("-i", "--IDEs", |
screamer | 25:aef6536015e3 | 125 | nargs = '+', |
screamer | 25:aef6536015e3 | 126 | dest="ides", |
screamer | 25:aef6536015e3 | 127 | help="tools you wish to perfrom build tests. (%s)" % ', '.join(accepted_ides), |
screamer | 25:aef6536015e3 | 128 | default = accepted_ides) |
screamer | 25:aef6536015e3 | 129 | |
screamer | 25:aef6536015e3 | 130 | parser.add_argument("-n", |
screamer | 25:aef6536015e3 | 131 | nargs='+', |
screamer | 25:aef6536015e3 | 132 | dest="tests", |
screamer | 25:aef6536015e3 | 133 | help="names of desired test programs", |
screamer | 25:aef6536015e3 | 134 | default = default_tests) |
screamer | 25:aef6536015e3 | 135 | |
screamer | 25:aef6536015e3 | 136 | parser.add_argument("-m", "--mcus", |
screamer | 25:aef6536015e3 | 137 | nargs='+', |
screamer | 25:aef6536015e3 | 138 | dest ="targets", |
screamer | 25:aef6536015e3 | 139 | help="generate project for the given MCUs (%s)" % '\n '.join(accepted_targets), |
screamer | 25:aef6536015e3 | 140 | default = accepted_targets) |
screamer | 25:aef6536015e3 | 141 | |
screamer | 25:aef6536015e3 | 142 | parser.add_argument("-c", "--clean", |
screamer | 25:aef6536015e3 | 143 | dest="clean", |
screamer | 25:aef6536015e3 | 144 | action = "store_true", |
screamer | 25:aef6536015e3 | 145 | help="clean up the exported project files", |
screamer | 25:aef6536015e3 | 146 | default=False) |
screamer | 25:aef6536015e3 | 147 | |
screamer | 25:aef6536015e3 | 148 | options = parser.parse_args() |
screamer | 25:aef6536015e3 | 149 | |
screamer | 25:aef6536015e3 | 150 | tests = options.tests |
screamer | 25:aef6536015e3 | 151 | ides = [ide.lower() for ide in options.ides] |
screamer | 25:aef6536015e3 | 152 | targets = [target.upper() for target in options.targets] |
screamer | 25:aef6536015e3 | 153 | |
screamer | 25:aef6536015e3 | 154 | if any(get_test_from_name(test) is None for test in tests): |
screamer | 25:aef6536015e3 | 155 | args_error(parser, "[ERROR] test name not recognized") |
screamer | 25:aef6536015e3 | 156 | |
screamer | 25:aef6536015e3 | 157 | if any(target not in accepted_targets for target in targets): |
screamer | 25:aef6536015e3 | 158 | args_error(parser, "[ERROR] mcu must be one of the following:\n %s" % '\n '.join(accepted_targets)) |
screamer | 25:aef6536015e3 | 159 | |
screamer | 25:aef6536015e3 | 160 | if any(ide not in accepted_ides for ide in ides): |
screamer | 25:aef6536015e3 | 161 | args_error(parser, "[ERROR] ide must be in %s" % ', '.join(accepted_ides)) |
screamer | 25:aef6536015e3 | 162 | |
screamer | 25:aef6536015e3 | 163 | build_test = ProgenBuildTest(ides, targets) |
screamer | 25:aef6536015e3 | 164 | successes, failures, skips = build_test.generate_and_build(tests, options.clean) |
screamer | 25:aef6536015e3 | 165 | print_results(successes, failures, skips) |
screamer | 25:aef6536015e3 | 166 | sys.exit(len(failures)) |
screamer | 25:aef6536015e3 | 167 | |
screamer | 25:aef6536015e3 | 168 | |
screamer | 25:aef6536015e3 | 169 |