Gleb Klochkov / Mbed OS Climatcontroll_Main

Dependencies:   esp8266-driver

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers __init__.py Source File

__init__.py

00001 """The generic interface for all exporters.
00002 """
00003 # mbed SDK
00004 # Copyright (c) 2011-2016 ARM Limited
00005 #
00006 # Licensed under the Apache License, Version 2.0 (the "License");
00007 # you may not use this file except in compliance with the License.
00008 # You may obtain a copy of the License at
00009 #
00010 #     http://www.apache.org/licenses/LICENSE-2.0
00011 #
00012 # Unless required by applicable law or agreed to in writing, software
00013 # distributed under the License is distributed on an "AS IS" BASIS,
00014 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015 # See the License for the specific language governing permissions and
00016 # limitations under the License.
00017 
00018 from __future__ import print_function, division, absolute_import
00019 
00020 import sys
00021 from os.path import join, abspath, dirname, exists
00022 from os.path import basename, relpath, normpath, splitext
00023 from os import makedirs, walk
00024 import copy
00025 from shutil import rmtree, copyfile
00026 import zipfile
00027 
00028 from ..build_api import prepare_toolchain, scan_resources
00029 from ..toolchains import Resources
00030 from ..targets import TARGET_NAMES
00031 from . import (lpcxpresso, ds5_5, iar, makefile, embitz, coide, kds, simplicity,
00032                atmelstudio, mcuxpresso, sw4stm32, e2studio, zip, cmsis, uvision,
00033                cdt, vscode, gnuarmeclipse, qtcreator, cmake, nb, cces, codeblocks)
00034 
00035 EXPORTERS = {
00036     u'uvision5': uvision.Uvision,
00037     u'uvision': uvision.Uvision,
00038     u'lpcxpresso': lpcxpresso.LPCXpresso,
00039     u'gcc_arm': makefile.GccArm,
00040     u'make_gcc_arm': makefile.GccArm,
00041     u'make_armc5': makefile.Armc5,
00042     u'make_armc6': makefile.Armc6,
00043     u'make_iar': makefile.IAR,
00044     u'ds5_5': ds5_5.DS5_5,
00045     u'iar': iar.IAR,
00046     u'embitz' : embitz.EmBitz,
00047     u'coide' : coide.CoIDE,
00048     u'kds' : kds.KDS,
00049     u'simplicityv3' : simplicity.SimplicityV3,
00050     u'atmelstudio' : atmelstudio.AtmelStudio,
00051     u'sw4stm32'    : sw4stm32.Sw4STM32,
00052     u'e2studio' : e2studio.E2Studio,
00053     u'eclipse_gcc_arm'  : cdt.EclipseGcc,
00054     u'eclipse_iar'      : cdt.EclipseIAR,
00055     u'eclipse_armc5'    : cdt.EclipseArmc5,
00056     u'gnuarmeclipse': gnuarmeclipse.GNUARMEclipse,
00057     u'mcuxpresso': mcuxpresso.MCUXpresso,
00058     u'netbeans':     nb.GNUARMNetbeans,
00059     u'qtcreator': qtcreator.QtCreator,
00060     u'vscode_gcc_arm' : vscode.VSCodeGcc,
00061     u'vscode_iar' : vscode.VSCodeIAR,
00062     u'vscode_armc5' : vscode.VSCodeArmc5,
00063     u'cmake_gcc_arm': cmake.GccArm,
00064     u'cces' : cces.CCES,
00065     u'codeblocks': codeblocks.CodeBlocks
00066 }
00067 
00068 ERROR_MESSAGE_UNSUPPORTED_TOOLCHAIN = """
00069 Sorry, the target %s is not currently supported on the %s toolchain.
00070 Please refer to <a href='/handbook/Exporting-to-offline-toolchains' target='_blank'>Exporting to offline toolchains</a> for more information.
00071 """
00072 
00073 ERROR_MESSAGE_NOT_EXPORT_LIBS = """
00074 To export this project please <a href='http://mbed.org/compiler/?import=http://mbed.org/users/mbed_official/code/mbed-export/k&mode=lib' target='_blank'>import the export version of the mbed library</a>.
00075 """
00076 
00077 def mcu_ide_list ():
00078     """Shows list of exportable ides 
00079 
00080     """
00081     supported_ides = sorted(EXPORTERS.keys())
00082     return "\n".join(supported_ides)
00083 
00084 
00085 def mcu_ide_matrix (verbose_html=False):
00086     """Shows target map using prettytable
00087 
00088     Keyword argumets:
00089     verbose_html - print the matrix in html format
00090     """
00091     supported_ides = sorted(EXPORTERS.keys())
00092     # Only use it in this function so building works without extra modules
00093     from prettytable import PrettyTable, ALL
00094 
00095     # All tests status table print
00096     table_printer = PrettyTable(["Platform"] + supported_ides)
00097     # Align table
00098     for col in supported_ides:
00099         table_printer.align[col] = "c"
00100     table_printer.align["Platform"] = "l"
00101 
00102     perm_counter = 0
00103     for target in sorted(TARGET_NAMES):
00104         row = [target]  # First column is platform name
00105         for ide in supported_ides:
00106             text = "-"
00107             if EXPORTERS[ide].is_target_supported(target):
00108                 if verbose_html:
00109                     text = "&#10003;"
00110                 else:
00111                     text = "x"
00112                 perm_counter += 1
00113             row.append(text)
00114         table_printer.add_row(row)
00115 
00116     table_printer.border = True
00117     table_printer.vrules = ALL
00118     table_printer.hrules = ALL
00119     # creates a html page in a shorter format suitable for readme.md
00120     if verbose_html:
00121         result = table_printer.get_html_string()
00122     else:
00123         result = table_printer.get_string()
00124     result += "\n"
00125     result += "Total IDEs: %d\n"% (len(supported_ides))
00126     if verbose_html:
00127         result += "<br>"
00128     result += "Total platforms: %d\n"% (len(TARGET_NAMES))
00129     if verbose_html:
00130         result += "<br>"
00131     result += "Total permutations: %d"% (perm_counter)
00132     if verbose_html:
00133         result = result.replace("&amp;", "&")
00134     return result
00135 
00136 
00137 def get_exporter_toolchain (ide):
00138     """ Return the exporter class and the toolchain string as a tuple
00139 
00140     Positional arguments:
00141     ide - the ide name of an exporter
00142     """
00143     return EXPORTERS[ide], EXPORTERS[ide].TOOLCHAIN
00144 
00145 
00146 def rewrite_basepath (file_name, resources, export_path, loc):
00147     """ Replace the basepath of filename with export_path
00148 
00149     Positional arguments:
00150     file_name - the absolute path to a file
00151     resources - the resources object that the file came from
00152     export_path - the final destination of the file after export
00153     """
00154     new_f = join(loc, relpath(file_name, resources.file_basepath[file_name]))
00155     resources.file_basepath[new_f] = export_path
00156     return new_f
00157 
00158 
00159 def subtract_basepath (resources, export_path, loc=""):
00160     """ Rewrite all of the basepaths with the export_path
00161 
00162     Positional arguments:
00163     resources - the resource object to rewrite the basepaths of
00164     export_path - the final destination of the resources with respect to the
00165       generated project files
00166     """
00167     keys = ['s_sources', 'c_sources', 'cpp_sources', 'hex_files',
00168             'objects', 'libraries', 'inc_dirs', 'headers', 'linker_script',
00169             'lib_dirs']
00170     for key in keys:
00171         vals = getattr(resources, key)
00172         if isinstance(vals, set):
00173             vals = list(vals)
00174         if isinstance(vals, list):
00175             new_vals = []
00176             for val in vals:
00177                 new_vals.append(rewrite_basepath(val, resources, export_path,
00178                                                  loc))
00179             if isinstance(getattr(resources, key), set):
00180                 setattr(resources, key, set(new_vals))
00181             else:
00182                 setattr(resources, key, new_vals)
00183         elif vals:
00184             setattr(resources, key, rewrite_basepath(vals, resources,
00185                                                      export_path, loc))
00186 
00187 
00188 def generate_project_files (resources, export_path, target, name, toolchain, ide,
00189                            macros=None):
00190     """Generate the project files for a project
00191 
00192     Positional arguments:
00193     resources - a Resources object containing all of the files needed to build
00194       this project
00195     export_path - location to place project files
00196     name - name of the project
00197     toolchain - a toolchain class that corresponds to the toolchain used by the
00198       IDE or makefile
00199     ide - IDE name to export to
00200 
00201     Optional arguments:
00202     macros - additional macros that should be defined within the exported
00203       project
00204     """
00205     exporter_cls, _ = get_exporter_toolchain(ide)
00206     exporter = exporter_cls(target, export_path, name, toolchain,
00207                             extra_symbols=macros, resources=resources)
00208     exporter.generate()
00209     files = exporter.generated_files
00210     return files, exporter
00211 
00212 
00213 def zip_export (file_name, prefix, resources, project_files, inc_repos):
00214     """Create a zip file from an exported project.
00215 
00216     Positional Parameters:
00217     file_name - the file name of the resulting zip file
00218     prefix - a directory name that will prefix the entire zip file's contents
00219     resources - a resources object with files that must be included in the zip
00220     project_files - a list of extra files to be added to the root of the prefix
00221       directory
00222     """
00223     with zipfile.ZipFile(file_name, "w") as zip_file:
00224         for prj_file in project_files:
00225             zip_file.write(prj_file, join(prefix, basename(prj_file)))
00226         for loc, res in resources.items():
00227             to_zip = (
00228                 res.headers + res.s_sources + res.c_sources +\
00229                 res.cpp_sources + res.libraries + res.hex_files + \
00230                 [res.linker_script] + res.bin_files + res.objects + \
00231                 res.json_files + res.lib_refs + res.lib_builds)
00232             if inc_repos:
00233                 for directory in res.repo_dirs:
00234                     for root, _, files in walk(directory):
00235                         for repo_file in files:
00236                             source = join(root, repo_file)
00237                             to_zip.append(source)
00238                             res.file_basepath[source] = res.base_path
00239                 to_zip += res.repo_files
00240             for source in to_zip:
00241                 if source:
00242                     zip_file.write(
00243                         source,
00244                         join(prefix, loc,
00245                              relpath(source, res.file_basepath[source])))
00246             for source in res.lib_builds:
00247                 target_dir, _ = splitext(source)
00248                 dest = join(prefix, loc,
00249                             relpath(target_dir, res.file_basepath[source]),
00250                             ".bld", "bldrc")
00251                 zip_file.write(source, dest)
00252 
00253 
00254 
00255 def export_project (src_paths, export_path, target, ide, libraries_paths=None,
00256                    linker_script=None, notify=None, verbose=False, name=None,
00257                    inc_dirs=None, jobs=1, silent=False, extra_verbose=False,
00258                    config=None, macros=None, zip_proj=None, inc_repos=False,
00259                    build_profile=None, app_config=None):
00260     """Generates a project file and creates a zip archive if specified
00261 
00262     Positional Arguments:
00263     src_paths - a list of paths from which to find source files
00264     export_path - a path specifying the location of generated project files
00265     target - the mbed board/mcu for which to generate the executable
00266     ide - the ide for which to generate the project fields
00267 
00268     Keyword Arguments:
00269     libraries_paths - paths to additional libraries
00270     linker_script - path to the linker script for the specified target
00271     notify - function is passed all events, and expected to handle notification
00272       of the user, emit the events to a log, etc.
00273     verbose - assigns the notify function to toolchains print_notify_verbose
00274     name - project name
00275     inc_dirs - additional include directories
00276     jobs - number of threads
00277     silent - silent build - no output
00278     extra_verbose - assigns the notify function to toolchains
00279       print_notify_verbose
00280     config - toolchain's config object
00281     macros - User-defined macros
00282     zip_proj - string name of the zip archive you wish to creat (exclude arg
00283      if you do not wish to create an archive
00284     """
00285 
00286     # Convert src_path to a list if needed
00287     if isinstance(src_paths, dict):
00288         paths = sum(src_paths.values(), [])
00289     elif isinstance(src_paths, list):
00290         paths = src_paths[:]
00291     else:
00292         paths = [src_paths]
00293 
00294     # Extend src_paths wit libraries_paths
00295     if libraries_paths is not None:
00296         paths.extend(libraries_paths)
00297 
00298     if not isinstance(src_paths, dict):
00299         src_paths = {"": paths}
00300 
00301     # Export Directory
00302     if not exists(export_path):
00303         makedirs(export_path)
00304 
00305     _, toolchain_name = get_exporter_toolchain(ide)
00306 
00307     # Pass all params to the unified prepare_resources()
00308     toolchain = prepare_toolchain(
00309         paths, "", target, toolchain_name, macros=macros, jobs=jobs,
00310         notify=notify, silent=silent, verbose=verbose,
00311         extra_verbose=extra_verbose, config=config, build_profile=build_profile,
00312         app_config=app_config)
00313     # The first path will give the name to the library
00314     toolchain.RESPONSE_FILES = False
00315     if name is None:
00316         name = basename(normpath(abspath(src_paths[0])))
00317 
00318     # Call unified scan_resources
00319     resource_dict = {loc: sum((toolchain.scan_resources(p, collect_ignores=True)
00320                                for p in path),
00321                               Resources())
00322                      for loc, path in src_paths.items()}
00323     resources = Resources()
00324 
00325     if zip_proj:
00326         subtract_basepath(resources, ".")
00327         for loc, res in resource_dict.items():
00328             temp = copy.deepcopy(res)
00329             subtract_basepath(temp, ".", loc)
00330             resources.add(temp)
00331     else:
00332         for _, res in resource_dict.items():
00333             resources.add(res)
00334 
00335     toolchain.build_dir = export_path
00336     toolchain.config.load_resources(resources)
00337     toolchain.set_config_data(toolchain.config.get_config_data())
00338     config_header = toolchain.get_config_header()
00339     resources.headers.append(config_header)
00340     resources.file_basepath[config_header] = dirname(config_header)
00341 
00342     # Change linker script if specified
00343     if linker_script is not None:
00344         resources.linker_script = linker_script
00345 
00346     files, exporter = generate_project_files(resources, export_path,
00347                                              target, name, toolchain, ide,
00348                                              macros=macros)
00349     files.append(config_header)
00350     if zip_proj:
00351         for resource in resource_dict.values():
00352             for label, res in resource.features.items():
00353                 if label not in toolchain.target.features:
00354                     resource.add(res)
00355         if isinstance(zip_proj, basestring):
00356             zip_export(join(export_path, zip_proj), name, resource_dict,
00357                        files + list(exporter.static_files), inc_repos)
00358         else:
00359             zip_export(zip_proj, name, resource_dict,
00360                        files + list(exporter.static_files), inc_repos)
00361     else:
00362         for static_file in exporter.static_files:
00363             if not exists(join(export_path, basename(static_file))):
00364                 copyfile(static_file, join(export_path, basename(static_file)))
00365 
00366     return exporter