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.
Fork of mbed-sdk-tools by
Diff: toolchains/__init__.py
- Revision:
- 22:9e85236d8716
- Parent:
- 21:4fdf0dd04f6f
- Child:
- 24:25bff2709c20
diff -r 4fdf0dd04f6f -r 9e85236d8716 toolchains/__init__.py --- 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