Greg Steiert / pegasus_dev

Dependents:   blinky_max32630fthr

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 import shutil
00006 import re
00007 import sys
00008 
00009 from tools.targets import TARGET_MAP
00010 from tools.export.exporters import Exporter
00011 import json
00012 from tools.export.cmsis import DeviceCMSIS
00013 from multiprocessing import cpu_count
00014 
00015 class IAR(Exporter):
00016     NAME = 'iar'
00017     TOOLCHAIN = 'IAR'
00018 
00019     #iar_definitions.json location
00020     def_loc = os.path.join(
00021         os.path.dirname(os.path.abspath(__file__)), '..', '..', '..',
00022         'tools','export', 'iar', 'iar_definitions.json')
00023 
00024     #create a dictionary of the definitions
00025     with open(def_loc, 'r') as f:
00026         IAR_DEFS = json.load(f)
00027 
00028     #supported targets have a device name and corresponding definition in
00029     #iar_definitions.json
00030     TARGETS = [target for target, obj in TARGET_MAP.iteritems()
00031                if hasattr(obj, 'device_name') and
00032                obj.device_name in IAR_DEFS.keys() and "IAR" in obj.supported_toolchains
00033                and DeviceCMSIS.check_supported(target)]
00034 
00035     SPECIAL_TEMPLATES = {
00036         'rz_a1h'  : 'iar/iar_rz_a1h.ewp.tmpl',
00037         'nucleo_f746zg' : 'iar/iar_nucleo_f746zg.ewp.tmpl'
00038     }
00039 
00040     def iar_groups(self, grouped_src):
00041         """Return a namedtuple of group info
00042         Positional Arguments:
00043         grouped_src: dictionary mapping a group(str) to sources
00044             within it (list of file names)
00045         Relevant part of IAR template
00046         {% for group in groups %}
00047         <group>
00048             <name>group.name</name>
00049             {% for file in group.files %}
00050             <file>
00051             <name>$PROJ_DIR${{file}}</name>
00052             </file>
00053             {% endfor %}
00054         </group>
00055         {% endfor %}
00056         """
00057         IARgroup = namedtuple('IARgroup', ['name','files'])
00058         groups = []
00059         for name, files in grouped_src.items():
00060             groups.append(IARgroup(name,files))
00061         return groups
00062 
00063     def iar_device(self):
00064         """Retrieve info from iar_definitions.json"""
00065         device_name =  TARGET_MAP[self.target].device_name
00066         device_info = self.IAR_DEFS[device_name]
00067         iar_defaults ={
00068             "OGChipSelectEditMenu": "",
00069             "CoreVariant": '',
00070             "GFPUCoreSlave": '',
00071             "GFPUCoreSlave2": 40,
00072             "GBECoreSlave": 35
00073         }
00074 
00075         iar_defaults.update(device_info)
00076         IARdevice = namedtuple('IARdevice', iar_defaults.keys())
00077         return IARdevice(**iar_defaults)
00078 
00079     def format_file(self, file):
00080         """Make IAR compatible path"""
00081         return join('$PROJ_DIR$',file)
00082 
00083     def format_src(self, srcs):
00084         """Group source files"""
00085         grouped = self.group_project_files(srcs)
00086         for group, files in grouped.items():
00087             grouped[group] = [self.format_file(src) for src in files]
00088         return grouped
00089 
00090     def get_ewp_template(self):
00091         return self.SPECIAL_TEMPLATES.get(self.target.lower(), 'iar/ewp.tmpl')
00092 
00093     def generate(self):
00094         """Generate the .eww, .ewd, and .ewp files"""
00095         srcs = self.resources.headers + self.resources.s_sources + \
00096                self.resources.c_sources + self.resources.cpp_sources + \
00097                self.resources.objects + self.resources.libraries
00098         flags = self.flags
00099         flags['c_flags'] = list(set(flags['common_flags']
00100                                     + flags['c_flags']
00101                                     + flags['cxx_flags']))
00102         if '--vla' in flags['c_flags']:
00103             flags['c_flags'].remove('--vla')
00104         if '--no_static_destruction' in flags['c_flags']:
00105             flags['c_flags'].remove('--no_static_destruction')
00106         #Optimizations
00107         if '-Oh' in flags['c_flags']:
00108             flags['c_flags'].remove('-Oh')
00109         ctx = {
00110             'name': self.project_name,
00111             'groups': self.iar_groups(self.format_src(srcs)),
00112             'linker_script': self.format_file(self.resources.linker_script),
00113             'include_paths': [self.format_file(src) for src in self.resources.inc_dirs],
00114             'device': self.iar_device(),
00115             'ewp': sep+self.project_name + ".ewp",
00116             'debugger': DeviceCMSIS(self.target).debug.replace('-','').upper()
00117         }
00118         ctx.update(flags)
00119 
00120         self.gen_file('iar/eww.tmpl', ctx, self.project_name+".eww")
00121         self.gen_file('iar/ewd.tmpl', ctx, self.project_name + ".ewd")
00122         self.gen_file(self.get_ewp_template(), ctx, self.project_name + ".ewp")
00123 
00124     @staticmethod
00125     def build(project_name, log_name="build_log.txt", cleanup=True):
00126         """ Build IAR project """
00127         # > IarBuild [project_path] -build [project_name]
00128         proj_file = project_name + ".ewp"
00129         cmd = ["IarBuild", proj_file, '-build', project_name]
00130 
00131         # IAR does not support a '0' option to automatically use all
00132         # available CPUs, so we use Python's multiprocessing library
00133         # to detect the number of CPUs available
00134         cpus_available = cpu_count()
00135         jobs = cpus_available if cpus_available else None
00136 
00137         # Only add the parallel flag if we're using more than one CPU
00138         if jobs:
00139             cmd += ['-parallel', str(jobs)]
00140 
00141         # Build the project
00142         p = Popen(cmd, stdout=PIPE, stderr=PIPE)
00143         out, err = p.communicate()
00144         ret_code = p.returncode
00145 
00146         out_string = "=" * 10 + "STDOUT" + "=" * 10 + "\n"
00147         out_string += out
00148         out_string += "=" * 10 + "STDERR" + "=" * 10 + "\n"
00149         out_string += err
00150 
00151         if ret_code == 0:
00152             out_string += "SUCCESS"
00153         else:
00154             out_string += "FAILURE"
00155 
00156         print out_string
00157 
00158         if log_name:
00159             # Write the output to the log file
00160             with open(log_name, 'w+') as f:
00161                 f.write(out_string)
00162 
00163         # Cleanup the exported and built files
00164         if cleanup:
00165             os.remove(project_name + ".ewp")
00166             os.remove(project_name + ".ewd")
00167             os.remove(project_name + ".eww")
00168             if exists('.build'):
00169                 shutil.rmtree('.build')
00170 
00171         if ret_code !=0:
00172             # Seems like something went wrong.
00173             return -1
00174         else:
00175             return 0