Clone of official tools

Committer:
The Other Jimmy
Date:
Wed Jan 04 11:58:24 2017 -0600
Revision:
31:8ea194f6145b
Child:
35:da9c89f8be7d
Update tools to follow mbed-os tools release 5.3.1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
The Other Jimmy 31:8ea194f6145b 1 import os
The Other Jimmy 31:8ea194f6145b 2 from os.path import sep, join, exists
The Other Jimmy 31:8ea194f6145b 3 from collections import namedtuple
The Other Jimmy 31:8ea194f6145b 4 from subprocess import Popen, PIPE
The Other Jimmy 31:8ea194f6145b 5 import shutil
The Other Jimmy 31:8ea194f6145b 6 import re
The Other Jimmy 31:8ea194f6145b 7 import sys
The Other Jimmy 31:8ea194f6145b 8
The Other Jimmy 31:8ea194f6145b 9 from tools.targets import TARGET_MAP
The Other Jimmy 31:8ea194f6145b 10 from tools.export.exporters import Exporter, TargetNotSupportedException
The Other Jimmy 31:8ea194f6145b 11 import json
The Other Jimmy 31:8ea194f6145b 12 from tools.export.cmsis import DeviceCMSIS
The Other Jimmy 31:8ea194f6145b 13 from multiprocessing import cpu_count
The Other Jimmy 31:8ea194f6145b 14
The Other Jimmy 31:8ea194f6145b 15 class IAR(Exporter):
The Other Jimmy 31:8ea194f6145b 16 NAME = 'iar'
The Other Jimmy 31:8ea194f6145b 17 TOOLCHAIN = 'IAR'
The Other Jimmy 31:8ea194f6145b 18
The Other Jimmy 31:8ea194f6145b 19 #iar_definitions.json location
The Other Jimmy 31:8ea194f6145b 20 def_loc = os.path.join(
The Other Jimmy 31:8ea194f6145b 21 os.path.dirname(os.path.abspath(__file__)), '..', '..', '..',
The Other Jimmy 31:8ea194f6145b 22 'tools','export', 'iar', 'iar_definitions.json')
The Other Jimmy 31:8ea194f6145b 23
The Other Jimmy 31:8ea194f6145b 24 #create a dictionary of the definitions
The Other Jimmy 31:8ea194f6145b 25 with open(def_loc, 'r') as f:
The Other Jimmy 31:8ea194f6145b 26 IAR_DEFS = json.load(f)
The Other Jimmy 31:8ea194f6145b 27
The Other Jimmy 31:8ea194f6145b 28 #supported targets have a device name and corresponding definition in
The Other Jimmy 31:8ea194f6145b 29 #iar_definitions.json
The Other Jimmy 31:8ea194f6145b 30 TARGETS = [target for target, obj in TARGET_MAP.iteritems()
The Other Jimmy 31:8ea194f6145b 31 if hasattr(obj, 'device_name') and
The Other Jimmy 31:8ea194f6145b 32 obj.device_name in IAR_DEFS.keys() and "IAR" in obj.supported_toolchains]
The Other Jimmy 31:8ea194f6145b 33
The Other Jimmy 31:8ea194f6145b 34 def iar_groups(self, grouped_src):
The Other Jimmy 31:8ea194f6145b 35 """Return a namedtuple of group info
The Other Jimmy 31:8ea194f6145b 36 Positional Arguments:
The Other Jimmy 31:8ea194f6145b 37 grouped_src: dictionary mapping a group(str) to sources
The Other Jimmy 31:8ea194f6145b 38 within it (list of file names)
The Other Jimmy 31:8ea194f6145b 39 Relevant part of IAR template
The Other Jimmy 31:8ea194f6145b 40 {% for group in groups %}
The Other Jimmy 31:8ea194f6145b 41 <group>
The Other Jimmy 31:8ea194f6145b 42 <name>group.name</name>
The Other Jimmy 31:8ea194f6145b 43 {% for file in group.files %}
The Other Jimmy 31:8ea194f6145b 44 <file>
The Other Jimmy 31:8ea194f6145b 45 <name>$PROJ_DIR${{file}}</name>
The Other Jimmy 31:8ea194f6145b 46 </file>
The Other Jimmy 31:8ea194f6145b 47 {% endfor %}
The Other Jimmy 31:8ea194f6145b 48 </group>
The Other Jimmy 31:8ea194f6145b 49 {% endfor %}
The Other Jimmy 31:8ea194f6145b 50 """
The Other Jimmy 31:8ea194f6145b 51 IARgroup = namedtuple('IARgroup', ['name','files'])
The Other Jimmy 31:8ea194f6145b 52 groups = []
The Other Jimmy 31:8ea194f6145b 53 for name, files in grouped_src.items():
The Other Jimmy 31:8ea194f6145b 54 groups.append(IARgroup(name,files))
The Other Jimmy 31:8ea194f6145b 55 return groups
The Other Jimmy 31:8ea194f6145b 56
The Other Jimmy 31:8ea194f6145b 57 def iar_device(self):
The Other Jimmy 31:8ea194f6145b 58 """Retrieve info from iar_definitions.json"""
The Other Jimmy 31:8ea194f6145b 59 device_name = TARGET_MAP[self.target].device_name
The Other Jimmy 31:8ea194f6145b 60 device_info = self.IAR_DEFS[device_name]
The Other Jimmy 31:8ea194f6145b 61 iar_defaults ={
The Other Jimmy 31:8ea194f6145b 62 "OGChipSelectEditMenu": "",
The Other Jimmy 31:8ea194f6145b 63 "CoreVariant": '',
The Other Jimmy 31:8ea194f6145b 64 "GFPUCoreSlave": '',
The Other Jimmy 31:8ea194f6145b 65 "GFPUCoreSlave2": 40,
The Other Jimmy 31:8ea194f6145b 66 "GBECoreSlave": 35,
The Other Jimmy 31:8ea194f6145b 67 "FPU2": 0,
The Other Jimmy 31:8ea194f6145b 68 "NrRegs": 0,
The Other Jimmy 31:8ea194f6145b 69 }
The Other Jimmy 31:8ea194f6145b 70
The Other Jimmy 31:8ea194f6145b 71 iar_defaults.update(device_info)
The Other Jimmy 31:8ea194f6145b 72 IARdevice = namedtuple('IARdevice', iar_defaults.keys())
The Other Jimmy 31:8ea194f6145b 73 return IARdevice(**iar_defaults)
The Other Jimmy 31:8ea194f6145b 74
The Other Jimmy 31:8ea194f6145b 75 def format_file(self, file):
The Other Jimmy 31:8ea194f6145b 76 """Make IAR compatible path"""
The Other Jimmy 31:8ea194f6145b 77 return join('$PROJ_DIR$',file)
The Other Jimmy 31:8ea194f6145b 78
The Other Jimmy 31:8ea194f6145b 79 def format_src(self, srcs):
The Other Jimmy 31:8ea194f6145b 80 """Group source files"""
The Other Jimmy 31:8ea194f6145b 81 grouped = self.group_project_files(srcs)
The Other Jimmy 31:8ea194f6145b 82 for group, files in grouped.items():
The Other Jimmy 31:8ea194f6145b 83 grouped[group] = [self.format_file(src) for src in files]
The Other Jimmy 31:8ea194f6145b 84 return grouped
The Other Jimmy 31:8ea194f6145b 85
The Other Jimmy 31:8ea194f6145b 86 def generate(self):
The Other Jimmy 31:8ea194f6145b 87 """Generate the .eww, .ewd, and .ewp files"""
The Other Jimmy 31:8ea194f6145b 88 srcs = self.resources.headers + self.resources.s_sources + \
The Other Jimmy 31:8ea194f6145b 89 self.resources.c_sources + self.resources.cpp_sources + \
The Other Jimmy 31:8ea194f6145b 90 self.resources.objects + self.resources.libraries
The Other Jimmy 31:8ea194f6145b 91 flags = self.flags
The Other Jimmy 31:8ea194f6145b 92 flags['c_flags'] = list(set(flags['common_flags']
The Other Jimmy 31:8ea194f6145b 93 + flags['c_flags']
The Other Jimmy 31:8ea194f6145b 94 + flags['cxx_flags']))
The Other Jimmy 31:8ea194f6145b 95 if '--vla' in flags['c_flags']:
The Other Jimmy 31:8ea194f6145b 96 flags['c_flags'].remove('--vla')
The Other Jimmy 31:8ea194f6145b 97 if '--no_static_destruction' in flags['c_flags']:
The Other Jimmy 31:8ea194f6145b 98 flags['c_flags'].remove('--no_static_destruction')
The Other Jimmy 31:8ea194f6145b 99 #Optimizations
The Other Jimmy 31:8ea194f6145b 100 if '-Oh' in flags['c_flags']:
The Other Jimmy 31:8ea194f6145b 101 flags['c_flags'].remove('-Oh')
The Other Jimmy 31:8ea194f6145b 102
The Other Jimmy 31:8ea194f6145b 103 try:
The Other Jimmy 31:8ea194f6145b 104 debugger = DeviceCMSIS(self.target).debug.replace('-','').upper()
The Other Jimmy 31:8ea194f6145b 105 except TargetNotSupportedException:
The Other Jimmy 31:8ea194f6145b 106 debugger = "CMSISDAP"
The Other Jimmy 31:8ea194f6145b 107
The Other Jimmy 31:8ea194f6145b 108 ctx = {
The Other Jimmy 31:8ea194f6145b 109 'name': self.project_name,
The Other Jimmy 31:8ea194f6145b 110 'groups': self.iar_groups(self.format_src(srcs)),
The Other Jimmy 31:8ea194f6145b 111 'linker_script': self.format_file(self.resources.linker_script),
The Other Jimmy 31:8ea194f6145b 112 'include_paths': [self.format_file(src) for src in self.resources.inc_dirs],
The Other Jimmy 31:8ea194f6145b 113 'device': self.iar_device(),
The Other Jimmy 31:8ea194f6145b 114 'ewp': sep+self.project_name + ".ewp",
The Other Jimmy 31:8ea194f6145b 115 'debugger': debugger
The Other Jimmy 31:8ea194f6145b 116 }
The Other Jimmy 31:8ea194f6145b 117 ctx.update(flags)
The Other Jimmy 31:8ea194f6145b 118
The Other Jimmy 31:8ea194f6145b 119 self.gen_file('iar/eww.tmpl', ctx, self.project_name + ".eww")
The Other Jimmy 31:8ea194f6145b 120 self.gen_file('iar/ewd.tmpl', ctx, self.project_name + ".ewd")
The Other Jimmy 31:8ea194f6145b 121 self.gen_file('iar/ewp.tmpl', ctx, self.project_name + ".ewp")
The Other Jimmy 31:8ea194f6145b 122
The Other Jimmy 31:8ea194f6145b 123 @staticmethod
The Other Jimmy 31:8ea194f6145b 124 def build(project_name, log_name="build_log.txt", cleanup=True):
The Other Jimmy 31:8ea194f6145b 125 """ Build IAR project """
The Other Jimmy 31:8ea194f6145b 126 # > IarBuild [project_path] -build [project_name]
The Other Jimmy 31:8ea194f6145b 127 proj_file = project_name + ".ewp"
The Other Jimmy 31:8ea194f6145b 128 cmd = ["IarBuild", proj_file, '-build', project_name]
The Other Jimmy 31:8ea194f6145b 129
The Other Jimmy 31:8ea194f6145b 130 # IAR does not support a '0' option to automatically use all
The Other Jimmy 31:8ea194f6145b 131 # available CPUs, so we use Python's multiprocessing library
The Other Jimmy 31:8ea194f6145b 132 # to detect the number of CPUs available
The Other Jimmy 31:8ea194f6145b 133 cpus_available = cpu_count()
The Other Jimmy 31:8ea194f6145b 134 jobs = cpus_available if cpus_available else None
The Other Jimmy 31:8ea194f6145b 135
The Other Jimmy 31:8ea194f6145b 136 # Only add the parallel flag if we're using more than one CPU
The Other Jimmy 31:8ea194f6145b 137 if jobs:
The Other Jimmy 31:8ea194f6145b 138 cmd += ['-parallel', str(jobs)]
The Other Jimmy 31:8ea194f6145b 139
The Other Jimmy 31:8ea194f6145b 140 # Build the project
The Other Jimmy 31:8ea194f6145b 141 p = Popen(cmd, stdout=PIPE, stderr=PIPE)
The Other Jimmy 31:8ea194f6145b 142 out, err = p.communicate()
The Other Jimmy 31:8ea194f6145b 143 ret_code = p.returncode
The Other Jimmy 31:8ea194f6145b 144
The Other Jimmy 31:8ea194f6145b 145 out_string = "=" * 10 + "STDOUT" + "=" * 10 + "\n"
The Other Jimmy 31:8ea194f6145b 146 out_string += out
The Other Jimmy 31:8ea194f6145b 147 out_string += "=" * 10 + "STDERR" + "=" * 10 + "\n"
The Other Jimmy 31:8ea194f6145b 148 out_string += err
The Other Jimmy 31:8ea194f6145b 149
The Other Jimmy 31:8ea194f6145b 150 if ret_code == 0:
The Other Jimmy 31:8ea194f6145b 151 out_string += "SUCCESS"
The Other Jimmy 31:8ea194f6145b 152 else:
The Other Jimmy 31:8ea194f6145b 153 out_string += "FAILURE"
The Other Jimmy 31:8ea194f6145b 154
The Other Jimmy 31:8ea194f6145b 155 print out_string
The Other Jimmy 31:8ea194f6145b 156
The Other Jimmy 31:8ea194f6145b 157 if log_name:
The Other Jimmy 31:8ea194f6145b 158 # Write the output to the log file
The Other Jimmy 31:8ea194f6145b 159 with open(log_name, 'w+') as f:
The Other Jimmy 31:8ea194f6145b 160 f.write(out_string)
The Other Jimmy 31:8ea194f6145b 161
The Other Jimmy 31:8ea194f6145b 162 # Cleanup the exported and built files
The Other Jimmy 31:8ea194f6145b 163 if cleanup:
The Other Jimmy 31:8ea194f6145b 164 os.remove(project_name + ".ewp")
The Other Jimmy 31:8ea194f6145b 165 os.remove(project_name + ".ewd")
The Other Jimmy 31:8ea194f6145b 166 os.remove(project_name + ".eww")
The Other Jimmy 31:8ea194f6145b 167 # legacy output file location
The Other Jimmy 31:8ea194f6145b 168 if exists('.build'):
The Other Jimmy 31:8ea194f6145b 169 shutil.rmtree('.build')
The Other Jimmy 31:8ea194f6145b 170 if exists('BUILD'):
The Other Jimmy 31:8ea194f6145b 171 shutil.rmtree('BUILD')
The Other Jimmy 31:8ea194f6145b 172
The Other Jimmy 31:8ea194f6145b 173 if ret_code !=0:
The Other Jimmy 31:8ea194f6145b 174 # Seems like something went wrong.
The Other Jimmy 31:8ea194f6145b 175 return -1
The Other Jimmy 31:8ea194f6145b 176 else:
The Other Jimmy 31:8ea194f6145b 177 return 0