Development mbed library for MAX32630FTHR
Dependents: blinky_max32630fthr
tools/project_api.py@3:1198227e6421, 2016-12-16 (annotated)
- Committer:
- switches
- Date:
- Fri Dec 16 16:27:57 2016 +0000
- Revision:
- 3:1198227e6421
- Parent:
- 0:5c4d7b2438d3
Changed ADC scale for MAX32625 platforms to 1.2V full scale to match MAX32630 platforms
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
switches | 0:5c4d7b2438d3 | 1 | """ The new way of doing exports """ |
switches | 0:5c4d7b2438d3 | 2 | import sys |
switches | 0:5c4d7b2438d3 | 3 | from os.path import join, abspath, dirname, exists |
switches | 0:5c4d7b2438d3 | 4 | from os.path import basename, relpath, normpath, splitext |
switches | 0:5c4d7b2438d3 | 5 | from os import makedirs, walk |
switches | 0:5c4d7b2438d3 | 6 | ROOT = abspath(join(dirname(__file__), "..")) |
switches | 0:5c4d7b2438d3 | 7 | sys.path.insert(0, ROOT) |
switches | 0:5c4d7b2438d3 | 8 | import copy |
switches | 0:5c4d7b2438d3 | 9 | from shutil import rmtree |
switches | 0:5c4d7b2438d3 | 10 | import zipfile |
switches | 0:5c4d7b2438d3 | 11 | |
switches | 0:5c4d7b2438d3 | 12 | from tools.build_api import prepare_toolchain |
switches | 0:5c4d7b2438d3 | 13 | from tools.build_api import scan_resources |
switches | 0:5c4d7b2438d3 | 14 | from tools.export import EXPORTERS |
switches | 0:5c4d7b2438d3 | 15 | from tools.toolchains import Resources |
switches | 0:5c4d7b2438d3 | 16 | |
switches | 0:5c4d7b2438d3 | 17 | |
switches | 0:5c4d7b2438d3 | 18 | def get_exporter_toolchain(ide): |
switches | 0:5c4d7b2438d3 | 19 | """ Return the exporter class and the toolchain string as a tuple |
switches | 0:5c4d7b2438d3 | 20 | |
switches | 0:5c4d7b2438d3 | 21 | Positional arguments: |
switches | 0:5c4d7b2438d3 | 22 | ide - the ide name of an exporter |
switches | 0:5c4d7b2438d3 | 23 | """ |
switches | 0:5c4d7b2438d3 | 24 | return EXPORTERS[ide], EXPORTERS[ide].TOOLCHAIN |
switches | 0:5c4d7b2438d3 | 25 | |
switches | 0:5c4d7b2438d3 | 26 | |
switches | 0:5c4d7b2438d3 | 27 | def rewrite_basepath(file_name, resources, export_path, loc): |
switches | 0:5c4d7b2438d3 | 28 | """ Replace the basepath of filename with export_path |
switches | 0:5c4d7b2438d3 | 29 | |
switches | 0:5c4d7b2438d3 | 30 | Positional arguments: |
switches | 0:5c4d7b2438d3 | 31 | file_name - the absolute path to a file |
switches | 0:5c4d7b2438d3 | 32 | resources - the resources object that the file came from |
switches | 0:5c4d7b2438d3 | 33 | export_path - the final destination of the file after export |
switches | 0:5c4d7b2438d3 | 34 | """ |
switches | 0:5c4d7b2438d3 | 35 | new_f = join(loc, relpath(file_name, resources.file_basepath[file_name])) |
switches | 0:5c4d7b2438d3 | 36 | resources.file_basepath[join(export_path, new_f)] = export_path |
switches | 0:5c4d7b2438d3 | 37 | return new_f |
switches | 0:5c4d7b2438d3 | 38 | |
switches | 0:5c4d7b2438d3 | 39 | |
switches | 0:5c4d7b2438d3 | 40 | def subtract_basepath(resources, export_path, loc=""): |
switches | 0:5c4d7b2438d3 | 41 | """ Rewrite all of the basepaths with the export_path |
switches | 0:5c4d7b2438d3 | 42 | |
switches | 0:5c4d7b2438d3 | 43 | Positional arguments: |
switches | 0:5c4d7b2438d3 | 44 | resources - the resource object to rewrite the basepaths of |
switches | 0:5c4d7b2438d3 | 45 | export_path - the final destination of the resources with respect to the |
switches | 0:5c4d7b2438d3 | 46 | generated project files |
switches | 0:5c4d7b2438d3 | 47 | """ |
switches | 0:5c4d7b2438d3 | 48 | keys = ['s_sources', 'c_sources', 'cpp_sources', 'hex_files', |
switches | 0:5c4d7b2438d3 | 49 | 'objects', 'libraries', 'inc_dirs', 'headers', 'linker_script', |
switches | 0:5c4d7b2438d3 | 50 | 'lib_dirs'] |
switches | 0:5c4d7b2438d3 | 51 | for key in keys: |
switches | 0:5c4d7b2438d3 | 52 | vals = getattr(resources, key) |
switches | 0:5c4d7b2438d3 | 53 | if isinstance(vals, set): |
switches | 0:5c4d7b2438d3 | 54 | vals = list(vals) |
switches | 0:5c4d7b2438d3 | 55 | if isinstance(vals, list): |
switches | 0:5c4d7b2438d3 | 56 | new_vals = [] |
switches | 0:5c4d7b2438d3 | 57 | for val in vals: |
switches | 0:5c4d7b2438d3 | 58 | new_vals.append(rewrite_basepath(val, resources, export_path, |
switches | 0:5c4d7b2438d3 | 59 | loc)) |
switches | 0:5c4d7b2438d3 | 60 | if isinstance(getattr(resources, key), set): |
switches | 0:5c4d7b2438d3 | 61 | setattr(resources, key, set(new_vals)) |
switches | 0:5c4d7b2438d3 | 62 | else: |
switches | 0:5c4d7b2438d3 | 63 | setattr(resources, key, new_vals) |
switches | 0:5c4d7b2438d3 | 64 | elif vals: |
switches | 0:5c4d7b2438d3 | 65 | setattr(resources, key, rewrite_basepath(vals, resources, |
switches | 0:5c4d7b2438d3 | 66 | export_path, loc)) |
switches | 0:5c4d7b2438d3 | 67 | |
switches | 0:5c4d7b2438d3 | 68 | |
switches | 0:5c4d7b2438d3 | 69 | def generate_project_files(resources, export_path, target, name, toolchain, ide, |
switches | 0:5c4d7b2438d3 | 70 | macros=None): |
switches | 0:5c4d7b2438d3 | 71 | """Generate the project files for a project |
switches | 0:5c4d7b2438d3 | 72 | |
switches | 0:5c4d7b2438d3 | 73 | Positional arguments: |
switches | 0:5c4d7b2438d3 | 74 | resources - a Resources object containing all of the files needed to build |
switches | 0:5c4d7b2438d3 | 75 | this project |
switches | 0:5c4d7b2438d3 | 76 | export_path - location to place project files |
switches | 0:5c4d7b2438d3 | 77 | name - name of the project |
switches | 0:5c4d7b2438d3 | 78 | toolchain - a toolchain class that corresponds to the toolchain used by the |
switches | 0:5c4d7b2438d3 | 79 | IDE or makefile |
switches | 0:5c4d7b2438d3 | 80 | ide - IDE name to export to |
switches | 0:5c4d7b2438d3 | 81 | |
switches | 0:5c4d7b2438d3 | 82 | Optional arguments: |
switches | 0:5c4d7b2438d3 | 83 | macros - additional macros that should be defined within the exported |
switches | 0:5c4d7b2438d3 | 84 | project |
switches | 0:5c4d7b2438d3 | 85 | """ |
switches | 0:5c4d7b2438d3 | 86 | exporter_cls, _ = get_exporter_toolchain(ide) |
switches | 0:5c4d7b2438d3 | 87 | exporter = exporter_cls(target, export_path, name, toolchain, |
switches | 0:5c4d7b2438d3 | 88 | extra_symbols=macros, resources=resources) |
switches | 0:5c4d7b2438d3 | 89 | exporter.generate() |
switches | 0:5c4d7b2438d3 | 90 | files = exporter.generated_files |
switches | 0:5c4d7b2438d3 | 91 | return files, exporter |
switches | 0:5c4d7b2438d3 | 92 | |
switches | 0:5c4d7b2438d3 | 93 | |
switches | 0:5c4d7b2438d3 | 94 | def zip_export(file_name, prefix, resources, project_files, inc_repos): |
switches | 0:5c4d7b2438d3 | 95 | """Create a zip file from an exported project. |
switches | 0:5c4d7b2438d3 | 96 | |
switches | 0:5c4d7b2438d3 | 97 | Positional Parameters: |
switches | 0:5c4d7b2438d3 | 98 | file_name - the file name of the resulting zip file |
switches | 0:5c4d7b2438d3 | 99 | prefix - a directory name that will prefix the entire zip file's contents |
switches | 0:5c4d7b2438d3 | 100 | resources - a resources object with files that must be included in the zip |
switches | 0:5c4d7b2438d3 | 101 | project_files - a list of extra files to be added to the root of the prefix |
switches | 0:5c4d7b2438d3 | 102 | directory |
switches | 0:5c4d7b2438d3 | 103 | """ |
switches | 0:5c4d7b2438d3 | 104 | with zipfile.ZipFile(file_name, "w") as zip_file: |
switches | 0:5c4d7b2438d3 | 105 | for prj_file in project_files: |
switches | 0:5c4d7b2438d3 | 106 | zip_file.write(prj_file, join(prefix, basename(prj_file))) |
switches | 0:5c4d7b2438d3 | 107 | for loc, resource in resources.iteritems(): |
switches | 0:5c4d7b2438d3 | 108 | for res in [resource] + resource.features.values(): |
switches | 0:5c4d7b2438d3 | 109 | to_zip = ( |
switches | 0:5c4d7b2438d3 | 110 | res.headers + res.s_sources + res.c_sources +\ |
switches | 0:5c4d7b2438d3 | 111 | res.cpp_sources + res.libraries + res.hex_files + \ |
switches | 0:5c4d7b2438d3 | 112 | [res.linker_script] + res.bin_files + res.objects + \ |
switches | 0:5c4d7b2438d3 | 113 | res.json_files + res.lib_refs + res.lib_builds) |
switches | 0:5c4d7b2438d3 | 114 | if inc_repos: |
switches | 0:5c4d7b2438d3 | 115 | for directory in res.repo_dirs: |
switches | 0:5c4d7b2438d3 | 116 | for root, _, files in walk(directory): |
switches | 0:5c4d7b2438d3 | 117 | for repo_file in files: |
switches | 0:5c4d7b2438d3 | 118 | source = join(root, repo_file) |
switches | 0:5c4d7b2438d3 | 119 | to_zip.append(source) |
switches | 0:5c4d7b2438d3 | 120 | res.file_basepath[source] = res.base_path |
switches | 0:5c4d7b2438d3 | 121 | to_zip += res.repo_files |
switches | 0:5c4d7b2438d3 | 122 | for source in to_zip: |
switches | 0:5c4d7b2438d3 | 123 | if source: |
switches | 0:5c4d7b2438d3 | 124 | zip_file.write( |
switches | 0:5c4d7b2438d3 | 125 | source, |
switches | 0:5c4d7b2438d3 | 126 | join(prefix, loc, |
switches | 0:5c4d7b2438d3 | 127 | relpath(source, res.file_basepath[source]))) |
switches | 0:5c4d7b2438d3 | 128 | for source in res.lib_builds: |
switches | 0:5c4d7b2438d3 | 129 | target_dir, _ = splitext(source) |
switches | 0:5c4d7b2438d3 | 130 | dest = join(prefix, loc, |
switches | 0:5c4d7b2438d3 | 131 | relpath(target_dir, res.file_basepath[source]), |
switches | 0:5c4d7b2438d3 | 132 | ".bld", "bldrc") |
switches | 0:5c4d7b2438d3 | 133 | zip_file.write(source, dest) |
switches | 0:5c4d7b2438d3 | 134 | |
switches | 0:5c4d7b2438d3 | 135 | |
switches | 0:5c4d7b2438d3 | 136 | |
switches | 0:5c4d7b2438d3 | 137 | def export_project(src_paths, export_path, target, ide, |
switches | 0:5c4d7b2438d3 | 138 | libraries_paths=None, linker_script=None, clean=False, |
switches | 0:5c4d7b2438d3 | 139 | notify=None, verbose=False, name=None, inc_dirs=None, |
switches | 0:5c4d7b2438d3 | 140 | jobs=1, silent=False, extra_verbose=False, config=None, |
switches | 0:5c4d7b2438d3 | 141 | macros=None, zip_proj=None, inc_repos=False, |
switches | 0:5c4d7b2438d3 | 142 | build_profile=None): |
switches | 0:5c4d7b2438d3 | 143 | """Generates a project file and creates a zip archive if specified |
switches | 0:5c4d7b2438d3 | 144 | |
switches | 0:5c4d7b2438d3 | 145 | Positional Arguments: |
switches | 0:5c4d7b2438d3 | 146 | src_paths - a list of paths from which to find source files |
switches | 0:5c4d7b2438d3 | 147 | export_path - a path specifying the location of generated project files |
switches | 0:5c4d7b2438d3 | 148 | target - the mbed board/mcu for which to generate the executable |
switches | 0:5c4d7b2438d3 | 149 | ide - the ide for which to generate the project fields |
switches | 0:5c4d7b2438d3 | 150 | |
switches | 0:5c4d7b2438d3 | 151 | Keyword Arguments: |
switches | 0:5c4d7b2438d3 | 152 | libraries_paths - paths to additional libraries |
switches | 0:5c4d7b2438d3 | 153 | linker_script - path to the linker script for the specified target |
switches | 0:5c4d7b2438d3 | 154 | clean - removes the export_path if it exists |
switches | 0:5c4d7b2438d3 | 155 | notify - function is passed all events, and expected to handle notification |
switches | 0:5c4d7b2438d3 | 156 | of the user, emit the events to a log, etc. |
switches | 0:5c4d7b2438d3 | 157 | verbose - assigns the notify function to toolchains print_notify_verbose |
switches | 0:5c4d7b2438d3 | 158 | name - project name |
switches | 0:5c4d7b2438d3 | 159 | inc_dirs - additional include directories |
switches | 0:5c4d7b2438d3 | 160 | jobs - number of threads |
switches | 0:5c4d7b2438d3 | 161 | silent - silent build - no output |
switches | 0:5c4d7b2438d3 | 162 | extra_verbose - assigns the notify function to toolchains |
switches | 0:5c4d7b2438d3 | 163 | print_notify_verbose |
switches | 0:5c4d7b2438d3 | 164 | config - toolchain's config object |
switches | 0:5c4d7b2438d3 | 165 | macros - User-defined macros |
switches | 0:5c4d7b2438d3 | 166 | zip_proj - string name of the zip archive you wish to creat (exclude arg |
switches | 0:5c4d7b2438d3 | 167 | if you do not wish to create an archive |
switches | 0:5c4d7b2438d3 | 168 | """ |
switches | 0:5c4d7b2438d3 | 169 | |
switches | 0:5c4d7b2438d3 | 170 | # Convert src_path to a list if needed |
switches | 0:5c4d7b2438d3 | 171 | if isinstance(src_paths, dict): |
switches | 0:5c4d7b2438d3 | 172 | paths = sum(src_paths.values(), []) |
switches | 0:5c4d7b2438d3 | 173 | elif isinstance(src_paths, list): |
switches | 0:5c4d7b2438d3 | 174 | paths = src_paths[:] |
switches | 0:5c4d7b2438d3 | 175 | else: |
switches | 0:5c4d7b2438d3 | 176 | paths = [src_paths] |
switches | 0:5c4d7b2438d3 | 177 | |
switches | 0:5c4d7b2438d3 | 178 | # Extend src_paths wit libraries_paths |
switches | 0:5c4d7b2438d3 | 179 | if libraries_paths is not None: |
switches | 0:5c4d7b2438d3 | 180 | paths.extend(libraries_paths) |
switches | 0:5c4d7b2438d3 | 181 | |
switches | 0:5c4d7b2438d3 | 182 | if not isinstance(src_paths, dict): |
switches | 0:5c4d7b2438d3 | 183 | src_paths = {"": paths} |
switches | 0:5c4d7b2438d3 | 184 | |
switches | 0:5c4d7b2438d3 | 185 | # Export Directory |
switches | 0:5c4d7b2438d3 | 186 | if exists(export_path) and clean: |
switches | 0:5c4d7b2438d3 | 187 | rmtree(export_path) |
switches | 0:5c4d7b2438d3 | 188 | if not exists(export_path): |
switches | 0:5c4d7b2438d3 | 189 | makedirs(export_path) |
switches | 0:5c4d7b2438d3 | 190 | |
switches | 0:5c4d7b2438d3 | 191 | _, toolchain_name = get_exporter_toolchain(ide) |
switches | 0:5c4d7b2438d3 | 192 | |
switches | 0:5c4d7b2438d3 | 193 | # Pass all params to the unified prepare_resources() |
switches | 0:5c4d7b2438d3 | 194 | toolchain = prepare_toolchain(paths, target, toolchain_name, |
switches | 0:5c4d7b2438d3 | 195 | macros=macros, clean=clean, jobs=jobs, |
switches | 0:5c4d7b2438d3 | 196 | notify=notify, silent=silent, verbose=verbose, |
switches | 0:5c4d7b2438d3 | 197 | extra_verbose=extra_verbose, config=config, |
switches | 0:5c4d7b2438d3 | 198 | build_profile=build_profile) |
switches | 0:5c4d7b2438d3 | 199 | # The first path will give the name to the library |
switches | 0:5c4d7b2438d3 | 200 | if name is None: |
switches | 0:5c4d7b2438d3 | 201 | name = basename(normpath(abspath(src_paths[0]))) |
switches | 0:5c4d7b2438d3 | 202 | |
switches | 0:5c4d7b2438d3 | 203 | # Call unified scan_resources |
switches | 0:5c4d7b2438d3 | 204 | resource_dict = {loc: scan_resources(path, toolchain, inc_dirs=inc_dirs) |
switches | 0:5c4d7b2438d3 | 205 | for loc, path in src_paths.iteritems()} |
switches | 0:5c4d7b2438d3 | 206 | resources = Resources() |
switches | 0:5c4d7b2438d3 | 207 | toolchain.build_dir = export_path |
switches | 0:5c4d7b2438d3 | 208 | config_header = toolchain.get_config_header() |
switches | 0:5c4d7b2438d3 | 209 | resources.headers.append(config_header) |
switches | 0:5c4d7b2438d3 | 210 | resources.file_basepath[config_header] = dirname(config_header) |
switches | 0:5c4d7b2438d3 | 211 | |
switches | 0:5c4d7b2438d3 | 212 | if zip_proj: |
switches | 0:5c4d7b2438d3 | 213 | subtract_basepath(resources, export_path) |
switches | 0:5c4d7b2438d3 | 214 | for loc, res in resource_dict.iteritems(): |
switches | 0:5c4d7b2438d3 | 215 | temp = copy.deepcopy(res) |
switches | 0:5c4d7b2438d3 | 216 | subtract_basepath(temp, export_path, loc) |
switches | 0:5c4d7b2438d3 | 217 | resources.add(temp) |
switches | 0:5c4d7b2438d3 | 218 | else: |
switches | 0:5c4d7b2438d3 | 219 | for _, res in resource_dict.iteritems(): |
switches | 0:5c4d7b2438d3 | 220 | resources.add(res) |
switches | 0:5c4d7b2438d3 | 221 | |
switches | 0:5c4d7b2438d3 | 222 | # Change linker script if specified |
switches | 0:5c4d7b2438d3 | 223 | if linker_script is not None: |
switches | 0:5c4d7b2438d3 | 224 | resources.linker_script = linker_script |
switches | 0:5c4d7b2438d3 | 225 | |
switches | 0:5c4d7b2438d3 | 226 | files, exporter = generate_project_files(resources, export_path, |
switches | 0:5c4d7b2438d3 | 227 | target, name, toolchain, ide, |
switches | 0:5c4d7b2438d3 | 228 | macros=macros) |
switches | 0:5c4d7b2438d3 | 229 | files.append(config_header) |
switches | 0:5c4d7b2438d3 | 230 | if zip_proj: |
switches | 0:5c4d7b2438d3 | 231 | if isinstance(zip_proj, basestring): |
switches | 0:5c4d7b2438d3 | 232 | zip_export(join(export_path, zip_proj), name, resource_dict, files, inc_repos) |
switches | 0:5c4d7b2438d3 | 233 | else: |
switches | 0:5c4d7b2438d3 | 234 | zip_export(zip_proj, name, resource_dict, files, inc_repos) |
switches | 0:5c4d7b2438d3 | 235 | |
switches | 0:5c4d7b2438d3 | 236 | return exporter |
switches | 0:5c4d7b2438d3 | 237 | |
switches | 0:5c4d7b2438d3 | 238 | |
switches | 0:5c4d7b2438d3 | 239 | def print_results(successes, failures, skips=None): |
switches | 0:5c4d7b2438d3 | 240 | """ Print out the results of an export process |
switches | 0:5c4d7b2438d3 | 241 | |
switches | 0:5c4d7b2438d3 | 242 | Positional arguments: |
switches | 0:5c4d7b2438d3 | 243 | successes - The list of exports that succeeded |
switches | 0:5c4d7b2438d3 | 244 | failures - The list of exports that failed |
switches | 0:5c4d7b2438d3 | 245 | |
switches | 0:5c4d7b2438d3 | 246 | Keyword arguments: |
switches | 0:5c4d7b2438d3 | 247 | skips - The list of exports that were skipped |
switches | 0:5c4d7b2438d3 | 248 | """ |
switches | 0:5c4d7b2438d3 | 249 | |
switches | 0:5c4d7b2438d3 | 250 | if successes: |
switches | 0:5c4d7b2438d3 | 251 | print "Successful: " |
switches | 0:5c4d7b2438d3 | 252 | for success in successes: |
switches | 0:5c4d7b2438d3 | 253 | print " * %s" % success |
switches | 0:5c4d7b2438d3 | 254 | if failures: |
switches | 0:5c4d7b2438d3 | 255 | print "Failed: " |
switches | 0:5c4d7b2438d3 | 256 | for failure in failures: |
switches | 0:5c4d7b2438d3 | 257 | print " * %s" % failure |
switches | 0:5c4d7b2438d3 | 258 | if skips: |
switches | 0:5c4d7b2438d3 | 259 | print "Skipped: " |
switches | 0:5c4d7b2438d3 | 260 | for skip in skips: |
switches | 0:5c4d7b2438d3 | 261 | print " * %s" % skip |
switches | 0:5c4d7b2438d3 | 262 |