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.
__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, TargetNotSupportedException 00011 import json 00012 from tools.export.cmsis import DeviceCMSIS 00013 from tools.utils import NotSupportedException 00014 from multiprocessing import cpu_count 00015 00016 00017 def _supported(mcu, iar_targets): 00018 if "IAR" not in mcu.supported_toolchains: 00019 return False 00020 if hasattr(mcu, 'device_name') and mcu.device_name in iar_targets: 00021 return True 00022 if mcu.name in iar_targets: 00023 return True 00024 return False 00025 00026 00027 _iar_defs = os.path.join( 00028 os.path.dirname(os.path.abspath(__file__)), 'iar_definitions.json') 00029 00030 with open(_iar_defs, 'r') as f: 00031 _GUI_OPTIONS = json.load(f) 00032 00033 00034 class IAR(Exporter): 00035 NAME = 'iar' 00036 TOOLCHAIN = 'IAR' 00037 00038 @classmethod 00039 def is_target_supported(cls, target_name): 00040 target = TARGET_MAP[target_name] 00041 return _supported(target, _GUI_OPTIONS.keys()) 00042 00043 00044 def iar_groups(self, grouped_src): 00045 """Return a namedtuple of group info 00046 Positional Arguments: 00047 grouped_src: dictionary mapping a group(str) to sources 00048 within it (list of file names) 00049 Relevant part of IAR template 00050 {% for group in groups %} 00051 <group> 00052 <name>group.name</name> 00053 {% for file in group.files %} 00054 <file> 00055 <name>$PROJ_DIR${{file}}</name> 00056 </file> 00057 {% endfor %} 00058 </group> 00059 {% endfor %} 00060 """ 00061 IARgroup = namedtuple('IARgroup', ['name','files']) 00062 groups = [] 00063 for name, files in grouped_src.items(): 00064 groups.append(IARgroup(name,files)) 00065 return groups 00066 00067 def iar_device(self): 00068 """Retrieve info from iar_definitions.json""" 00069 tgt = TARGET_MAP[self.target] 00070 device_name = (tgt.device_name if hasattr(tgt, "device_name") else 00071 tgt.name) 00072 device_info = _GUI_OPTIONS[device_name] 00073 iar_defaults ={ 00074 "OGChipSelectEditMenu": "", 00075 "CoreVariant": '', 00076 "GFPUCoreSlave": '', 00077 "GFPUCoreSlave2": 40, 00078 "GBECoreSlave": 35, 00079 "GBECoreSlave2": '', 00080 "FPU2": 0, 00081 "NrRegs": 0, 00082 "NEON": '', 00083 "CExtraOptionsCheck": 0, 00084 "CExtraOptions": "", 00085 "CMSISDAPJtagSpeedList": 0, 00086 } 00087 00088 iar_defaults.update(device_info) 00089 IARdevice = namedtuple('IARdevice', iar_defaults.keys()) 00090 return IARdevice(**iar_defaults) 00091 00092 def format_file(self, file): 00093 """Make IAR compatible path""" 00094 return join('$PROJ_DIR$',file) 00095 00096 def format_src(self, srcs): 00097 """Group source files""" 00098 grouped = self.group_project_files(srcs) 00099 for group, files in grouped.items(): 00100 grouped[group] = [self.format_file(src) for src in files] 00101 return grouped 00102 00103 def generate(self): 00104 """Generate the .eww, .ewd, and .ewp files""" 00105 if not self.resources.linker_script: 00106 raise NotSupportedException("No linker script found.") 00107 srcs = self.resources.headers + self.resources.s_sources + \ 00108 self.resources.c_sources + self.resources.cpp_sources + \ 00109 self.resources.objects + self.resources.libraries 00110 flags = self.flags 00111 c_flags = list(set(flags['common_flags'] 00112 + flags['c_flags'] 00113 + flags['cxx_flags'])) 00114 # Flags set in template to be set by user in IDE 00115 template = ["--vla", "--no_static_destruction"] 00116 # Flag invalid if set in template 00117 # Optimizations are also set in template 00118 invalid_flag = lambda x: x in template or re.match("-O(\d|time|n|hz?)", x) 00119 flags['c_flags'] = [flag for flag in c_flags if not invalid_flag(flag)] 00120 00121 try: 00122 debugger = DeviceCMSIS(self.target).debug.replace('-','').upper() 00123 except TargetNotSupportedException: 00124 debugger = "CMSISDAP" 00125 00126 ctx = { 00127 'name': self.project_name, 00128 'groups': self.iar_groups(self.format_src(srcs)), 00129 'linker_script': self.format_file(self.resources.linker_script), 00130 'include_paths': [self.format_file(src) for src in self.resources.inc_dirs], 00131 'device': self.iar_device(), 00132 'ewp': sep+self.project_name + ".ewp", 00133 'debugger': debugger 00134 } 00135 ctx.update(flags) 00136 00137 self.gen_file('iar/eww.tmpl', ctx, self.project_name + ".eww") 00138 self.gen_file('iar/ewd.tmpl', ctx, self.project_name + ".ewd") 00139 self.gen_file('iar/ewp.tmpl', ctx, self.project_name + ".ewp") 00140 00141 @staticmethod 00142 def build(project_name, log_name="build_log.txt", cleanup=True): 00143 """ Build IAR project """ 00144 # > IarBuild [project_path] -build [project_name] 00145 proj_file = project_name + ".ewp" 00146 cmd = ["IarBuild", proj_file, '-build', project_name] 00147 00148 # IAR does not support a '0' option to automatically use all 00149 # available CPUs, so we use Python's multiprocessing library 00150 # to detect the number of CPUs available 00151 cpus_available = cpu_count() 00152 jobs = cpus_available if cpus_available else None 00153 00154 # Only add the parallel flag if we're using more than one CPU 00155 if jobs: 00156 cmd += ['-parallel', str(jobs)] 00157 00158 # Build the project 00159 p = Popen(cmd, stdout=PIPE, stderr=PIPE) 00160 out, err = p.communicate() 00161 ret_code = p.returncode 00162 00163 out_string = "=" * 10 + "STDOUT" + "=" * 10 + "\n" 00164 out_string += out 00165 out_string += "=" * 10 + "STDERR" + "=" * 10 + "\n" 00166 out_string += err 00167 00168 if ret_code == 0: 00169 out_string += "SUCCESS" 00170 else: 00171 out_string += "FAILURE" 00172 00173 print out_string 00174 00175 if log_name: 00176 # Write the output to the log file 00177 with open(log_name, 'w+') as f: 00178 f.write(out_string) 00179 00180 # Cleanup the exported and built files 00181 if cleanup: 00182 os.remove(project_name + ".ewp") 00183 os.remove(project_name + ".ewd") 00184 os.remove(project_name + ".eww") 00185 # legacy output file location 00186 if exists('.build'): 00187 shutil.rmtree('.build') 00188 if exists('BUILD'): 00189 shutil.rmtree('BUILD') 00190 00191 if ret_code !=0: 00192 # Seems like something went wrong. 00193 return -1 00194 else: 00195 return 0 00196 00197
Generated on Thu Jul 14 2022 14:36:11 by
