]> git.gir.st - tmk_keyboard.git/blob - tool/mbed/mbed-sdk/workspace_tools/toolchains/gcc.py
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[tmk_keyboard.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)
Imprint / Impressum