mbed-os

Dependents:   cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more

Committer:
be_bryan
Date:
Mon Dec 11 17:54:04 2017 +0000
Revision:
0:b74591d5ab33
motor ++

Who changed what in which revision?

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