Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
__init__.py
00001 """ 00002 mbed SDK 00003 Copyright (c) 2011-2016 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 from __future__ import print_function, absolute_import 00018 from builtins import str 00019 00020 from os.path import splitext, basename, relpath, join, abspath, dirname,\ 00021 exists 00022 from os import remove 00023 import sys 00024 from subprocess import check_output, CalledProcessError, Popen, PIPE 00025 import shutil 00026 from jinja2.exceptions import TemplateNotFound 00027 from tools.export.exporters import Exporter, apply_supported_whitelist 00028 from tools.utils import NotSupportedException 00029 from tools.targets import TARGET_MAP 00030 00031 00032 class Makefile (Exporter ): 00033 """Generic Makefile template that mimics the behavior of the python build 00034 system 00035 """ 00036 00037 DOT_IN_RELATIVE_PATH = True 00038 00039 MBED_CONFIG_HEADER_SUPPORTED = True 00040 00041 PREPROCESS_ASM = False 00042 00043 POST_BINARY_WHITELIST = set([ 00044 "MCU_NRF51Code.binary_hook", 00045 "TEENSY3_1Code.binary_hook", 00046 "LPCTargetCode.lpc_patch", 00047 "LPC4088Code.binary_hook" 00048 ]) 00049 00050 @classmethod 00051 def is_target_supported (cls, target_name): 00052 target = TARGET_MAP[target_name] 00053 return apply_supported_whitelist( 00054 cls.TOOLCHAIN, cls.POST_BINARY_WHITELIST, target) 00055 00056 def generate (self): 00057 """Generate the makefile 00058 00059 Note: subclasses should not need to override this method 00060 """ 00061 if not self.resources.linker_script: 00062 raise NotSupportedException("No linker script found.") 00063 00064 self.resources.win_to_unix() 00065 00066 to_be_compiled = [splitext(src)[0] + ".o" for src in 00067 self.resources.s_sources + 00068 self.resources.c_sources + 00069 self.resources.cpp_sources] 00070 00071 libraries = [self.prepare_lib(basename(lib)) for lib 00072 in self.resources.libraries] 00073 sys_libs = [self.prepare_sys_lib(lib) for lib 00074 in self.toolchain.sys_libs] 00075 00076 ctx = { 00077 'name': self.project_name, 00078 'to_be_compiled': to_be_compiled, 00079 'object_files': self.resources.objects, 00080 'include_paths': list(set(self.resources.inc_dirs)), 00081 'library_paths': self.resources.lib_dirs, 00082 'linker_script': self.resources.linker_script, 00083 'libraries': libraries, 00084 'ld_sys_libs': sys_libs, 00085 'hex_files': self.resources.hex_files, 00086 'vpath': (["../../.."] 00087 if (basename(dirname(dirname(self.export_dir))) 00088 == "projectfiles") 00089 else [".."]), 00090 'cc_cmd': " ".join(["\'" + part + "\'" for part 00091 in ([basename(self.toolchain.cc[0])] + 00092 self.toolchain.cc[1:])]), 00093 'cppc_cmd': " ".join(["\'" + part + "\'" for part 00094 in ([basename(self.toolchain.cppc[0])] + 00095 self.toolchain.cppc[1:])]), 00096 'asm_cmd': " ".join(["\'" + part + "\'" for part 00097 in ([basename(self.toolchain.asm[0])] + 00098 self.toolchain.asm[1:])]), 00099 'ld_cmd': "\'" + basename(self.toolchain.ld[0]) + "\'", 00100 'elf2bin_cmd': "\'" + basename(self.toolchain.elf2bin) + "\'", 00101 'link_script_ext': self.toolchain.LINKER_EXT, 00102 'link_script_option': self.LINK_SCRIPT_OPTION, 00103 'user_library_flag': self.USER_LIBRARY_FLAG, 00104 'needs_asm_preproc': self.PREPROCESS_ASM , 00105 } 00106 00107 if hasattr(self.toolchain, "preproc"): 00108 ctx['pp_cmd'] = " ".join(["\'" + part + "\'" for part 00109 in ([basename(self.toolchain.preproc[0])] + 00110 self.toolchain.preproc[1:] + 00111 self.toolchain.ld[1:])]) 00112 else: 00113 ctx['pp_cmd'] = None 00114 00115 for key in ['include_paths', 'library_paths', 'linker_script', 00116 'hex_files']: 00117 if isinstance(ctx[key], list): 00118 ctx[key] = [ctx['vpath'][0] + "/" + t for t in ctx[key]] 00119 else: 00120 ctx[key] = ctx['vpath'][0] + "/" + ctx[key] 00121 if "../." not in ctx["include_paths"]: 00122 ctx["include_paths"] += ['../.'] 00123 for key in ['include_paths', 'library_paths', 'hex_files', 00124 'to_be_compiled']: 00125 ctx[key] = sorted(ctx[key]) 00126 ctx.update(self.format_flags ()) 00127 # Add the virtual path the the include option in the ASM flags 00128 for index, flag in enumerate(ctx['asm_flags']): 00129 if flag.startswith('-I'): 00130 ctx['asm_flags'][index] = "-I" + ctx['vpath'][0] + "/" + ctx['asm_flags'][index][2:] 00131 00132 for templatefile in \ 00133 ['makefile/%s_%s.tmpl' % (self.TEMPLATE, 00134 self.target.lower())] + \ 00135 ['makefile/%s_%s.tmpl' % (self.TEMPLATE, 00136 label.lower()) for label 00137 in self.toolchain.target.extra_labels] +\ 00138 ['makefile/%s.tmpl' % self.TEMPLATE]: 00139 try: 00140 self.gen_file(templatefile, ctx, 'Makefile') 00141 break 00142 except TemplateNotFound: 00143 pass 00144 else: 00145 raise NotSupportedException("This make tool is in development") 00146 00147 def format_flags (self): 00148 """Format toolchain flags for Makefile""" 00149 flags = {} 00150 for k, v in self.flags.items(): 00151 if k in ['asm_flags', 'c_flags', 'cxx_flags']: 00152 flags[k] = map(lambda x: x.replace('"', '\\"'), v) 00153 else: 00154 flags[k] = v 00155 00156 return flags 00157 00158 @staticmethod 00159 def clean (_): 00160 remove("Makefile") 00161 # legacy .build directory cleaned if exists 00162 if exists('.build'): 00163 shutil.rmtree('.build') 00164 if exists('BUILD'): 00165 shutil.rmtree('BUILD') 00166 00167 @staticmethod 00168 def build (project_name, log_name="build_log.txt", cleanup=True): 00169 """ Build Make project """ 00170 # > Make -j 00171 cmd = ["make", "-j"] 00172 00173 # Build the project 00174 p = Popen(cmd, stdout=PIPE, stderr=PIPE) 00175 out, err = p.communicate() 00176 ret_code = p.returncode 00177 00178 out_string = "=" * 10 + "STDOUT" + "=" * 10 + "\n" 00179 out_string += out 00180 out_string += "=" * 10 + "STDERR" + "=" * 10 + "\n" 00181 out_string += err 00182 00183 if ret_code == 0: 00184 out_string += "SUCCESS" 00185 else: 00186 out_string += "FAILURE" 00187 00188 print(out_string) 00189 00190 if log_name: 00191 # Write the output to the log file 00192 with open(log_name, 'w+') as f: 00193 f.write(out_string) 00194 00195 # Cleanup the exported and built files 00196 if cleanup: 00197 remove(log_name) 00198 Makefile.clean(project_name) 00199 00200 if ret_code != 0: 00201 # Seems like something went wrong. 00202 return -1 00203 else: 00204 return 0 00205 00206 00207 class GccArm (Makefile ): 00208 """GCC ARM specific makefile target""" 00209 NAME = 'Make-GCC-ARM' 00210 TEMPLATE = 'make-gcc-arm' 00211 TOOLCHAIN = "GCC_ARM" 00212 LINK_SCRIPT_OPTION = "-T" 00213 USER_LIBRARY_FLAG = "-L" 00214 00215 @staticmethod 00216 def prepare_lib(libname): 00217 if "lib" == libname[:3]: 00218 libname = libname[3:-2] 00219 return "-l" + libname 00220 00221 @staticmethod 00222 def prepare_sys_lib(libname): 00223 return "-l" + libname 00224 00225 00226 class Arm (Makefile ): 00227 """ARM Compiler generic makefile target""" 00228 LINK_SCRIPT_OPTION = "--scatter" 00229 USER_LIBRARY_FLAG = "--userlibpath " 00230 TEMPLATE = 'make-arm' 00231 00232 @staticmethod 00233 def prepare_lib(libname): 00234 return libname 00235 00236 @staticmethod 00237 def prepare_sys_lib(libname): 00238 return libname 00239 00240 def generate (self): 00241 if self.resources.linker_script: 00242 sct_file = self.resources.linker_script 00243 new_script = self.toolchain.correct_scatter_shebang( 00244 sct_file, join(self.resources.file_basepath[sct_file], "BUILD")) 00245 if new_script is not sct_file: 00246 self.resources.linker_script = new_script 00247 self.generated_files.append(new_script) 00248 return super(Arm, self).generate() 00249 00250 class Armc5 (Arm ): 00251 """ARM Compiler 5 (armcc) specific makefile target""" 00252 NAME = 'Make-ARMc5' 00253 TOOLCHAIN = "ARM" 00254 PREPROCESS_ASM = True 00255 00256 class Armc6 (Arm ): 00257 """ARM Compiler 6 (armclang) specific generic makefile target""" 00258 NAME = 'Make-ARMc6' 00259 TOOLCHAIN = "ARMC6" 00260 00261 00262 class IAR (Makefile ): 00263 """IAR specific makefile target""" 00264 NAME = 'Make-IAR' 00265 TEMPLATE = 'make-iar' 00266 TOOLCHAIN = "IAR" 00267 LINK_SCRIPT_OPTION = "--config" 00268 USER_LIBRARY_FLAG = "-L" 00269 00270 @staticmethod 00271 def prepare_lib(libname): 00272 if "lib" == libname[:3]: 00273 libname = libname[3:] 00274 return "-l" + splitext(libname)[0] 00275 00276 @staticmethod 00277 def prepare_sys_lib(libname): 00278 if "lib" == libname[:3]: 00279 libname = libname[3:] 00280 return "-l" + splitext(libname)[0]
Generated on Tue Jul 12 2022 14:22:58 by
