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