Daiki Kato / mbed-os-lychee

Dependents:   mbed-os-example-blinky-gr-lychee GR-Boads_Camera_sample GR-Boards_Audio_Recoder GR-Boads_Camera_DisplayApp ... more

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         else:
00049             cpuchoice = target.core
00050 
00051         # flags_cmd are used only by our scripts, the project files have them already defined,
00052         # using this flags results in the errors (duplication)
00053         # asm accepts --cpu Core or --fpu FPU, not like c/c++ --cpu=Core
00054         if target.core == "Cortex-M4F":
00055           asm_flags_cmd = [
00056               "--cpu", "Cortex-M4F"
00057           ]
00058         else:
00059           asm_flags_cmd = [
00060               "--cpu", cpuchoice
00061           ]
00062         # custom c flags
00063         if target.core == "Cortex-M4F":
00064           c_flags_cmd = [
00065               "--cpu", "Cortex-M4F"
00066           ]
00067         else:
00068           c_flags_cmd = [
00069               "--cpu", cpuchoice
00070           ]
00071 
00072         c_flags_cmd.extend([
00073             "--thumb", "--dlib_config", "DLib_Config_Full.h"
00074         ])
00075         # custom c++ cmd flags
00076         cxx_flags_cmd = [
00077             "--c++", "--no_rtti", "--no_exceptions"
00078         ]
00079         if target.core == "Cortex-M7FD":
00080             asm_flags_cmd += ["--fpu", "VFPv5"]
00081             c_flags_cmd.append("--fpu=VFPv5")
00082         elif target.core == "Cortex-M7F":
00083             asm_flags_cmd += ["--fpu", "VFPv5_sp"]
00084             c_flags_cmd.append("--fpu=VFPv5_sp")
00085 
00086         IAR_BIN = join(TOOLCHAIN_PATHS['IAR'], "bin")
00087         main_cc = join(IAR_BIN, "iccarm")
00088 
00089         self.asm  = [join(IAR_BIN, "iasmarm")] + asm_flags_cmd + self.flags["asm"]
00090         self.cc   = [main_cc]
00091         self.cppc = [main_cc]
00092         self.cc += self.flags["common"] + c_flags_cmd + self.flags["c"]
00093         self.cppc += self.flags["common"] + c_flags_cmd + cxx_flags_cmd + self.flags["cxx"]
00094         self.ld   = [join(IAR_BIN, "ilinkarm")]
00095         self.ar = join(IAR_BIN, "iarchive")
00096         self.elf2bin = join(IAR_BIN, "ielftool")
00097 
00098     def parse_dependencies(self, dep_path):
00099         return [(self.CHROOT if self.CHROOT else '')+path.strip() for path in open(dep_path).readlines()
00100                 if (path and not path.isspace())]
00101 
00102     def parse_output(self, output):
00103         msg = None
00104         for line in output.splitlines():
00105             match = IAR.DIAGNOSTIC_PATTERN.match(line)
00106             if match is not None:
00107                 if msg is not None:
00108                     self.cc_info(msg)
00109                     msg = None
00110                 msg = {
00111                     'severity': match.group('severity').lower(),
00112                     'file': match.group('file'),
00113                     'line': match.group('line'),
00114                     'col': 0,
00115                     'message': match.group('message'),
00116                     'text': '',
00117                     'target_name': self.target.name,
00118                     'toolchain_name': self.name
00119                 }
00120             elif msg is not None:
00121                 # Determine the warning/error column by calculating the ^ position
00122                 match = IAR.INDEX_PATTERN.match(line)
00123                 if match is not None:
00124                     msg['col'] = len(match.group('col'))
00125                     self.cc_info(msg)
00126                     msg = None
00127                 else:
00128                     msg['text'] += line+"\n"
00129 
00130         if msg is not None:
00131             self.cc_info(msg)
00132 
00133     def get_dep_option(self, object):
00134         base, _ = splitext(object)
00135         dep_path = base + '.d'
00136         return ["--dependencies", dep_path]
00137 
00138     def cc_extra(self, object):
00139         base, _ = splitext(object)
00140         return ["-l", base + '.s.txt']
00141 
00142     def get_config_option(self, config_header):
00143         return ['--preinclude=' + config_header]
00144 
00145     def get_compile_options(self, defines, includes, for_asm=False):
00146         opts = ['-D%s' % d for d in defines]
00147         if self.RESPONSE_FILES:
00148             opts += ['-f', self.get_inc_file(includes)]
00149         else:
00150             opts += ["-I%s" % i for i in includes]
00151 
00152         if not for_asm:
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 + self.flags['ld']
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         # Build binary command
00228         cmd = [self.elf2bin, "--bin", elf, bin]
00229 
00230         # Call cmdline hook
00231         cmd = self.hook.get_cmdline_binary(cmd)
00232 
00233         # Exec command
00234         self.cc_verbose("FromELF: %s" % ' '.join(cmd))
00235         self.default_cmd(cmd)
00236 
00237     @staticmethod
00238     def name_mangle(name):
00239         return "_Z%i%sv" % (len(name), name)
00240 
00241     @staticmethod
00242     def make_ld_define(name, value):
00243         return "--config_def %s=0x%x" % (name, value)
00244 
00245     @staticmethod
00246     def redirect_symbol(source, sync, build_dir):
00247         return "--redirect %s=%s" % (source, sync)