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-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510
exporters.py
00001 """Just a template for subclassing""" 00002 import os 00003 from abc import abstractmethod, ABCMeta 00004 import logging 00005 from os.path import join, dirname, relpath, basename, realpath, normpath 00006 from itertools import groupby 00007 from jinja2 import FileSystemLoader 00008 from jinja2.environment import Environment 00009 import copy 00010 00011 from tools.targets import TARGET_MAP 00012 00013 00014 class TargetNotSupportedException (Exception): 00015 """Indicates that an IDE does not support a particular MCU""" 00016 pass 00017 00018 class ExporterTargetsProperty (object): 00019 """ Exporter descriptor for TARGETS 00020 TARGETS as class attribute for backward compatibility 00021 (allows: if in Exporter.TARGETS) 00022 """ 00023 def __init__(self, func): 00024 self.func = func 00025 def __get__(self, inst, cls): 00026 return self.func(cls) 00027 00028 class Exporter (object): 00029 """Exporter base class 00030 00031 This class is meant to be extended by individual exporters, and provides a 00032 few helper methods for implementing an exporter with either jinja2 or 00033 progen. 00034 """ 00035 __metaclass__ = ABCMeta 00036 TEMPLATE_DIR = dirname(__file__) 00037 DOT_IN_RELATIVE_PATH = False 00038 NAME = None 00039 TARGETS = None 00040 TOOLCHAIN = None 00041 00042 00043 def __init__ (self, target, export_dir, project_name, toolchain, 00044 extra_symbols=None, resources=None): 00045 """Initialize an instance of class exporter 00046 Positional arguments: 00047 target - the target mcu/board for this project 00048 export_dir - the directory of the exported project files 00049 project_name - the name of the project 00050 toolchain - an instance of class toolchain 00051 00052 Keyword arguments: 00053 extra_symbols - a list of extra macros for the toolchain 00054 resources - an instance of class Resources 00055 """ 00056 self.export_dir = export_dir 00057 self.target = target 00058 self.project_name = project_name 00059 self.toolchain = toolchain 00060 jinja_loader = FileSystemLoader(os.path.dirname(os.path.abspath(__file__))) 00061 self.jinja_environment = Environment(loader=jinja_loader) 00062 self.resources = resources 00063 self.generated_files = [join(self.TEMPLATE_DIR ,"GettingStarted.html")] 00064 self.builder_files_dict = {} 00065 self.add_config () 00066 00067 def get_toolchain (self): 00068 """A helper getter function that we should probably eliminate""" 00069 return self.TOOLCHAIN 00070 00071 def add_config (self): 00072 """Add the containgin directory of mbed_config.h to include dirs""" 00073 config = self.toolchain .get_config_header() 00074 if config: 00075 self.resources .inc_dirs.append( 00076 dirname(relpath(config, 00077 self.resources .file_basepath[config]))) 00078 00079 @property 00080 def flags (self): 00081 """Returns a dictionary of toolchain flags. 00082 Keys of the dictionary are: 00083 cxx_flags - c++ flags 00084 c_flags - c flags 00085 ld_flags - linker flags 00086 asm_flags - assembler flags 00087 common_flags - common options 00088 """ 00089 config_header = self.toolchain .get_config_header() 00090 flags = {key + "_flags": copy.deepcopy(value) for key, value 00091 in self.toolchain .flags.iteritems()} 00092 asm_defines = ["-D" + symbol for symbol in self.toolchain .get_symbols(True)] 00093 c_defines = ["-D" + symbol for symbol in self.toolchain .get_symbols()] 00094 flags['asm_flags'] += asm_defines 00095 flags['c_flags'] += c_defines 00096 flags['cxx_flags'] += c_defines 00097 if config_header: 00098 config_header = relpath(config_header, 00099 self.resources .file_basepath[config_header]) 00100 flags['c_flags'] += self.toolchain .get_config_option(config_header) 00101 flags['cxx_flags'] += self.toolchain .get_config_option( 00102 config_header) 00103 return flags 00104 00105 def get_source_paths (self): 00106 """Returns a list of the directories where source files are contained""" 00107 source_keys = ['s_sources', 'c_sources', 'cpp_sources', 'hex_files', 00108 'objects', 'libraries'] 00109 source_files = [] 00110 for key in source_keys: 00111 source_files.extend(getattr(self.resources , key)) 00112 return list(set([os.path.dirname(src) for src in source_files])) 00113 00114 def gen_file (self, template_file, data, target_file): 00115 """Generates a project file from a template using jinja""" 00116 jinja_loader = FileSystemLoader( 00117 os.path.dirname(os.path.abspath(__file__))) 00118 jinja_environment = Environment(loader=jinja_loader) 00119 00120 template = jinja_environment.get_template(template_file) 00121 target_text = template.render(data) 00122 00123 target_path = join(self.export_dir , target_file) 00124 logging.debug("Generating: %s", target_path) 00125 open(target_path, "w").write(target_text) 00126 self.generated_files += [target_path] 00127 00128 def make_key (self, src): 00129 """From a source file, extract group name 00130 Positional Arguments: 00131 src - the src's location 00132 """ 00133 rel_path = relpath(src, self.resources .file_basepath[src]) 00134 path_list = os.path.normpath(rel_path).split(os.sep) 00135 assert path_list >= 1 00136 if len(path_list) == 1: 00137 key = self.project_name 00138 else: 00139 key = path_list[0] 00140 return key 00141 00142 def group_project_files (self, sources): 00143 """Group the source files by their encompassing directory 00144 Positional Arguments: 00145 sources - array of source locations 00146 00147 Returns a dictionary of {group name: list of source locations} 00148 """ 00149 data = sorted(sources, key=self.make_key ) 00150 return {k: list(g) for k,g in groupby(data, self.make_key )} 00151 00152 @staticmethod 00153 def build (project_name, log_name='build_log.txt', cleanup=True): 00154 """Invoke exporters build command within a subprocess. 00155 This method is assumed to be executed at the same level as exporter 00156 project files and project source code. 00157 See uvision/__init__.py, iar/__init__.py, and makefile/__init__.py for 00158 example implemenation. 00159 00160 Positional Arguments: 00161 project_name - the name of the project to build; often required by 00162 exporter's build command. 00163 00164 Keyword Args: 00165 log_name - name of the build log to create. Written and printed out, 00166 deleted if cleanup = True 00167 cleanup - a boolean dictating whether exported project files and 00168 build log are removed after build 00169 00170 Returns -1 on failure and 0 on success 00171 """ 00172 raise NotImplemented("Implement in derived Exporter class.") 00173 00174 @abstractmethod 00175 def generate (self): 00176 """Generate an IDE/tool specific project file""" 00177 raise NotImplemented("Implement a generate function in Exporter child class")
Generated on Tue Jul 12 2022 11:02:38 by
