Daiki Kato / mbed-os-lychee

Dependents:   mbed-os-example-blinky-gr-lychee GR-Boads_Camera_sample GR-Boards_Audio_Recoder GR-Boads_Camera_DisplayApp ... more

Committer:
dkato
Date:
Fri Feb 02 05:42:23 2018 +0000
Revision:
0:f782d9c66c49
mbed-os for GR-LYCHEE

Who changed what in which revision?

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