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