Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: mbed-os-example-blinky-gr-lychee GR-Boads_Camera_sample GR-Boards_Audio_Recoder GR-Boads_Camera_DisplayApp ... more
project_api.py
00001 """ The new way of doing exports """ 00002 import sys 00003 from os.path import join, abspath, dirname, exists 00004 from os.path import basename, relpath, normpath, splitext 00005 from os import makedirs, walk 00006 ROOT = abspath(join(dirname(__file__), "..")) 00007 sys.path.insert(0, ROOT) 00008 import copy 00009 from shutil import rmtree 00010 import zipfile 00011 00012 from tools.build_api import prepare_toolchain 00013 from tools.build_api import scan_resources 00014 from tools.export import EXPORTERS 00015 from tools.toolchains import Resources 00016 00017 00018 def get_exporter_toolchain (ide): 00019 """ Return the exporter class and the toolchain string as a tuple 00020 00021 Positional arguments: 00022 ide - the ide name of an exporter 00023 """ 00024 return EXPORTERS[ide], EXPORTERS[ide].TOOLCHAIN 00025 00026 00027 def rewrite_basepath (file_name, resources, export_path, loc): 00028 """ Replace the basepath of filename with export_path 00029 00030 Positional arguments: 00031 file_name - the absolute path to a file 00032 resources - the resources object that the file came from 00033 export_path - the final destination of the file after export 00034 """ 00035 new_f = join(loc, relpath(file_name, resources.file_basepath[file_name])) 00036 resources.file_basepath[join(export_path, new_f)] = export_path 00037 return new_f 00038 00039 00040 def subtract_basepath (resources, export_path, loc=""): 00041 """ Rewrite all of the basepaths with the export_path 00042 00043 Positional arguments: 00044 resources - the resource object to rewrite the basepaths of 00045 export_path - the final destination of the resources with respect to the 00046 generated project files 00047 """ 00048 keys = ['s_sources', 'c_sources', 'cpp_sources', 'hex_files', 00049 'objects', 'libraries', 'inc_dirs', 'headers', 'linker_script', 00050 'lib_dirs'] 00051 for key in keys: 00052 vals = getattr(resources, key) 00053 if isinstance(vals, set): 00054 vals = list(vals) 00055 if isinstance(vals, list): 00056 new_vals = [] 00057 for val in vals: 00058 new_vals.append(rewrite_basepath(val, resources, export_path, 00059 loc)) 00060 if isinstance(getattr(resources, key), set): 00061 setattr(resources, key, set(new_vals)) 00062 else: 00063 setattr(resources, key, new_vals) 00064 elif vals: 00065 setattr(resources, key, rewrite_basepath(vals, resources, 00066 export_path, loc)) 00067 00068 00069 def generate_project_files (resources, export_path, target, name, toolchain, ide, 00070 macros=None): 00071 """Generate the project files for a project 00072 00073 Positional arguments: 00074 resources - a Resources object containing all of the files needed to build 00075 this project 00076 export_path - location to place project files 00077 name - name of the project 00078 toolchain - a toolchain class that corresponds to the toolchain used by the 00079 IDE or makefile 00080 ide - IDE name to export to 00081 00082 Optional arguments: 00083 macros - additional macros that should be defined within the exported 00084 project 00085 """ 00086 exporter_cls, _ = get_exporter_toolchain(ide) 00087 exporter = exporter_cls(target, export_path, name, toolchain, 00088 extra_symbols=macros, resources=resources) 00089 exporter.generate() 00090 files = exporter.generated_files 00091 return files, exporter 00092 00093 00094 def zip_export (file_name, prefix, resources, project_files, inc_repos): 00095 """Create a zip file from an exported project. 00096 00097 Positional Parameters: 00098 file_name - the file name of the resulting zip file 00099 prefix - a directory name that will prefix the entire zip file's contents 00100 resources - a resources object with files that must be included in the zip 00101 project_files - a list of extra files to be added to the root of the prefix 00102 directory 00103 """ 00104 with zipfile.ZipFile(file_name, "w") as zip_file: 00105 for prj_file in project_files: 00106 zip_file.write(prj_file, join(prefix, basename(prj_file))) 00107 for loc, res in resources.iteritems(): 00108 to_zip = ( 00109 res.headers + res.s_sources + res.c_sources +\ 00110 res.cpp_sources + res.libraries + res.hex_files + \ 00111 [res.linker_script] + res.bin_files + res.objects + \ 00112 res.json_files + res.lib_refs + res.lib_builds) 00113 if inc_repos: 00114 for directory in res.repo_dirs: 00115 for root, _, files in walk(directory): 00116 for repo_file in files: 00117 source = join(root, repo_file) 00118 to_zip.append(source) 00119 res.file_basepath[source] = res.base_path 00120 to_zip += res.repo_files 00121 for source in to_zip: 00122 if source: 00123 zip_file.write( 00124 source, 00125 join(prefix, loc, 00126 relpath(source, res.file_basepath[source]))) 00127 for source in res.lib_builds: 00128 target_dir, _ = splitext(source) 00129 dest = join(prefix, loc, 00130 relpath(target_dir, res.file_basepath[source]), 00131 ".bld", "bldrc") 00132 zip_file.write(source, dest) 00133 00134 00135 00136 def export_project (src_paths, export_path, target, ide, libraries_paths=None, 00137 linker_script=None, notify=None, verbose=False, name=None, 00138 inc_dirs=None, jobs=1, silent=False, extra_verbose=False, 00139 config=None, macros=None, zip_proj=None, inc_repos=False, 00140 build_profile=None): 00141 """Generates a project file and creates a zip archive if specified 00142 00143 Positional Arguments: 00144 src_paths - a list of paths from which to find source files 00145 export_path - a path specifying the location of generated project files 00146 target - the mbed board/mcu for which to generate the executable 00147 ide - the ide for which to generate the project fields 00148 00149 Keyword Arguments: 00150 libraries_paths - paths to additional libraries 00151 linker_script - path to the linker script for the specified target 00152 notify - function is passed all events, and expected to handle notification 00153 of the user, emit the events to a log, etc. 00154 verbose - assigns the notify function to toolchains print_notify_verbose 00155 name - project name 00156 inc_dirs - additional include directories 00157 jobs - number of threads 00158 silent - silent build - no output 00159 extra_verbose - assigns the notify function to toolchains 00160 print_notify_verbose 00161 config - toolchain's config object 00162 macros - User-defined macros 00163 zip_proj - string name of the zip archive you wish to creat (exclude arg 00164 if you do not wish to create an archive 00165 """ 00166 00167 # Convert src_path to a list if needed 00168 if isinstance(src_paths, dict): 00169 paths = sum(src_paths.values(), []) 00170 elif isinstance(src_paths, list): 00171 paths = src_paths[:] 00172 else: 00173 paths = [src_paths] 00174 00175 # Extend src_paths wit libraries_paths 00176 if libraries_paths is not None: 00177 paths.extend(libraries_paths) 00178 00179 if not isinstance(src_paths, dict): 00180 src_paths = {"": paths} 00181 00182 # Export Directory 00183 if not exists(export_path): 00184 makedirs(export_path) 00185 00186 _, toolchain_name = get_exporter_toolchain(ide) 00187 00188 # Pass all params to the unified prepare_resources() 00189 toolchain = prepare_toolchain( 00190 paths, "", target, toolchain_name, macros=macros, jobs=jobs, 00191 notify=notify, silent=silent, verbose=verbose, 00192 extra_verbose=extra_verbose, config=config, build_profile=build_profile) 00193 # The first path will give the name to the library 00194 if name is None: 00195 name = basename(normpath(abspath(src_paths[0]))) 00196 00197 # Call unified scan_resources 00198 resource_dict = {loc: scan_resources(path, toolchain, inc_dirs=inc_dirs) 00199 for loc, path in src_paths.iteritems()} 00200 resources = Resources() 00201 toolchain.build_dir = export_path 00202 config_header = toolchain.get_config_header() 00203 resources.headers.append(config_header) 00204 resources.file_basepath[config_header] = dirname(config_header) 00205 00206 if zip_proj: 00207 subtract_basepath(resources, export_path) 00208 for loc, res in resource_dict.iteritems(): 00209 temp = copy.deepcopy(res) 00210 subtract_basepath(temp, export_path, loc) 00211 resources.add(temp) 00212 else: 00213 for _, res in resource_dict.iteritems(): 00214 resources.add(res) 00215 00216 # Change linker script if specified 00217 if linker_script is not None: 00218 resources.linker_script = linker_script 00219 00220 files, exporter = generate_project_files(resources, export_path, 00221 target, name, toolchain, ide, 00222 macros=macros) 00223 files.append(config_header) 00224 if zip_proj: 00225 for resource in resource_dict.values(): 00226 for label, res in resource.features.iteritems(): 00227 if label not in toolchain.target.features: 00228 resource.add(res) 00229 if isinstance(zip_proj, basestring): 00230 zip_export(join(export_path, zip_proj), name, resource_dict, files, 00231 inc_repos) 00232 else: 00233 zip_export(zip_proj, name, resource_dict, files, inc_repos) 00234 00235 return exporter 00236 00237 00238 def print_results (successes, failures, skips=None): 00239 """ Print out the results of an export process 00240 00241 Positional arguments: 00242 successes - The list of exports that succeeded 00243 failures - The list of exports that failed 00244 00245 Keyword arguments: 00246 skips - The list of exports that were skipped 00247 """ 00248 print 00249 if successes: 00250 print "Successful: " 00251 for success in successes: 00252 print " * %s" % success 00253 if failures: 00254 print "Failed: " 00255 for failure in failures: 00256 print " * %s" % failure 00257 if skips: 00258 print "Skipped: " 00259 for skip in skips: 00260 print " * %s" % skip 00261
Generated on Tue Jul 12 2022 11:02:31 by
1.7.2