Marco Zecchini
/
Example_RTOS
Rtos API example
mbed-os/tools/test/examples/examples_lib.py@0:9fca2b23d0ba, 2019-02-23 (annotated)
- Committer:
- marcozecchini
- Date:
- Sat Feb 23 12:13:36 2019 +0000
- Revision:
- 0:9fca2b23d0ba
final commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
marcozecchini | 0:9fca2b23d0ba | 1 | """ Import and bulid a bunch of example programs |
marcozecchini | 0:9fca2b23d0ba | 2 | |
marcozecchini | 0:9fca2b23d0ba | 3 | This library includes functions that are shared between the examples.py and |
marcozecchini | 0:9fca2b23d0ba | 4 | the update.py modules. |
marcozecchini | 0:9fca2b23d0ba | 5 | |
marcozecchini | 0:9fca2b23d0ba | 6 | """ |
marcozecchini | 0:9fca2b23d0ba | 7 | import os |
marcozecchini | 0:9fca2b23d0ba | 8 | from os.path import dirname, abspath, basename |
marcozecchini | 0:9fca2b23d0ba | 9 | import os.path |
marcozecchini | 0:9fca2b23d0ba | 10 | import sys |
marcozecchini | 0:9fca2b23d0ba | 11 | import subprocess |
marcozecchini | 0:9fca2b23d0ba | 12 | from shutil import rmtree |
marcozecchini | 0:9fca2b23d0ba | 13 | from sets import Set |
marcozecchini | 0:9fca2b23d0ba | 14 | |
marcozecchini | 0:9fca2b23d0ba | 15 | ROOT = abspath(dirname(dirname(dirname(dirname(__file__))))) |
marcozecchini | 0:9fca2b23d0ba | 16 | sys.path.insert(0, ROOT) |
marcozecchini | 0:9fca2b23d0ba | 17 | |
marcozecchini | 0:9fca2b23d0ba | 18 | from tools.build_api import get_mbed_official_release |
marcozecchini | 0:9fca2b23d0ba | 19 | from tools.targets import TARGET_MAP |
marcozecchini | 0:9fca2b23d0ba | 20 | from tools.export import EXPORTERS |
marcozecchini | 0:9fca2b23d0ba | 21 | |
marcozecchini | 0:9fca2b23d0ba | 22 | SUPPORTED_TOOLCHAINS = ["ARM", "IAR", "GCC_ARM", "ARMC6"] |
marcozecchini | 0:9fca2b23d0ba | 23 | SUPPORTED_IDES = [exp for exp in EXPORTERS.keys() if exp != "cmsis" and exp != "zip"] |
marcozecchini | 0:9fca2b23d0ba | 24 | |
marcozecchini | 0:9fca2b23d0ba | 25 | |
marcozecchini | 0:9fca2b23d0ba | 26 | def print_list(lst): |
marcozecchini | 0:9fca2b23d0ba | 27 | """Prints to screen the contents of a list |
marcozecchini | 0:9fca2b23d0ba | 28 | |
marcozecchini | 0:9fca2b23d0ba | 29 | Args: |
marcozecchini | 0:9fca2b23d0ba | 30 | lst - a list of any type, to be displayed |
marcozecchini | 0:9fca2b23d0ba | 31 | |
marcozecchini | 0:9fca2b23d0ba | 32 | """ |
marcozecchini | 0:9fca2b23d0ba | 33 | if lst: |
marcozecchini | 0:9fca2b23d0ba | 34 | for thing in lst: |
marcozecchini | 0:9fca2b23d0ba | 35 | print("# %s" % thing) |
marcozecchini | 0:9fca2b23d0ba | 36 | |
marcozecchini | 0:9fca2b23d0ba | 37 | |
marcozecchini | 0:9fca2b23d0ba | 38 | def print_category(results, index, message): |
marcozecchini | 0:9fca2b23d0ba | 39 | summary = [example for key, summ in results.iteritems() |
marcozecchini | 0:9fca2b23d0ba | 40 | for example in summ[index]] |
marcozecchini | 0:9fca2b23d0ba | 41 | if all(len(s) == 0 for s in summary): |
marcozecchini | 0:9fca2b23d0ba | 42 | return |
marcozecchini | 0:9fca2b23d0ba | 43 | print("#") |
marcozecchini | 0:9fca2b23d0ba | 44 | print("#" * 80) |
marcozecchini | 0:9fca2b23d0ba | 45 | print("# %s" % message) |
marcozecchini | 0:9fca2b23d0ba | 46 | print("#" * 80) |
marcozecchini | 0:9fca2b23d0ba | 47 | split_summ = [s.rsplit(" ", 1) for s in summary] |
marcozecchini | 0:9fca2b23d0ba | 48 | |
marcozecchini | 0:9fca2b23d0ba | 49 | print_list(summary) |
marcozecchini | 0:9fca2b23d0ba | 50 | |
marcozecchini | 0:9fca2b23d0ba | 51 | |
marcozecchini | 0:9fca2b23d0ba | 52 | def print_summary(results, export=False): |
marcozecchini | 0:9fca2b23d0ba | 53 | """Prints to screen the results of compiling/exporting combinations of example programs, |
marcozecchini | 0:9fca2b23d0ba | 54 | targets and compile toolchains/IDEs. |
marcozecchini | 0:9fca2b23d0ba | 55 | |
marcozecchini | 0:9fca2b23d0ba | 56 | Args: |
marcozecchini | 0:9fca2b23d0ba | 57 | results - results of the compilation stage. See compile_repos() and export_repos() |
marcozecchini | 0:9fca2b23d0ba | 58 | for details of the format. |
marcozecchini | 0:9fca2b23d0ba | 59 | |
marcozecchini | 0:9fca2b23d0ba | 60 | """ |
marcozecchini | 0:9fca2b23d0ba | 61 | |
marcozecchini | 0:9fca2b23d0ba | 62 | print("#"*80) |
marcozecchini | 0:9fca2b23d0ba | 63 | print("# Examples compilation summary") |
marcozecchini | 0:9fca2b23d0ba | 64 | print("#"*80) |
marcozecchini | 0:9fca2b23d0ba | 65 | |
marcozecchini | 0:9fca2b23d0ba | 66 | print_category(results, 2, "Passed example combinations") |
marcozecchini | 0:9fca2b23d0ba | 67 | |
marcozecchini | 0:9fca2b23d0ba | 68 | second_result = "Failed example combinations" if not export else \ |
marcozecchini | 0:9fca2b23d0ba | 69 | "Failed export example combinations" |
marcozecchini | 0:9fca2b23d0ba | 70 | |
marcozecchini | 0:9fca2b23d0ba | 71 | print_category(results, 3, second_result) |
marcozecchini | 0:9fca2b23d0ba | 72 | |
marcozecchini | 0:9fca2b23d0ba | 73 | if export: |
marcozecchini | 0:9fca2b23d0ba | 74 | print_category(results, 4, "Failed build combinations") |
marcozecchini | 0:9fca2b23d0ba | 75 | print_category(results, 5, "Skipped build combinations") |
marcozecchini | 0:9fca2b23d0ba | 76 | |
marcozecchini | 0:9fca2b23d0ba | 77 | print("#") |
marcozecchini | 0:9fca2b23d0ba | 78 | print("#"*80) |
marcozecchini | 0:9fca2b23d0ba | 79 | |
marcozecchini | 0:9fca2b23d0ba | 80 | def valid_choices(allowed_choices, all_choices): |
marcozecchini | 0:9fca2b23d0ba | 81 | if len(allowed_choices) > 0: |
marcozecchini | 0:9fca2b23d0ba | 82 | return [t for t in all_choices if t in allowed_choices] |
marcozecchini | 0:9fca2b23d0ba | 83 | else: |
marcozecchini | 0:9fca2b23d0ba | 84 | return all_choices |
marcozecchini | 0:9fca2b23d0ba | 85 | |
marcozecchini | 0:9fca2b23d0ba | 86 | |
marcozecchini | 0:9fca2b23d0ba | 87 | def target_cross_toolchain(allowed_targets, allowed_toolchains, features=[]): |
marcozecchini | 0:9fca2b23d0ba | 88 | """Generate pairs of target and toolchains |
marcozecchini | 0:9fca2b23d0ba | 89 | |
marcozecchini | 0:9fca2b23d0ba | 90 | Args: |
marcozecchini | 0:9fca2b23d0ba | 91 | allowed_targets - a list of all possible targets |
marcozecchini | 0:9fca2b23d0ba | 92 | allowed_toolchains - a list of all possible toolchains |
marcozecchini | 0:9fca2b23d0ba | 93 | |
marcozecchini | 0:9fca2b23d0ba | 94 | Kwargs: |
marcozecchini | 0:9fca2b23d0ba | 95 | features - the features that must be in the features array of a |
marcozecchini | 0:9fca2b23d0ba | 96 | target |
marcozecchini | 0:9fca2b23d0ba | 97 | """ |
marcozecchini | 0:9fca2b23d0ba | 98 | for target in allowed_targets: |
marcozecchini | 0:9fca2b23d0ba | 99 | for toolchain in allowed_toolchains: |
marcozecchini | 0:9fca2b23d0ba | 100 | if all(feature in TARGET_MAP[target].features |
marcozecchini | 0:9fca2b23d0ba | 101 | for feature in features): |
marcozecchini | 0:9fca2b23d0ba | 102 | yield target, toolchain |
marcozecchini | 0:9fca2b23d0ba | 103 | |
marcozecchini | 0:9fca2b23d0ba | 104 | |
marcozecchini | 0:9fca2b23d0ba | 105 | def target_cross_ide(allowed_targets, allowed_ides, features=[], toolchains=[]): |
marcozecchini | 0:9fca2b23d0ba | 106 | """Generate pairs of target and ides |
marcozecchini | 0:9fca2b23d0ba | 107 | |
marcozecchini | 0:9fca2b23d0ba | 108 | Args: |
marcozecchini | 0:9fca2b23d0ba | 109 | allowed_targets - a list of all possible targets |
marcozecchini | 0:9fca2b23d0ba | 110 | allowed_ides - a list of all possible IDEs |
marcozecchini | 0:9fca2b23d0ba | 111 | |
marcozecchini | 0:9fca2b23d0ba | 112 | Kwargs: |
marcozecchini | 0:9fca2b23d0ba | 113 | features - the features that must be in the features array of a |
marcozecchini | 0:9fca2b23d0ba | 114 | target |
marcozecchini | 0:9fca2b23d0ba | 115 | """ |
marcozecchini | 0:9fca2b23d0ba | 116 | for target in allowed_targets: |
marcozecchini | 0:9fca2b23d0ba | 117 | for ide in allowed_ides: |
marcozecchini | 0:9fca2b23d0ba | 118 | if (EXPORTERS[ide].is_target_supported(target) and |
marcozecchini | 0:9fca2b23d0ba | 119 | (not toolchains or EXPORTERS[ide].TOOLCHAIN in toolchains) and |
marcozecchini | 0:9fca2b23d0ba | 120 | all(feature in TARGET_MAP[target].features |
marcozecchini | 0:9fca2b23d0ba | 121 | for feature in features)): |
marcozecchini | 0:9fca2b23d0ba | 122 | yield target, ide |
marcozecchini | 0:9fca2b23d0ba | 123 | |
marcozecchini | 0:9fca2b23d0ba | 124 | |
marcozecchini | 0:9fca2b23d0ba | 125 | def get_repo_list(example): |
marcozecchini | 0:9fca2b23d0ba | 126 | """ Returns a list of all the repos and their types associated with the |
marcozecchini | 0:9fca2b23d0ba | 127 | specific example in the json config file. |
marcozecchini | 0:9fca2b23d0ba | 128 | If the key 'test-repo-source' is set to 'mbed', then it will return the |
marcozecchini | 0:9fca2b23d0ba | 129 | mbed section as a list. Otherwise, it will return the single github repo. |
marcozecchini | 0:9fca2b23d0ba | 130 | NOTE: This does not currently deal with multiple examples underneath a github |
marcozecchini | 0:9fca2b23d0ba | 131 | sourced exampe repo. |
marcozecchini | 0:9fca2b23d0ba | 132 | |
marcozecchini | 0:9fca2b23d0ba | 133 | Args: |
marcozecchini | 0:9fca2b23d0ba | 134 | example - Example for which the repo list is requested |
marcozecchini | 0:9fca2b23d0ba | 135 | |
marcozecchini | 0:9fca2b23d0ba | 136 | """ |
marcozecchini | 0:9fca2b23d0ba | 137 | repos = [] |
marcozecchini | 0:9fca2b23d0ba | 138 | if example['test-repo-source'] == 'mbed': |
marcozecchini | 0:9fca2b23d0ba | 139 | for repo in example['mbed']: |
marcozecchini | 0:9fca2b23d0ba | 140 | repos.append({ |
marcozecchini | 0:9fca2b23d0ba | 141 | 'repo': repo, |
marcozecchini | 0:9fca2b23d0ba | 142 | 'type': 'hg' |
marcozecchini | 0:9fca2b23d0ba | 143 | }) |
marcozecchini | 0:9fca2b23d0ba | 144 | else: |
marcozecchini | 0:9fca2b23d0ba | 145 | repos.append({ |
marcozecchini | 0:9fca2b23d0ba | 146 | 'repo': example['github'], |
marcozecchini | 0:9fca2b23d0ba | 147 | 'type': 'git' |
marcozecchini | 0:9fca2b23d0ba | 148 | }) |
marcozecchini | 0:9fca2b23d0ba | 149 | return repos |
marcozecchini | 0:9fca2b23d0ba | 150 | |
marcozecchini | 0:9fca2b23d0ba | 151 | |
marcozecchini | 0:9fca2b23d0ba | 152 | def source_repos(config, examples): |
marcozecchini | 0:9fca2b23d0ba | 153 | """ Imports each of the repos and its dependencies (.lib files) associated |
marcozecchini | 0:9fca2b23d0ba | 154 | with the specific examples name from the json config file. Note if |
marcozecchini | 0:9fca2b23d0ba | 155 | there is already a clone of the repo then it will first be removed to |
marcozecchini | 0:9fca2b23d0ba | 156 | ensure a clean, up to date cloning. |
marcozecchini | 0:9fca2b23d0ba | 157 | Args: |
marcozecchini | 0:9fca2b23d0ba | 158 | config - the json object imported from the file. |
marcozecchini | 0:9fca2b23d0ba | 159 | |
marcozecchini | 0:9fca2b23d0ba | 160 | """ |
marcozecchini | 0:9fca2b23d0ba | 161 | print("\nImporting example repos....\n") |
marcozecchini | 0:9fca2b23d0ba | 162 | for example in config['examples']: |
marcozecchini | 0:9fca2b23d0ba | 163 | for repo_info in get_repo_list(example): |
marcozecchini | 0:9fca2b23d0ba | 164 | name = basename(repo_info['repo']) |
marcozecchini | 0:9fca2b23d0ba | 165 | if name in examples: |
marcozecchini | 0:9fca2b23d0ba | 166 | if os.path.exists(name): |
marcozecchini | 0:9fca2b23d0ba | 167 | print("'%s' example directory already exists. Deleting..." % name) |
marcozecchini | 0:9fca2b23d0ba | 168 | rmtree(name) |
marcozecchini | 0:9fca2b23d0ba | 169 | |
marcozecchini | 0:9fca2b23d0ba | 170 | subprocess.call(["mbed-cli", "import", repo_info['repo']]) |
marcozecchini | 0:9fca2b23d0ba | 171 | |
marcozecchini | 0:9fca2b23d0ba | 172 | def clone_repos(config, examples , retry = 3): |
marcozecchini | 0:9fca2b23d0ba | 173 | """ Clones each of the repos associated with the specific examples name from the |
marcozecchini | 0:9fca2b23d0ba | 174 | json config file. Note if there is already a clone of the repo then it will first |
marcozecchini | 0:9fca2b23d0ba | 175 | be removed to ensure a clean, up to date cloning. |
marcozecchini | 0:9fca2b23d0ba | 176 | Args: |
marcozecchini | 0:9fca2b23d0ba | 177 | config - the json object imported from the file. |
marcozecchini | 0:9fca2b23d0ba | 178 | |
marcozecchini | 0:9fca2b23d0ba | 179 | """ |
marcozecchini | 0:9fca2b23d0ba | 180 | print("\nCloning example repos....\n") |
marcozecchini | 0:9fca2b23d0ba | 181 | for example in config['examples']: |
marcozecchini | 0:9fca2b23d0ba | 182 | for repo_info in get_repo_list(example): |
marcozecchini | 0:9fca2b23d0ba | 183 | name = basename(repo_info['repo']) |
marcozecchini | 0:9fca2b23d0ba | 184 | if name in examples: |
marcozecchini | 0:9fca2b23d0ba | 185 | if os.path.exists(name): |
marcozecchini | 0:9fca2b23d0ba | 186 | print("'%s' example directory already exists. Deleting..." % name) |
marcozecchini | 0:9fca2b23d0ba | 187 | rmtree(name) |
marcozecchini | 0:9fca2b23d0ba | 188 | for i in range(0, retry): |
marcozecchini | 0:9fca2b23d0ba | 189 | if subprocess.call([repo_info['type'], "clone", repo_info['repo']]) == 0: |
marcozecchini | 0:9fca2b23d0ba | 190 | break |
marcozecchini | 0:9fca2b23d0ba | 191 | else: |
marcozecchini | 0:9fca2b23d0ba | 192 | print("ERROR : unable to clone the repo {}".format(name)) |
marcozecchini | 0:9fca2b23d0ba | 193 | |
marcozecchini | 0:9fca2b23d0ba | 194 | def deploy_repos(config, examples): |
marcozecchini | 0:9fca2b23d0ba | 195 | """ If the example directory exists as provided by the json config file, |
marcozecchini | 0:9fca2b23d0ba | 196 | pull in the examples dependencies by using `mbed-cli deploy`. |
marcozecchini | 0:9fca2b23d0ba | 197 | Args: |
marcozecchini | 0:9fca2b23d0ba | 198 | config - the json object imported from the file. |
marcozecchini | 0:9fca2b23d0ba | 199 | |
marcozecchini | 0:9fca2b23d0ba | 200 | """ |
marcozecchini | 0:9fca2b23d0ba | 201 | print("\nDeploying example repos....\n") |
marcozecchini | 0:9fca2b23d0ba | 202 | for example in config['examples']: |
marcozecchini | 0:9fca2b23d0ba | 203 | for repo_info in get_repo_list(example): |
marcozecchini | 0:9fca2b23d0ba | 204 | name = basename(repo_info['repo']) |
marcozecchini | 0:9fca2b23d0ba | 205 | if name in examples: |
marcozecchini | 0:9fca2b23d0ba | 206 | if os.path.exists(name): |
marcozecchini | 0:9fca2b23d0ba | 207 | os.chdir(name) |
marcozecchini | 0:9fca2b23d0ba | 208 | subprocess.call(["mbed-cli", "deploy"]) |
marcozecchini | 0:9fca2b23d0ba | 209 | os.chdir("..") |
marcozecchini | 0:9fca2b23d0ba | 210 | else: |
marcozecchini | 0:9fca2b23d0ba | 211 | print("'%s' example directory doesn't exist. Skipping..." % name) |
marcozecchini | 0:9fca2b23d0ba | 212 | |
marcozecchini | 0:9fca2b23d0ba | 213 | |
marcozecchini | 0:9fca2b23d0ba | 214 | def get_num_failures(results, export=False): |
marcozecchini | 0:9fca2b23d0ba | 215 | """ Returns the number of failed compilations from the results summary |
marcozecchini | 0:9fca2b23d0ba | 216 | Args: |
marcozecchini | 0:9fca2b23d0ba | 217 | results - results summary of the compilation stage. See compile_repos() for |
marcozecchini | 0:9fca2b23d0ba | 218 | details of the format. |
marcozecchini | 0:9fca2b23d0ba | 219 | num_failures |
marcozecchini | 0:9fca2b23d0ba | 220 | |
marcozecchini | 0:9fca2b23d0ba | 221 | """ |
marcozecchini | 0:9fca2b23d0ba | 222 | num_failures = 0 |
marcozecchini | 0:9fca2b23d0ba | 223 | |
marcozecchini | 0:9fca2b23d0ba | 224 | for key, val in results.iteritems(): |
marcozecchini | 0:9fca2b23d0ba | 225 | num_failures = num_failures + len(val[3]) |
marcozecchini | 0:9fca2b23d0ba | 226 | if export: |
marcozecchini | 0:9fca2b23d0ba | 227 | num_failures += len(val[4]) |
marcozecchini | 0:9fca2b23d0ba | 228 | |
marcozecchini | 0:9fca2b23d0ba | 229 | return num_failures |
marcozecchini | 0:9fca2b23d0ba | 230 | |
marcozecchini | 0:9fca2b23d0ba | 231 | def export_repos(config, ides, targets, examples): |
marcozecchini | 0:9fca2b23d0ba | 232 | """Exports and builds combinations of example programs, targets and IDEs. |
marcozecchini | 0:9fca2b23d0ba | 233 | |
marcozecchini | 0:9fca2b23d0ba | 234 | The results are returned in a [key: value] dictionary format: |
marcozecchini | 0:9fca2b23d0ba | 235 | Where key = The example name from the json config file |
marcozecchini | 0:9fca2b23d0ba | 236 | value = a list containing: pass_status, successes, export failures, build_failures, |
marcozecchini | 0:9fca2b23d0ba | 237 | and build_skips |
marcozecchini | 0:9fca2b23d0ba | 238 | |
marcozecchini | 0:9fca2b23d0ba | 239 | where pass_status = The overall pass status for the export of the full |
marcozecchini | 0:9fca2b23d0ba | 240 | set of example programs comprising the example suite. |
marcozecchini | 0:9fca2b23d0ba | 241 | IE they must build and export) True if all examples pass, false otherwise |
marcozecchini | 0:9fca2b23d0ba | 242 | successes = list of examples that exported and built (if possible) |
marcozecchini | 0:9fca2b23d0ba | 243 | If the exporter has no build functionality, then it is a pass |
marcozecchini | 0:9fca2b23d0ba | 244 | if exported |
marcozecchini | 0:9fca2b23d0ba | 245 | export_failures = list of examples that failed to export. |
marcozecchini | 0:9fca2b23d0ba | 246 | build_failures = list of examples that failed to build |
marcozecchini | 0:9fca2b23d0ba | 247 | build_skips = list of examples that cannot build |
marcozecchini | 0:9fca2b23d0ba | 248 | |
marcozecchini | 0:9fca2b23d0ba | 249 | Both successes and failures contain the example name, target and IDE |
marcozecchini | 0:9fca2b23d0ba | 250 | |
marcozecchini | 0:9fca2b23d0ba | 251 | Args: |
marcozecchini | 0:9fca2b23d0ba | 252 | config - the json object imported from the file. |
marcozecchini | 0:9fca2b23d0ba | 253 | ides - List of IDES to export to |
marcozecchini | 0:9fca2b23d0ba | 254 | """ |
marcozecchini | 0:9fca2b23d0ba | 255 | results = {} |
marcozecchini | 0:9fca2b23d0ba | 256 | valid_examples = Set(examples) |
marcozecchini | 0:9fca2b23d0ba | 257 | print("\nExporting example repos....\n") |
marcozecchini | 0:9fca2b23d0ba | 258 | for example in config['examples']: |
marcozecchini | 0:9fca2b23d0ba | 259 | example_names = [basename(x['repo']) for x in get_repo_list(example)] |
marcozecchini | 0:9fca2b23d0ba | 260 | common_examples = valid_examples.intersection(Set(example_names)) |
marcozecchini | 0:9fca2b23d0ba | 261 | if not common_examples: |
marcozecchini | 0:9fca2b23d0ba | 262 | continue |
marcozecchini | 0:9fca2b23d0ba | 263 | export_failures = [] |
marcozecchini | 0:9fca2b23d0ba | 264 | build_failures = [] |
marcozecchini | 0:9fca2b23d0ba | 265 | build_skips = [] |
marcozecchini | 0:9fca2b23d0ba | 266 | successes = [] |
marcozecchini | 0:9fca2b23d0ba | 267 | exported = True |
marcozecchini | 0:9fca2b23d0ba | 268 | pass_status = True |
marcozecchini | 0:9fca2b23d0ba | 269 | if example['export']: |
marcozecchini | 0:9fca2b23d0ba | 270 | for repo_info in get_repo_list(example): |
marcozecchini | 0:9fca2b23d0ba | 271 | example_project_name = basename(repo_info['repo']) |
marcozecchini | 0:9fca2b23d0ba | 272 | os.chdir(example_project_name) |
marcozecchini | 0:9fca2b23d0ba | 273 | # Check that the target, IDE, and features combinations are valid and return a |
marcozecchini | 0:9fca2b23d0ba | 274 | # list of valid combinations to work through |
marcozecchini | 0:9fca2b23d0ba | 275 | for target, ide in target_cross_ide(valid_choices(example['targets'], targets), |
marcozecchini | 0:9fca2b23d0ba | 276 | valid_choices(example['exporters'], ides), |
marcozecchini | 0:9fca2b23d0ba | 277 | example['features'], example['toolchains']): |
marcozecchini | 0:9fca2b23d0ba | 278 | example_name = "{} {} {}".format(example_project_name, target, |
marcozecchini | 0:9fca2b23d0ba | 279 | ide) |
marcozecchini | 0:9fca2b23d0ba | 280 | def status(message): |
marcozecchini | 0:9fca2b23d0ba | 281 | print(message + " %s" % example_name) |
marcozecchini | 0:9fca2b23d0ba | 282 | sys.stdout.flush() |
marcozecchini | 0:9fca2b23d0ba | 283 | |
marcozecchini | 0:9fca2b23d0ba | 284 | status("Exporting") |
marcozecchini | 0:9fca2b23d0ba | 285 | proc = subprocess.Popen(["mbed-cli", "export", "-i", ide, |
marcozecchini | 0:9fca2b23d0ba | 286 | "-m", target]) |
marcozecchini | 0:9fca2b23d0ba | 287 | proc.wait() |
marcozecchini | 0:9fca2b23d0ba | 288 | if proc.returncode: |
marcozecchini | 0:9fca2b23d0ba | 289 | export_failures.append(example_name) |
marcozecchini | 0:9fca2b23d0ba | 290 | status("FAILURE exporting") |
marcozecchini | 0:9fca2b23d0ba | 291 | else: |
marcozecchini | 0:9fca2b23d0ba | 292 | status("SUCCESS exporting") |
marcozecchini | 0:9fca2b23d0ba | 293 | status("Building") |
marcozecchini | 0:9fca2b23d0ba | 294 | try: |
marcozecchini | 0:9fca2b23d0ba | 295 | if EXPORTERS[ide].build(example_project_name, cleanup=False): |
marcozecchini | 0:9fca2b23d0ba | 296 | status("FAILURE building") |
marcozecchini | 0:9fca2b23d0ba | 297 | build_failures.append(example_name) |
marcozecchini | 0:9fca2b23d0ba | 298 | else: |
marcozecchini | 0:9fca2b23d0ba | 299 | status("SUCCESS building") |
marcozecchini | 0:9fca2b23d0ba | 300 | successes.append(example_name) |
marcozecchini | 0:9fca2b23d0ba | 301 | except TypeError: |
marcozecchini | 0:9fca2b23d0ba | 302 | successes.append(example_name) |
marcozecchini | 0:9fca2b23d0ba | 303 | build_skips.append(example_name) |
marcozecchini | 0:9fca2b23d0ba | 304 | os.chdir("..") |
marcozecchini | 0:9fca2b23d0ba | 305 | |
marcozecchini | 0:9fca2b23d0ba | 306 | if len(build_failures+export_failures) > 0: |
marcozecchini | 0:9fca2b23d0ba | 307 | pass_status= False |
marcozecchini | 0:9fca2b23d0ba | 308 | else: |
marcozecchini | 0:9fca2b23d0ba | 309 | exported = False |
marcozecchini | 0:9fca2b23d0ba | 310 | |
marcozecchini | 0:9fca2b23d0ba | 311 | results[example['name']] = [exported, pass_status, successes, |
marcozecchini | 0:9fca2b23d0ba | 312 | export_failures, build_failures, build_skips] |
marcozecchini | 0:9fca2b23d0ba | 313 | |
marcozecchini | 0:9fca2b23d0ba | 314 | return results |
marcozecchini | 0:9fca2b23d0ba | 315 | |
marcozecchini | 0:9fca2b23d0ba | 316 | |
marcozecchini | 0:9fca2b23d0ba | 317 | def compile_repos(config, toolchains, targets, profile, examples): |
marcozecchini | 0:9fca2b23d0ba | 318 | """Compiles combinations of example programs, targets and compile chains. |
marcozecchini | 0:9fca2b23d0ba | 319 | |
marcozecchini | 0:9fca2b23d0ba | 320 | The results are returned in a [key: value] dictionary format: |
marcozecchini | 0:9fca2b23d0ba | 321 | Where key = The example name from the json config file |
marcozecchini | 0:9fca2b23d0ba | 322 | value = a list containing: pass_status, successes, and failures |
marcozecchini | 0:9fca2b23d0ba | 323 | |
marcozecchini | 0:9fca2b23d0ba | 324 | where pass_status = The overall pass status for the compilation of the full |
marcozecchini | 0:9fca2b23d0ba | 325 | set of example programs comprising the example suite. |
marcozecchini | 0:9fca2b23d0ba | 326 | True if all examples pass, false otherwise |
marcozecchini | 0:9fca2b23d0ba | 327 | successes = list of passing examples. |
marcozecchini | 0:9fca2b23d0ba | 328 | failures = list of failing examples. |
marcozecchini | 0:9fca2b23d0ba | 329 | |
marcozecchini | 0:9fca2b23d0ba | 330 | Both successes and failures contain the example name, target and compile chain |
marcozecchini | 0:9fca2b23d0ba | 331 | |
marcozecchini | 0:9fca2b23d0ba | 332 | Args: |
marcozecchini | 0:9fca2b23d0ba | 333 | config - the json object imported from the file. |
marcozecchini | 0:9fca2b23d0ba | 334 | toolchains - List of toolchains to compile for. |
marcozecchini | 0:9fca2b23d0ba | 335 | results - results of the compilation stage. |
marcozecchini | 0:9fca2b23d0ba | 336 | |
marcozecchini | 0:9fca2b23d0ba | 337 | """ |
marcozecchini | 0:9fca2b23d0ba | 338 | results = {} |
marcozecchini | 0:9fca2b23d0ba | 339 | valid_examples = Set(examples) |
marcozecchini | 0:9fca2b23d0ba | 340 | print("\nCompiling example repos....\n") |
marcozecchini | 0:9fca2b23d0ba | 341 | for example in config['examples']: |
marcozecchini | 0:9fca2b23d0ba | 342 | example_names = [basename(x['repo']) for x in get_repo_list(example)] |
marcozecchini | 0:9fca2b23d0ba | 343 | common_examples = valid_examples.intersection(Set(example_names)) |
marcozecchini | 0:9fca2b23d0ba | 344 | if not common_examples: |
marcozecchini | 0:9fca2b23d0ba | 345 | continue |
marcozecchini | 0:9fca2b23d0ba | 346 | failures = [] |
marcozecchini | 0:9fca2b23d0ba | 347 | successes = [] |
marcozecchini | 0:9fca2b23d0ba | 348 | compiled = True |
marcozecchini | 0:9fca2b23d0ba | 349 | pass_status = True |
marcozecchini | 0:9fca2b23d0ba | 350 | if example['compile']: |
marcozecchini | 0:9fca2b23d0ba | 351 | for repo_info in get_repo_list(example): |
marcozecchini | 0:9fca2b23d0ba | 352 | name = basename(repo_info['repo']) |
marcozecchini | 0:9fca2b23d0ba | 353 | os.chdir(name) |
marcozecchini | 0:9fca2b23d0ba | 354 | |
marcozecchini | 0:9fca2b23d0ba | 355 | # Check that the target, toolchain and features combinations are valid and return a |
marcozecchini | 0:9fca2b23d0ba | 356 | # list of valid combinations to work through |
marcozecchini | 0:9fca2b23d0ba | 357 | for target, toolchain in target_cross_toolchain(valid_choices(example['targets'], targets), |
marcozecchini | 0:9fca2b23d0ba | 358 | valid_choices(example['toolchains'], toolchains), |
marcozecchini | 0:9fca2b23d0ba | 359 | example['features']): |
marcozecchini | 0:9fca2b23d0ba | 360 | print("Compiling %s for %s, %s" % (name, target, toolchain)) |
marcozecchini | 0:9fca2b23d0ba | 361 | build_command = ["mbed-cli", "compile", "-t", toolchain, "-m", target, "-v"] |
marcozecchini | 0:9fca2b23d0ba | 362 | |
marcozecchini | 0:9fca2b23d0ba | 363 | if profile: |
marcozecchini | 0:9fca2b23d0ba | 364 | build_command.append("--profile") |
marcozecchini | 0:9fca2b23d0ba | 365 | build_command.append(profile) |
marcozecchini | 0:9fca2b23d0ba | 366 | |
marcozecchini | 0:9fca2b23d0ba | 367 | proc = subprocess.Popen(build_command) |
marcozecchini | 0:9fca2b23d0ba | 368 | |
marcozecchini | 0:9fca2b23d0ba | 369 | proc.wait() |
marcozecchini | 0:9fca2b23d0ba | 370 | example_summary = "{} {} {}".format(name, target, toolchain) |
marcozecchini | 0:9fca2b23d0ba | 371 | if proc.returncode: |
marcozecchini | 0:9fca2b23d0ba | 372 | failures.append(example_summary) |
marcozecchini | 0:9fca2b23d0ba | 373 | else: |
marcozecchini | 0:9fca2b23d0ba | 374 | successes.append(example_summary) |
marcozecchini | 0:9fca2b23d0ba | 375 | os.chdir("..") |
marcozecchini | 0:9fca2b23d0ba | 376 | |
marcozecchini | 0:9fca2b23d0ba | 377 | # If there are any compilation failures for the example 'set' then the overall status is fail. |
marcozecchini | 0:9fca2b23d0ba | 378 | if len(failures) > 0: |
marcozecchini | 0:9fca2b23d0ba | 379 | pass_status = False |
marcozecchini | 0:9fca2b23d0ba | 380 | else: |
marcozecchini | 0:9fca2b23d0ba | 381 | compiled = False |
marcozecchini | 0:9fca2b23d0ba | 382 | |
marcozecchini | 0:9fca2b23d0ba | 383 | results[example['name']] = [compiled, pass_status, successes, failures] |
marcozecchini | 0:9fca2b23d0ba | 384 | |
marcozecchini | 0:9fca2b23d0ba | 385 | return results |
marcozecchini | 0:9fca2b23d0ba | 386 | |
marcozecchini | 0:9fca2b23d0ba | 387 | |
marcozecchini | 0:9fca2b23d0ba | 388 | def update_mbedos_version(config, tag, examples): |
marcozecchini | 0:9fca2b23d0ba | 389 | """ For each example repo identified in the config json object, update the version of |
marcozecchini | 0:9fca2b23d0ba | 390 | mbed-os to that specified by the supplied GitHub tag. This function assumes that each |
marcozecchini | 0:9fca2b23d0ba | 391 | example repo has already been cloned. |
marcozecchini | 0:9fca2b23d0ba | 392 | |
marcozecchini | 0:9fca2b23d0ba | 393 | Args: |
marcozecchini | 0:9fca2b23d0ba | 394 | config - the json object imported from the file. |
marcozecchini | 0:9fca2b23d0ba | 395 | tag - GitHub tag corresponding to a version of mbed-os to upgrade to. |
marcozecchini | 0:9fca2b23d0ba | 396 | |
marcozecchini | 0:9fca2b23d0ba | 397 | """ |
marcozecchini | 0:9fca2b23d0ba | 398 | print("Updating mbed-os in examples to version %s\n" % tag) |
marcozecchini | 0:9fca2b23d0ba | 399 | for example in config['examples']: |
marcozecchini | 0:9fca2b23d0ba | 400 | if example['name'] not in examples: |
marcozecchini | 0:9fca2b23d0ba | 401 | continue |
marcozecchini | 0:9fca2b23d0ba | 402 | for repo_info in get_repo_list(example): |
marcozecchini | 0:9fca2b23d0ba | 403 | update_dir = basename(repo_info['repo']) + "/mbed-os" |
marcozecchini | 0:9fca2b23d0ba | 404 | print("\nChanging dir to %s\n" % update_dir) |
marcozecchini | 0:9fca2b23d0ba | 405 | os.chdir(update_dir) |
marcozecchini | 0:9fca2b23d0ba | 406 | subprocess.call(["mbed-cli", "update", tag, "--clean"]) |
marcozecchini | 0:9fca2b23d0ba | 407 | os.chdir("../..") |