joey shelton / LED_Demo

Dependencies:   MAX44000 PWM_Tone_Library nexpaq_mdk

Fork of LED_Demo by Maxim nexpaq

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers gcc.py Source File

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, dirname, exists
00019 from distutils.spawn import find_executable
00020 
00021 from tools.toolchains import mbedToolchain, TOOLCHAIN_PATHS
00022 from tools.hooks import hook_tool
00023 
00024 class GCC(mbedToolchain):
00025     LINKER_EXT = '.ld'
00026     LIBRARY_EXT = '.a'
00027 
00028     STD_LIB_NAME = "lib%s.a"
00029     DIAGNOSTIC_PATTERN = re.compile('((?P<file>[^:]+):(?P<line>\d+):)(\d+:)? (?P<severity>warning|error): (?P<message>.+)')
00030     INDEX_PATTERN  = re.compile('(?P<col>\s*)\^')
00031 
00032     DEFAULT_FLAGS = {
00033         'common': ["-c", "-Wall", "-Wextra",
00034             "-Wno-unused-parameter", "-Wno-missing-field-initializers",
00035             "-fmessage-length=0", "-fno-exceptions", "-fno-builtin",
00036             "-ffunction-sections", "-fdata-sections", "-funsigned-char",
00037             "-MMD", "-fno-delete-null-pointer-checks", "-fomit-frame-pointer"
00038             ],
00039         'asm': ["-x", "assembler-with-cpp"],
00040         'c': ["-std=gnu99"],
00041         'cxx': ["-std=gnu++98", "-fno-rtti", "-Wvla"],
00042         'ld': ["-Wl,--gc-sections", "-Wl,--wrap,main",
00043             "-Wl,--wrap,_malloc_r", "-Wl,--wrap,_free_r", "-Wl,--wrap,_realloc_r", "-Wl,--wrap,_calloc_r"],
00044     }
00045 
00046     def __init__(self, target, options=None, notify=None, macros=None, silent=False, tool_path="", extra_verbose=False):
00047         mbedToolchain.__init__(self, target, options, notify, macros, silent, extra_verbose=extra_verbose)
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 
00076 
00077         if target.core == "Cortex-A9":
00078             self.cpu.append("-mthumb-interwork")
00079             self.cpu.append("-marm")
00080             self.cpu.append("-march=armv7-a")
00081             self.cpu.append("-mfpu=vfpv3")
00082             self.cpu.append("-mfloat-abi=hard")
00083             self.cpu.append("-mno-unaligned-access")
00084 
00085 
00086         # Note: We are using "-O2" instead of "-Os" to avoid this known GCC bug:
00087         # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46762
00088         self.flags["common"] += self.cpu
00089 
00090         if "save-asm" in self.options:
00091             self.flags["common"].append("-save-temps")
00092 
00093         if "debug-info" in self.options:
00094             self.flags["common"].append("-g")
00095             self.flags["common"].append("-O0")
00096         else:
00097             self.flags["common"].append("-Os")
00098 
00099         main_cc = join(tool_path, "arm-none-eabi-gcc")
00100         main_cppc = join(tool_path, "arm-none-eabi-g++")
00101         self.asm = [main_cc] + self.flags['asm'] + self.flags["common"]
00102         self.cc  = [main_cc]
00103         self.cppc =[main_cppc]
00104         self.cc += self.flags['c'] + self.flags['common']
00105         self.cppc += self.flags['cxx'] + self.flags['common']
00106 
00107         self.flags['ld'] += self.cpu
00108         self.ld = [join(tool_path, "arm-none-eabi-gcc")] + self.flags['ld']
00109         self.sys_libs = ["stdc++", "supc++", "m", "c", "gcc"]
00110 
00111         self.ar = join(tool_path, "arm-none-eabi-ar")
00112         self.elf2bin = join(tool_path, "arm-none-eabi-objcopy")
00113 
00114         if tool_path:
00115             self.toolchain_path = main_cc
00116         else:
00117             self.toolchain_path = find_executable("arm-none-eabi-gcc") or ''
00118 
00119     def parse_dependencies(self, dep_path):
00120         dependencies = []
00121         buff = open(dep_path).readlines()
00122         buff[0] = re.sub('^(.*?)\: ', '', buff[0])
00123         for line in buff:
00124             file = line.replace('\\\n', '').strip()
00125             if file:
00126                 # GCC might list more than one dependency on a single line, in this case
00127                 # the dependencies are separated by a space. However, a space might also
00128                 # indicate an actual space character in a dependency path, but in this case
00129                 # the space character is prefixed by a backslash.
00130                 # Temporary replace all '\ ' with a special char that is not used (\a in this
00131                 # case) to keep them from being interpreted by 'split' (they will be converted
00132                 # back later to a space char)
00133                 file = file.replace('\\ ', '\a')
00134                 if file.find(" ") == -1:
00135                     dependencies.append((self.CHROOT if self.CHROOT else '') + file.replace('\a', ' '))
00136                 else:
00137                     dependencies = dependencies + [(self.CHROOT if self.CHROOT else '') + f.replace('\a', ' ') for f in file.split(" ")]
00138         return dependencies
00139 
00140     def is_not_supported_error(self, output):
00141         return "error: #error [NOT_SUPPORTED]" in output
00142 
00143     def parse_output(self, output):
00144         # The warning/error notification is multiline
00145         msg = None
00146         for line in output.splitlines():
00147             match = GCC.DIAGNOSTIC_PATTERN.search(line)
00148             if match is not None:
00149                 if msg is not None:
00150                     self.cc_info(msg)
00151                 msg = {
00152                     'severity': match.group('severity').lower(),
00153                     'file': match.group('file'),
00154                     'line': match.group('line'),
00155                     'col': 0,
00156                     'message': match.group('message'),
00157                     'text': '',
00158                     'target_name': self.target.name,
00159                     'toolchain_name': self.name
00160                 }
00161             elif msg is not None:
00162                 # Determine the warning/error column by calculating the ^ position
00163                 match = GCC.INDEX_PATTERN.match(line)
00164                 if match is not None:
00165                     msg['col'] = len(match.group('col'))
00166                     self.cc_info(msg)
00167                     msg = None
00168                 else:
00169                     msg['text'] += line+"\n"
00170 
00171     def get_dep_option(self, object):
00172         base, _ = splitext(object)
00173         dep_path = base + '.d'
00174         return ["-MD", "-MF", dep_path]
00175 
00176     def get_config_option(self, config_header):
00177         return ['-include', config_header]
00178 
00179     def get_compile_options(self, defines, includes, for_asm=False):
00180         opts = ['-D%s' % d for d in defines]
00181         if self.RESPONSE_FILES:
00182             opts += ['@%s' % self.get_inc_file(includes)]
00183         else:
00184             opts += ["-I%s" % i for i in includes]
00185 
00186         if not for_asm:
00187             config_header = self.get_config_header()
00188             if config_header is not None:
00189                 opts = opts + self.get_config_option(config_header)
00190         return opts
00191 
00192     @hook_tool
00193     def assemble(self, source, object, includes):
00194         # Build assemble command
00195         cmd = self.asm + self.get_compile_options(self.get_symbols(True), includes) + ["-o", object, source]
00196 
00197         # Call cmdline hook
00198         cmd = self.hook.get_cmdline_assembler(cmd)
00199 
00200         # Return command array, don't execute
00201         return [cmd]
00202 
00203     @hook_tool
00204     def compile(self, cc, source, object, includes):
00205         # Build compile command
00206         cmd = cc + self.get_compile_options(self.get_symbols(), includes)
00207 
00208         cmd.extend(self.get_dep_option(object))
00209 
00210         cmd.extend(["-o", object, source])
00211 
00212         # Call cmdline hook
00213         cmd = self.hook.get_cmdline_compiler(cmd)
00214 
00215         return [cmd]
00216 
00217     def compile_c(self, source, object, includes):
00218         return self.compile(self.cc, source, object, includes)
00219 
00220     def compile_cpp(self, source, object, includes):
00221         return self.compile(self.cppc, source, object, includes)
00222 
00223     @hook_tool
00224     def link(self, output, objects, libraries, lib_dirs, mem_map):
00225         libs = []
00226         for l in libraries:
00227             name, _ = splitext(basename(l))
00228             libs.append("-l%s" % name[3:])
00229         libs.extend(["-l%s" % l for l in self.sys_libs])
00230 
00231         # Build linker command
00232         map_file = splitext(output)[0] + ".map"
00233         cmd = self.ld + ["-o", output, "-Wl,-Map=%s" % map_file] + objects + ["-Wl,--start-group"] + libs + ["-Wl,--end-group"]
00234         if mem_map:
00235             cmd.extend(['-T', mem_map])
00236 
00237         for L in lib_dirs:
00238             cmd.extend(['-L', L])
00239         cmd.extend(libs)
00240 
00241         # Call cmdline hook
00242         cmd = self.hook.get_cmdline_linker(cmd)
00243 
00244         if self.RESPONSE_FILES:
00245             # Split link command to linker executable + response file
00246             cmd_linker = cmd[0]
00247             link_files = self.get_link_file(cmd[1:])
00248             cmd = [cmd_linker, "@%s" % link_files]
00249 
00250         # Exec command
00251         self.cc_verbose("Link: %s" % ' '.join(cmd))
00252         self.default_cmd(cmd)
00253 
00254     @hook_tool
00255     def archive(self, objects, lib_path):
00256         if self.RESPONSE_FILES:
00257             param = ["@%s" % self.get_arch_file(objects)]
00258         else:
00259             param = objects
00260 
00261         # Exec command
00262         self.default_cmd([self.ar, 'rcs', lib_path] + param)
00263 
00264     @hook_tool
00265     def binary(self, resources, elf, bin):
00266         # Build binary command
00267         cmd = [self.elf2bin, "-O", "binary", elf, bin]
00268 
00269         # Call cmdline hook
00270         cmd = self.hook.get_cmdline_binary(cmd)
00271 
00272         # Exec command
00273         self.cc_verbose("FromELF: %s" % ' '.join(cmd))
00274         self.default_cmd(cmd)
00275 
00276 
00277 class GCC_ARM(GCC):
00278     def __init__(self, target, options=None, notify=None, macros=None, silent=False, extra_verbose=False):
00279         GCC.__init__(self, target, options, notify, macros, silent, TOOLCHAIN_PATHS['GCC_ARM'], extra_verbose=extra_verbose)
00280 
00281         # Use latest gcc nanolib
00282         if "std-lib" in self.options:
00283             use_nano = False
00284         elif "small-lib" in self.options:
00285             use_nano = True
00286         elif target.default_lib == "std":
00287             use_nano = False
00288         elif target.default_lib == "small":
00289             use_nano = True
00290         else:
00291             use_nano = False
00292 
00293         if use_nano:
00294             self.ld.append("--specs=nano.specs")
00295             self.flags['ld'].append("--specs=nano.specs")
00296             self.cc += ["-DMBED_RTOS_SINGLE_THREAD"]
00297             self.cppc += ["-DMBED_RTOS_SINGLE_THREAD"]
00298             self.macros.extend(["MBED_RTOS_SINGLE_THREAD"])
00299         self.sys_libs.append("nosys")
00300 
00301 
00302 class GCC_CR(GCC):
00303     def __init__(self, target, options=None, notify=None, macros=None, silent=False, extra_verbose=False):
00304         GCC.__init__(self, target, options, notify, macros, silent, TOOLCHAIN_PATHS['GCC_CR'], extra_verbose=extra_verbose)
00305 
00306         additional_compiler_flags = [
00307             "-D__NEWLIB__", "-D__CODE_RED", "-D__USE_CMSIS", "-DCPP_USE_HEAP",
00308         ]
00309         self.cc += additional_compiler_flags
00310         self.cppc += additional_compiler_flags
00311 
00312         # Use latest gcc nanolib
00313         self.ld.append("--specs=nano.specs")
00314         if target.name in ["LPC1768", "LPC4088", "LPC4088_DM", "LPC4330", "UBLOX_C027", "LPC2368"]:
00315             self.ld.extend(["-u _printf_float", "-u _scanf_float"])
00316         self.ld += ["-nostdlib"]