Keyboard firmwares for Atmel AVR and Cortex-M
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

gcc.py 11KB

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