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 arm.py Source File

arm.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.path import join, dirname, splitext, basename, exists
00019 from os import makedirs, write
00020 from tempfile import mkstemp
00021 
00022 from tools.toolchains import mbedToolchain, TOOLCHAIN_PATHS
00023 from tools.hooks import hook_tool
00024 from tools.utils import mkdir
00025 
00026 class ARM(mbedToolchain):
00027     LINKER_EXT = '.sct'
00028     LIBRARY_EXT = '.ar'
00029 
00030     STD_LIB_NAME = "%s.ar"
00031     DIAGNOSTIC_PATTERN  = re.compile('"(?P<file>[^"]+)", line (?P<line>\d+)( \(column (?P<column>\d+)\)|): (?P<severity>Warning|Error|Fatal error): (?P<message>.+)')
00032     INDEX_PATTERN  = re.compile('(?P<col>\s*)\^')
00033     DEP_PATTERN = re.compile('\S+:\s(?P<file>.+)\n')
00034 
00035     @staticmethod
00036     def check_executable():
00037         """Returns True if the executable (armcc) location specified by the
00038          user exists OR the executable can be found on the PATH.
00039          Returns False otherwise."""
00040         return mbedToolchain.generic_check_executable("ARM", 'armcc', 2, 'bin')
00041 
00042     def __init__(self, target, notify=None, macros=None,
00043                  silent=False, extra_verbose=False, build_profile=None,
00044                  build_dir=None):
00045         mbedToolchain.__init__(self, target, notify, macros, silent,
00046                                build_dir=build_dir,
00047                                extra_verbose=extra_verbose,
00048                                build_profile=build_profile)
00049 
00050         if target.core == "Cortex-M0+":
00051             cpu = "Cortex-M0"
00052         elif target.core == "Cortex-M4F":
00053             cpu = "Cortex-M4.fp"
00054         elif target.core == "Cortex-M7FD":
00055             cpu = "Cortex-M7.fp.dp"
00056         elif target.core == "Cortex-M7F":
00057             cpu = "Cortex-M7.fp.sp"
00058         else:
00059             cpu = target.core
00060 
00061         ARM_BIN = join(TOOLCHAIN_PATHS['ARM'], "bin")
00062         ARM_INC = join(TOOLCHAIN_PATHS['ARM'], "include")
00063         
00064         main_cc = join(ARM_BIN, "armcc")
00065 
00066         self.flags['common'] += ["--cpu=%s" % cpu]
00067 
00068         self.asm = [main_cc] + self.flags['common'] + self.flags['asm']
00069         self.cc = [main_cc] + self.flags['common'] + self.flags['c']
00070         self.cppc = [main_cc] + self.flags['common'] + self.flags['c'] + self.flags['cxx']
00071 
00072         self.ld = [join(ARM_BIN, "armlink")]
00073 
00074         self.ar = join(ARM_BIN, "armar")
00075         self.elf2bin = join(ARM_BIN, "fromelf")
00076 
00077     def parse_dependencies(self, dep_path):
00078         dependencies = []
00079         for line in open(dep_path).readlines():
00080             match = ARM.DEP_PATTERN.match(line)
00081             if match is not None:
00082                 #we need to append chroot, because when the .d files are generated the compiler is chrooted
00083                 dependencies.append((self.CHROOT if self.CHROOT else '') + match.group('file'))
00084         return dependencies
00085         
00086     def parse_output(self, output):
00087         msg = None
00088         for line in output.splitlines():
00089             match = ARM.DIAGNOSTIC_PATTERN.match(line)
00090             if match is not None:
00091                 if msg is not None:
00092                     self.cc_info(msg)
00093                     msg = None
00094                 msg = {
00095                     'severity': match.group('severity').lower(),
00096                     'file': match.group('file'),
00097                     'line': match.group('line'),
00098                     'col': match.group('column') if match.group('column') else 0,
00099                     'message': match.group('message'),
00100                     'text': '',
00101                     'target_name': self.target.name,
00102                     'toolchain_name': self.name
00103                 }
00104             elif msg is not None:
00105                 # Determine the warning/error column by calculating the ^ position
00106                 match = ARM.INDEX_PATTERN.match(line)
00107                 if match is not None:
00108                     msg['col'] = len(match.group('col'))
00109                     self.cc_info(msg)
00110                     msg = None
00111                 else:
00112                     msg['text'] += line+"\n"
00113         
00114         if msg is not None:
00115             self.cc_info(msg)
00116 
00117     def get_dep_option(self, object):
00118         base, _ = splitext(object)
00119         dep_path = base + '.d'
00120         return ["--depend", dep_path]
00121 
00122     def get_config_option(self, config_header):
00123         return ['--preinclude=' + config_header]
00124 
00125     def get_compile_options(self, defines, includes, for_asm=False):        
00126         opts = ['-D%s' % d for d in defines]
00127         if self.RESPONSE_FILES:
00128             opts += ['--via', self.get_inc_file(includes)]
00129         else:
00130             opts += ["-I%s" % i for i in includes]
00131 
00132         if not for_asm:
00133             config_header = self.get_config_header()
00134             if config_header is not None:
00135                 opts = opts + self.get_config_option(config_header)
00136         return opts
00137 
00138     @hook_tool
00139     def assemble(self, source, object, includes):
00140         # Preprocess first, then assemble
00141         dir = join(dirname(object), '.temp')
00142         mkdir(dir)
00143         tempfile = join(dir, basename(object) + '.E.s')
00144         
00145         # Build preprocess assemble command
00146         cmd_pre = self.asm + self.get_compile_options(self.get_symbols(True), includes) + ["-E", "-o", tempfile, source]
00147 
00148         # Build main assemble command
00149         cmd = self.asm + ["-o", object, tempfile]
00150 
00151         # Call cmdline hook
00152         cmd_pre = self.hook.get_cmdline_assembler(cmd_pre)
00153         cmd = self.hook.get_cmdline_assembler(cmd)
00154        
00155         # Return command array, don't execute
00156         return [cmd_pre, cmd]
00157 
00158     @hook_tool
00159     def compile(self, cc, source, object, includes):
00160         # Build compile command
00161         cmd = cc + self.get_compile_options(self.get_symbols(), includes)
00162         
00163         cmd.extend(self.get_dep_option(object))
00164             
00165         cmd.extend(["-o", object, source])
00166 
00167         # Call cmdline hook
00168         cmd = self.hook.get_cmdline_compiler(cmd)
00169 
00170         return [cmd]
00171 
00172     def compile_c(self, source, object, includes):
00173         return self.compile(self.cc, source, object, includes)
00174 
00175     def compile_cpp(self, source, object, includes):
00176         return self.compile(self.cppc, source, object, includes)
00177 
00178     @hook_tool
00179     def link(self, output, objects, libraries, lib_dirs, mem_map):
00180         map_file = splitext(output)[0] + ".map"
00181         if len(lib_dirs):
00182             args = ["-o", output, "--userlibpath", ",".join(lib_dirs), "--info=totals", "--map", "--list=%s" % map_file]
00183         else:
00184             args = ["-o", output, "--info=totals", "--map", "--list=%s" % map_file]
00185 
00186         args.extend(self.flags['ld'])
00187 
00188         if mem_map:
00189             args.extend(["--scatter", mem_map])
00190 
00191         # Build linker command
00192         cmd = self.ld + args + objects + libraries + self.sys_libs
00193 
00194         # Call cmdline hook
00195         cmd = self.hook.get_cmdline_linker(cmd)
00196 
00197         if self.RESPONSE_FILES:
00198             # Split link command to linker executable + response file
00199             cmd_linker = cmd[0]
00200             link_files = self.get_link_file(cmd[1:])
00201             cmd = [cmd_linker, '--via', link_files]
00202 
00203         # Exec command
00204         self.cc_verbose("Link: %s" % ' '.join(cmd))
00205         self.default_cmd(cmd)
00206 
00207     @hook_tool
00208     def archive(self, objects, lib_path):
00209         if self.RESPONSE_FILES:
00210             param = ['--via', self.get_arch_file(objects)]
00211         else:
00212             param = objects
00213 
00214         # Exec command
00215         self.default_cmd([self.ar, '-r', lib_path] + param)
00216 
00217     @hook_tool
00218     def binary(self, resources, elf, bin):
00219         # Build binary command
00220         cmd = [self.elf2bin, '--bin', '-o', bin, elf]
00221 
00222         # Call cmdline hook
00223         cmd = self.hook.get_cmdline_binary(cmd)
00224 
00225         # Exec command
00226         self.cc_verbose("FromELF: %s" % ' '.join(cmd))
00227         self.default_cmd(cmd)
00228 
00229     @staticmethod
00230     def name_mangle(name):
00231         return "_Z%i%sv" % (len(name), name)
00232 
00233     @staticmethod
00234     def make_ld_define(name, value):
00235         return "--predefine=\"-D%s=0x%x\"" % (name, value)
00236 
00237     @staticmethod
00238     def redirect_symbol(source, sync, build_dir):
00239         if not exists(build_dir):
00240             makedirs(build_dir)
00241         handle, filename = mkstemp(prefix=".redirect-symbol.", dir=build_dir)
00242         write(handle, "RESOLVE %s AS %s\n" % (source, sync))
00243         return "--edit=%s" % filename
00244 
00245 
00246 class ARM_STD(ARM):
00247     pass
00248 
00249 
00250 class ARM_MICRO(ARM):
00251     PATCHED_LIBRARY = False