Clone of official tools

Committer:
Anders Blomdell
Date:
Thu Feb 04 17:17:13 2021 +0100
Revision:
47:21ae3e5a7128
Parent:
43:2a7da56ebd24
Add a few normpath calls

Who changed what in which revision?

UserRevisionLine numberNew contents of line
screamer 0:66f3b5499f7f 1 """Just a template for subclassing"""
The Other Jimmy 31:8ea194f6145b 2 import os
The Other Jimmy 31:8ea194f6145b 3 from abc import abstractmethod, ABCMeta
The Other Jimmy 31:8ea194f6145b 4 import logging
theotherjimmy 43:2a7da56ebd24 5 from os.path import join, dirname, relpath, basename, realpath, normpath, exists
The Other Jimmy 31:8ea194f6145b 6 from itertools import groupby
The Other Jimmy 35:da9c89f8be7d 7 from jinja2 import FileSystemLoader, StrictUndefined
screamer 0:66f3b5499f7f 8 from jinja2.environment import Environment
The Other Jimmy 31:8ea194f6145b 9 import copy
screamer 0:66f3b5499f7f 10
screamer 0:66f3b5499f7f 11 from tools.targets import TARGET_MAP
theotherjimmy 43:2a7da56ebd24 12 from tools.utils import mkdir
theotherjimmy 43:2a7da56ebd24 13 from tools.resources import FileType
screamer 0:66f3b5499f7f 14
screamer 0:66f3b5499f7f 15
The Other Jimmy 31:8ea194f6145b 16 class TargetNotSupportedException(Exception):
The Other Jimmy 31:8ea194f6145b 17 """Indicates that an IDE does not support a particular MCU"""
The Other Jimmy 31:8ea194f6145b 18 pass
screamer 13:ab47a20b66f0 19
screamer 24:25bff2709c20 20 class ExporterTargetsProperty(object):
The Other Jimmy 31:8ea194f6145b 21 """ Exporter descriptor for TARGETS
The Other Jimmy 31:8ea194f6145b 22 TARGETS as class attribute for backward compatibility
The Other Jimmy 31:8ea194f6145b 23 (allows: if in Exporter.TARGETS)
The Other Jimmy 31:8ea194f6145b 24 """
screamer 24:25bff2709c20 25 def __init__(self, func):
screamer 24:25bff2709c20 26 self.func = func
screamer 24:25bff2709c20 27 def __get__(self, inst, cls):
screamer 24:25bff2709c20 28 return self.func(cls)
screamer 24:25bff2709c20 29
theotherjimmy 40:7d3fa6b99b2b 30 def deprecated_exporter(CLS):
theotherjimmy 40:7d3fa6b99b2b 31 old_init = CLS.__init__
theotherjimmy 40:7d3fa6b99b2b 32 old_name = CLS.NAME
theotherjimmy 40:7d3fa6b99b2b 33 def __init__(*args, **kwargs):
theotherjimmy 40:7d3fa6b99b2b 34 print("==================== DEPRECATION NOTICE ====================")
theotherjimmy 40:7d3fa6b99b2b 35 print("The exporter %s is no longer maintained, and deprecated." % old_name)
theotherjimmy 40:7d3fa6b99b2b 36 print("%s will be removed from mbed OS for the mbed OS 5.6 release." % old_name)
theotherjimmy 40:7d3fa6b99b2b 37 old_init(*args, **kwargs)
theotherjimmy 40:7d3fa6b99b2b 38 CLS.__init__ = __init__
theotherjimmy 40:7d3fa6b99b2b 39 CLS.NAME = "%s (DEPRECATED)" % old_name
theotherjimmy 40:7d3fa6b99b2b 40 return CLS
theotherjimmy 40:7d3fa6b99b2b 41
screamer 0:66f3b5499f7f 42 class Exporter(object):
The Other Jimmy 31:8ea194f6145b 43 """Exporter base class
The Other Jimmy 31:8ea194f6145b 44
The Other Jimmy 31:8ea194f6145b 45 This class is meant to be extended by individual exporters, and provides a
The Other Jimmy 31:8ea194f6145b 46 few helper methods for implementing an exporter with either jinja2 or
The Other Jimmy 31:8ea194f6145b 47 progen.
The Other Jimmy 31:8ea194f6145b 48 """
The Other Jimmy 31:8ea194f6145b 49 __metaclass__ = ABCMeta
screamer 0:66f3b5499f7f 50 TEMPLATE_DIR = dirname(__file__)
screamer 0:66f3b5499f7f 51 DOT_IN_RELATIVE_PATH = False
The Other Jimmy 31:8ea194f6145b 52 NAME = None
theotherjimmy 40:7d3fa6b99b2b 53 TARGETS = set()
The Other Jimmy 31:8ea194f6145b 54 TOOLCHAIN = None
theotherjimmy 43:2a7da56ebd24 55 CLEAN_FILES = ("GettingStarted.html",)
screamer 0:66f3b5499f7f 56
The Other Jimmy 31:8ea194f6145b 57
The Other Jimmy 31:8ea194f6145b 58 def __init__(self, target, export_dir, project_name, toolchain,
The Other Jimmy 31:8ea194f6145b 59 extra_symbols=None, resources=None):
The Other Jimmy 31:8ea194f6145b 60 """Initialize an instance of class exporter
The Other Jimmy 31:8ea194f6145b 61 Positional arguments:
The Other Jimmy 31:8ea194f6145b 62 target - the target mcu/board for this project
The Other Jimmy 31:8ea194f6145b 63 export_dir - the directory of the exported project files
The Other Jimmy 31:8ea194f6145b 64 project_name - the name of the project
The Other Jimmy 31:8ea194f6145b 65 toolchain - an instance of class toolchain
The Other Jimmy 31:8ea194f6145b 66
The Other Jimmy 31:8ea194f6145b 67 Keyword arguments:
The Other Jimmy 31:8ea194f6145b 68 extra_symbols - a list of extra macros for the toolchain
The Other Jimmy 31:8ea194f6145b 69 resources - an instance of class Resources
The Other Jimmy 31:8ea194f6145b 70 """
The Other Jimmy 31:8ea194f6145b 71 self.export_dir = export_dir
screamer 0:66f3b5499f7f 72 self.target = target
The Other Jimmy 31:8ea194f6145b 73 self.project_name = project_name
The Other Jimmy 31:8ea194f6145b 74 self.toolchain = toolchain
screamer 0:66f3b5499f7f 75 jinja_loader = FileSystemLoader(os.path.dirname(os.path.abspath(__file__)))
screamer 0:66f3b5499f7f 76 self.jinja_environment = Environment(loader=jinja_loader)
The Other Jimmy 31:8ea194f6145b 77 self.resources = resources
theotherjimmy 40:7d3fa6b99b2b 78 self.generated_files = []
theotherjimmy 40:7d3fa6b99b2b 79 self.static_files = (
theotherjimmy 40:7d3fa6b99b2b 80 join(self.TEMPLATE_DIR, "GettingStarted.html"),
theotherjimmy 40:7d3fa6b99b2b 81 join(self.TEMPLATE_DIR, ".mbed"),
theotherjimmy 40:7d3fa6b99b2b 82 )
The Other Jimmy 31:8ea194f6145b 83 self.builder_files_dict = {}
The Other Jimmy 31:8ea194f6145b 84 self.add_config()
screamer 0:66f3b5499f7f 85
screamer 0:66f3b5499f7f 86 def get_toolchain(self):
The Other Jimmy 31:8ea194f6145b 87 """A helper getter function that we should probably eliminate"""
screamer 0:66f3b5499f7f 88 return self.TOOLCHAIN
screamer 0:66f3b5499f7f 89
The Other Jimmy 31:8ea194f6145b 90 def add_config(self):
theotherjimmy 43:2a7da56ebd24 91 """Add the containing directory of mbed_config.h to include dirs"""
theotherjimmy 43:2a7da56ebd24 92 pass
The Other Jimmy 31:8ea194f6145b 93
screamer 13:ab47a20b66f0 94 @property
screamer 13:ab47a20b66f0 95 def flags(self):
The Other Jimmy 31:8ea194f6145b 96 """Returns a dictionary of toolchain flags.
The Other Jimmy 31:8ea194f6145b 97 Keys of the dictionary are:
The Other Jimmy 31:8ea194f6145b 98 cxx_flags - c++ flags
The Other Jimmy 31:8ea194f6145b 99 c_flags - c flags
The Other Jimmy 31:8ea194f6145b 100 ld_flags - linker flags
The Other Jimmy 31:8ea194f6145b 101 asm_flags - assembler flags
The Other Jimmy 31:8ea194f6145b 102 common_flags - common options
The Other Jimmy 31:8ea194f6145b 103 """
theotherjimmy 43:2a7da56ebd24 104 flags = self.toolchain_flags(self.toolchain)
theotherjimmy 40:7d3fa6b99b2b 105 asm_defines = self.toolchain.get_compile_options(
theotherjimmy 40:7d3fa6b99b2b 106 self.toolchain.get_symbols(for_asm=True),
theotherjimmy 40:7d3fa6b99b2b 107 filter(None, self.resources.inc_dirs),
theotherjimmy 40:7d3fa6b99b2b 108 for_asm=True)
The Other Jimmy 31:8ea194f6145b 109 c_defines = ["-D" + symbol for symbol in self.toolchain.get_symbols()]
The Other Jimmy 31:8ea194f6145b 110 flags['asm_flags'] += asm_defines
The Other Jimmy 31:8ea194f6145b 111 flags['c_flags'] += c_defines
The Other Jimmy 31:8ea194f6145b 112 flags['cxx_flags'] += c_defines
theotherjimmy 43:2a7da56ebd24 113 config_header = self.config_header_ref
The Other Jimmy 31:8ea194f6145b 114 if config_header:
theotherjimmy 43:2a7da56ebd24 115 config_option = self.toolchain.get_config_option(
theotherjimmy 43:2a7da56ebd24 116 config_header.name)
theotherjimmy 43:2a7da56ebd24 117 flags['c_flags'] += config_option
theotherjimmy 43:2a7da56ebd24 118 flags['cxx_flags'] += config_option
The Other Jimmy 31:8ea194f6145b 119 return flags
The Other Jimmy 31:8ea194f6145b 120
theotherjimmy 43:2a7da56ebd24 121 @property
theotherjimmy 43:2a7da56ebd24 122 def libraries(self):
theotherjimmy 43:2a7da56ebd24 123 return [l for l in self.resources.get_file_names(FileType.LIB)
theotherjimmy 43:2a7da56ebd24 124 if l.endswith(self.toolchain.LIBRARY_EXT)]
theotherjimmy 43:2a7da56ebd24 125
theotherjimmy 43:2a7da56ebd24 126 def toolchain_flags(self, toolchain):
theotherjimmy 43:2a7da56ebd24 127 """Returns a dictionary of toolchain flags.
theotherjimmy 43:2a7da56ebd24 128 Keys of the dictionary are:
theotherjimmy 43:2a7da56ebd24 129 cxx_flags - c++ flags
theotherjimmy 43:2a7da56ebd24 130 c_flags - c flags
theotherjimmy 43:2a7da56ebd24 131 ld_flags - linker flags
theotherjimmy 43:2a7da56ebd24 132 asm_flags - assembler flags
theotherjimmy 43:2a7da56ebd24 133 common_flags - common options
theotherjimmy 43:2a7da56ebd24 134
theotherjimmy 43:2a7da56ebd24 135 The difference from the above is that it takes a parameter.
theotherjimmy 43:2a7da56ebd24 136 """
theotherjimmy 43:2a7da56ebd24 137 flags = {key + "_flags": copy.deepcopy(value) for key, value
theotherjimmy 43:2a7da56ebd24 138 in toolchain.flags.items()}
theotherjimmy 43:2a7da56ebd24 139 config_header = self.config_header_ref
theotherjimmy 43:2a7da56ebd24 140 if config_header:
theotherjimmy 43:2a7da56ebd24 141 header_options = self.toolchain.get_config_option(
theotherjimmy 43:2a7da56ebd24 142 config_header.name)
theotherjimmy 43:2a7da56ebd24 143 flags['c_flags'] += header_options
theotherjimmy 43:2a7da56ebd24 144 flags['cxx_flags'] += header_options
theotherjimmy 43:2a7da56ebd24 145 return flags
theotherjimmy 43:2a7da56ebd24 146
theotherjimmy 43:2a7da56ebd24 147 @property
theotherjimmy 43:2a7da56ebd24 148 def config_header_ref(self):
theotherjimmy 43:2a7da56ebd24 149 config_header = self.toolchain.get_config_header()
theotherjimmy 43:2a7da56ebd24 150 if config_header:
theotherjimmy 43:2a7da56ebd24 151 def is_config_header(f):
theotherjimmy 43:2a7da56ebd24 152 return f.path == config_header
theotherjimmy 43:2a7da56ebd24 153 return list(filter(
theotherjimmy 43:2a7da56ebd24 154 is_config_header, self.resources.get_file_refs(FileType.HEADER)
theotherjimmy 43:2a7da56ebd24 155 ))[0]
theotherjimmy 43:2a7da56ebd24 156 else:
theotherjimmy 43:2a7da56ebd24 157 return None
theotherjimmy 43:2a7da56ebd24 158
The Other Jimmy 31:8ea194f6145b 159 def get_source_paths(self):
The Other Jimmy 31:8ea194f6145b 160 """Returns a list of the directories where source files are contained"""
The Other Jimmy 31:8ea194f6145b 161 source_keys = ['s_sources', 'c_sources', 'cpp_sources', 'hex_files',
The Other Jimmy 31:8ea194f6145b 162 'objects', 'libraries']
The Other Jimmy 31:8ea194f6145b 163 source_files = []
The Other Jimmy 31:8ea194f6145b 164 for key in source_keys:
The Other Jimmy 31:8ea194f6145b 165 source_files.extend(getattr(self.resources, key))
The Other Jimmy 31:8ea194f6145b 166 return list(set([os.path.dirname(src) for src in source_files]))
screamer 13:ab47a20b66f0 167
theotherjimmy 43:2a7da56ebd24 168 def gen_file_dest(self, target_file):
theotherjimmy 43:2a7da56ebd24 169 """Generate the project file location in an exported project"""
theotherjimmy 43:2a7da56ebd24 170 return join(self.export_dir, target_file)
theotherjimmy 43:2a7da56ebd24 171
The Other Jimmy 35:da9c89f8be7d 172 def gen_file(self, template_file, data, target_file, **kwargs):
The Other Jimmy 31:8ea194f6145b 173 """Generates a project file from a template using jinja"""
theotherjimmy 43:2a7da56ebd24 174 target_text = self._gen_file_inner(template_file, data, target_file, **kwargs)
theotherjimmy 43:2a7da56ebd24 175 target_path = self.gen_file_dest(target_file)
theotherjimmy 43:2a7da56ebd24 176 mkdir(dirname(target_path))
theotherjimmy 43:2a7da56ebd24 177 logging.debug("Generating: %s", target_path)
theotherjimmy 43:2a7da56ebd24 178 open(target_path, "w").write(target_text)
theotherjimmy 43:2a7da56ebd24 179 self.generated_files += [target_path]
theotherjimmy 43:2a7da56ebd24 180
theotherjimmy 43:2a7da56ebd24 181 def gen_file_nonoverwrite(self, template_file, data, target_file, **kwargs):
theotherjimmy 43:2a7da56ebd24 182 """Generates a project file from a template using jinja"""
theotherjimmy 43:2a7da56ebd24 183 target_text = self._gen_file_inner(template_file, data, target_file, **kwargs)
theotherjimmy 43:2a7da56ebd24 184 target_path = self.gen_file_dest(target_file)
theotherjimmy 43:2a7da56ebd24 185 if exists(target_path):
theotherjimmy 43:2a7da56ebd24 186 with open(target_path) as fdin:
theotherjimmy 43:2a7da56ebd24 187 old_text = fdin.read()
theotherjimmy 43:2a7da56ebd24 188 if target_text not in old_text:
theotherjimmy 43:2a7da56ebd24 189 with open(target_path, "a") as fdout:
theotherjimmy 43:2a7da56ebd24 190 fdout.write(target_text)
theotherjimmy 43:2a7da56ebd24 191 else:
theotherjimmy 43:2a7da56ebd24 192 logging.debug("Generating: %s", target_path)
theotherjimmy 43:2a7da56ebd24 193 open(target_path, "w").write(target_text)
theotherjimmy 43:2a7da56ebd24 194 self.generated_files += [target_path]
theotherjimmy 43:2a7da56ebd24 195
theotherjimmy 43:2a7da56ebd24 196 def _gen_file_inner(self, template_file, data, target_file, **kwargs):
theotherjimmy 43:2a7da56ebd24 197 """Generates a project file from a template using jinja"""
The Other Jimmy 31:8ea194f6145b 198 jinja_loader = FileSystemLoader(
The Other Jimmy 31:8ea194f6145b 199 os.path.dirname(os.path.abspath(__file__)))
The Other Jimmy 35:da9c89f8be7d 200 jinja_environment = Environment(loader=jinja_loader,
The Other Jimmy 35:da9c89f8be7d 201 undefined=StrictUndefined, **kwargs)
The Other Jimmy 31:8ea194f6145b 202
The Other Jimmy 31:8ea194f6145b 203 template = jinja_environment.get_template(template_file)
The Other Jimmy 31:8ea194f6145b 204 target_text = template.render(data)
theotherjimmy 43:2a7da56ebd24 205 return target_text
The Other Jimmy 31:8ea194f6145b 206
The Other Jimmy 31:8ea194f6145b 207 target_path = join(self.export_dir, target_file)
The Other Jimmy 31:8ea194f6145b 208 logging.debug("Generating: %s", target_path)
The Other Jimmy 31:8ea194f6145b 209 open(target_path, "w").write(target_text)
The Other Jimmy 31:8ea194f6145b 210 self.generated_files += [target_path]
screamer 13:ab47a20b66f0 211
The Other Jimmy 31:8ea194f6145b 212 def make_key(self, src):
The Other Jimmy 31:8ea194f6145b 213 """From a source file, extract group name
The Other Jimmy 31:8ea194f6145b 214 Positional Arguments:
The Other Jimmy 31:8ea194f6145b 215 src - the src's location
The Other Jimmy 31:8ea194f6145b 216 """
theotherjimmy 43:2a7da56ebd24 217 path_list = os.path.normpath(src).split(os.sep)
The Other Jimmy 35:da9c89f8be7d 218 assert len(path_list) >= 1
The Other Jimmy 35:da9c89f8be7d 219 if len(path_list) == 1:
The Other Jimmy 35:da9c89f8be7d 220 key = self.project_name
The Other Jimmy 35:da9c89f8be7d 221 else:
The Other Jimmy 35:da9c89f8be7d 222 key = path_list[0]
The Other Jimmy 31:8ea194f6145b 223 return key
screamer 0:66f3b5499f7f 224
The Other Jimmy 31:8ea194f6145b 225 def group_project_files(self, sources):
The Other Jimmy 31:8ea194f6145b 226 """Group the source files by their encompassing directory
The Other Jimmy 31:8ea194f6145b 227 Positional Arguments:
The Other Jimmy 31:8ea194f6145b 228 sources - array of source locations
The Other Jimmy 31:8ea194f6145b 229
The Other Jimmy 31:8ea194f6145b 230 Returns a dictionary of {group name: list of source locations}
The Other Jimmy 31:8ea194f6145b 231 """
The Other Jimmy 31:8ea194f6145b 232 data = sorted(sources, key=self.make_key)
The Other Jimmy 31:8ea194f6145b 233 return {k: list(g) for k,g in groupby(data, self.make_key)}
screamer 0:66f3b5499f7f 234
screamer 0:66f3b5499f7f 235 @staticmethod
The Other Jimmy 31:8ea194f6145b 236 def build(project_name, log_name='build_log.txt', cleanup=True):
The Other Jimmy 31:8ea194f6145b 237 """Invoke exporters build command within a subprocess.
The Other Jimmy 31:8ea194f6145b 238 This method is assumed to be executed at the same level as exporter
The Other Jimmy 31:8ea194f6145b 239 project files and project source code.
The Other Jimmy 31:8ea194f6145b 240 See uvision/__init__.py, iar/__init__.py, and makefile/__init__.py for
The Other Jimmy 31:8ea194f6145b 241 example implemenation.
screamer 0:66f3b5499f7f 242
The Other Jimmy 31:8ea194f6145b 243 Positional Arguments:
The Other Jimmy 31:8ea194f6145b 244 project_name - the name of the project to build; often required by
The Other Jimmy 31:8ea194f6145b 245 exporter's build command.
screamer 0:66f3b5499f7f 246
The Other Jimmy 31:8ea194f6145b 247 Keyword Args:
The Other Jimmy 31:8ea194f6145b 248 log_name - name of the build log to create. Written and printed out,
The Other Jimmy 31:8ea194f6145b 249 deleted if cleanup = True
The Other Jimmy 31:8ea194f6145b 250 cleanup - a boolean dictating whether exported project files and
The Other Jimmy 31:8ea194f6145b 251 build log are removed after build
screamer 0:66f3b5499f7f 252
The Other Jimmy 31:8ea194f6145b 253 Returns -1 on failure and 0 on success
screamer 0:66f3b5499f7f 254 """
theotherjimmy 43:2a7da56ebd24 255 raise NotImplementedError("Implement in derived Exporter class.")
theotherjimmy 43:2a7da56ebd24 256
theotherjimmy 43:2a7da56ebd24 257 @staticmethod
theotherjimmy 43:2a7da56ebd24 258 def clean(project_name):
theotherjimmy 43:2a7da56ebd24 259 """Clean a previously exported project
theotherjimmy 43:2a7da56ebd24 260 This method is assumed to be executed at the same level as exporter
theotherjimmy 43:2a7da56ebd24 261 project files and project source code.
theotherjimmy 43:2a7da56ebd24 262 See uvision/__init__.py, iar/__init__.py, and makefile/__init__.py for
theotherjimmy 43:2a7da56ebd24 263 example implemenation.
theotherjimmy 43:2a7da56ebd24 264
theotherjimmy 43:2a7da56ebd24 265 Positional Arguments:
theotherjimmy 43:2a7da56ebd24 266 project_name - the name of the project to build; often required by
theotherjimmy 43:2a7da56ebd24 267 exporter's build command.
theotherjimmy 43:2a7da56ebd24 268
theotherjimmy 43:2a7da56ebd24 269 Returns nothing. May raise exceptions
theotherjimmy 43:2a7da56ebd24 270 """
theotherjimmy 43:2a7da56ebd24 271 raise NotImplementedError("Implement in derived Exporter class.")
screamer 29:1210849dba19 272
The Other Jimmy 31:8ea194f6145b 273 @abstractmethod
The Other Jimmy 31:8ea194f6145b 274 def generate(self):
The Other Jimmy 31:8ea194f6145b 275 """Generate an IDE/tool specific project file"""
theotherjimmy 43:2a7da56ebd24 276 raise NotImplementedError("Implement a generate function in Exporter child class")
The Other Jimmy 36:96847d42f010 277
theotherjimmy 40:7d3fa6b99b2b 278 @classmethod
theotherjimmy 40:7d3fa6b99b2b 279 def is_target_supported(cls, target_name):
theotherjimmy 40:7d3fa6b99b2b 280 """Query support for a particular target
The Other Jimmy 36:96847d42f010 281
theotherjimmy 40:7d3fa6b99b2b 282 NOTE: override this method if your exporter does not provide a static list of targets
theotherjimmy 40:7d3fa6b99b2b 283
theotherjimmy 40:7d3fa6b99b2b 284 Positional Arguments:
theotherjimmy 40:7d3fa6b99b2b 285 target_name - the name of the target.
theotherjimmy 40:7d3fa6b99b2b 286 """
theotherjimmy 40:7d3fa6b99b2b 287 target = TARGET_MAP[target_name]
theotherjimmy 40:7d3fa6b99b2b 288 return bool(set(target.resolution_order_names).intersection(set(cls.TARGETS))) \
theotherjimmy 40:7d3fa6b99b2b 289 and cls.TOOLCHAIN in target.supported_toolchains
theotherjimmy 40:7d3fa6b99b2b 290
theotherjimmy 40:7d3fa6b99b2b 291
theotherjimmy 40:7d3fa6b99b2b 292 @classmethod
theotherjimmy 40:7d3fa6b99b2b 293 def all_supported_targets(cls):
theotherjimmy 40:7d3fa6b99b2b 294 return [t for t in TARGET_MAP.keys() if cls.is_target_supported(t)]
theotherjimmy 40:7d3fa6b99b2b 295
theotherjimmy 43:2a7da56ebd24 296 @staticmethod
theotherjimmy 43:2a7da56ebd24 297 def filter_dot(str):
theotherjimmy 43:2a7da56ebd24 298 """
theotherjimmy 43:2a7da56ebd24 299 Remove the './' or '.\\' prefix, if present.
theotherjimmy 43:2a7da56ebd24 300 """
theotherjimmy 43:2a7da56ebd24 301 if str == None:
theotherjimmy 43:2a7da56ebd24 302 return None
theotherjimmy 43:2a7da56ebd24 303 if str[:2] == './':
theotherjimmy 43:2a7da56ebd24 304 return str[2:]
theotherjimmy 43:2a7da56ebd24 305 if str[:2] == '.\\':
theotherjimmy 43:2a7da56ebd24 306 return str[2:]
theotherjimmy 43:2a7da56ebd24 307 return str
theotherjimmy 43:2a7da56ebd24 308
theotherjimmy 43:2a7da56ebd24 309
theotherjimmy 40:7d3fa6b99b2b 310
theotherjimmy 40:7d3fa6b99b2b 311 def apply_supported_whitelist(compiler, whitelist, target):
The Other Jimmy 36:96847d42f010 312 """Generate a list of supported targets for a given compiler and post-binary hook
The Other Jimmy 36:96847d42f010 313 white-list."""
theotherjimmy 40:7d3fa6b99b2b 314 if compiler not in target.supported_toolchains:
theotherjimmy 40:7d3fa6b99b2b 315 return False
theotherjimmy 40:7d3fa6b99b2b 316 if not hasattr(target, "post_binary_hook"):
theotherjimmy 40:7d3fa6b99b2b 317 return True
theotherjimmy 40:7d3fa6b99b2b 318 if target.post_binary_hook['function'] in whitelist:
theotherjimmy 40:7d3fa6b99b2b 319 return True
theotherjimmy 40:7d3fa6b99b2b 320 else:
theotherjimmy 40:7d3fa6b99b2b 321 return False