Clone of official tools

Committer:
Anders Blomdell
Date:
Thu Feb 04 17:17:13 2021 +0100
Revision:
47:21ae3e5a7128
Parent:
43:2a7da56ebd24
Add a few normpath calls

Who changed what in which revision?

UserRevisionLine numberNew contents of line
screamer 0:66f3b5499f7f 1 """
screamer 0:66f3b5499f7f 2 mbed SDK
screamer 0:66f3b5499f7f 3 Copyright (c) 2011-2013 ARM Limited
screamer 0:66f3b5499f7f 4
screamer 0:66f3b5499f7f 5 Licensed under the Apache License, Version 2.0 (the "License");
screamer 0:66f3b5499f7f 6 you may not use this file except in compliance with the License.
screamer 0:66f3b5499f7f 7 You may obtain a copy of the License at
screamer 0:66f3b5499f7f 8
screamer 0:66f3b5499f7f 9 http://www.apache.org/licenses/LICENSE-2.0
screamer 0:66f3b5499f7f 10
screamer 0:66f3b5499f7f 11 Unless required by applicable law or agreed to in writing, software
screamer 0:66f3b5499f7f 12 distributed under the License is distributed on an "AS IS" BASIS,
screamer 0:66f3b5499f7f 13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
screamer 0:66f3b5499f7f 14 See the License for the specific language governing permissions and
screamer 0:66f3b5499f7f 15 limitations under the License.
screamer 0:66f3b5499f7f 16 """
theotherjimmy 43:2a7da56ebd24 17 from __future__ import print_function, absolute_import
theotherjimmy 43:2a7da56ebd24 18 from builtins import str
theotherjimmy 43:2a7da56ebd24 19
screamer 0:66f3b5499f7f 20 import re
theotherjimmy 40:7d3fa6b99b2b 21 from copy import copy
theotherjimmy 43:2a7da56ebd24 22 from os.path import join, dirname, splitext, basename, exists, relpath, isfile
theotherjimmy 43:2a7da56ebd24 23 from os import makedirs, write, curdir, remove
The Other Jimmy 36:96847d42f010 24 from tempfile import mkstemp
theotherjimmy 43:2a7da56ebd24 25 from shutil import rmtree
theotherjimmy 43:2a7da56ebd24 26 from distutils.version import LooseVersion
screamer 0:66f3b5499f7f 27
theotherjimmy 43:2a7da56ebd24 28 from tools.targets import CORE_ARCH
screamer 20:835f6355470d 29 from tools.toolchains import mbedToolchain, TOOLCHAIN_PATHS
screamer 0:66f3b5499f7f 30 from tools.hooks import hook_tool
theotherjimmy 43:2a7da56ebd24 31 from tools.utils import mkdir, NotSupportedException, run_cmd
screamer 0:66f3b5499f7f 32
screamer 0:66f3b5499f7f 33 class ARM(mbedToolchain):
screamer 0:66f3b5499f7f 34 LINKER_EXT = '.sct'
screamer 0:66f3b5499f7f 35 LIBRARY_EXT = '.ar'
screamer 0:66f3b5499f7f 36
screamer 0:66f3b5499f7f 37 STD_LIB_NAME = "%s.ar"
The Other Jimmy 35:da9c89f8be7d 38 DIAGNOSTIC_PATTERN = re.compile('"(?P<file>[^"]+)", line (?P<line>\d+)( \(column (?P<column>\d+)\)|): (?P<severity>Warning|Error|Fatal error): (?P<message>.+)')
screamer 21:4fdf0dd04f6f 39 INDEX_PATTERN = re.compile('(?P<col>\s*)\^')
screamer 0:66f3b5499f7f 40 DEP_PATTERN = re.compile('\S+:\s(?P<file>.+)\n')
theotherjimmy 40:7d3fa6b99b2b 41 SHEBANG = "#! armcc -E"
theotherjimmy 42:2cf3f29fece1 42 SUPPORTED_CORES = ["Cortex-M0", "Cortex-M0+", "Cortex-M3", "Cortex-M4",
theotherjimmy 43:2a7da56ebd24 43 "Cortex-M4F", "Cortex-M7", "Cortex-M7F", "Cortex-M7FD", "Cortex-A9"]
theotherjimmy 43:2a7da56ebd24 44 ARMCC_RANGE = (LooseVersion("5.06"), LooseVersion("5.07"))
theotherjimmy 43:2a7da56ebd24 45 ARMCC_VERSION_RE = re.compile(b"Component: ARM Compiler (\d+\.\d+)")
screamer 0:66f3b5499f7f 46
The Other Jimmy 31:8ea194f6145b 47 @staticmethod
The Other Jimmy 31:8ea194f6145b 48 def check_executable():
The Other Jimmy 31:8ea194f6145b 49 """Returns True if the executable (armcc) location specified by the
The Other Jimmy 31:8ea194f6145b 50 user exists OR the executable can be found on the PATH.
The Other Jimmy 31:8ea194f6145b 51 Returns False otherwise."""
The Other Jimmy 31:8ea194f6145b 52 return mbedToolchain.generic_check_executable("ARM", 'armcc', 2, 'bin')
screamer 13:ab47a20b66f0 53
The Other Jimmy 31:8ea194f6145b 54 def __init__(self, target, notify=None, macros=None,
theotherjimmy 43:2a7da56ebd24 55 build_profile=None, build_dir=None):
theotherjimmy 43:2a7da56ebd24 56 mbedToolchain.__init__(
theotherjimmy 43:2a7da56ebd24 57 self, target, notify, macros, build_dir=build_dir,
theotherjimmy 43:2a7da56ebd24 58 build_profile=build_profile)
theotherjimmy 42:2cf3f29fece1 59 if target.core not in self.SUPPORTED_CORES:
theotherjimmy 42:2cf3f29fece1 60 raise NotSupportedException(
theotherjimmy 42:2cf3f29fece1 61 "this compiler does not support the core %s" % target.core)
screamer 0:66f3b5499f7f 62
theotherjimmy 43:2a7da56ebd24 63 if getattr(target, "default_lib", "std") == "small":
theotherjimmy 43:2a7da56ebd24 64 if "-DMBED_RTOS_SINGLE_THREAD" not in self.flags['common']:
theotherjimmy 43:2a7da56ebd24 65 self.flags['common'].append("-DMBED_RTOS_SINGLE_THREAD")
theotherjimmy 43:2a7da56ebd24 66 if "-D__MICROLIB" not in self.flags['common']:
theotherjimmy 43:2a7da56ebd24 67 self.flags['common'].append("-D__MICROLIB")
theotherjimmy 43:2a7da56ebd24 68 if "--library_type=microlib" not in self.flags['ld']:
theotherjimmy 43:2a7da56ebd24 69 self.flags['ld'].append("--library_type=microlib")
theotherjimmy 43:2a7da56ebd24 70 if "--library_type=microlib" not in self.flags['common']:
theotherjimmy 43:2a7da56ebd24 71 self.flags['common'].append("--library_type=microlib")
theotherjimmy 43:2a7da56ebd24 72
screamer 0:66f3b5499f7f 73 if target.core == "Cortex-M0+":
screamer 0:66f3b5499f7f 74 cpu = "Cortex-M0"
screamer 0:66f3b5499f7f 75 elif target.core == "Cortex-M4F":
screamer 0:66f3b5499f7f 76 cpu = "Cortex-M4.fp"
screamer 13:ab47a20b66f0 77 elif target.core == "Cortex-M7FD":
screamer 13:ab47a20b66f0 78 cpu = "Cortex-M7.fp.dp"
screamer 0:66f3b5499f7f 79 elif target.core == "Cortex-M7F":
screamer 0:66f3b5499f7f 80 cpu = "Cortex-M7.fp.sp"
screamer 0:66f3b5499f7f 81 else:
screamer 0:66f3b5499f7f 82 cpu = target.core
screamer 0:66f3b5499f7f 83
screamer 20:835f6355470d 84 ARM_BIN = join(TOOLCHAIN_PATHS['ARM'], "bin")
screamer 20:835f6355470d 85 ARM_INC = join(TOOLCHAIN_PATHS['ARM'], "include")
theotherjimmy 43:2a7da56ebd24 86
screamer 0:66f3b5499f7f 87 main_cc = join(ARM_BIN, "armcc")
screamer 0:66f3b5499f7f 88
screamer 13:ab47a20b66f0 89 self.flags['common'] += ["--cpu=%s" % cpu]
screamer 0:66f3b5499f7f 90
The Other Jimmy 31:8ea194f6145b 91 self.asm = [main_cc] + self.flags['common'] + self.flags['asm']
The Other Jimmy 31:8ea194f6145b 92 self.cc = [main_cc] + self.flags['common'] + self.flags['c']
The Other Jimmy 31:8ea194f6145b 93 self.cppc = [main_cc] + self.flags['common'] + self.flags['c'] + self.flags['cxx']
screamer 0:66f3b5499f7f 94
theotherjimmy 40:7d3fa6b99b2b 95 self.ld = [join(ARM_BIN, "armlink")] + self.flags['ld']
screamer 0:66f3b5499f7f 96
screamer 0:66f3b5499f7f 97 self.ar = join(ARM_BIN, "armar")
screamer 0:66f3b5499f7f 98 self.elf2bin = join(ARM_BIN, "fromelf")
screamer 0:66f3b5499f7f 99
theotherjimmy 43:2a7da56ebd24 100 self.SHEBANG += " --cpu=%s" % cpu
theotherjimmy 43:2a7da56ebd24 101
theotherjimmy 43:2a7da56ebd24 102 def version_check(self):
theotherjimmy 43:2a7da56ebd24 103 stdout, _, retcode = run_cmd([self.cc[0], "--vsn"], redirect=True)
theotherjimmy 43:2a7da56ebd24 104 msg = None
theotherjimmy 43:2a7da56ebd24 105 min_ver, max_ver = self.ARMCC_RANGE
theotherjimmy 43:2a7da56ebd24 106 match = self.ARMCC_VERSION_RE.search(stdout)
theotherjimmy 43:2a7da56ebd24 107 found_version = LooseVersion(match.group(1).decode("utf-8")) if match else None
theotherjimmy 43:2a7da56ebd24 108 min_ver, max_ver = self.ARMCC_RANGE
theotherjimmy 43:2a7da56ebd24 109 if found_version and (found_version < min_ver or found_version >= max_ver):
theotherjimmy 43:2a7da56ebd24 110 msg = ("Compiler version mismatch: Have {}; "
theotherjimmy 43:2a7da56ebd24 111 "expected version >= {} and < {}"
theotherjimmy 43:2a7da56ebd24 112 .format(found_version, min_ver, max_ver))
theotherjimmy 43:2a7da56ebd24 113 elif not match or len(match.groups()) != 1:
theotherjimmy 43:2a7da56ebd24 114 msg = ("Compiler version mismatch: Could not detect version; "
theotherjimmy 43:2a7da56ebd24 115 "expected version >= {} and < {}"
theotherjimmy 43:2a7da56ebd24 116 .format(min_ver, max_ver))
theotherjimmy 43:2a7da56ebd24 117
theotherjimmy 43:2a7da56ebd24 118 if msg:
theotherjimmy 43:2a7da56ebd24 119 self.notify.cc_info({
theotherjimmy 43:2a7da56ebd24 120 "message": msg,
theotherjimmy 43:2a7da56ebd24 121 "file": "",
theotherjimmy 43:2a7da56ebd24 122 "line": "",
theotherjimmy 43:2a7da56ebd24 123 "col": "",
theotherjimmy 43:2a7da56ebd24 124 "severity": "ERROR",
theotherjimmy 43:2a7da56ebd24 125 })
theotherjimmy 43:2a7da56ebd24 126
theotherjimmy 43:2a7da56ebd24 127 def _get_toolchain_labels(self):
theotherjimmy 43:2a7da56ebd24 128 if getattr(self.target, "default_lib", "std") == "small":
theotherjimmy 43:2a7da56ebd24 129 return ["ARM", "ARM_MICRO"]
theotherjimmy 43:2a7da56ebd24 130 else:
theotherjimmy 43:2a7da56ebd24 131 return ["ARM", "ARM_STD"]
theotherjimmy 43:2a7da56ebd24 132
screamer 0:66f3b5499f7f 133 def parse_dependencies(self, dep_path):
screamer 0:66f3b5499f7f 134 dependencies = []
screamer 0:66f3b5499f7f 135 for line in open(dep_path).readlines():
screamer 0:66f3b5499f7f 136 match = ARM.DEP_PATTERN.match(line)
screamer 0:66f3b5499f7f 137 if match is not None:
screamer 21:4fdf0dd04f6f 138 #we need to append chroot, because when the .d files are generated the compiler is chrooted
screamer 21:4fdf0dd04f6f 139 dependencies.append((self.CHROOT if self.CHROOT else '') + match.group('file'))
screamer 0:66f3b5499f7f 140 return dependencies
theotherjimmy 40:7d3fa6b99b2b 141
screamer 0:66f3b5499f7f 142 def parse_output(self, output):
screamer 21:4fdf0dd04f6f 143 msg = None
screamer 0:66f3b5499f7f 144 for line in output.splitlines():
screamer 0:66f3b5499f7f 145 match = ARM.DIAGNOSTIC_PATTERN.match(line)
screamer 0:66f3b5499f7f 146 if match is not None:
screamer 21:4fdf0dd04f6f 147 if msg is not None:
theotherjimmy 43:2a7da56ebd24 148 self.notify.cc_info(msg)
The Other Jimmy 31:8ea194f6145b 149 msg = None
screamer 21:4fdf0dd04f6f 150 msg = {
screamer 21:4fdf0dd04f6f 151 'severity': match.group('severity').lower(),
screamer 21:4fdf0dd04f6f 152 'file': match.group('file'),
screamer 21:4fdf0dd04f6f 153 'line': match.group('line'),
screamer 21:4fdf0dd04f6f 154 'col': match.group('column') if match.group('column') else 0,
screamer 21:4fdf0dd04f6f 155 'message': match.group('message'),
screamer 21:4fdf0dd04f6f 156 'text': '',
screamer 21:4fdf0dd04f6f 157 'target_name': self.target.name,
screamer 21:4fdf0dd04f6f 158 'toolchain_name': self.name
screamer 21:4fdf0dd04f6f 159 }
screamer 21:4fdf0dd04f6f 160 elif msg is not None:
screamer 24:25bff2709c20 161 # Determine the warning/error column by calculating the ^ position
screamer 21:4fdf0dd04f6f 162 match = ARM.INDEX_PATTERN.match(line)
screamer 21:4fdf0dd04f6f 163 if match is not None:
screamer 21:4fdf0dd04f6f 164 msg['col'] = len(match.group('col'))
theotherjimmy 43:2a7da56ebd24 165 self.notify.cc_info(msg)
screamer 21:4fdf0dd04f6f 166 msg = None
screamer 21:4fdf0dd04f6f 167 else:
screamer 21:4fdf0dd04f6f 168 msg['text'] += line+"\n"
screamer 21:4fdf0dd04f6f 169
screamer 21:4fdf0dd04f6f 170 if msg is not None:
theotherjimmy 43:2a7da56ebd24 171 self.notify.cc_info(msg)
screamer 0:66f3b5499f7f 172
screamer 0:66f3b5499f7f 173 def get_dep_option(self, object):
screamer 0:66f3b5499f7f 174 base, _ = splitext(object)
screamer 0:66f3b5499f7f 175 dep_path = base + '.d'
screamer 0:66f3b5499f7f 176 return ["--depend", dep_path]
screamer 0:66f3b5499f7f 177
screamer 20:835f6355470d 178 def get_config_option(self, config_header):
screamer 13:ab47a20b66f0 179 return ['--preinclude=' + config_header]
screamer 13:ab47a20b66f0 180
theotherjimmy 43:2a7da56ebd24 181 def get_compile_options(self, defines, includes, for_asm=False):
screamer 21:4fdf0dd04f6f 182 opts = ['-D%s' % d for d in defines]
theotherjimmy 43:2a7da56ebd24 183 config_header = self.get_config_header()
theotherjimmy 43:2a7da56ebd24 184 if config_header is not None:
theotherjimmy 43:2a7da56ebd24 185 opts = opts + self.get_config_option(config_header)
theotherjimmy 43:2a7da56ebd24 186 if for_asm:
theotherjimmy 43:2a7da56ebd24 187 return opts
screamer 21:4fdf0dd04f6f 188 if self.RESPONSE_FILES:
screamer 21:4fdf0dd04f6f 189 opts += ['--via', self.get_inc_file(includes)]
screamer 21:4fdf0dd04f6f 190 else:
screamer 21:4fdf0dd04f6f 191 opts += ["-I%s" % i for i in includes]
screamer 21:4fdf0dd04f6f 192
screamer 13:ab47a20b66f0 193 return opts
screamer 0:66f3b5499f7f 194
screamer 0:66f3b5499f7f 195 @hook_tool
screamer 0:66f3b5499f7f 196 def assemble(self, source, object, includes):
screamer 0:66f3b5499f7f 197 # Preprocess first, then assemble
screamer 0:66f3b5499f7f 198 dir = join(dirname(object), '.temp')
screamer 0:66f3b5499f7f 199 mkdir(dir)
screamer 0:66f3b5499f7f 200 tempfile = join(dir, basename(object) + '.E.s')
theotherjimmy 43:2a7da56ebd24 201
screamer 0:66f3b5499f7f 202 # Build preprocess assemble command
theotherjimmy 43:2a7da56ebd24 203 cmd_pre = copy(self.asm)
theotherjimmy 43:2a7da56ebd24 204 cmd_pre.extend(self.get_compile_options(
theotherjimmy 43:2a7da56ebd24 205 self.get_symbols(True), includes, True))
theotherjimmy 43:2a7da56ebd24 206 cmd_pre.extend(["-E", "-o", tempfile, source])
screamer 0:66f3b5499f7f 207
screamer 0:66f3b5499f7f 208 # Build main assemble command
screamer 0:66f3b5499f7f 209 cmd = self.asm + ["-o", object, tempfile]
screamer 0:66f3b5499f7f 210
screamer 0:66f3b5499f7f 211 # Call cmdline hook
screamer 0:66f3b5499f7f 212 cmd_pre = self.hook.get_cmdline_assembler(cmd_pre)
screamer 0:66f3b5499f7f 213 cmd = self.hook.get_cmdline_assembler(cmd)
theotherjimmy 43:2a7da56ebd24 214
screamer 0:66f3b5499f7f 215 # Return command array, don't execute
screamer 0:66f3b5499f7f 216 return [cmd_pre, cmd]
screamer 0:66f3b5499f7f 217
screamer 0:66f3b5499f7f 218 @hook_tool
screamer 0:66f3b5499f7f 219 def compile(self, cc, source, object, includes):
screamer 0:66f3b5499f7f 220 # Build compile command
screamer 0:66f3b5499f7f 221 cmd = cc + self.get_compile_options(self.get_symbols(), includes)
theotherjimmy 43:2a7da56ebd24 222
screamer 0:66f3b5499f7f 223 cmd.extend(self.get_dep_option(object))
theotherjimmy 43:2a7da56ebd24 224
screamer 0:66f3b5499f7f 225 cmd.extend(["-o", object, source])
screamer 0:66f3b5499f7f 226
screamer 0:66f3b5499f7f 227 # Call cmdline hook
screamer 0:66f3b5499f7f 228 cmd = self.hook.get_cmdline_compiler(cmd)
screamer 0:66f3b5499f7f 229
screamer 0:66f3b5499f7f 230 return [cmd]
screamer 0:66f3b5499f7f 231
screamer 0:66f3b5499f7f 232 def compile_c(self, source, object, includes):
screamer 0:66f3b5499f7f 233 return self.compile(self.cc, source, object, includes)
screamer 0:66f3b5499f7f 234
screamer 0:66f3b5499f7f 235 def compile_cpp(self, source, object, includes):
screamer 0:66f3b5499f7f 236 return self.compile(self.cppc, source, object, includes)
screamer 0:66f3b5499f7f 237
theotherjimmy 43:2a7da56ebd24 238 def correct_scatter_shebang(self, scatter_file, cur_dir_name=None):
theotherjimmy 40:7d3fa6b99b2b 239 """Correct the shebang at the top of a scatter file.
theotherjimmy 40:7d3fa6b99b2b 240
theotherjimmy 40:7d3fa6b99b2b 241 Positional arguments:
theotherjimmy 40:7d3fa6b99b2b 242 scatter_file -- the scatter file to correct
theotherjimmy 40:7d3fa6b99b2b 243
theotherjimmy 43:2a7da56ebd24 244 Keyword arguments:
theotherjimmy 43:2a7da56ebd24 245 cur_dir_name -- the name (not path) of the directory containing the
theotherjimmy 43:2a7da56ebd24 246 scatter file
theotherjimmy 43:2a7da56ebd24 247
theotherjimmy 40:7d3fa6b99b2b 248 Return:
theotherjimmy 40:7d3fa6b99b2b 249 The location of the correct scatter file
screamer 0:66f3b5499f7f 250
theotherjimmy 40:7d3fa6b99b2b 251 Side Effects:
theotherjimmy 40:7d3fa6b99b2b 252 This method MAY write a new scatter file to disk
theotherjimmy 40:7d3fa6b99b2b 253 """
theotherjimmy 43:2a7da56ebd24 254 with open(scatter_file, "r") as input:
theotherjimmy 40:7d3fa6b99b2b 255 lines = input.readlines()
theotherjimmy 43:2a7da56ebd24 256 if (lines[0].startswith(self.SHEBANG) or
theotherjimmy 43:2a7da56ebd24 257 not lines[0].startswith("#!")):
theotherjimmy 40:7d3fa6b99b2b 258 return scatter_file
theotherjimmy 40:7d3fa6b99b2b 259 else:
theotherjimmy 40:7d3fa6b99b2b 260 new_scatter = join(self.build_dir, ".link_script.sct")
theotherjimmy 43:2a7da56ebd24 261 if cur_dir_name is None:
theotherjimmy 43:2a7da56ebd24 262 cur_dir_name = dirname(scatter_file)
theotherjimmy 43:2a7da56ebd24 263 self.SHEBANG += " -I %s" % cur_dir_name
theotherjimmy 40:7d3fa6b99b2b 264 if self.need_update(new_scatter, [scatter_file]):
theotherjimmy 43:2a7da56ebd24 265 with open(new_scatter, "w") as out:
theotherjimmy 40:7d3fa6b99b2b 266 out.write(self.SHEBANG)
theotherjimmy 40:7d3fa6b99b2b 267 out.write("\n")
theotherjimmy 40:7d3fa6b99b2b 268 out.write("".join(lines[1:]))
theotherjimmy 43:2a7da56ebd24 269
theotherjimmy 40:7d3fa6b99b2b 270 return new_scatter
screamer 0:66f3b5499f7f 271
theotherjimmy 40:7d3fa6b99b2b 272 @hook_tool
theotherjimmy 40:7d3fa6b99b2b 273 def link(self, output, objects, libraries, lib_dirs, scatter_file):
theotherjimmy 40:7d3fa6b99b2b 274 base, _ = splitext(output)
theotherjimmy 40:7d3fa6b99b2b 275 map_file = base + ".map"
theotherjimmy 40:7d3fa6b99b2b 276 args = ["-o", output, "--info=totals", "--map", "--list=%s" % map_file]
theotherjimmy 40:7d3fa6b99b2b 277 args.extend(objects)
theotherjimmy 40:7d3fa6b99b2b 278 args.extend(libraries)
theotherjimmy 40:7d3fa6b99b2b 279 if lib_dirs:
theotherjimmy 40:7d3fa6b99b2b 280 args.extend(["--userlibpath", ",".join(lib_dirs)])
theotherjimmy 40:7d3fa6b99b2b 281 if scatter_file:
theotherjimmy 40:7d3fa6b99b2b 282 new_scatter = self.correct_scatter_shebang(scatter_file)
theotherjimmy 40:7d3fa6b99b2b 283 args.extend(["--scatter", new_scatter])
screamer 0:66f3b5499f7f 284
theotherjimmy 40:7d3fa6b99b2b 285 cmd_pre = self.ld + args
theotherjimmy 40:7d3fa6b99b2b 286 cmd = self.hook.get_cmdline_linker(cmd_pre)
screamer 0:66f3b5499f7f 287
screamer 21:4fdf0dd04f6f 288 if self.RESPONSE_FILES:
screamer 21:4fdf0dd04f6f 289 cmd_linker = cmd[0]
screamer 21:4fdf0dd04f6f 290 link_files = self.get_link_file(cmd[1:])
screamer 21:4fdf0dd04f6f 291 cmd = [cmd_linker, '--via', link_files]
screamer 0:66f3b5499f7f 292
theotherjimmy 43:2a7da56ebd24 293 self.notify.cc_verbose("Link: %s" % ' '.join(cmd))
screamer 21:4fdf0dd04f6f 294 self.default_cmd(cmd)
screamer 0:66f3b5499f7f 295
screamer 0:66f3b5499f7f 296 @hook_tool
screamer 0:66f3b5499f7f 297 def archive(self, objects, lib_path):
screamer 21:4fdf0dd04f6f 298 if self.RESPONSE_FILES:
screamer 22:9e85236d8716 299 param = ['--via', self.get_arch_file(objects)]
screamer 21:4fdf0dd04f6f 300 else:
screamer 21:4fdf0dd04f6f 301 param = objects
screamer 21:4fdf0dd04f6f 302 self.default_cmd([self.ar, '-r', lib_path] + param)
screamer 0:66f3b5499f7f 303
screamer 0:66f3b5499f7f 304 @hook_tool
screamer 0:66f3b5499f7f 305 def binary(self, resources, elf, bin):
The Other Jimmy 36:96847d42f010 306 _, fmt = splitext(bin)
theotherjimmy 43:2a7da56ebd24 307 # On .hex format, combine multiple .hex files (for multiple load regions) into one
theotherjimmy 43:2a7da56ebd24 308 bin_arg = {".bin": "--bin", ".hex": "--i32combined"}[fmt]
The Other Jimmy 36:96847d42f010 309 cmd = [self.elf2bin, bin_arg, '-o', bin, elf]
screamer 0:66f3b5499f7f 310 cmd = self.hook.get_cmdline_binary(cmd)
theotherjimmy 43:2a7da56ebd24 311
theotherjimmy 43:2a7da56ebd24 312 # remove target binary file/path
theotherjimmy 43:2a7da56ebd24 313 if exists(bin):
theotherjimmy 43:2a7da56ebd24 314 if isfile(bin):
theotherjimmy 43:2a7da56ebd24 315 remove(bin)
theotherjimmy 43:2a7da56ebd24 316 else:
theotherjimmy 43:2a7da56ebd24 317 rmtree(bin)
theotherjimmy 43:2a7da56ebd24 318
theotherjimmy 43:2a7da56ebd24 319 self.notify.cc_verbose("FromELF: %s" % ' '.join(cmd))
screamer 0:66f3b5499f7f 320 self.default_cmd(cmd)
screamer 0:66f3b5499f7f 321
The Other Jimmy 36:96847d42f010 322 @staticmethod
The Other Jimmy 36:96847d42f010 323 def name_mangle(name):
The Other Jimmy 36:96847d42f010 324 return "_Z%i%sv" % (len(name), name)
The Other Jimmy 36:96847d42f010 325
The Other Jimmy 36:96847d42f010 326 @staticmethod
The Other Jimmy 36:96847d42f010 327 def make_ld_define(name, value):
theotherjimmy 43:2a7da56ebd24 328 return "--predefine=\"-D%s=%s\"" % (name, value)
The Other Jimmy 36:96847d42f010 329
The Other Jimmy 36:96847d42f010 330 @staticmethod
The Other Jimmy 36:96847d42f010 331 def redirect_symbol(source, sync, build_dir):
The Other Jimmy 36:96847d42f010 332 if not exists(build_dir):
The Other Jimmy 36:96847d42f010 333 makedirs(build_dir)
The Other Jimmy 36:96847d42f010 334 handle, filename = mkstemp(prefix=".redirect-symbol.", dir=build_dir)
The Other Jimmy 36:96847d42f010 335 write(handle, "RESOLVE %s AS %s\n" % (source, sync))
The Other Jimmy 36:96847d42f010 336 return "--edit=%s" % filename
The Other Jimmy 36:96847d42f010 337
screamer 0:66f3b5499f7f 338
screamer 0:66f3b5499f7f 339 class ARM_STD(ARM):
theotherjimmy 41:2a77626a4c21 340 def __init__(self, target, notify=None, macros=None,
theotherjimmy 43:2a7da56ebd24 341 build_profile=None, build_dir=None):
theotherjimmy 43:2a7da56ebd24 342 ARM.__init__(self, target, notify, macros, build_dir=build_dir,
theotherjimmy 41:2a77626a4c21 343 build_profile=build_profile)
theotherjimmy 43:2a7da56ebd24 344 if not set(("ARM", "uARM")).intersection(set(target.supported_toolchains)):
theotherjimmy 43:2a7da56ebd24 345 raise NotSupportedException("ARM/uARM compiler support is required for ARM build")
theotherjimmy 41:2a77626a4c21 346
screamer 0:66f3b5499f7f 347
screamer 0:66f3b5499f7f 348 class ARM_MICRO(ARM):
screamer 0:66f3b5499f7f 349 PATCHED_LIBRARY = False
theotherjimmy 41:2a77626a4c21 350 def __init__(self, target, notify=None, macros=None,
theotherjimmy 41:2a77626a4c21 351 silent=False, extra_verbose=False, build_profile=None,
theotherjimmy 41:2a77626a4c21 352 build_dir=None):
theotherjimmy 43:2a7da56ebd24 353 target.default_lib = "small"
theotherjimmy 43:2a7da56ebd24 354 ARM.__init__(self, target, notify, macros, build_dir=build_dir,
theotherjimmy 41:2a77626a4c21 355 build_profile=build_profile)
theotherjimmy 41:2a77626a4c21 356 if not set(("ARM", "uARM")).intersection(set(target.supported_toolchains)):
theotherjimmy 41:2a77626a4c21 357 raise NotSupportedException("ARM/uARM compiler support is required for ARM build")
theotherjimmy 40:7d3fa6b99b2b 358
theotherjimmy 40:7d3fa6b99b2b 359 class ARMC6(ARM_STD):
theotherjimmy 40:7d3fa6b99b2b 360 SHEBANG = "#! armclang -E --target=arm-arm-none-eabi -x c"
theotherjimmy 42:2cf3f29fece1 361 SUPPORTED_CORES = ["Cortex-M0", "Cortex-M0+", "Cortex-M3", "Cortex-M4",
theotherjimmy 42:2cf3f29fece1 362 "Cortex-M4F", "Cortex-M7", "Cortex-M7F", "Cortex-M7FD",
theotherjimmy 42:2cf3f29fece1 363 "Cortex-M23", "Cortex-M23-NS", "Cortex-M33",
theotherjimmy 43:2a7da56ebd24 364 "Cortex-M33-NS", "Cortex-A9"]
theotherjimmy 43:2a7da56ebd24 365 ARMCC_RANGE = (LooseVersion("6.10"), LooseVersion("7.0"))
theotherjimmy 43:2a7da56ebd24 366
theotherjimmy 40:7d3fa6b99b2b 367 @staticmethod
theotherjimmy 40:7d3fa6b99b2b 368 def check_executable():
theotherjimmy 40:7d3fa6b99b2b 369 return mbedToolchain.generic_check_executable("ARMC6", "armclang", 1)
theotherjimmy 40:7d3fa6b99b2b 370
theotherjimmy 40:7d3fa6b99b2b 371 def __init__(self, target, *args, **kwargs):
theotherjimmy 40:7d3fa6b99b2b 372 mbedToolchain.__init__(self, target, *args, **kwargs)
theotherjimmy 42:2cf3f29fece1 373 if target.core not in self.SUPPORTED_CORES:
theotherjimmy 42:2cf3f29fece1 374 raise NotSupportedException(
theotherjimmy 42:2cf3f29fece1 375 "this compiler does not support the core %s" % target.core)
theotherjimmy 43:2a7da56ebd24 376 if CORE_ARCH[target.core] < 8:
theotherjimmy 43:2a7da56ebd24 377 self.notify.cc_info({
theotherjimmy 43:2a7da56ebd24 378 'severity': "Error", 'file': "", 'line': "", 'col': "",
theotherjimmy 43:2a7da56ebd24 379 'message': "ARMC6 does not support ARM architecture v{}"
theotherjimmy 43:2a7da56ebd24 380 " targets".format(CORE_ARCH[target.core]),
theotherjimmy 43:2a7da56ebd24 381 'text': '', 'target_name': self.target.name,
theotherjimmy 43:2a7da56ebd24 382 'toolchain_name': self.name
theotherjimmy 43:2a7da56ebd24 383 })
theotherjimmy 40:7d3fa6b99b2b 384
theotherjimmy 40:7d3fa6b99b2b 385 if not set(("ARM", "ARMC6")).intersection(set(target.supported_toolchains)):
theotherjimmy 40:7d3fa6b99b2b 386 raise NotSupportedException("ARM/ARMC6 compiler support is required for ARMC6 build")
theotherjimmy 40:7d3fa6b99b2b 387
theotherjimmy 40:7d3fa6b99b2b 388 if target.core.lower().endswith("fd"):
theotherjimmy 40:7d3fa6b99b2b 389 self.flags['common'].append("-mcpu=%s" % target.core.lower()[:-2])
theotherjimmy 40:7d3fa6b99b2b 390 self.flags['ld'].append("--cpu=%s" % target.core.lower()[:-2])
theotherjimmy 43:2a7da56ebd24 391 self.SHEBANG += " -mcpu=%s" % target.core.lower()[:-2]
theotherjimmy 40:7d3fa6b99b2b 392 elif target.core.lower().endswith("f"):
theotherjimmy 40:7d3fa6b99b2b 393 self.flags['common'].append("-mcpu=%s" % target.core.lower()[:-1])
theotherjimmy 40:7d3fa6b99b2b 394 self.flags['ld'].append("--cpu=%s" % target.core.lower()[:-1])
theotherjimmy 43:2a7da56ebd24 395 self.SHEBANG += " -mcpu=%s" % target.core.lower()[:-1]
theotherjimmy 43:2a7da56ebd24 396 elif target.core.startswith("Cortex-M33"):
theotherjimmy 43:2a7da56ebd24 397 self.flags['common'].append("-mcpu=cortex-m33+nodsp")
theotherjimmy 43:2a7da56ebd24 398 self.flags['common'].append("-mfpu=none")
theotherjimmy 43:2a7da56ebd24 399 self.flags['ld'].append("--cpu=Cortex-M33.no_dsp.no_fp")
theotherjimmy 43:2a7da56ebd24 400 elif not target.core.startswith("Cortex-M23"):
theotherjimmy 40:7d3fa6b99b2b 401 self.flags['common'].append("-mcpu=%s" % target.core.lower())
theotherjimmy 40:7d3fa6b99b2b 402 self.flags['ld'].append("--cpu=%s" % target.core.lower())
theotherjimmy 43:2a7da56ebd24 403 self.SHEBANG += " -mcpu=%s" % target.core.lower()
theotherjimmy 40:7d3fa6b99b2b 404
theotherjimmy 40:7d3fa6b99b2b 405 if target.core == "Cortex-M4F":
theotherjimmy 40:7d3fa6b99b2b 406 self.flags['common'].append("-mfpu=fpv4-sp-d16")
theotherjimmy 40:7d3fa6b99b2b 407 self.flags['common'].append("-mfloat-abi=hard")
theotherjimmy 40:7d3fa6b99b2b 408 elif target.core == "Cortex-M7F":
theotherjimmy 40:7d3fa6b99b2b 409 self.flags['common'].append("-mfpu=fpv5-sp-d16")
theotherjimmy 40:7d3fa6b99b2b 410 self.flags['common'].append("-mfloat-abi=softfp")
theotherjimmy 40:7d3fa6b99b2b 411 elif target.core == "Cortex-M7FD":
theotherjimmy 40:7d3fa6b99b2b 412 self.flags['common'].append("-mfpu=fpv5-d16")
theotherjimmy 40:7d3fa6b99b2b 413 self.flags['common'].append("-mfloat-abi=softfp")
theotherjimmy 40:7d3fa6b99b2b 414 elif target.core.startswith("Cortex-M23"):
theotherjimmy 40:7d3fa6b99b2b 415 self.flags['common'].append("-march=armv8-m.base")
theotherjimmy 40:7d3fa6b99b2b 416
theotherjimmy 40:7d3fa6b99b2b 417 if target.core == "Cortex-M23" or target.core == "Cortex-M33":
theotherjimmy 43:2a7da56ebd24 418 self.flags['cxx'].append("-mcmse")
theotherjimmy 43:2a7da56ebd24 419 self.flags['c'].append("-mcmse")
theotherjimmy 43:2a7da56ebd24 420
theotherjimmy 43:2a7da56ebd24 421 # Create Secure library
theotherjimmy 43:2a7da56ebd24 422 if ((target.core == "Cortex-M23" or self.target.core == "Cortex-M33") and
theotherjimmy 43:2a7da56ebd24 423 kwargs.get('build_dir', False)):
theotherjimmy 43:2a7da56ebd24 424 build_dir = kwargs['build_dir']
theotherjimmy 43:2a7da56ebd24 425 secure_file = join(build_dir, "cmse_lib.o")
theotherjimmy 43:2a7da56ebd24 426 self.flags["ld"] += ["--import_cmse_lib_out=%s" % secure_file]
theotherjimmy 43:2a7da56ebd24 427 # Add linking time preprocessor macro __DOMAIN_NS
theotherjimmy 43:2a7da56ebd24 428 if target.core == "Cortex-M23-NS" or self.target.core == "Cortex-M33-NS":
theotherjimmy 43:2a7da56ebd24 429 define_string = self.make_ld_define("__DOMAIN_NS", "0x1")
theotherjimmy 43:2a7da56ebd24 430 self.flags["ld"].append(define_string)
theotherjimmy 40:7d3fa6b99b2b 431
theotherjimmy 40:7d3fa6b99b2b 432 asm_cpu = {
theotherjimmy 40:7d3fa6b99b2b 433 "Cortex-M0+": "Cortex-M0",
theotherjimmy 40:7d3fa6b99b2b 434 "Cortex-M4F": "Cortex-M4.fp",
theotherjimmy 40:7d3fa6b99b2b 435 "Cortex-M7F": "Cortex-M7.fp.sp",
theotherjimmy 40:7d3fa6b99b2b 436 "Cortex-M7FD": "Cortex-M7.fp.dp",
theotherjimmy 40:7d3fa6b99b2b 437 "Cortex-M23-NS": "Cortex-M23",
theotherjimmy 40:7d3fa6b99b2b 438 "Cortex-M33-NS": "Cortex-M33" }.get(target.core, target.core)
theotherjimmy 40:7d3fa6b99b2b 439
theotherjimmy 43:2a7da56ebd24 440 if target.core.startswith("Cortex-M33"):
theotherjimmy 43:2a7da56ebd24 441 self.flags['asm'].append("--cpu=Cortex-M33.no_dsp.no_fp")
theotherjimmy 43:2a7da56ebd24 442 else :
theotherjimmy 43:2a7da56ebd24 443 self.flags['asm'].append("--cpu=%s" % asm_cpu)
theotherjimmy 40:7d3fa6b99b2b 444
theotherjimmy 40:7d3fa6b99b2b 445 self.cc = ([join(TOOLCHAIN_PATHS["ARMC6"], "armclang")] +
theotherjimmy 40:7d3fa6b99b2b 446 self.flags['common'] + self.flags['c'])
theotherjimmy 40:7d3fa6b99b2b 447 self.cppc = ([join(TOOLCHAIN_PATHS["ARMC6"], "armclang")] +
theotherjimmy 40:7d3fa6b99b2b 448 self.flags['common'] + self.flags['cxx'])
theotherjimmy 40:7d3fa6b99b2b 449 self.asm = [join(TOOLCHAIN_PATHS["ARMC6"], "armasm")] + self.flags['asm']
theotherjimmy 40:7d3fa6b99b2b 450 self.ld = [join(TOOLCHAIN_PATHS["ARMC6"], "armlink")] + self.flags['ld']
theotherjimmy 40:7d3fa6b99b2b 451 self.ar = [join(TOOLCHAIN_PATHS["ARMC6"], "armar")]
theotherjimmy 40:7d3fa6b99b2b 452 self.elf2bin = join(TOOLCHAIN_PATHS["ARMC6"], "fromelf")
theotherjimmy 40:7d3fa6b99b2b 453
theotherjimmy 43:2a7da56ebd24 454 def _get_toolchain_labels(self):
theotherjimmy 43:2a7da56ebd24 455 return ["ARM", "ARM_STD", "ARMC6"]
theotherjimmy 40:7d3fa6b99b2b 456
theotherjimmy 40:7d3fa6b99b2b 457 def parse_dependencies(self, dep_path):
theotherjimmy 40:7d3fa6b99b2b 458 return mbedToolchain.parse_dependencies(self, dep_path)
theotherjimmy 40:7d3fa6b99b2b 459
theotherjimmy 40:7d3fa6b99b2b 460 def is_not_supported_error(self, output):
theotherjimmy 40:7d3fa6b99b2b 461 return "#error [NOT_SUPPORTED]" in output
theotherjimmy 40:7d3fa6b99b2b 462
theotherjimmy 40:7d3fa6b99b2b 463 def parse_output(self, output):
theotherjimmy 40:7d3fa6b99b2b 464 pass
theotherjimmy 40:7d3fa6b99b2b 465
theotherjimmy 40:7d3fa6b99b2b 466 def get_config_option(self, config_header):
theotherjimmy 40:7d3fa6b99b2b 467 return ["-include", config_header]
theotherjimmy 40:7d3fa6b99b2b 468
theotherjimmy 40:7d3fa6b99b2b 469 def get_compile_options(self, defines, includes, for_asm=False):
theotherjimmy 40:7d3fa6b99b2b 470 opts = ['-D%s' % d for d in defines]
theotherjimmy 40:7d3fa6b99b2b 471 opts.extend(["-I%s" % i for i in includes])
theotherjimmy 40:7d3fa6b99b2b 472 if for_asm:
theotherjimmy 40:7d3fa6b99b2b 473 return ["--cpreproc",
theotherjimmy 40:7d3fa6b99b2b 474 "--cpreproc_opts=%s" % ",".join(self.flags['common'] + opts)]
theotherjimmy 40:7d3fa6b99b2b 475 else:
theotherjimmy 40:7d3fa6b99b2b 476 config_header = self.get_config_header()
theotherjimmy 40:7d3fa6b99b2b 477 if config_header:
theotherjimmy 40:7d3fa6b99b2b 478 opts.extend(self.get_config_option(config_header))
theotherjimmy 40:7d3fa6b99b2b 479 return opts
theotherjimmy 40:7d3fa6b99b2b 480
theotherjimmy 40:7d3fa6b99b2b 481 @hook_tool
theotherjimmy 40:7d3fa6b99b2b 482 def assemble(self, source, object, includes):
theotherjimmy 40:7d3fa6b99b2b 483 cmd_pre = copy(self.asm)
theotherjimmy 40:7d3fa6b99b2b 484 cmd_pre.extend(self.get_compile_options(
theotherjimmy 40:7d3fa6b99b2b 485 self.get_symbols(True), includes, for_asm=True))
theotherjimmy 40:7d3fa6b99b2b 486 cmd_pre.extend(["-o", object, source])
theotherjimmy 40:7d3fa6b99b2b 487 return [self.hook.get_cmdline_assembler(cmd_pre)]
theotherjimmy 40:7d3fa6b99b2b 488
theotherjimmy 40:7d3fa6b99b2b 489 @hook_tool
theotherjimmy 40:7d3fa6b99b2b 490 def compile(self, cc, source, object, includes):
theotherjimmy 40:7d3fa6b99b2b 491 cmd = copy(cc)
theotherjimmy 40:7d3fa6b99b2b 492 cmd.extend(self.get_compile_options(self.get_symbols(), includes))
theotherjimmy 40:7d3fa6b99b2b 493 cmd.extend(["-o", object, source])
theotherjimmy 40:7d3fa6b99b2b 494 cmd = self.hook.get_cmdline_compiler(cmd)
theotherjimmy 40:7d3fa6b99b2b 495 return [cmd]