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.
iar.py
00001 """ 00002 mbed SDK 00003 Copyright (c) 2011-2013 ARM Limited 00004 00005 Licensed under the Apache License, Version 2.0 (the "License"); 00006 you may not use this file except in compliance with the License. 00007 You may obtain a copy of the License at 00008 00009 http://www.apache.org/licenses/LICENSE-2.0 00010 00011 Unless required by applicable law or agreed to in writing, software 00012 distributed under the License is distributed on an "AS IS" BASIS, 00013 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 See the License for the specific language governing permissions and 00015 limitations under the License. 00016 """ 00017 import re 00018 from os import remove 00019 from os.path import join, splitext, exists 00020 from distutils.version import LooseVersion 00021 00022 from tools.toolchains import mbedToolchain, TOOLCHAIN_PATHS 00023 from tools.hooks import hook_tool 00024 from tools.utils import run_cmd, NotSupportedException 00025 00026 class IAR(mbedToolchain): 00027 LIBRARY_EXT = '.a' 00028 LINKER_EXT = '.icf' 00029 STD_LIB_NAME = "%s.a" 00030 00031 DIAGNOSTIC_PATTERN = re.compile('"(?P<file>[^"]+)",(?P<line>[\d]+)\s+(?P<severity>Warning|Error|Fatal error)(?P<message>.+)') 00032 INDEX_PATTERN = re.compile('(?P<col>\s*)\^') 00033 IAR_VERSION_RE = re.compile(b"IAR ANSI C/C\+\+ Compiler V(\d+\.\d+)") 00034 IAR_VERSION = LooseVersion("7.80") 00035 00036 @staticmethod 00037 def check_executable(): 00038 """Returns True if the executable (arm-none-eabi-gcc) location 00039 specified by the user exists OR the executable can be found on the PATH. 00040 Returns False otherwise.""" 00041 return mbedToolchain.generic_check_executable("IAR", 'iccarm', 2, "bin") 00042 00043 def __init__(self, target, notify=None, macros=None, build_profile=None, 00044 build_dir=None): 00045 mbedToolchain.__init__(self, target, notify, macros, build_dir=build_dir, 00046 build_profile=build_profile) 00047 if target.core == "Cortex-M7F" or target.core == "Cortex-M7FD": 00048 cpuchoice = "Cortex-M7" 00049 elif target.core.startswith("Cortex-M23"): 00050 cpuchoice = "8-M.baseline" 00051 elif target.core.startswith("Cortex-M33"): 00052 cpuchoice = "8-M.mainline" 00053 else: 00054 cpuchoice = target.core 00055 00056 # flags_cmd are used only by our scripts, the project files have them already defined, 00057 # using this flags results in the errors (duplication) 00058 # asm accepts --cpu Core or --fpu FPU, not like c/c++ --cpu=Core 00059 asm_flags_cmd = ["--cpu", cpuchoice] 00060 # custom c flags 00061 c_flags_cmd = ["--cpu", cpuchoice] 00062 00063 c_flags_cmd.extend([ 00064 "--thumb", "--dlib_config", "DLib_Config_Full.h" 00065 ]) 00066 # custom c++ cmd flags 00067 cxx_flags_cmd = [ 00068 "--c++", "--no_rtti", "--no_exceptions" 00069 ] 00070 if target.core == "Cortex-M7FD": 00071 asm_flags_cmd += ["--fpu", "VFPv5"] 00072 c_flags_cmd.append("--fpu=VFPv5") 00073 elif target.core == "Cortex-M7F": 00074 asm_flags_cmd += ["--fpu", "VFPv5_sp"] 00075 c_flags_cmd.append("--fpu=VFPv5_sp") 00076 elif target.core == "Cortex-M23" or target.core == "Cortex-M33": 00077 self.flags["asm"] += ["--cmse"] 00078 self.flags["common"] += ["--cmse"] 00079 00080 # Create Secure library 00081 if target.core == "Cortex-M23" or self.target.core == "Cortex-M33": 00082 secure_file = join(build_dir, "cmse_lib.o") 00083 self.flags["ld"] += ["--import_cmse_lib_out=%s" % secure_file] 00084 00085 IAR_BIN = join(TOOLCHAIN_PATHS['IAR'], "bin") 00086 main_cc = join(IAR_BIN, "iccarm") 00087 00088 self.asm = [join(IAR_BIN, "iasmarm")] + asm_flags_cmd + self.flags["asm"] 00089 self.cc = [main_cc] 00090 self.cppc = [main_cc] 00091 self.cc += self.flags["common"] + c_flags_cmd + self.flags["c"] 00092 self.cppc += self.flags["common"] + c_flags_cmd + cxx_flags_cmd + self.flags["cxx"] 00093 00094 self.ld = [join(IAR_BIN, "ilinkarm")] + self.flags['ld'] 00095 self.ar = join(IAR_BIN, "iarchive") 00096 self.elf2bin = join(IAR_BIN, "ielftool") 00097 00098 def version_check(self): 00099 stdout, _, retcode = run_cmd([self.cc[0], "--version"], redirect=True) 00100 msg = None 00101 match = self.IAR_VERSION_RE.search(stdout) 00102 found_version = match.group(1).decode("utf-8") if match else None 00103 if found_version and LooseVersion(found_version) != self.IAR_VERSION: 00104 msg = "Compiler version mismatch: Have {}; expected {}".format( 00105 found_version, self.IAR_VERSION) 00106 elif not match or len(match.groups()) != 1: 00107 msg = ("Compiler version mismatch: Could Not detect compiler " 00108 "version; expected {}".format(self.IAR_VERSION)) 00109 if msg: 00110 self.notify.cc_info({ 00111 "message": msg, 00112 "file": "", 00113 "line": "", 00114 "col": "", 00115 "severity": "ERROR", 00116 }) 00117 00118 00119 def parse_dependencies(self, dep_path): 00120 return [(self.CHROOT if self.CHROOT else '')+path.strip() for path in open(dep_path).readlines() 00121 if (path and not path.isspace())] 00122 00123 def parse_output(self, output): 00124 msg = None 00125 for line in output.splitlines(): 00126 match = IAR.DIAGNOSTIC_PATTERN.match(line) 00127 if match is not None: 00128 if msg is not None: 00129 self.notify.cc_info(msg) 00130 msg = None 00131 msg = { 00132 'severity': match.group('severity').lower(), 00133 'file': match.group('file'), 00134 'line': match.group('line'), 00135 'col': 0, 00136 'message': match.group('message'), 00137 'text': '', 00138 'target_name': self.target.name, 00139 'toolchain_name': self.name 00140 } 00141 elif msg is not None: 00142 # Determine the warning/error column by calculating the ^ position 00143 match = IAR.INDEX_PATTERN.match(line) 00144 if match is not None: 00145 msg['col'] = len(match.group('col')) 00146 self.notify.cc_info(msg) 00147 msg = None 00148 else: 00149 msg['text'] += line+"\n" 00150 00151 if msg is not None: 00152 self.notify.cc_info(msg) 00153 00154 def get_dep_option(self, object): 00155 base, _ = splitext(object) 00156 dep_path = base + '.d' 00157 return ["--dependencies", dep_path] 00158 00159 def cc_extra(self, object): 00160 base, _ = splitext(object) 00161 return ["-l", base + '.s.txt'] 00162 00163 def get_config_option(self, config_header): 00164 return ['--preinclude=' + config_header] 00165 00166 def get_compile_options(self, defines, includes, for_asm=False): 00167 opts = ['-D%s' % d for d in defines] 00168 if for_asm: 00169 config_macros = self.config.get_config_data_macros() 00170 macros_cmd = ['"-D%s"' % d.replace('"', '').replace('//','/\/') for d in config_macros] 00171 if self.RESPONSE_FILES: 00172 via_file = self.make_option_file( 00173 macros_cmd, "asm_macros_{}.xcl") 00174 opts += ['-f', via_file] 00175 else: 00176 opts += macros_cmd 00177 return opts 00178 else: 00179 if self.RESPONSE_FILES: 00180 opts += ['-f', self.get_inc_file(includes)] 00181 else: 00182 opts += ["-I%s" % i for i in includes] 00183 config_header = self.get_config_header() 00184 if config_header is not None: 00185 opts = opts + self.get_config_option(config_header) 00186 00187 return opts 00188 00189 @hook_tool 00190 def assemble(self, source, object, includes): 00191 # Build assemble command 00192 cmd = self.asm + self.get_compile_options(self.get_symbols(True), includes, True) + ["-o", object, source] 00193 00194 # Call cmdline hook 00195 cmd = self.hook.get_cmdline_assembler(cmd) 00196 00197 # Return command array, don't execute 00198 return [cmd] 00199 00200 @hook_tool 00201 def compile(self, cc, source, object, includes): 00202 # Build compile command 00203 cmd = cc + self.get_compile_options(self.get_symbols(), includes) 00204 00205 cmd.extend(self.get_dep_option(object)) 00206 00207 cmd.extend(self.cc_extra(object)) 00208 00209 cmd.extend(["-o", object, source]) 00210 00211 # Call cmdline hook 00212 cmd = self.hook.get_cmdline_compiler(cmd) 00213 00214 return [cmd] 00215 00216 def compile_c(self, source, object, includes): 00217 return self.compile(self.cc, source, object, includes) 00218 00219 def compile_cpp(self, source, object, includes): 00220 return self.compile(self.cppc, source, object, includes) 00221 00222 @hook_tool 00223 def link(self, output, objects, libraries, lib_dirs, mem_map): 00224 # Build linker command 00225 map_file = splitext(output)[0] + ".map" 00226 cmd = self.ld + [ "-o", output, "--map=%s" % map_file] + objects + libraries 00227 00228 if mem_map: 00229 cmd.extend(["--config", mem_map]) 00230 00231 # Call cmdline hook 00232 cmd = self.hook.get_cmdline_linker(cmd) 00233 00234 if self.RESPONSE_FILES: 00235 # Split link command to linker executable + response file 00236 cmd_linker = cmd[0] 00237 link_files = self.get_link_file(cmd[1:]) 00238 cmd = [cmd_linker, '-f', link_files] 00239 00240 # Exec command 00241 self.notify.cc_verbose("Link: %s" % ' '.join(cmd)) 00242 self.default_cmd(cmd) 00243 00244 @hook_tool 00245 def archive(self, objects, lib_path): 00246 if self.RESPONSE_FILES: 00247 param = ['-f', self.get_arch_file(objects)] 00248 else: 00249 param = objects 00250 00251 if exists(lib_path): 00252 remove(lib_path) 00253 00254 self.default_cmd([self.ar, lib_path] + param) 00255 00256 @hook_tool 00257 def binary(self, resources, elf, bin): 00258 _, fmt = splitext(bin) 00259 bin_arg = {".bin": "--bin", ".hex": "--ihex"}[fmt] 00260 # Build binary command 00261 cmd = [self.elf2bin, bin_arg, elf, bin] 00262 00263 # Call cmdline hook 00264 cmd = self.hook.get_cmdline_binary(cmd) 00265 00266 # Exec command 00267 self.notify.cc_verbose("FromELF: %s" % ' '.join(cmd)) 00268 self.default_cmd(cmd) 00269 00270 @staticmethod 00271 def name_mangle(name): 00272 return "_Z%i%sv" % (len(name), name) 00273 00274 @staticmethod 00275 def make_ld_define(name, value): 00276 return "--config_def %s=%s" % (name, value) 00277 00278 @staticmethod 00279 def redirect_symbol(source, sync, build_dir): 00280 return "--redirect %s=%s" % (source, sync)
Generated on Tue Jul 12 2022 17:12:47 by
1.7.2