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.
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.check_supported() 00090 exporter.generate() 00091 files = exporter.generated_files 00092 return files, exporter 00093 00094 00095 def zip_export (file_name, prefix, resources, project_files, inc_repos): 00096 """Create a zip file from an exported project. 00097 00098 Positional Parameters: 00099 file_name - the file name of the resulting zip file 00100 prefix - a directory name that will prefix the entire zip file's contents 00101 resources - a resources object with files that must be included in the zip 00102 project_files - a list of extra files to be added to the root of the prefix 00103 directory 00104 """ 00105 with zipfile.ZipFile(file_name, "w") as zip_file: 00106 for prj_file in project_files: 00107 zip_file.write(prj_file, join(prefix, basename(prj_file))) 00108 for loc, resource in resources.iteritems(): 00109 for res in [resource] + resource.features.values(): 00110 to_zip = ( 00111 res.headers + res.s_sources + res.c_sources +\ 00112 res.cpp_sources + res.libraries + res.hex_files + \ 00113 [res.linker_script] + res.bin_files + res.objects + \ 00114 res.json_files + res.lib_refs + res.lib_builds) 00115 if inc_repos: 00116 for directory in res.repo_dirs: 00117 for root, _, files in walk(directory): 00118 for repo_file in files: 00119 source = join(root, repo_file) 00120 to_zip.append(source) 00121 res.file_basepath[source] = res.base_path 00122 to_zip += res.repo_files 00123 for source in to_zip: 00124 if source: 00125 zip_file.write( 00126 source, 00127 join(prefix, loc, 00128 relpath(source, res.file_basepath[source]))) 00129 for source in res.lib_builds: 00130 target_dir, _ = splitext(source) 00131 dest = join(prefix, loc, 00132 relpath(target_dir, res.file_basepath[source]), 00133 ".bld", "bldrc") 00134 zip_file.write(source, dest) 00135 00136 00137 00138 def export_project (src_paths, export_path, target, ide, 00139 libraries_paths=None, linker_script=None, clean=False, 00140 notify=None, verbose=False, name=None, inc_dirs=None, 00141 jobs=1, silent=False, extra_verbose=False, config=None, 00142 macros=None, zip_proj=None, inc_repos=False, 00143 build_profile=None): 00144 """Generates a project file and creates a zip archive if specified 00145 00146 Positional Arguments: 00147 src_paths - a list of paths from which to find source files 00148 export_path - a path specifying the location of generated project files 00149 target - the mbed board/mcu for which to generate the executable 00150 ide - the ide for which to generate the project fields 00151 00152 Keyword Arguments: 00153 libraries_paths - paths to additional libraries 00154 linker_script - path to the linker script for the specified target 00155 clean - removes the export_path if it exists 00156 notify - function is passed all events, and expected to handle notification 00157 of the user, emit the events to a log, etc. 00158 verbose - assigns the notify function to toolchains print_notify_verbose 00159 name - project name 00160 inc_dirs - additional include directories 00161 jobs - number of threads 00162 silent - silent build - no output 00163 extra_verbose - assigns the notify function to toolchains 00164 print_notify_verbose 00165 config - toolchain's config object 00166 macros - User-defined macros 00167 zip_proj - string name of the zip archive you wish to creat (exclude arg 00168 if you do not wish to create an archive 00169 """ 00170 00171 # Convert src_path to a list if needed 00172 if isinstance(src_paths, dict): 00173 paths = sum(src_paths.values(), []) 00174 elif isinstance(src_paths, list): 00175 paths = src_paths[:] 00176 else: 00177 paths = [src_paths] 00178 00179 # Extend src_paths wit libraries_paths 00180 if libraries_paths is not None: 00181 paths.extend(libraries_paths) 00182 00183 if not isinstance(src_paths, dict): 00184 src_paths = {"": paths} 00185 00186 # Export Directory 00187 if exists(export_path) and clean: 00188 rmtree(export_path) 00189 if not exists(export_path): 00190 makedirs(export_path) 00191 00192 _, toolchain_name = get_exporter_toolchain(ide) 00193 00194 # Pass all params to the unified prepare_resources() 00195 toolchain = prepare_toolchain(paths, target, toolchain_name, 00196 macros=macros, clean=clean, jobs=jobs, 00197 notify=notify, silent=silent, verbose=verbose, 00198 extra_verbose=extra_verbose, config=config, 00199 build_profile=build_profile) 00200 # The first path will give the name to the library 00201 if name is None: 00202 name = basename(normpath(abspath(src_paths[0]))) 00203 00204 # Call unified scan_resources 00205 resource_dict = {loc: scan_resources(path, toolchain, inc_dirs=inc_dirs) 00206 for loc, path in src_paths.iteritems()} 00207 resources = Resources() 00208 toolchain.build_dir = export_path 00209 config_header = toolchain.get_config_header() 00210 resources.headers.append(config_header) 00211 resources.file_basepath[config_header] = dirname(config_header) 00212 00213 if zip_proj: 00214 subtract_basepath(resources, export_path) 00215 for loc, res in resource_dict.iteritems(): 00216 temp = copy.deepcopy(res) 00217 subtract_basepath(temp, export_path, loc) 00218 resources.add(temp) 00219 else: 00220 for _, res in resource_dict.iteritems(): 00221 resources.add(res) 00222 00223 # Change linker script if specified 00224 if linker_script is not None: 00225 resources.linker_script = linker_script 00226 00227 files, exporter = generate_project_files(resources, export_path, 00228 target, name, toolchain, ide, 00229 macros=macros) 00230 files.append(config_header) 00231 if zip_proj: 00232 if isinstance(zip_proj, basestring): 00233 zip_export(join(export_path, zip_proj), name, resource_dict, files, inc_repos) 00234 else: 00235 zip_export(zip_proj, name, resource_dict, files, inc_repos) 00236 00237 return exporter 00238 00239 00240 def print_results (successes, failures, skips=None): 00241 """ Print out the results of an export process 00242 00243 Positional arguments: 00244 successes - The list of exports that succeeded 00245 failures - The list of exports that failed 00246 00247 Keyword arguments: 00248 skips - The list of exports that were skipped 00249 """ 00250 print 00251 if successes: 00252 print "Successful: " 00253 for success in successes: 00254 print " * %s" % success 00255 if failures: 00256 print "Failed: " 00257 for failure in failures: 00258 print " * %s" % failure 00259 if skips: 00260 print "Skipped: " 00261 for skip in skips: 00262 print " * %s" % skip 00263
Generated on Tue Jul 12 2022 17:34:52 by
