ON Semiconductor / mbed-os

Dependents:   mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510

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)(?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         mbedToolchain.__init__(self, target, notify, macros, silent,
00042                                extra_verbose=extra_verbose,
00043                                build_profile=build_profile)
00044         if target.core == "Cortex-M7F" or target.core == "Cortex-M7FD":
00045             cpuchoice = "Cortex-M7"
00046         else:
00047             cpuchoice = target.core
00048 
00049         # flags_cmd are used only by our scripts, the project files have them already defined,
00050         # using this flags results in the errors (duplication)
00051         # asm accepts --cpu Core or --fpu FPU, not like c/c++ --cpu=Core
00052         if target.core == "Cortex-M4F":
00053           asm_flags_cmd = [
00054               "--cpu", "Cortex-M4F"
00055           ]
00056         else:
00057           asm_flags_cmd = [
00058               "--cpu", cpuchoice
00059           ]
00060         # custom c flags
00061         if target.core == "Cortex-M4F":
00062           c_flags_cmd = [
00063               "--cpu", "Cortex-M4F"
00064           ]
00065         else:
00066           c_flags_cmd = [
00067               "--cpu", cpuchoice
00068           ]
00069 
00070         c_flags_cmd.extend([
00071             "--thumb", "--dlib_config", "DLib_Config_Full.h"
00072         ])
00073         # custom c++ cmd flags
00074         cxx_flags_cmd = [
00075             "--c++", "--no_rtti", "--no_exceptions"
00076         ]
00077         if target.core == "Cortex-M7FD":
00078             asm_flags_cmd += ["--fpu", "VFPv5"]
00079             c_flags_cmd.append("--fpu=VFPv5")
00080         elif target.core == "Cortex-M7F":
00081             asm_flags_cmd += ["--fpu", "VFPv5_sp"]
00082             c_flags_cmd.append("--fpu=VFPv5_sp")
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         self.ld   = [join(IAR_BIN, "ilinkarm")]
00093         self.ar = join(IAR_BIN, "iarchive")
00094         self.elf2bin = join(IAR_BIN, "ielftool")
00095 
00096     def parse_dependencies(self, dep_path):
00097         return [(self.CHROOT if self.CHROOT else '')+path.strip() for path in open(dep_path).readlines()
00098                 if (path and not path.isspace())]
00099 
00100     def parse_output(self, output):
00101         msg = None
00102         for line in output.splitlines():
00103             match = IAR.DIAGNOSTIC_PATTERN.match(line)
00104             if match is not None:
00105                 if msg is not None:
00106                     self.cc_info(msg)
00107                     msg = None
00108                 msg = {
00109                     'severity': match.group('severity').lower(),
00110                     'file': match.group('file'),
00111                     'line': match.group('line'),
00112                     'col': 0,
00113                     'message': match.group('message'),
00114                     'text': '',
00115                     'target_name': self.target.name,
00116                     'toolchain_name': self.name
00117                 }
00118             elif msg is not None:
00119                 # Determine the warning/error column by calculating the ^ position
00120                 match = IAR.INDEX_PATTERN.match(line)
00121                 if match is not None:
00122                     msg['col'] = len(match.group('col'))
00123                     self.cc_info(msg)
00124                     msg = None
00125                 else:
00126                     msg['text'] += line+"\n"
00127 
00128         if msg is not None:
00129             self.cc_info(msg)
00130 
00131     def get_dep_option(self, object):
00132         base, _ = splitext(object)
00133         dep_path = base + '.d'
00134         return ["--dependencies", dep_path]
00135 
00136     def cc_extra(self, object):
00137         base, _ = splitext(object)
00138         return ["-l", base + '.s.txt']
00139 
00140     def get_config_option(self, config_header):
00141         return ['--preinclude=' + config_header]
00142 
00143     def get_compile_options(self, defines, includes, for_asm=False):
00144         opts = ['-D%s' % d for d in defines]
00145         if self.RESPONSE_FILES:
00146             opts += ['-f', self.get_inc_file(includes)]
00147         else:
00148             opts += ["-I%s" % i for i in includes]
00149 
00150         if not for_asm:
00151             config_header = self.get_config_header()
00152             if config_header is not None:
00153                 opts = opts + self.get_config_option(config_header)
00154         return opts
00155 
00156     @hook_tool
00157     def assemble(self, source, object, includes):
00158         # Build assemble command
00159         cmd = self.asm + self.get_compile_options(self.get_symbols(True), includes, True) + ["-o", object, source]
00160 
00161         # Call cmdline hook
00162         cmd = self.hook.get_cmdline_assembler(cmd)
00163 
00164         # Return command array, don't execute
00165         return [cmd]
00166 
00167     @hook_tool
00168     def compile(self, cc, source, object, includes):
00169         # Build compile command
00170         cmd = cc +  self.get_compile_options(self.get_symbols(), includes)
00171 
00172         cmd.extend(self.get_dep_option(object))
00173 
00174         cmd.extend(self.cc_extra(object))
00175         
00176         cmd.extend(["-o", object, source])
00177 
00178         # Call cmdline hook
00179         cmd = self.hook.get_cmdline_compiler(cmd)
00180 
00181         return [cmd]
00182 
00183     def compile_c(self, source, object, includes):
00184         return self.compile(self.cc, source, object, includes)
00185 
00186     def compile_cpp(self, source, object, includes):
00187         return self.compile(self.cppc, source, object, includes)
00188 
00189     @hook_tool
00190     def link(self, output, objects, libraries, lib_dirs, mem_map):
00191         # Build linker command
00192         map_file = splitext(output)[0] + ".map"
00193         cmd = self.ld + [ "-o", output, "--map=%s" % map_file] + objects + libraries + self.flags['ld']
00194 
00195         if mem_map:
00196             cmd.extend(["--config", mem_map])
00197 
00198         # Call cmdline hook
00199         cmd = self.hook.get_cmdline_linker(cmd)
00200 
00201         if self.RESPONSE_FILES:
00202             # Split link command to linker executable + response file
00203             cmd_linker = cmd[0]
00204             link_files = self.get_link_file(cmd[1:])
00205             cmd = [cmd_linker, '-f', link_files]
00206 
00207         # Exec command
00208         self.cc_verbose("Link: %s" % ' '.join(cmd))
00209         self.default_cmd(cmd)
00210 
00211     @hook_tool
00212     def archive(self, objects, lib_path):
00213         if self.RESPONSE_FILES:
00214             param = ['-f', self.get_arch_file(objects)]
00215         else:
00216             param = objects
00217 
00218         if exists(lib_path):
00219             remove(lib_path)
00220 
00221         self.default_cmd([self.ar, lib_path] + param)
00222 
00223     @hook_tool
00224     def binary(self, resources, elf, bin):
00225         # Build binary command
00226         cmd = [self.elf2bin, "--bin", elf, bin]
00227 
00228         # Call cmdline hook
00229         cmd = self.hook.get_cmdline_binary(cmd)
00230 
00231         # Exec command
00232         self.cc_verbose("FromELF: %s" % ' '.join(cmd))
00233         self.default_cmd(cmd)