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.
Dependents: mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510
gcc.py
00001 """ 00002 mbed SDK 00003 Copyright (c) 2011-2013 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 import re 00018 from os.path import join, basename, splitext 00019 00020 from tools.toolchains import mbedToolchain, TOOLCHAIN_PATHS 00021 from tools.hooks import hook_tool 00022 00023 class GCC(mbedToolchain): 00024 LINKER_EXT = '.ld' 00025 LIBRARY_EXT = '.a' 00026 00027 STD_LIB_NAME = "lib%s.a" 00028 DIAGNOSTIC_PATTERN = re.compile('((?P<file>[^:]+):(?P<line>\d+):)(\d+:)? (?P<severity>warning|error): (?P<message>.+)') 00029 INDEX_PATTERN = re.compile('(?P<col>\s*)\^') 00030 00031 def __init__(self, target, notify=None, macros=None, 00032 silent=False, tool_path="", extra_verbose=False, 00033 build_profile=None): 00034 mbedToolchain.__init__(self, target, notify, macros, silent, 00035 extra_verbose=extra_verbose, 00036 build_profile=build_profile) 00037 00038 # Add flags for current size setting 00039 default_lib = "std" 00040 if hasattr(target, "default_lib"): 00041 default_lib = target.default_lib 00042 elif hasattr(target, "default_build"): # Legacy 00043 default_lib = target.default_build 00044 00045 if default_lib == "small": 00046 self.flags["common"].append("-DMBED_RTOS_SINGLE_THREAD") 00047 self.flags["ld"].append("--specs=nano.specs") 00048 00049 if target.core == "Cortex-M0+": 00050 cpu = "cortex-m0plus" 00051 elif target.core == "Cortex-M4F": 00052 cpu = "cortex-m4" 00053 elif target.core == "Cortex-M7F": 00054 cpu = "cortex-m7" 00055 elif target.core == "Cortex-M7FD": 00056 cpu = "cortex-m7" 00057 else: 00058 cpu = target.core.lower() 00059 00060 self.cpu = ["-mcpu=%s" % cpu] 00061 if target.core.startswith("Cortex"): 00062 self.cpu.append("-mthumb") 00063 00064 # FPU handling, M7 possibly to have double FPU 00065 if target.core == "Cortex-M4F": 00066 self.cpu.append("-mfpu=fpv4-sp-d16") 00067 self.cpu.append("-mfloat-abi=softfp") 00068 elif target.core == "Cortex-M7F": 00069 self.cpu.append("-mfpu=fpv5-sp-d16") 00070 self.cpu.append("-mfloat-abi=softfp") 00071 elif target.core == "Cortex-M7FD": 00072 self.cpu.append("-mfpu=fpv5-d16") 00073 self.cpu.append("-mfloat-abi=softfp") 00074 00075 if target.core == "Cortex-A9": 00076 self.cpu.append("-mthumb-interwork") 00077 self.cpu.append("-marm") 00078 self.cpu.append("-march=armv7-a") 00079 self.cpu.append("-mfpu=vfpv3") 00080 self.cpu.append("-mfloat-abi=hard") 00081 self.cpu.append("-mno-unaligned-access") 00082 00083 self.flags["common"] += self.cpu 00084 00085 main_cc = join(tool_path, "arm-none-eabi-gcc") 00086 main_cppc = join(tool_path, "arm-none-eabi-g++") 00087 self.asm = [main_cc] + self.flags['asm'] + self.flags["common"] 00088 self.cc = [main_cc] 00089 self.cppc =[main_cppc] 00090 self.cc += self.flags['c'] + self.flags['common'] 00091 self.cppc += self.flags['cxx'] + self.flags['common'] 00092 00093 self.flags['ld'] += self.cpu 00094 self.ld = [join(tool_path, "arm-none-eabi-gcc")] + self.flags['ld'] 00095 self.sys_libs = ["stdc++", "supc++", "m", "c", "gcc"] 00096 00097 self.ar = join(tool_path, "arm-none-eabi-ar") 00098 self.elf2bin = join(tool_path, "arm-none-eabi-objcopy") 00099 00100 def parse_dependencies(self, dep_path): 00101 dependencies = [] 00102 buff = open(dep_path).readlines() 00103 buff[0] = re.sub('^(.*?)\: ', '', buff[0]) 00104 for line in buff: 00105 file = line.replace('\\\n', '').strip() 00106 if file: 00107 # GCC might list more than one dependency on a single line, in this case 00108 # the dependencies are separated by a space. However, a space might also 00109 # indicate an actual space character in a dependency path, but in this case 00110 # the space character is prefixed by a backslash. 00111 # Temporary replace all '\ ' with a special char that is not used (\a in this 00112 # case) to keep them from being interpreted by 'split' (they will be converted 00113 # back later to a space char) 00114 file = file.replace('\\ ', '\a') 00115 if file.find(" ") == -1: 00116 dependencies.append((self.CHROOT if self.CHROOT else '') + file.replace('\a', ' ')) 00117 else: 00118 dependencies = dependencies + [(self.CHROOT if self.CHROOT else '') + f.replace('\a', ' ') for f in file.split(" ")] 00119 return dependencies 00120 00121 def is_not_supported_error(self, output): 00122 return "error: #error [NOT_SUPPORTED]" in output 00123 00124 def parse_output(self, output): 00125 # The warning/error notification is multiline 00126 msg = None 00127 for line in output.splitlines(): 00128 match = GCC.DIAGNOSTIC_PATTERN.search(line) 00129 if match is not None: 00130 if msg is not None: 00131 self.cc_info(msg) 00132 msg = None 00133 msg = { 00134 'severity': match.group('severity').lower(), 00135 'file': match.group('file'), 00136 'line': match.group('line'), 00137 'col': 0, 00138 'message': match.group('message'), 00139 'text': '', 00140 'target_name': self.target.name, 00141 'toolchain_name': self.name 00142 } 00143 elif msg is not None: 00144 # Determine the warning/error column by calculating the ^ position 00145 match = GCC.INDEX_PATTERN.match(line) 00146 if match is not None: 00147 msg['col'] = len(match.group('col')) 00148 self.cc_info(msg) 00149 msg = None 00150 else: 00151 msg['text'] += line+"\n" 00152 00153 if msg is not None: 00154 self.cc_info(msg) 00155 00156 def get_dep_option(self, object): 00157 base, _ = splitext(object) 00158 dep_path = base + '.d' 00159 return ["-MD", "-MF", dep_path] 00160 00161 def get_config_option(self, config_header): 00162 return ['-include', config_header] 00163 00164 def get_compile_options(self, defines, includes, for_asm=False): 00165 opts = ['-D%s' % d for d in defines] 00166 if self.RESPONSE_FILES: 00167 opts += ['@%s' % self.get_inc_file(includes)] 00168 else: 00169 opts += ["-I%s" % i for i in includes] 00170 00171 if not for_asm: 00172 config_header = self.get_config_header() 00173 if config_header is not None: 00174 opts = opts + self.get_config_option(config_header) 00175 return opts 00176 00177 @hook_tool 00178 def assemble(self, source, object, includes): 00179 # Build assemble command 00180 cmd = self.asm + self.get_compile_options(self.get_symbols(True), includes) + ["-o", object, source] 00181 00182 # Call cmdline hook 00183 cmd = self.hook.get_cmdline_assembler(cmd) 00184 00185 # Return command array, don't execute 00186 return [cmd] 00187 00188 @hook_tool 00189 def compile(self, cc, source, object, includes): 00190 # Build compile command 00191 cmd = cc + self.get_compile_options(self.get_symbols(), includes) 00192 00193 cmd.extend(self.get_dep_option(object)) 00194 00195 cmd.extend(["-o", object, source]) 00196 00197 # Call cmdline hook 00198 cmd = self.hook.get_cmdline_compiler(cmd) 00199 00200 return [cmd] 00201 00202 def compile_c(self, source, object, includes): 00203 return self.compile(self.cc, source, object, includes) 00204 00205 def compile_cpp(self, source, object, includes): 00206 return self.compile(self.cppc, source, object, includes) 00207 00208 @hook_tool 00209 def link(self, output, objects, libraries, lib_dirs, mem_map): 00210 libs = [] 00211 for l in libraries: 00212 name, _ = splitext(basename(l)) 00213 libs.append("-l%s" % name[3:]) 00214 libs.extend(["-l%s" % l for l in self.sys_libs]) 00215 00216 # Build linker command 00217 map_file = splitext(output)[0] + ".map" 00218 cmd = self.ld + ["-o", output, "-Wl,-Map=%s" % map_file] + objects + ["-Wl,--start-group"] + libs + ["-Wl,--end-group"] 00219 if mem_map: 00220 cmd.extend(['-T', mem_map]) 00221 00222 for L in lib_dirs: 00223 cmd.extend(['-L', L]) 00224 cmd.extend(libs) 00225 00226 # Call cmdline hook 00227 cmd = self.hook.get_cmdline_linker(cmd) 00228 00229 if self.RESPONSE_FILES: 00230 # Split link command to linker executable + response file 00231 cmd_linker = cmd[0] 00232 link_files = self.get_link_file(cmd[1:]) 00233 cmd = [cmd_linker, "@%s" % link_files] 00234 00235 # Exec command 00236 self.cc_verbose("Link: %s" % ' '.join(cmd)) 00237 self.default_cmd(cmd) 00238 00239 @hook_tool 00240 def archive(self, objects, lib_path): 00241 if self.RESPONSE_FILES: 00242 param = ["@%s" % self.get_arch_file(objects)] 00243 else: 00244 param = objects 00245 00246 # Exec command 00247 self.default_cmd([self.ar, 'rcs', lib_path] + param) 00248 00249 @hook_tool 00250 def binary(self, resources, elf, bin): 00251 # Build binary command 00252 cmd = [self.elf2bin, "-O", "binary", elf, bin] 00253 00254 # Call cmdline hook 00255 cmd = self.hook.get_cmdline_binary(cmd) 00256 00257 # Exec command 00258 self.cc_verbose("FromELF: %s" % ' '.join(cmd)) 00259 self.default_cmd(cmd) 00260 00261 00262 class GCC_ARM(GCC): 00263 @staticmethod 00264 def check_executable(): 00265 """Returns True if the executable (arm-none-eabi-gcc) location 00266 specified by the user exists OR the executable can be found on the PATH. 00267 Returns False otherwise.""" 00268 return mbedToolchain.generic_check_executable("GCC_ARM", 'arm-none-eabi-gcc', 1) 00269 00270 def __init__(self, target, notify=None, macros=None, 00271 silent=False, extra_verbose=False, build_profile=None): 00272 GCC.__init__(self, target, notify, macros, silent, 00273 TOOLCHAIN_PATHS['GCC_ARM'], extra_verbose=extra_verbose, 00274 build_profile=build_profile) 00275 00276 self.sys_libs.append("nosys") 00277 00278 00279 class GCC_CR(GCC): 00280 @staticmethod 00281 def check_executable(): 00282 """Returns True if the executable (arm-none-eabi-gcc) location 00283 specified by the user exists OR the executable can be found on the PATH. 00284 Returns False otherwise.""" 00285 return mbedToolchain.generic_check_executable("GCC_CR", 'arm-none-eabi-gcc', 1) 00286 00287 def __init__(self, target, notify=None, macros=None, 00288 silent=False, extra_verbose=False, build_profile=None): 00289 GCC.__init__(self, target, notify, macros, silent, 00290 TOOLCHAIN_PATHS['GCC_CR'], extra_verbose=extra_verbose, 00291 build_profile=build_profile) 00292 00293 additional_compiler_flags = [ 00294 "-D__NEWLIB__", "-D__CODE_RED", "-D__USE_CMSIS", "-DCPP_USE_HEAP", 00295 ] 00296 self.cc += additional_compiler_flags 00297 self.cppc += additional_compiler_flags 00298 00299 # Use latest gcc nanolib 00300 self.ld.append("--specs=nano.specs") 00301 if target.name in ["LPC1768", "LPC4088", "LPC4088_DM", "LPC4330", "UBLOX_C027", "LPC2368"]: 00302 self.ld.extend(["-u _printf_float", "-u _scanf_float"]) 00303 self.ld += ["-nostdlib"]
Generated on Tue Jul 12 2022 11:02:38 by
