Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers iar.py Source File

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 
00021 from tools.toolchains import mbedToolchain, TOOLCHAIN_PATHS
00022 from tools.hooks import hook_tool
00023 
00024 class IAR(mbedToolchain):
00025     LIBRARY_EXT = '.a'
00026     LINKER_EXT = '.icf'
00027     STD_LIB_NAME = "%s.a"
00028 
00029     DIAGNOSTIC_PATTERN = re.compile('"(?P<file>[^"]+)",(?P<line>[\d]+)\s+(?P<severity>Warning|Error|Fatal error)(?P<message>.+)')
00030     INDEX_PATTERN  = re.compile('(?P<col>\s*)\^')
00031 
00032     @staticmethod
00033     def check_executable():
00034         """Returns True if the executable (arm-none-eabi-gcc) location
00035         specified by the user exists OR the executable can be found on the PATH.
00036         Returns False otherwise."""
00037         return mbedToolchain.generic_check_executable("IAR", 'iccarm', 2, "bin")
00038 
00039     def __init__(self, target, notify=None, macros=None,
00040                  silent=False, extra_verbose=False, build_profile=None,
00041                  build_dir=None):
00042         mbedToolchain.__init__(self, target, notify, macros, silent,
00043                                build_dir=build_dir,
00044                                extra_verbose=extra_verbose,
00045                                build_profile=build_profile)
00046         if target.core == "Cortex-M7F" or target.core == "Cortex-M7FD":
00047             cpuchoice = "Cortex-M7"
00048         elif target.core.startswith("Cortex-M23"):
00049             cpuchoice = "8-M.baseline"
00050         elif target.core.startswith("Cortex-M33"):
00051             cpuchoice = "8-M.mainline"
00052         else:
00053             cpuchoice = target.core
00054 
00055         # flags_cmd are used only by our scripts, the project files have them already defined,
00056         # using this flags results in the errors (duplication)
00057         # asm accepts --cpu Core or --fpu FPU, not like c/c++ --cpu=Core
00058         asm_flags_cmd = ["--cpu", cpuchoice]
00059         # custom c flags
00060         c_flags_cmd = ["--cpu", cpuchoice]
00061 
00062         c_flags_cmd.extend([
00063             "--thumb", "--dlib_config", "DLib_Config_Full.h"
00064         ])
00065         # custom c++ cmd flags
00066         cxx_flags_cmd = [
00067             "--c++", "--no_rtti", "--no_exceptions"
00068         ]
00069         if target.core == "Cortex-M7FD":
00070             asm_flags_cmd += ["--fpu", "VFPv5"]
00071             c_flags_cmd.append("--fpu=VFPv5")
00072         elif target.core == "Cortex-M7F":
00073             asm_flags_cmd += ["--fpu", "VFPv5_sp"]
00074             c_flags_cmd.append("--fpu=VFPv5_sp")
00075         elif target.core == "Cortex-M23" or target.core == "Cortex-M33":
00076             self.flags["asm"] += ["--cmse"]
00077             self.flags["common"] += ["--cmse"]
00078 
00079         # Create Secure library
00080         if target.core == "Cortex-M23" or self.target.core == "Cortex-M33":
00081             secure_file = join(build_dir, "cmse_lib.o")
00082             self.flags["ld"] += ["--import_cmse_lib_out=%s" % secure_file]
00083 
00084         IAR_BIN = join(TOOLCHAIN_PATHS['IAR'], "bin")
00085         main_cc = join(IAR_BIN, "iccarm")
00086 
00087         self.asm  = [join(IAR_BIN, "iasmarm")] + asm_flags_cmd + self.flags["asm"]
00088         self.cc   = [main_cc]
00089         self.cppc = [main_cc]
00090         self.cc += self.flags["common"] + c_flags_cmd + self.flags["c"]
00091         self.cppc += self.flags["common"] + c_flags_cmd + cxx_flags_cmd + self.flags["cxx"]
00092         
00093         self.ld   = [join(IAR_BIN, "ilinkarm")] + self.flags['ld']
00094         self.ar = join(IAR_BIN, "iarchive")
00095         self.elf2bin = join(IAR_BIN, "ielftool")
00096 
00097     def parse_dependencies(self, dep_path):
00098         return [(self.CHROOT if self.CHROOT else '')+path.strip() for path in open(dep_path).readlines()
00099                 if (path and not path.isspace())]
00100 
00101     def parse_output(self, output):
00102         msg = None
00103         for line in output.splitlines():
00104             match = IAR.DIAGNOSTIC_PATTERN.match(line)
00105             if match is not None:
00106                 if msg is not None:
00107                     self.cc_info(msg)
00108                     msg = None
00109                 msg = {
00110                     'severity': match.group('severity').lower(),
00111                     'file': match.group('file'),
00112                     'line': match.group('line'),
00113                     'col': 0,
00114                     'message': match.group('message'),
00115                     'text': '',
00116                     'target_name': self.target.name,
00117                     'toolchain_name': self.name
00118                 }
00119             elif msg is not None:
00120                 # Determine the warning/error column by calculating the ^ position
00121                 match = IAR.INDEX_PATTERN.match(line)
00122                 if match is not None:
00123                     msg['col'] = len(match.group('col'))
00124                     self.cc_info(msg)
00125                     msg = None
00126                 else:
00127                     msg['text'] += line+"\n"
00128 
00129         if msg is not None:
00130             self.cc_info(msg)
00131 
00132     def get_dep_option(self, object):
00133         base, _ = splitext(object)
00134         dep_path = base + '.d'
00135         return ["--dependencies", dep_path]
00136 
00137     def cc_extra(self, object):
00138         base, _ = splitext(object)
00139         return ["-l", base + '.s.txt']
00140 
00141     def get_config_option(self, config_header):
00142         return ['--preinclude=' + config_header]
00143 
00144     def get_compile_options(self, defines, includes, for_asm=False):
00145         opts = ['-D%s' % d for d in defines]
00146         if for_asm :
00147             return opts
00148         if self.RESPONSE_FILES:
00149             opts += ['-f', self.get_inc_file(includes)]
00150         else:
00151             opts += ["-I%s" % i for i in includes]
00152 
00153         config_header = self.get_config_header()
00154         if config_header is not None:
00155             opts = opts + self.get_config_option(config_header)
00156         return opts
00157 
00158     @hook_tool
00159     def assemble(self, source, object, includes):
00160         # Build assemble command
00161         cmd = self.asm + self.get_compile_options(self.get_symbols(True), includes, True) + ["-o", object, source]
00162 
00163         # Call cmdline hook
00164         cmd = self.hook.get_cmdline_assembler(cmd)
00165 
00166         # Return command array, don't execute
00167         return [cmd]
00168 
00169     @hook_tool
00170     def compile(self, cc, source, object, includes):
00171         # Build compile command
00172         cmd = cc +  self.get_compile_options(self.get_symbols(), includes)
00173 
00174         cmd.extend(self.get_dep_option(object))
00175 
00176         cmd.extend(self.cc_extra(object))
00177         
00178         cmd.extend(["-o", object, source])
00179 
00180         # Call cmdline hook
00181         cmd = self.hook.get_cmdline_compiler(cmd)
00182 
00183         return [cmd]
00184 
00185     def compile_c(self, source, object, includes):
00186         return self.compile(self.cc, source, object, includes)
00187 
00188     def compile_cpp(self, source, object, includes):
00189         return self.compile(self.cppc, source, object, includes)
00190 
00191     @hook_tool
00192     def link(self, output, objects, libraries, lib_dirs, mem_map):
00193         # Build linker command
00194         map_file = splitext(output)[0] + ".map"
00195         cmd = self.ld + [ "-o", output, "--map=%s" % map_file] + objects + libraries
00196 
00197         if mem_map:
00198             cmd.extend(["--config", mem_map])
00199 
00200         # Call cmdline hook
00201         cmd = self.hook.get_cmdline_linker(cmd)
00202 
00203         if self.RESPONSE_FILES:
00204             # Split link command to linker executable + response file
00205             cmd_linker = cmd[0]
00206             link_files = self.get_link_file(cmd[1:])
00207             cmd = [cmd_linker, '-f', link_files]
00208 
00209         # Exec command
00210         self.cc_verbose("Link: %s" % ' '.join(cmd))
00211         self.default_cmd(cmd)
00212 
00213     @hook_tool
00214     def archive(self, objects, lib_path):
00215         if self.RESPONSE_FILES:
00216             param = ['-f', self.get_arch_file(objects)]
00217         else:
00218             param = objects
00219 
00220         if exists(lib_path):
00221             remove(lib_path)
00222 
00223         self.default_cmd([self.ar, lib_path] + param)
00224 
00225     @hook_tool
00226     def binary(self, resources, elf, bin):
00227         _, fmt = splitext(bin)
00228         bin_arg = {".bin": "--bin", ".hex": "--ihex"}[fmt]
00229         # Build binary command
00230         cmd = [self.elf2bin, bin_arg, elf, bin]
00231 
00232         # Call cmdline hook
00233         cmd = self.hook.get_cmdline_binary(cmd)
00234 
00235         # Exec command
00236         self.cc_verbose("FromELF: %s" % ' '.join(cmd))
00237         self.default_cmd(cmd)
00238 
00239     @staticmethod
00240     def name_mangle(name):
00241         return "_Z%i%sv" % (len(name), name)
00242 
00243     @staticmethod
00244     def make_ld_define(name, value):
00245         return "--config_def %s=0x%x" % (name, value)
00246 
00247     @staticmethod
00248     def redirect_symbol(source, sync, build_dir):
00249         return "--redirect %s=%s" % (source, sync)