Clone of official tools
Diff: export/iar/__init__.py
- Revision:
- 31:8ea194f6145b
- Child:
- 35:da9c89f8be7d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/export/iar/__init__.py Wed Jan 04 11:58:24 2017 -0600 @@ -0,0 +1,177 @@ +import os +from os.path import sep, join, exists +from collections import namedtuple +from subprocess import Popen, PIPE +import shutil +import re +import sys + +from tools.targets import TARGET_MAP +from tools.export.exporters import Exporter, TargetNotSupportedException +import json +from tools.export.cmsis import DeviceCMSIS +from multiprocessing import cpu_count + +class IAR(Exporter): + NAME = 'iar' + TOOLCHAIN = 'IAR' + + #iar_definitions.json location + def_loc = os.path.join( + os.path.dirname(os.path.abspath(__file__)), '..', '..', '..', + 'tools','export', 'iar', 'iar_definitions.json') + + #create a dictionary of the definitions + with open(def_loc, 'r') as f: + IAR_DEFS = json.load(f) + + #supported targets have a device name and corresponding definition in + #iar_definitions.json + TARGETS = [target for target, obj in TARGET_MAP.iteritems() + if hasattr(obj, 'device_name') and + obj.device_name in IAR_DEFS.keys() and "IAR" in obj.supported_toolchains] + + def iar_groups(self, grouped_src): + """Return a namedtuple of group info + Positional Arguments: + grouped_src: dictionary mapping a group(str) to sources + within it (list of file names) + Relevant part of IAR template + {% for group in groups %} + <group> + <name>group.name</name> + {% for file in group.files %} + <file> + <name>$PROJ_DIR${{file}}</name> + </file> + {% endfor %} + </group> + {% endfor %} + """ + IARgroup = namedtuple('IARgroup', ['name','files']) + groups = [] + for name, files in grouped_src.items(): + groups.append(IARgroup(name,files)) + return groups + + def iar_device(self): + """Retrieve info from iar_definitions.json""" + device_name = TARGET_MAP[self.target].device_name + device_info = self.IAR_DEFS[device_name] + iar_defaults ={ + "OGChipSelectEditMenu": "", + "CoreVariant": '', + "GFPUCoreSlave": '', + "GFPUCoreSlave2": 40, + "GBECoreSlave": 35, + "FPU2": 0, + "NrRegs": 0, + } + + iar_defaults.update(device_info) + IARdevice = namedtuple('IARdevice', iar_defaults.keys()) + return IARdevice(**iar_defaults) + + def format_file(self, file): + """Make IAR compatible path""" + return join('$PROJ_DIR$',file) + + def format_src(self, srcs): + """Group source files""" + grouped = self.group_project_files(srcs) + for group, files in grouped.items(): + grouped[group] = [self.format_file(src) for src in files] + return grouped + + def generate(self): + """Generate the .eww, .ewd, and .ewp files""" + srcs = self.resources.headers + self.resources.s_sources + \ + self.resources.c_sources + self.resources.cpp_sources + \ + self.resources.objects + self.resources.libraries + flags = self.flags + flags['c_flags'] = list(set(flags['common_flags'] + + flags['c_flags'] + + flags['cxx_flags'])) + if '--vla' in flags['c_flags']: + flags['c_flags'].remove('--vla') + if '--no_static_destruction' in flags['c_flags']: + flags['c_flags'].remove('--no_static_destruction') + #Optimizations + if '-Oh' in flags['c_flags']: + flags['c_flags'].remove('-Oh') + + try: + debugger = DeviceCMSIS(self.target).debug.replace('-','').upper() + except TargetNotSupportedException: + debugger = "CMSISDAP" + + ctx = { + 'name': self.project_name, + 'groups': self.iar_groups(self.format_src(srcs)), + 'linker_script': self.format_file(self.resources.linker_script), + 'include_paths': [self.format_file(src) for src in self.resources.inc_dirs], + 'device': self.iar_device(), + 'ewp': sep+self.project_name + ".ewp", + 'debugger': debugger + } + ctx.update(flags) + + self.gen_file('iar/eww.tmpl', ctx, self.project_name + ".eww") + self.gen_file('iar/ewd.tmpl', ctx, self.project_name + ".ewd") + self.gen_file('iar/ewp.tmpl', ctx, self.project_name + ".ewp") + + @staticmethod + def build(project_name, log_name="build_log.txt", cleanup=True): + """ Build IAR project """ + # > IarBuild [project_path] -build [project_name] + proj_file = project_name + ".ewp" + cmd = ["IarBuild", proj_file, '-build', project_name] + + # IAR does not support a '0' option to automatically use all + # available CPUs, so we use Python's multiprocessing library + # to detect the number of CPUs available + cpus_available = cpu_count() + jobs = cpus_available if cpus_available else None + + # Only add the parallel flag if we're using more than one CPU + if jobs: + cmd += ['-parallel', str(jobs)] + + # Build the project + p = Popen(cmd, stdout=PIPE, stderr=PIPE) + out, err = p.communicate() + ret_code = p.returncode + + out_string = "=" * 10 + "STDOUT" + "=" * 10 + "\n" + out_string += out + out_string += "=" * 10 + "STDERR" + "=" * 10 + "\n" + out_string += err + + if ret_code == 0: + out_string += "SUCCESS" + else: + out_string += "FAILURE" + + print out_string + + if log_name: + # Write the output to the log file + with open(log_name, 'w+') as f: + f.write(out_string) + + # Cleanup the exported and built files + if cleanup: + os.remove(project_name + ".ewp") + os.remove(project_name + ".ewd") + os.remove(project_name + ".eww") + # legacy output file location + if exists('.build'): + shutil.rmtree('.build') + if exists('BUILD'): + shutil.rmtree('BUILD') + + if ret_code !=0: + # Seems like something went wrong. + return -1 + else: + return 0