Greg Steiert / pegasus_dev

Dependents:   blinky_max32630fthr

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