]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/workspace_tools/toolchains/gcc.py
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / workspace_tools / toolchains / gcc.py
1 """
2 mbed SDK
3 Copyright (c) 2011-2013 ARM Limited
4
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8
9     http://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16 """
17 import re
18 from os.path import join, basename, splitext
19
20 from workspace_tools.toolchains import mbedToolchain
21 from workspace_tools.settings import GCC_ARM_PATH, GCC_CR_PATH, GCC_CS_PATH, CW_EWL_PATH, CW_GCC_PATH
22 from workspace_tools.settings import GOANNA_PATH
23 from workspace_tools.hooks import hook_tool
24
25 class GCC(mbedToolchain):
26     LINKER_EXT = '.ld'
27     LIBRARY_EXT = '.a'
28
29     STD_LIB_NAME = "lib%s.a"
30     CIRCULAR_DEPENDENCIES = True
31     DIAGNOSTIC_PATTERN = re.compile('((?P<line>\d+):)(\d+:)? (?P<severity>warning|error): (?P<message>.+)')
32
33     def __init__(self, target, options=None, notify=None, macros=None, silent=False, tool_path=""):
34         mbedToolchain.__init__(self, target, options, notify, macros, silent)
35
36         if target.core == "Cortex-M0+":
37             cpu = "cortex-m0plus"
38         elif target.core == "Cortex-M4F":
39             cpu = "cortex-m4"
40         else:
41             cpu = target.core.lower()
42
43         self.cpu = ["-mcpu=%s" % cpu]
44         if target.core.startswith("Cortex"):
45             self.cpu.append("-mthumb")
46
47         if target.core == "Cortex-M4F":
48             self.cpu.append("-mfpu=fpv4-sp-d16")
49             self.cpu.append("-mfloat-abi=softfp")
50
51         if target.core == "Cortex-A9":
52             self.cpu.append("-mthumb-interwork")
53             self.cpu.append("-marm")
54             self.cpu.append("-march=armv7-a")
55             self.cpu.append("-mfpu=vfpv3-d16")
56             self.cpu.append("-mfloat-abi=hard")
57             self.cpu.append("-mno-unaligned-access")
58
59
60         # Note: We are using "-O2" instead of "-Os" to avoid this known GCC bug:
61         # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46762
62         common_flags = ["-c", "-Wall", "-Wextra",
63             "-Wno-unused-parameter", "-Wno-missing-field-initializers",
64             "-fmessage-length=0", "-fno-exceptions", "-fno-builtin",
65             "-ffunction-sections", "-fdata-sections",
66             "-MMD", "-fno-delete-null-pointer-checks", "-fomit-frame-pointer"
67             ] + self.cpu
68
69         if "save-asm" in self.options:
70             common_flags.append("-save-temps")
71
72         if "debug-info" in self.options:
73             common_flags.append("-g")
74             common_flags.append("-O0")
75         else:
76             common_flags.append("-O2")
77
78         main_cc = join(tool_path, "arm-none-eabi-gcc")
79         main_cppc = join(tool_path, "arm-none-eabi-g++")
80         self.asm = [main_cc, "-x", "assembler-with-cpp"] + common_flags
81         if not "analyze" in self.options:
82             self.cc  = [main_cc, "-std=gnu99"] + common_flags
83             self.cppc =[main_cppc, "-std=gnu++98", "-fno-rtti"] + common_flags
84         else:
85             self.cc  = [join(GOANNA_PATH, "goannacc"), "--with-cc=" + main_cc.replace('\\', '/'), "-std=gnu99", "--dialect=gnu", '--output-format="%s"' % self.GOANNA_FORMAT] + common_flags
86             self.cppc= [join(GOANNA_PATH, "goannac++"), "--with-cxx=" + main_cppc.replace('\\', '/'), "-std=gnu++98", "-fno-rtti", "--dialect=gnu", '--output-format="%s"' % self.GOANNA_FORMAT] + common_flags
87
88         self.ld = [join(tool_path, "arm-none-eabi-gcc"), "-Wl,--gc-sections", "-Wl,--wrap,main"] + self.cpu
89         self.sys_libs = ["stdc++", "supc++", "m", "c", "gcc"]
90
91         self.ar = join(tool_path, "arm-none-eabi-ar")
92         self.elf2bin = join(tool_path, "arm-none-eabi-objcopy")
93
94     def assemble(self, source, object, includes):
95         return [self.hook.get_cmdline_assembler(self.asm + ['-D%s' % s for s in self.get_symbols() + self.macros] + ["-I%s" % i for i in includes] + ["-o", object, source])]
96
97     def parse_dependencies(self, dep_path):
98         dependencies = []
99         for line in open(dep_path).readlines()[1:]:
100             file = line.replace('\\\n', '').strip()
101             if file:
102                 # GCC might list more than one dependency on a single line, in this case
103                 # the dependencies are separated by a space. However, a space might also
104                 # indicate an actual space character in a dependency path, but in this case
105                 # the space character is prefixed by a backslash.
106                 # Temporary replace all '\ ' with a special char that is not used (\a in this
107                 # case) to keep them from being interpreted by 'split' (they will be converted
108                 # back later to a space char)
109                 file = file.replace('\\ ', '\a')
110                 if file.find(" ") == -1:
111                     dependencies.append(file.replace('\a', ' '))
112                 else:
113                     dependencies = dependencies + [f.replace('\a', ' ') for f in file.split(" ")]
114         return dependencies
115
116     def parse_output(self, output):
117         # The warning/error notification is multiline
118         WHERE, WHAT = 0, 1
119         state, file, message = WHERE, None, None
120         for line in output.splitlines():
121             match = self.goanna_parse_line(line)
122             if match is not None:
123                 self.cc_info(
124                     match.group('severity').lower(),
125                     match.group('file'),
126                     match.group('line'),
127                     match.group('message'),
128                     target_name=self.target.name,
129                     toolchain_name=self.name
130                 )
131                 continue
132
133             # Each line should start with the file information: "filepath: ..."
134             # i should point past the file path                          ^
135             # avoid the first column in Windows (C:\)
136             i = line.find(':', 2)
137             if i == -1: continue
138
139             if state == WHERE:
140                 file = line[:i]
141                 message = line[i+1:].strip() + ' '
142                 state = WHAT
143
144             elif state == WHAT:
145                 match = GCC.DIAGNOSTIC_PATTERN.match(line[i+1:])
146                 if match is None:
147                     state = WHERE
148                     continue
149
150                 self.cc_info(
151                     match.group('severity'),
152                     file, match.group('line'),
153                     message + match.group('message')
154                 )
155
156     def archive(self, objects, lib_path):
157         self.default_cmd([self.ar, "rcs", lib_path] + objects)
158
159     def link(self, output, objects, libraries, lib_dirs, mem_map):
160         libs = []
161         for l in libraries:
162             name, _ = splitext(basename(l))
163             libs.append("-l%s" % name[3:])
164         libs.extend(["-l%s" % l for l in self.sys_libs])
165
166         # NOTE: There is a circular dependency between the mbed library and the clib
167         # We could define a set of week symbols to satisfy the clib dependencies in "sys.o",
168         # but if an application uses only clib symbols and not mbed symbols, then the final
169         # image is not correctly retargeted
170         if self.CIRCULAR_DEPENDENCIES:
171             libs.extend(libs)
172
173         self.default_cmd(self.hook.get_cmdline_linker(self.ld + ["-T%s" % mem_map, "-o", output] +
174             objects + ["-L%s" % L for L in lib_dirs] + libs))
175
176     @hook_tool
177     def binary(self, resources, elf, bin):
178         self.default_cmd(self.hook.get_cmdline_binary([self.elf2bin, "-O", "binary", elf, bin]))
179
180
181 class GCC_ARM(GCC):
182     def __init__(self, target, options=None, notify=None, macros=None, silent=False):
183         GCC.__init__(self, target, options, notify, macros, silent, GCC_ARM_PATH)
184
185         # Use latest gcc nanolib
186         self.ld.append("--specs=nano.specs")
187         if target.name in ["LPC1768", "LPC4088", "LPC4088_DM", "LPC4330", "UBLOX_C027", "LPC2368"]:
188             self.ld.extend(["-u _printf_float", "-u _scanf_float"])
189         elif target.name in ["RZ_A1H", "ARCH_MAX", "DISCO_F407VG", "DISCO_F429ZI", "NUCLEO_F401RE", "NUCLEO_F411RE"]:
190             self.ld.extend(["-u_printf_float", "-u_scanf_float"])
191
192         self.sys_libs.append("nosys")
193
194
195 class GCC_CR(GCC):
196     def __init__(self, target, options=None, notify=None, macros=None, silent=False):
197         GCC.__init__(self, target, options, notify, macros, silent, GCC_CR_PATH)
198
199         additional_compiler_flags = [
200             "-D__NEWLIB__", "-D__CODE_RED", "-D__USE_CMSIS", "-DCPP_USE_HEAP",
201         ]
202         self.cc += additional_compiler_flags
203         self.cppc += additional_compiler_flags
204
205         # Use latest gcc nanolib
206         self.ld.append("--specs=nano.specs")
207         if target.name in ["LPC1768", "LPC4088", "LPC4088_DM", "LPC4330", "UBLOX_C027", "LPC2368"]:
208             self.ld.extend(["-u _printf_float", "-u _scanf_float"])
209         self.ld += ["-nostdlib"]
210
211
212 class GCC_CS(GCC):
213     def __init__(self, target, options=None, notify=None, macros=None, silent=False):
214         GCC.__init__(self, target, options, notify, macros, silent, GCC_CS_PATH)
215
216
217 class GCC_CW(GCC):
218     ARCH_LIB = {
219         "Cortex-M0+": "armv6-m",
220     }
221
222     def __init__(self, target, options=None, notify=None, macros=None, silent=False):
223         GCC.__init__(self, target, options, notify, macros, silent, CW_GCC_PATH)
224
225
226 class GCC_CW_EWL(GCC_CW):
227     def __init__(self, target, options=None, notify=None, macros=None, silent=False):
228         GCC_CW.__init__(self, target, options, notify, macros, silent)
229
230         # Compiler
231         common = [
232             '-mfloat-abi=soft',
233             '-nostdinc', '-I%s' % join(CW_EWL_PATH, "EWL_C", "include"),
234         ]
235         self.cc += common + [
236             '-include', join(CW_EWL_PATH, "EWL_C", "include", 'lib_c99.prefix')
237         ]
238         self.cppc += common + [
239             '-nostdinc++', '-I%s' % join(CW_EWL_PATH, "EWL_C++", "include"),
240             '-include', join(CW_EWL_PATH, "EWL_C++", "include", 'lib_ewl_c++.prefix')
241         ]
242
243         # Linker
244         self.sys_libs = []
245         self.CIRCULAR_DEPENDENCIES = False
246         self.ld = [join(CW_GCC_PATH, "arm-none-eabi-g++"),
247             "-Xlinker --gc-sections",
248             "-L%s" % join(CW_EWL_PATH, "lib", GCC_CW.ARCH_LIB[target.core]),
249             "-n", "-specs=ewl_c++.specs", "-mfloat-abi=soft",
250             "-Xlinker --undefined=__pformatter_", "-Xlinker --defsym=__pformatter=__pformatter_",
251             "-Xlinker --undefined=__sformatter", "-Xlinker --defsym=__sformatter=__sformatter",
252         ] + self.cpu
253
254
255 class GCC_CW_NEWLIB(GCC_CW):
256     def __init__(self, target, options=None, notify=None, macros=None, silent=False):
257         GCC_CW.__init__(self, target, options, notify, macros, silent)