Greg Steiert / pegasus_dev

Dependents:   blinky_max32630fthr

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