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