Development mbed library for MAX32630FTHR
Dependents: blinky_max32630fthr
examples_lib.py
00001 """ Import and bulid a bunch of example programs 00002 00003 This library includes functions that are shared between the examples.py and 00004 the update.py modules. 00005 00006 """ 00007 import os 00008 from os.path import dirname, abspath, basename 00009 import os.path 00010 import sys 00011 import subprocess 00012 from shutil import rmtree 00013 00014 ROOT = abspath(dirname(dirname(dirname(dirname(__file__))))) 00015 sys.path.insert(0, ROOT) 00016 00017 from tools.build_api import get_mbed_official_release 00018 from tools.targets import TARGET_MAP 00019 from tools.export import EXPORTERS 00020 00021 SUPPORTED_TOOLCHAINS = ["ARM", "IAR", "GCC_ARM"] 00022 SUPPORTED_IDES = [exp for exp in EXPORTERS.keys() if exp != "cmsis" and exp != "zip"] 00023 00024 00025 def print_list (lst): 00026 """Prints to screen the contents of a list 00027 00028 Args: 00029 lst - a list of any type, to be displayed 00030 00031 """ 00032 if lst: 00033 for thing in lst: 00034 print("# %s" % thing) 00035 00036 00037 def print_category(results, index, message): 00038 summary = [example for key, summ in results.iteritems() 00039 for example in summ[index]] 00040 if all(len(s) == 0 for s in summary): 00041 return 00042 print("#") 00043 print("#" * 80) 00044 print("# %s" % message) 00045 print("#" * 80) 00046 split_summ = [s.rsplit(" ", 1) for s in summary] 00047 00048 print_list(summary) 00049 00050 00051 def print_summary (results, export=False): 00052 """Prints to screen the results of compiling/exporting combinations of example programs, 00053 targets and compile toolchains/IDEs. 00054 00055 Args: 00056 results - results of the compilation stage. See compile_repos() and export_repos() 00057 for details of the format. 00058 00059 """ 00060 00061 print("#"*80) 00062 print("# Examples compilation summary") 00063 print("#"*80) 00064 00065 print_category(results, 2, "Passed example combinations") 00066 00067 second_result = "Failed example combinations" if not export else \ 00068 "Failed export example combinations" 00069 00070 print_category(results, 3, second_result) 00071 00072 if export: 00073 print_category(results, 4, "Failed build combinations") 00074 print_category(results, 5, "Skipped build combinations") 00075 00076 print("#") 00077 print("#"*80) 00078 00079 def valid_choices(allowed_choices, all_choices): 00080 if len(allowed_choices) > 0: 00081 return [t for t in all_choices if t in allowed_choices] 00082 else: 00083 return all_choices 00084 00085 00086 def target_cross_toolchain (allowed_targets, allowed_toolchains, features=[]): 00087 """Generate pairs of target and toolchains 00088 00089 Args: 00090 allowed_targets - a list of all possible targets 00091 allowed_toolchains - a list of all possible toolchains 00092 00093 Kwargs: 00094 features - the features that must be in the features array of a 00095 target 00096 """ 00097 for target in allowed_targets: 00098 for toolchain in allowed_toolchains: 00099 if all(feature in TARGET_MAP[target].features 00100 for feature in features): 00101 yield target, toolchain 00102 00103 00104 def target_cross_ide (allowed_targets, allowed_ides, features=[]): 00105 """Generate pairs of target and ides 00106 00107 Args: 00108 allowed_targets - a list of all possible targets 00109 allowed_ides - a list of all possible IDEs 00110 00111 Kwargs: 00112 features - the features that must be in the features array of a 00113 target 00114 """ 00115 for target in allowed_targets: 00116 for ide in allowed_ides: 00117 if (target in EXPORTERS[ide].TARGETS and 00118 all(feature in TARGET_MAP[target].features 00119 for feature in features)): 00120 yield target, ide 00121 00122 00123 def get_repo_list (example): 00124 """ Returns a list of all the repos associated with the specific example in the json 00125 config file. 00126 If there are repos listed under the mbed section then these will be returned as a 00127 list. If not then the github single repo with be returned. 00128 NOTE: This does not currently deal with multiple examples underneath a github 00129 sourced exampe repo. 00130 00131 Args: 00132 example - Example for which the repo list is requested 00133 repos - The list of repos and types contained within that example in the json file 00134 00135 """ 00136 repos = [] 00137 if len(example['mbed']) > 0: 00138 for repo in example['mbed']: 00139 repos.append({ 00140 'repo': repo, 00141 'type': 'hg' 00142 }) 00143 else: 00144 repos.append({ 00145 'repo': example['github'], 00146 'type': 'git' 00147 }) 00148 return repos 00149 00150 00151 def source_repos (config, examples): 00152 """ Imports each of the repos and its dependencies (.lib files) associated 00153 with the specific examples name from the json config file. Note if 00154 there is already a clone of the repo then it will first be removed to 00155 ensure a clean, up to date cloning. 00156 Args: 00157 config - the json object imported from the file. 00158 00159 """ 00160 print("\nImporting example repos....\n") 00161 for example in config['examples']: 00162 for repo_info in get_repo_list(example): 00163 name = basename(repo_info['repo']) 00164 if name in examples: 00165 if os.path.exists(name): 00166 print("'%s' example directory already exists. Deleting..." % name) 00167 rmtree(name) 00168 00169 subprocess.call(["mbed-cli", "import", repo_info['repo']]) 00170 00171 def clone_repos (config, examples): 00172 """ Clones each of the repos associated with the specific examples name from the 00173 json config file. Note if there is already a clone of the repo then it will first 00174 be removed to ensure a clean, up to date cloning. 00175 Args: 00176 config - the json object imported from the file. 00177 00178 """ 00179 print("\nCloning example repos....\n") 00180 for example in config['examples']: 00181 for repo_info in get_repo_list(example): 00182 name = basename(repo_info['repo']) 00183 if name in examples: 00184 if os.path.exists(name): 00185 print("'%s' example directory already exists. Deleting..." % name) 00186 rmtree(name) 00187 00188 subprocess.call([repo_info['type'], "clone", repo_info['repo']]) 00189 00190 def deploy_repos (config, examples): 00191 """ If the example directory exists as provided by the json config file, 00192 pull in the examples dependencies by using `mbed-cli deploy`. 00193 Args: 00194 config - the json object imported from the file. 00195 00196 """ 00197 print("\nDeploying example repos....\n") 00198 for example in config['examples']: 00199 for repo_info in get_repo_list(example): 00200 name = basename(repo_info['repo']) 00201 if name in examples: 00202 if os.path.exists(name): 00203 os.chdir(name) 00204 subprocess.call(["mbed-cli", "deploy"]) 00205 os.chdir("..") 00206 else: 00207 print("'%s' example directory doesn't exist. Skipping..." % name) 00208 00209 00210 def get_num_failures (results, export=False): 00211 """ Returns the number of failed compilations from the results summary 00212 Args: 00213 results - results summary of the compilation stage. See compile_repos() for 00214 details of the format. 00215 num_failures 00216 00217 """ 00218 num_failures = 0 00219 00220 for key, val in results.iteritems(): 00221 num_failures = num_failures + len(val[3]) 00222 if export: 00223 num_failures += len(val[4]) 00224 00225 return num_failures 00226 00227 def export_repos (config, ides, targets, examples): 00228 """Exports and builds combinations of example programs, targets and IDEs. 00229 00230 The results are returned in a [key: value] dictionary format: 00231 Where key = The example name from the json config file 00232 value = a list containing: pass_status, successes, export failures, build_failures, 00233 and build_skips 00234 00235 where pass_status = The overall pass status for the export of the full 00236 set of example programs comprising the example suite. 00237 IE they must build and export) True if all examples pass, false otherwise 00238 successes = list of examples that exported and built (if possible) 00239 If the exporter has no build functionality, then it is a pass 00240 if exported 00241 export_failures = list of examples that failed to export. 00242 build_failures = list of examples that failed to build 00243 build_skips = list of examples that cannot build 00244 00245 Both successes and failures contain the example name, target and IDE 00246 00247 Args: 00248 config - the json object imported from the file. 00249 ides - List of IDES to export to 00250 """ 00251 results = {} 00252 print("\nExporting example repos....\n") 00253 for example in config['examples']: 00254 if example['name'] not in examples: 00255 continue 00256 00257 export_failures = [] 00258 build_failures = [] 00259 build_skips = [] 00260 successes = [] 00261 exported = True 00262 pass_status = True 00263 if example['export']: 00264 for repo_info in get_repo_list(example): 00265 example_project_name = basename(repo_info['repo']) 00266 os.chdir(example_project_name) 00267 # Check that the target, IDE, and features combinations are valid and return a 00268 # list of valid combinations to work through 00269 for target, ide in target_cross_ide(valid_choices(example['targets'], targets), 00270 valid_choices(example['exporters'], ides), 00271 example['features']): 00272 example_name = "{} {} {}".format(example_project_name, target, 00273 ide) 00274 def status(message): 00275 print(message + " %s" % example_name) 00276 sys.stdout.flush() 00277 00278 status("Exporting") 00279 proc = subprocess.Popen(["mbed-cli", "export", "-i", ide, 00280 "-m", target]) 00281 proc.wait() 00282 if proc.returncode: 00283 export_failures.append(example_name) 00284 status("FAILURE exporting") 00285 else: 00286 status("SUCCESS exporting") 00287 status("Building") 00288 try: 00289 if EXPORTERS[ide].build(example_project_name): 00290 status("FAILURE building") 00291 build_failures.append(example_name) 00292 else: 00293 status("SUCCESS building") 00294 successes.append(example_name) 00295 except TypeError: 00296 successes.append(example_name) 00297 build_skips.append(example_name) 00298 os.chdir("..") 00299 00300 if len(build_failures+export_failures) > 0: 00301 pass_status= False 00302 else: 00303 exported = False 00304 00305 results[example['name']] = [exported, pass_status, successes, 00306 export_failures, build_failures, build_skips] 00307 00308 return results 00309 00310 00311 def compile_repos (config, toolchains, targets, examples): 00312 """Compiles combinations of example programs, targets and compile chains. 00313 00314 The results are returned in a [key: value] dictionary format: 00315 Where key = The example name from the json config file 00316 value = a list containing: pass_status, successes, and failures 00317 00318 where pass_status = The overall pass status for the compilation of the full 00319 set of example programs comprising the example suite. 00320 True if all examples pass, false otherwise 00321 successes = list of passing examples. 00322 failures = list of failing examples. 00323 00324 Both successes and failures contain the example name, target and compile chain 00325 00326 Args: 00327 config - the json object imported from the file. 00328 toolchains - List of toolchains to compile for. 00329 results - results of the compilation stage. 00330 00331 """ 00332 results = {} 00333 print("\nCompiling example repos....\n") 00334 for example in config['examples']: 00335 if example['name'] not in examples: 00336 continue 00337 failures = [] 00338 successes = [] 00339 compiled = True 00340 pass_status = True 00341 if example['compile']: 00342 for repo_info in get_repo_list(example): 00343 name = basename(repo_info['repo']) 00344 os.chdir(name) 00345 00346 # Check that the target, toolchain and features combinations are valid and return a 00347 # list of valid combinations to work through 00348 for target, toolchain in target_cross_toolchain(valid_choices(example['targets'], targets), 00349 valid_choices(example['toolchains'], toolchains), 00350 example['features']): 00351 proc = subprocess.Popen(["mbed-cli", "compile", "-t", toolchain, 00352 "-m", target, "--silent"]) 00353 proc.wait() 00354 example_summary = "{} {} {}".format(name, target, toolchain) 00355 if proc.returncode: 00356 failures.append(example_summary) 00357 else: 00358 successes.append(example_summary) 00359 os.chdir("..") 00360 00361 # If there are any compilation failures for the example 'set' then the overall status is fail. 00362 if len(failures) > 0: 00363 pass_status = False 00364 else: 00365 compiled = False 00366 00367 results[example['name']] = [compiled, pass_status, successes, failures] 00368 00369 return results 00370 00371 00372 def update_mbedos_version (config, tag, examples): 00373 """ For each example repo identified in the config json object, update the version of 00374 mbed-os to that specified by the supplied GitHub tag. This function assumes that each 00375 example repo has already been cloned. 00376 00377 Args: 00378 config - the json object imported from the file. 00379 tag - GitHub tag corresponding to a version of mbed-os to upgrade to. 00380 00381 """ 00382 print("Updating mbed-os in examples to version %s\n" % tag) 00383 for example in config['examples']: 00384 if example['name'] not in examples: 00385 continue 00386 for repo_info in get_repo_list(example): 00387 update_dir = basename(repo_info['repo']) + "/mbed-os" 00388 print("\nChanging dir to %s\n" % update_dir) 00389 os.chdir(update_dir) 00390 subprocess.call(["mbed-cli", "update", tag, "--clean"]) 00391 os.chdir("../..") 00392
Generated on Tue Jul 12 2022 14:21:04 by 1.7.2