Lee Kai Xuan / mbed-os

Fork of mbed-os by erkin yucel

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers __init__.py Source File

__init__.py

00001 import os
00002 from os.path import sep, join, exists
00003 from collections import namedtuple
00004 from subprocess import Popen, PIPE
00005 from distutils.spawn import find_executable
00006 import re
00007 import sys
00008 
00009 from tools.targets import TARGET_MAP
00010 from tools.export.exporters import Exporter, FailedBuildException
00011 import json
00012 from tools.export.cmsis import DeviceCMSIS
00013 
00014 class IAR(Exporter):
00015     NAME = 'iar'
00016     TOOLCHAIN = 'IAR'
00017 
00018     #iar_definitions.json location
00019     def_loc = os.path.join(
00020         os.path.dirname(os.path.abspath(__file__)), '..', '..', '..',
00021         'tools','export', 'iar', 'iar_definitions.json')
00022 
00023     #create a dictionary of the definitions
00024     with open(def_loc, 'r') as f:
00025         IAR_DEFS = json.load(f)
00026 
00027     #supported targets have a device name and corresponding definition in
00028     #iar_definitions.json
00029     TARGETS = [target for target, obj in TARGET_MAP.iteritems()
00030                if hasattr(obj, 'device_name') and
00031                obj.device_name in IAR_DEFS.keys()]
00032 
00033     SPECIAL_TEMPLATES = {
00034         'rz_a1h'  : 'iar/iar_rz_a1h.ewp.tmpl',
00035         'nucleo_f746zg' : 'iar/iar_nucleo_f746zg.ewp.tmpl'
00036     }
00037 
00038     def iar_groups(self, grouped_src):
00039         """Return a namedtuple of group info
00040         Positional Arguments:
00041         grouped_src: dictionary mapping a group(str) to sources
00042             within it (list of file names)
00043         Relevant part of IAR template
00044         {% for group in groups %}
00045         <group>
00046             <name>group.name</name>
00047             {% for file in group.files %}
00048             <file>
00049             <name>$PROJ_DIR${{file}}</name>
00050             </file>
00051             {% endfor %}
00052         </group>
00053         {% endfor %}
00054         """
00055         IARgroup = namedtuple('IARgroup', ['name','files'])
00056         groups = []
00057         for name, files in grouped_src.items():
00058             groups.append(IARgroup(name,files))
00059         return groups
00060 
00061     def iar_device(self):
00062         """Retrieve info from iar_definitions.json"""
00063         device_name =  TARGET_MAP[self.target].device_name
00064         device_info = self.IAR_DEFS[device_name]
00065         iar_defaults ={
00066             "OGChipSelectEditMenu": "",
00067             "CoreVariant": '',
00068             "GFPUCoreSlave": '',
00069             "GFPUCoreSlave2": 40,
00070             "GBECoreSlave": 35
00071         }
00072 
00073         iar_defaults.update(device_info)
00074         IARdevice = namedtuple('IARdevice', iar_defaults.keys())
00075         return IARdevice(**iar_defaults)
00076 
00077     def format_file(self, file):
00078         """Make IAR compatible path"""
00079         return join('$PROJ_DIR$',file)
00080 
00081     def format_src(self, srcs):
00082         """Group source files"""
00083         grouped = self.group_project_files(srcs)
00084         for group, files in grouped.items():
00085             grouped[group] = [self.format_file(src) for src in files]
00086         return grouped
00087 
00088     def get_ewp_template(self):
00089         return self.SPECIAL_TEMPLATES.get(self.target.lower(), 'iar/ewp.tmpl')
00090 
00091     def generate(self):
00092         """Generate the .eww, .ewd, and .ewp files"""
00093         srcs = self.resources.headers + self.resources.s_sources + \
00094                self.resources.c_sources + self.resources.cpp_sources + \
00095                self.resources.objects + self.resources.libraries
00096         flags = self.flags
00097         flags['c_flags'] = list(set(flags['common_flags']
00098                                     + flags['c_flags']
00099                                     + flags['cxx_flags']))
00100         if '--vla' in flags['c_flags']:
00101             flags['c_flags'].remove('--vla')
00102         if '--no_static_destruction' in flags['c_flags']:
00103             flags['c_flags'].remove('--no_static_destruction')
00104         #Optimizations 
00105         if '-Oh' in flags['c_flags']:
00106             flags['c_flags'].remove('-Oh')
00107         ctx = {
00108             'name': self.project_name,
00109             'groups': self.iar_groups(self.format_src(srcs)),
00110             'linker_script': self.format_file(self.resources.linker_script),
00111             'include_paths': [self.format_file(src) for src in self.resources.inc_dirs],
00112             'device': self.iar_device(),
00113             'ewp': sep+self.project_name + ".ewp",
00114             'debugger': DeviceCMSIS(self.target).debug.replace('-','').upper()
00115         }
00116         ctx.update(flags)
00117 
00118         self.gen_file('iar/eww.tmpl', ctx, self.project_name+".eww")
00119         self.gen_file('iar/ewd.tmpl', ctx, self.project_name + ".ewd")
00120         self.gen_file(self.get_ewp_template(), ctx, self.project_name + ".ewp")
00121 
00122     def build(self):
00123         """ Build IAR project """
00124         # > IarBuild [project_path] -build [project_name]
00125         proj_file = join(self.export_dir, self.project_name + ".ewp")
00126 
00127         if find_executable("IarBuild"):
00128             iar_exe = "IarBuild.exe"
00129         else:
00130             iar_exe = join('C:', sep,
00131                           'Program Files (x86)', 'IAR Systems',
00132                           'Embedded Workbench 7.5', 'common', 'bin',
00133                           'IarBuild.exe')
00134             if not exists(iar_exe):
00135                 raise Exception("IarBuild.exe not found. Add to path.")
00136 
00137         cmd = [iar_exe, proj_file, '-build', self.project_name]
00138         p = Popen(cmd, stdout=PIPE, stderr=PIPE)
00139         num_errors = 0
00140         #Parse the output for printing and errors
00141         for line in p.stdout.readlines():
00142             sys.stdout.write(line)
00143             error_re = '\s*Total number of errors:\s*(\d+)\s*'
00144             m = re.match(error_re, line)
00145             if m is not None:
00146                 num_errors = int(m.group(1))
00147         if num_errors !=0:
00148             # Seems like something went wrong.
00149             raise FailedBuildException("Project: %s build failed with %s erros" % (
00150             proj_file, num_errors))