Clone of official tools

Committer:
theotherjimmy
Date:
Tue Oct 10 16:56:30 2017 -0500
Revision:
40:7d3fa6b99b2b
Parent:
36:96847d42f010
Child:
43:2a7da56ebd24
Update to tools release 5.6.1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
The Other Jimmy 31:8ea194f6145b 1 """
The Other Jimmy 31:8ea194f6145b 2 mbed SDK
The Other Jimmy 31:8ea194f6145b 3 Copyright (c) 2011-2016 ARM Limited
The Other Jimmy 31:8ea194f6145b 4
The Other Jimmy 31:8ea194f6145b 5 Licensed under the Apache License, Version 2.0 (the "License");
The Other Jimmy 31:8ea194f6145b 6 you may not use this file except in compliance with the License.
The Other Jimmy 31:8ea194f6145b 7 You may obtain a copy of the License at
The Other Jimmy 31:8ea194f6145b 8
The Other Jimmy 31:8ea194f6145b 9 http://www.apache.org/licenses/LICENSE-2.0
The Other Jimmy 31:8ea194f6145b 10
The Other Jimmy 31:8ea194f6145b 11 Unless required by applicable law or agreed to in writing, software
The Other Jimmy 31:8ea194f6145b 12 distributed under the License is distributed on an "AS IS" BASIS,
The Other Jimmy 31:8ea194f6145b 13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
The Other Jimmy 31:8ea194f6145b 14 See the License for the specific language governing permissions and
The Other Jimmy 31:8ea194f6145b 15 limitations under the License.
The Other Jimmy 31:8ea194f6145b 16 """
The Other Jimmy 31:8ea194f6145b 17 from os.path import splitext, basename, relpath, join, abspath, dirname,\
The Other Jimmy 31:8ea194f6145b 18 exists
The Other Jimmy 31:8ea194f6145b 19 from os import remove
The Other Jimmy 31:8ea194f6145b 20 import sys
The Other Jimmy 31:8ea194f6145b 21 from subprocess import check_output, CalledProcessError, Popen, PIPE
The Other Jimmy 31:8ea194f6145b 22 import shutil
The Other Jimmy 31:8ea194f6145b 23 from jinja2.exceptions import TemplateNotFound
theotherjimmy 40:7d3fa6b99b2b 24 from tools.export.exporters import Exporter, apply_supported_whitelist
The Other Jimmy 31:8ea194f6145b 25 from tools.utils import NotSupportedException
The Other Jimmy 31:8ea194f6145b 26 from tools.targets import TARGET_MAP
The Other Jimmy 31:8ea194f6145b 27
The Other Jimmy 31:8ea194f6145b 28
The Other Jimmy 31:8ea194f6145b 29 class Makefile(Exporter):
The Other Jimmy 31:8ea194f6145b 30 """Generic Makefile template that mimics the behavior of the python build
The Other Jimmy 31:8ea194f6145b 31 system
The Other Jimmy 31:8ea194f6145b 32 """
The Other Jimmy 31:8ea194f6145b 33
The Other Jimmy 31:8ea194f6145b 34 DOT_IN_RELATIVE_PATH = True
The Other Jimmy 31:8ea194f6145b 35
The Other Jimmy 31:8ea194f6145b 36 MBED_CONFIG_HEADER_SUPPORTED = True
The Other Jimmy 31:8ea194f6145b 37
theotherjimmy 40:7d3fa6b99b2b 38 PREPROCESS_ASM = False
theotherjimmy 40:7d3fa6b99b2b 39
The Other Jimmy 36:96847d42f010 40 POST_BINARY_WHITELIST = set([
The Other Jimmy 36:96847d42f010 41 "MCU_NRF51Code.binary_hook",
The Other Jimmy 36:96847d42f010 42 "TEENSY3_1Code.binary_hook",
The Other Jimmy 36:96847d42f010 43 "LPCTargetCode.lpc_patch",
The Other Jimmy 36:96847d42f010 44 "LPC4088Code.binary_hook"
The Other Jimmy 36:96847d42f010 45 ])
The Other Jimmy 36:96847d42f010 46
theotherjimmy 40:7d3fa6b99b2b 47 @classmethod
theotherjimmy 40:7d3fa6b99b2b 48 def is_target_supported(cls, target_name):
theotherjimmy 40:7d3fa6b99b2b 49 target = TARGET_MAP[target_name]
theotherjimmy 40:7d3fa6b99b2b 50 return apply_supported_whitelist(
theotherjimmy 40:7d3fa6b99b2b 51 cls.TOOLCHAIN, cls.POST_BINARY_WHITELIST, target)
theotherjimmy 40:7d3fa6b99b2b 52
The Other Jimmy 31:8ea194f6145b 53 def generate(self):
The Other Jimmy 31:8ea194f6145b 54 """Generate the makefile
The Other Jimmy 31:8ea194f6145b 55
The Other Jimmy 31:8ea194f6145b 56 Note: subclasses should not need to override this method
The Other Jimmy 31:8ea194f6145b 57 """
The Other Jimmy 35:da9c89f8be7d 58 if not self.resources.linker_script:
The Other Jimmy 35:da9c89f8be7d 59 raise NotSupportedException("No linker script found.")
The Other Jimmy 35:da9c89f8be7d 60
The Other Jimmy 31:8ea194f6145b 61 self.resources.win_to_unix()
The Other Jimmy 31:8ea194f6145b 62
The Other Jimmy 31:8ea194f6145b 63 to_be_compiled = [splitext(src)[0] + ".o" for src in
The Other Jimmy 31:8ea194f6145b 64 self.resources.s_sources +
The Other Jimmy 31:8ea194f6145b 65 self.resources.c_sources +
The Other Jimmy 31:8ea194f6145b 66 self.resources.cpp_sources]
The Other Jimmy 31:8ea194f6145b 67
The Other Jimmy 31:8ea194f6145b 68 libraries = [self.prepare_lib(basename(lib)) for lib
The Other Jimmy 31:8ea194f6145b 69 in self.resources.libraries]
The Other Jimmy 35:da9c89f8be7d 70 sys_libs = [self.prepare_sys_lib(lib) for lib
The Other Jimmy 35:da9c89f8be7d 71 in self.toolchain.sys_libs]
The Other Jimmy 31:8ea194f6145b 72
The Other Jimmy 31:8ea194f6145b 73 ctx = {
The Other Jimmy 31:8ea194f6145b 74 'name': self.project_name,
The Other Jimmy 31:8ea194f6145b 75 'to_be_compiled': to_be_compiled,
The Other Jimmy 31:8ea194f6145b 76 'object_files': self.resources.objects,
The Other Jimmy 31:8ea194f6145b 77 'include_paths': list(set(self.resources.inc_dirs)),
The Other Jimmy 31:8ea194f6145b 78 'library_paths': self.resources.lib_dirs,
The Other Jimmy 31:8ea194f6145b 79 'linker_script': self.resources.linker_script,
The Other Jimmy 31:8ea194f6145b 80 'libraries': libraries,
The Other Jimmy 35:da9c89f8be7d 81 'ld_sys_libs': sys_libs,
The Other Jimmy 31:8ea194f6145b 82 'hex_files': self.resources.hex_files,
The Other Jimmy 31:8ea194f6145b 83 'vpath': (["../../.."]
The Other Jimmy 31:8ea194f6145b 84 if (basename(dirname(dirname(self.export_dir)))
The Other Jimmy 31:8ea194f6145b 85 == "projectfiles")
The Other Jimmy 31:8ea194f6145b 86 else [".."]),
The Other Jimmy 31:8ea194f6145b 87 'cc_cmd': " ".join(["\'" + part + "\'" for part
The Other Jimmy 31:8ea194f6145b 88 in ([basename(self.toolchain.cc[0])] +
The Other Jimmy 31:8ea194f6145b 89 self.toolchain.cc[1:])]),
The Other Jimmy 31:8ea194f6145b 90 'cppc_cmd': " ".join(["\'" + part + "\'" for part
The Other Jimmy 31:8ea194f6145b 91 in ([basename(self.toolchain.cppc[0])] +
The Other Jimmy 31:8ea194f6145b 92 self.toolchain.cppc[1:])]),
The Other Jimmy 31:8ea194f6145b 93 'asm_cmd': " ".join(["\'" + part + "\'" for part
The Other Jimmy 31:8ea194f6145b 94 in ([basename(self.toolchain.asm[0])] +
The Other Jimmy 31:8ea194f6145b 95 self.toolchain.asm[1:])]),
The Other Jimmy 36:96847d42f010 96 'ld_cmd': "\'" + basename(self.toolchain.ld[0]) + "\'",
The Other Jimmy 31:8ea194f6145b 97 'elf2bin_cmd': "\'" + basename(self.toolchain.elf2bin) + "\'",
The Other Jimmy 31:8ea194f6145b 98 'link_script_ext': self.toolchain.LINKER_EXT,
The Other Jimmy 31:8ea194f6145b 99 'link_script_option': self.LINK_SCRIPT_OPTION,
The Other Jimmy 31:8ea194f6145b 100 'user_library_flag': self.USER_LIBRARY_FLAG,
theotherjimmy 40:7d3fa6b99b2b 101 'needs_asm_preproc': self.PREPROCESS_ASM,
The Other Jimmy 31:8ea194f6145b 102 }
The Other Jimmy 31:8ea194f6145b 103
The Other Jimmy 36:96847d42f010 104 if hasattr(self.toolchain, "preproc"):
The Other Jimmy 36:96847d42f010 105 ctx['pp_cmd'] = " ".join(["\'" + part + "\'" for part
The Other Jimmy 36:96847d42f010 106 in ([basename(self.toolchain.preproc[0])] +
The Other Jimmy 36:96847d42f010 107 self.toolchain.preproc[1:] +
The Other Jimmy 36:96847d42f010 108 self.toolchain.ld[1:])])
The Other Jimmy 36:96847d42f010 109 else:
The Other Jimmy 36:96847d42f010 110 ctx['pp_cmd'] = None
The Other Jimmy 36:96847d42f010 111
The Other Jimmy 31:8ea194f6145b 112 for key in ['include_paths', 'library_paths', 'linker_script',
The Other Jimmy 31:8ea194f6145b 113 'hex_files']:
The Other Jimmy 31:8ea194f6145b 114 if isinstance(ctx[key], list):
The Other Jimmy 31:8ea194f6145b 115 ctx[key] = [ctx['vpath'][0] + "/" + t for t in ctx[key]]
The Other Jimmy 31:8ea194f6145b 116 else:
The Other Jimmy 31:8ea194f6145b 117 ctx[key] = ctx['vpath'][0] + "/" + ctx[key]
The Other Jimmy 31:8ea194f6145b 118 if "../." not in ctx["include_paths"]:
The Other Jimmy 31:8ea194f6145b 119 ctx["include_paths"] += ['../.']
The Other Jimmy 31:8ea194f6145b 120 for key in ['include_paths', 'library_paths', 'hex_files',
The Other Jimmy 31:8ea194f6145b 121 'to_be_compiled']:
The Other Jimmy 31:8ea194f6145b 122 ctx[key] = sorted(ctx[key])
The Other Jimmy 36:96847d42f010 123 ctx.update(self.format_flags())
The Other Jimmy 31:8ea194f6145b 124
The Other Jimmy 31:8ea194f6145b 125 for templatefile in \
The Other Jimmy 31:8ea194f6145b 126 ['makefile/%s_%s.tmpl' % (self.TEMPLATE,
The Other Jimmy 31:8ea194f6145b 127 self.target.lower())] + \
The Other Jimmy 31:8ea194f6145b 128 ['makefile/%s_%s.tmpl' % (self.TEMPLATE,
The Other Jimmy 31:8ea194f6145b 129 label.lower()) for label
The Other Jimmy 31:8ea194f6145b 130 in self.toolchain.target.extra_labels] +\
The Other Jimmy 31:8ea194f6145b 131 ['makefile/%s.tmpl' % self.TEMPLATE]:
The Other Jimmy 31:8ea194f6145b 132 try:
The Other Jimmy 31:8ea194f6145b 133 self.gen_file(templatefile, ctx, 'Makefile')
The Other Jimmy 31:8ea194f6145b 134 break
The Other Jimmy 31:8ea194f6145b 135 except TemplateNotFound:
The Other Jimmy 31:8ea194f6145b 136 pass
The Other Jimmy 31:8ea194f6145b 137 else:
The Other Jimmy 31:8ea194f6145b 138 raise NotSupportedException("This make tool is in development")
The Other Jimmy 31:8ea194f6145b 139
The Other Jimmy 36:96847d42f010 140 def format_flags(self):
The Other Jimmy 36:96847d42f010 141 """Format toolchain flags for Makefile"""
The Other Jimmy 36:96847d42f010 142 flags = {}
The Other Jimmy 36:96847d42f010 143 for k, v in self.flags.iteritems():
The Other Jimmy 36:96847d42f010 144 if k in ['asm_flags', 'c_flags', 'cxx_flags']:
The Other Jimmy 36:96847d42f010 145 flags[k] = map(lambda x: x.replace('"', '\\"'), v)
The Other Jimmy 36:96847d42f010 146 else:
The Other Jimmy 36:96847d42f010 147 flags[k] = v
The Other Jimmy 36:96847d42f010 148
The Other Jimmy 36:96847d42f010 149 return flags
The Other Jimmy 36:96847d42f010 150
The Other Jimmy 31:8ea194f6145b 151 @staticmethod
The Other Jimmy 31:8ea194f6145b 152 def build(project_name, log_name="build_log.txt", cleanup=True):
The Other Jimmy 31:8ea194f6145b 153 """ Build Make project """
The Other Jimmy 31:8ea194f6145b 154 # > Make -j
The Other Jimmy 31:8ea194f6145b 155 cmd = ["make", "-j"]
The Other Jimmy 31:8ea194f6145b 156
The Other Jimmy 31:8ea194f6145b 157 # Build the project
The Other Jimmy 31:8ea194f6145b 158 p = Popen(cmd, stdout=PIPE, stderr=PIPE)
The Other Jimmy 31:8ea194f6145b 159 out, err = p.communicate()
The Other Jimmy 31:8ea194f6145b 160 ret_code = p.returncode
The Other Jimmy 31:8ea194f6145b 161
The Other Jimmy 31:8ea194f6145b 162 out_string = "=" * 10 + "STDOUT" + "=" * 10 + "\n"
The Other Jimmy 31:8ea194f6145b 163 out_string += out
The Other Jimmy 31:8ea194f6145b 164 out_string += "=" * 10 + "STDERR" + "=" * 10 + "\n"
The Other Jimmy 31:8ea194f6145b 165 out_string += err
The Other Jimmy 31:8ea194f6145b 166
The Other Jimmy 31:8ea194f6145b 167 if ret_code == 0:
The Other Jimmy 31:8ea194f6145b 168 out_string += "SUCCESS"
The Other Jimmy 31:8ea194f6145b 169 else:
The Other Jimmy 31:8ea194f6145b 170 out_string += "FAILURE"
The Other Jimmy 31:8ea194f6145b 171
The Other Jimmy 31:8ea194f6145b 172 print out_string
The Other Jimmy 31:8ea194f6145b 173
The Other Jimmy 31:8ea194f6145b 174 if log_name:
The Other Jimmy 31:8ea194f6145b 175 # Write the output to the log file
The Other Jimmy 31:8ea194f6145b 176 with open(log_name, 'w+') as f:
The Other Jimmy 31:8ea194f6145b 177 f.write(out_string)
The Other Jimmy 31:8ea194f6145b 178
The Other Jimmy 31:8ea194f6145b 179 # Cleanup the exported and built files
The Other Jimmy 31:8ea194f6145b 180 if cleanup:
The Other Jimmy 31:8ea194f6145b 181 remove("Makefile")
The Other Jimmy 31:8ea194f6145b 182 remove(log_name)
The Other Jimmy 31:8ea194f6145b 183 # legacy .build directory cleaned if exists
The Other Jimmy 31:8ea194f6145b 184 if exists('.build'):
The Other Jimmy 31:8ea194f6145b 185 shutil.rmtree('.build')
The Other Jimmy 31:8ea194f6145b 186 if exists('BUILD'):
The Other Jimmy 31:8ea194f6145b 187 shutil.rmtree('BUILD')
The Other Jimmy 31:8ea194f6145b 188
The Other Jimmy 31:8ea194f6145b 189 if ret_code != 0:
The Other Jimmy 31:8ea194f6145b 190 # Seems like something went wrong.
The Other Jimmy 31:8ea194f6145b 191 return -1
The Other Jimmy 31:8ea194f6145b 192 else:
The Other Jimmy 31:8ea194f6145b 193 return 0
The Other Jimmy 31:8ea194f6145b 194
The Other Jimmy 31:8ea194f6145b 195
The Other Jimmy 31:8ea194f6145b 196 class GccArm(Makefile):
The Other Jimmy 31:8ea194f6145b 197 """GCC ARM specific makefile target"""
The Other Jimmy 31:8ea194f6145b 198 NAME = 'Make-GCC-ARM'
The Other Jimmy 31:8ea194f6145b 199 TEMPLATE = 'make-gcc-arm'
The Other Jimmy 31:8ea194f6145b 200 TOOLCHAIN = "GCC_ARM"
The Other Jimmy 31:8ea194f6145b 201 LINK_SCRIPT_OPTION = "-T"
The Other Jimmy 31:8ea194f6145b 202 USER_LIBRARY_FLAG = "-L"
The Other Jimmy 31:8ea194f6145b 203
The Other Jimmy 31:8ea194f6145b 204 @staticmethod
The Other Jimmy 31:8ea194f6145b 205 def prepare_lib(libname):
theotherjimmy 40:7d3fa6b99b2b 206 if "lib" == libname[:3]:
theotherjimmy 40:7d3fa6b99b2b 207 libname = libname[3:-2]
theotherjimmy 40:7d3fa6b99b2b 208 return "-l" + libname
The Other Jimmy 31:8ea194f6145b 209
The Other Jimmy 35:da9c89f8be7d 210 @staticmethod
The Other Jimmy 35:da9c89f8be7d 211 def prepare_sys_lib(libname):
The Other Jimmy 35:da9c89f8be7d 212 return "-l" + libname
The Other Jimmy 35:da9c89f8be7d 213
The Other Jimmy 31:8ea194f6145b 214
theotherjimmy 40:7d3fa6b99b2b 215 class Arm(Makefile):
theotherjimmy 40:7d3fa6b99b2b 216 """ARM Compiler generic makefile target"""
The Other Jimmy 31:8ea194f6145b 217 LINK_SCRIPT_OPTION = "--scatter"
The Other Jimmy 31:8ea194f6145b 218 USER_LIBRARY_FLAG = "--userlibpath "
theotherjimmy 40:7d3fa6b99b2b 219 TEMPLATE = 'make-arm'
The Other Jimmy 31:8ea194f6145b 220
The Other Jimmy 31:8ea194f6145b 221 @staticmethod
The Other Jimmy 31:8ea194f6145b 222 def prepare_lib(libname):
The Other Jimmy 31:8ea194f6145b 223 return libname
The Other Jimmy 31:8ea194f6145b 224
The Other Jimmy 35:da9c89f8be7d 225 @staticmethod
The Other Jimmy 35:da9c89f8be7d 226 def prepare_sys_lib(libname):
The Other Jimmy 35:da9c89f8be7d 227 return libname
The Other Jimmy 35:da9c89f8be7d 228
theotherjimmy 40:7d3fa6b99b2b 229 def generate(self):
theotherjimmy 40:7d3fa6b99b2b 230 if self.resources.linker_script:
theotherjimmy 40:7d3fa6b99b2b 231 new_script = self.toolchain.correct_scatter_shebang(
theotherjimmy 40:7d3fa6b99b2b 232 self.resources.linker_script)
theotherjimmy 40:7d3fa6b99b2b 233 if new_script is not self.resources.linker_script:
theotherjimmy 40:7d3fa6b99b2b 234 self.resources.linker_script = new_script
theotherjimmy 40:7d3fa6b99b2b 235 self.generated_files.append(new_script)
theotherjimmy 40:7d3fa6b99b2b 236 return super(Arm, self).generate()
theotherjimmy 40:7d3fa6b99b2b 237
theotherjimmy 40:7d3fa6b99b2b 238 class Armc5(Arm):
theotherjimmy 40:7d3fa6b99b2b 239 """ARM Compiler 5 (armcc) specific makefile target"""
theotherjimmy 40:7d3fa6b99b2b 240 NAME = 'Make-ARMc5'
theotherjimmy 40:7d3fa6b99b2b 241 TOOLCHAIN = "ARM"
theotherjimmy 40:7d3fa6b99b2b 242 PREPROCESS_ASM = True
theotherjimmy 40:7d3fa6b99b2b 243
theotherjimmy 40:7d3fa6b99b2b 244 class Armc6(Arm):
theotherjimmy 40:7d3fa6b99b2b 245 """ARM Compiler 6 (armclang) specific generic makefile target"""
theotherjimmy 40:7d3fa6b99b2b 246 NAME = 'Make-ARMc6'
theotherjimmy 40:7d3fa6b99b2b 247 TOOLCHAIN = "ARMC6"
theotherjimmy 40:7d3fa6b99b2b 248
The Other Jimmy 31:8ea194f6145b 249
The Other Jimmy 31:8ea194f6145b 250 class IAR(Makefile):
The Other Jimmy 31:8ea194f6145b 251 """IAR specific makefile target"""
The Other Jimmy 31:8ea194f6145b 252 NAME = 'Make-IAR'
The Other Jimmy 31:8ea194f6145b 253 TEMPLATE = 'make-iar'
The Other Jimmy 31:8ea194f6145b 254 TOOLCHAIN = "IAR"
The Other Jimmy 31:8ea194f6145b 255 LINK_SCRIPT_OPTION = "--config"
The Other Jimmy 31:8ea194f6145b 256 USER_LIBRARY_FLAG = "-L"
The Other Jimmy 31:8ea194f6145b 257
The Other Jimmy 31:8ea194f6145b 258 @staticmethod
The Other Jimmy 31:8ea194f6145b 259 def prepare_lib(libname):
The Other Jimmy 31:8ea194f6145b 260 if "lib" == libname[:3]:
The Other Jimmy 31:8ea194f6145b 261 libname = libname[3:]
The Other Jimmy 31:8ea194f6145b 262 return "-l" + splitext(libname)[0]
The Other Jimmy 35:da9c89f8be7d 263
The Other Jimmy 35:da9c89f8be7d 264 @staticmethod
The Other Jimmy 35:da9c89f8be7d 265 def prepare_sys_lib(libname):
The Other Jimmy 35:da9c89f8be7d 266 if "lib" == libname[:3]:
The Other Jimmy 35:da9c89f8be7d 267 libname = libname[3:]
The Other Jimmy 35:da9c89f8be7d 268 return "-l" + splitext(libname)[0]