Clone of official tools
Diff: toolchains/__init__.py
- Revision:
- 22:9e85236d8716
- Parent:
- 21:4fdf0dd04f6f
- Child:
- 24:25bff2709c20
--- a/toolchains/__init__.py Fri Jul 15 22:58:15 2016 +0100 +++ b/toolchains/__init__.py Sat Jul 16 00:34:03 2016 +0100 @@ -210,28 +210,28 @@ def __init__(self, target, options=None, notify=None, macros=None, silent=False, extra_verbose=False): self.target = target self.name = self.__class__.__name__ - + # compile/assemble/link/binary hooks self.hook = hooks.Hook(target, self) # Toolchain flags self.flags = deepcopy(self.DEFAULT_FLAGS) - + # User-defined macros self.macros = macros or [] - + # Macros generated from toolchain and target rules/features self.symbols = None - + # Labels generated from toolchain and target rules/features (used for selective build) self.labels = None - + # This will hold the configuration data (as returned by Config.get_config_data()) self.config_data = None # Non-incremental compile self.build_all = False - + # Build output dir self.build_dir = None self.timestamp = time() @@ -242,7 +242,7 @@ # Number of concurrent build jobs. 0 means auto (based on host system cores) self.jobs = 0 - self.CHROOT = None + self.CHROOT = None # Ignore patterns from .mbedignore files self.ignore_patterns = [] @@ -251,18 +251,27 @@ self.legacy_ignore_dirs = (LEGACY_IGNORE_DIRS | TOOLCHAINS) - set([target.name, LEGACY_TOOLCHAIN_NAMES[self.name]]) # Output notify function + # This function is passed all events, and expected to handle notification of the + # user, emit the events to a log, etc. + # The API for all notify methods passed into the notify parameter is as follows: + # def notify(Event, Silent) + # Where *Event* is a dict representing the toolchain event that was generated + # e.g.: a compile succeeded, or a warning was emitted by the compiler + # or an application was linked + # *Silent* is a boolean if notify: self.notify_fun = notify elif extra_verbose: self.notify_fun = self.print_notify_verbose else: self.notify_fun = self.print_notify - + # Silent builds (no output) self.silent = silent - + # Print output buffer - self.output = "" + self.output = str() + self.map_outputs = list() # Place to store memmap scan results in JSON like data structures # Build options passed by -o flag self.options = options if options is not None else [] @@ -272,7 +281,7 @@ if self.options: self.info("Build Options: %s" % (', '.join(self.options))) - + # uVisor spepcific rules if 'UVISOR' in self.target.features and 'UVISOR_SUPPORTED' in self.target.extra_labels: self.target.core = re.sub(r"F$", '', self.target.core) @@ -295,10 +304,10 @@ if not self.VERBOSE and event['type'] == 'tool_error': msg = event['message'] - + elif event['type'] in ['info', 'debug']: msg = event['message'] - + elif event['type'] == 'cc': event['severity'] = event['severity'].title() event['file'] = basename(event['file']) @@ -322,7 +331,6 @@ event['severity'] = event['severity'].title() event['file'] = basename(event['file']) event['mcu_name'] = "None" - event['toolchain'] = "None" event['target_name'] = event['target_name'].upper() if event['target_name'] else "Unknown" event['toolchain_name'] = event['toolchain_name'].upper() if event['toolchain_name'] else "Unknown" msg = '[%(severity)s] %(target_name)s::%(toolchain_name)s::%(file)s@%(line)s: %(message)s' % event @@ -335,6 +343,7 @@ def notify(self, event): """ Little closure for notify functions """ + event['toolchain'] = self return self.notify_fun(event, self.silent) def get_symbols(self): @@ -395,17 +404,14 @@ for d in dependencies: # Some objects are not provided with full path and here we do not have # information about the library paths. Safe option: assume an update - if not d: + if not d or not exists(d): return True - if self.stat_cache.has_key(d): - if self.stat_cache[d] >= target_mod_time: - return True - else: - if not exists(d): return True - + if not self.stat_cache.has_key(d): self.stat_cache[d] = stat(d).st_mtime - if self.stat_cache[d] >= target_mod_time: return True + + if self.stat_cache[d] >= target_mod_time: + return True return False @@ -597,7 +603,7 @@ def relative_object_path(self, build_path, base_dir, source): source_dir, name, _ = split_path(source) - + obj_dir = join(build_path, relpath(source_dir, base_dir)) if obj_dir is not self.prev_dir: self.prev_dir = obj_dir @@ -824,12 +830,12 @@ if self.target.OUTPUT_NAMING == "8.3": name = name[0:8] ext = ext[0:3] - + # Create destination directory head, tail = split(name) new_path = join(tmp_path, head) mkdir(new_path) - + filename = name+'.'+ext elf = join(tmp_path, name + '.elf') bin = join(tmp_path, filename) @@ -845,7 +851,7 @@ self.progress("elf2bin", name) self.binary(r, elf, bin) - self.mem_stats(map) + self.map_outputs = self.mem_stats(map) self.var("compile_succeded", True) self.var("binary", filename) @@ -898,7 +904,11 @@ self.notify({'type': 'var', 'key': key, 'val': value}) def mem_stats(self, map): - # Creates parser object + """! Creates parser object + @param map Path to linker map file to parse and decode + @return Memory summary structure with memory usage statistics + None if map file can't be opened and processed + """ toolchain = self.__class__.__name__ # Create memap object @@ -907,7 +917,7 @@ # Parse and decode a map file if memap.parse(abspath(map), toolchain) is False: self.info("Unknown toolchain for memory statistics %s" % toolchain) - return + return None # Write output to stdout in text (pretty table) format memap.generate_output('table') @@ -915,11 +925,16 @@ # Write output to file in JSON format map_out = splitext(map)[0] + "_map.json" memap.generate_output('json', map_out) - + # Write output to file in CSV format for the CI map_csv = splitext(map)[0] + "_map.csv" memap.generate_output('csv-ci', map_csv) + # Here we return memory statistics structure (constructed after + # call to generate_output) which contains raw data in bytes + # about sections + summary + return memap.get_memory_summary() + # Set the configuration data def set_config_data(self, config_data): self.config_data = config_data