mirror of https://github.com/ARMmbed/mbed-os.git
Initial toolchain class for ARMC6
While ARMC6 does use the same linker (armlink) as ARM Compiler 5, it is not compatible. The reason for this incompatibility are twofold: * armlink may invoke the C preprocessor by adding a shebang (`#!`) to the top of their input files. * ARMC6 and ARMC5 differ in how you invoke the preprocessor: * ARMC5: `#! armcc -E` * ARMC6: `#! armclang -E` This forces the tools to rewrite the shebang if it's wrong. This does not yet handle dependencies properlypull/4949/head
parent
cab660d980
commit
98b4768434
|
@ -769,8 +769,7 @@ class MemapParser(object):
|
||||||
# Common to all toolchains: first search for objects in BUILD
|
# Common to all toolchains: first search for objects in BUILD
|
||||||
self.list_dir_obj(os.path.abspath(mapfile))
|
self.list_dir_obj(os.path.abspath(mapfile))
|
||||||
|
|
||||||
if toolchain == "ARM" or toolchain == "ARM_STD" or\
|
if toolchain in ("ARM", "ARM_STD", "ARM_MICRO", "ARMC6"):
|
||||||
toolchain == "ARM_MICRO":
|
|
||||||
self.parse_map_file_armcc(file_input)
|
self.parse_map_file_armcc(file_input)
|
||||||
elif toolchain == "GCC_ARM" or toolchain == "GCC_CR":
|
elif toolchain == "GCC_ARM" or toolchain == "GCC_CR":
|
||||||
self.parse_map_file_gcc(file_input)
|
self.parse_map_file_gcc(file_input)
|
||||||
|
|
|
@ -15,6 +15,15 @@
|
||||||
"-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit",
|
"-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit",
|
||||||
"-Wl,-n"]
|
"-Wl,-n"]
|
||||||
},
|
},
|
||||||
|
"ARMC6": {
|
||||||
|
"common": ["-c", "--target=arm-arm-none-eabi", "-mthumb", "-g", "-O0",
|
||||||
|
"-Wno-armcc-pragma-push-pop", "-Wno-armcc-pragma-anon-unions"],
|
||||||
|
"asm": [],
|
||||||
|
"c": ["-D__ASSERT_MSG", "-std=gnu99"],
|
||||||
|
"cxx": ["-fno-rtti", "-std=gnu++98"],
|
||||||
|
"ld": ["--verbose", "--remove", "--legacyalign", "--no_strict_wchar_size",
|
||||||
|
"--no_strict_enum_size"]
|
||||||
|
},
|
||||||
"ARM": {
|
"ARM": {
|
||||||
"common": ["-c", "--gnu", "-Otime", "--split_sections",
|
"common": ["-c", "--gnu", "-Otime", "--split_sections",
|
||||||
"--apcs=interwork", "--brief_diagnostics", "--restrict",
|
"--apcs=interwork", "--brief_diagnostics", "--restrict",
|
||||||
|
|
|
@ -14,6 +14,14 @@
|
||||||
"-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit",
|
"-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit",
|
||||||
"-Wl,-n"]
|
"-Wl,-n"]
|
||||||
},
|
},
|
||||||
|
"ARMC6": {
|
||||||
|
"common": ["-c", "--target=arm-arm-none-eabi", "-mthumb", "-Os",
|
||||||
|
"-Wno-armcc-pragma-push-pop", "-Wno-armcc-pragma-anon-unions"],
|
||||||
|
"asm": [],
|
||||||
|
"c": ["-D__ASSERT_MSG", "-std=gnu99"],
|
||||||
|
"cxx": ["-fno-rtti", "-std=gnu++98"],
|
||||||
|
"ld": ["--legacyalign", "--no_strict_wchar_size", "--no_strict_enum_size"]
|
||||||
|
},
|
||||||
"ARM": {
|
"ARM": {
|
||||||
"common": ["-c", "--gnu", "-Otime", "--split_sections",
|
"common": ["-c", "--gnu", "-Otime", "--split_sections",
|
||||||
"--apcs=interwork", "--brief_diagnostics", "--restrict",
|
"--apcs=interwork", "--brief_diagnostics", "--restrict",
|
||||||
|
|
|
@ -14,6 +14,14 @@
|
||||||
"-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit",
|
"-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit",
|
||||||
"-Wl,-n"]
|
"-Wl,-n"]
|
||||||
},
|
},
|
||||||
|
"ARMC6": {
|
||||||
|
"common": ["-c", "--target=arm-arm-none-eabi", "-mthumb", "-Oz",
|
||||||
|
"-Wno-armcc-pragma-push-pop", "-Wno-armcc-pragma-anon-unions"],
|
||||||
|
"asm": [],
|
||||||
|
"c": ["-D__ASSERT_MSG", "-std=gnu99"],
|
||||||
|
"cxx": ["-fno-rtti", "-std=gnu++98"],
|
||||||
|
"ld": ["--legacyalign", "--no_strict_wchar_size", "--no_strict_enum_size"]
|
||||||
|
},
|
||||||
"ARM": {
|
"ARM": {
|
||||||
"common": ["-c", "--gnu", "-Ospace", "--split_sections",
|
"common": ["-c", "--gnu", "-Ospace", "--split_sections",
|
||||||
"--apcs=interwork", "--brief_diagnostics", "--restrict",
|
"--apcs=interwork", "--brief_diagnostics", "--restrict",
|
||||||
|
|
|
@ -30,6 +30,9 @@ BUILD_DIR = abspath(join(ROOT, "BUILD"))
|
||||||
# ARM Compiler 5
|
# ARM Compiler 5
|
||||||
ARM_PATH = ""
|
ARM_PATH = ""
|
||||||
|
|
||||||
|
# ARM Compiler 6
|
||||||
|
ARMC6_PATH = ""
|
||||||
|
|
||||||
# GCC ARM
|
# GCC ARM
|
||||||
GCC_ARM_PATH = ""
|
GCC_ARM_PATH = ""
|
||||||
|
|
||||||
|
@ -70,7 +73,8 @@ except ImportError:
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# User Settings (env vars)
|
# User Settings (env vars)
|
||||||
##############################################################################
|
##############################################################################
|
||||||
_ENV_PATHS = ['ARM_PATH', 'GCC_ARM_PATH', 'GCC_CR_PATH', 'IAR_PATH']
|
_ENV_PATHS = ['ARM_PATH', 'GCC_ARM_PATH', 'GCC_CR_PATH', 'IAR_PATH',
|
||||||
|
'ARMC6_PATH']
|
||||||
|
|
||||||
for _n in _ENV_PATHS:
|
for _n in _ENV_PATHS:
|
||||||
if getenv('MBED_'+_n):
|
if getenv('MBED_'+_n):
|
||||||
|
|
|
@ -302,11 +302,13 @@ LEGACY_IGNORE_DIRS = set([
|
||||||
'LPC11U24', 'LPC1768', 'LPC2368', 'LPC4088', 'LPC812', 'KL25Z',
|
'LPC11U24', 'LPC1768', 'LPC2368', 'LPC4088', 'LPC812', 'KL25Z',
|
||||||
'ARM', 'uARM', 'IAR',
|
'ARM', 'uARM', 'IAR',
|
||||||
'GCC_ARM', 'GCC_CS', 'GCC_CR', 'GCC_CW', 'GCC_CW_EWL', 'GCC_CW_NEWLIB',
|
'GCC_ARM', 'GCC_CS', 'GCC_CR', 'GCC_CW', 'GCC_CW_EWL', 'GCC_CW_NEWLIB',
|
||||||
|
'ARMC6'
|
||||||
])
|
])
|
||||||
LEGACY_TOOLCHAIN_NAMES = {
|
LEGACY_TOOLCHAIN_NAMES = {
|
||||||
'ARM_STD':'ARM', 'ARM_MICRO': 'uARM',
|
'ARM_STD':'ARM', 'ARM_MICRO': 'uARM',
|
||||||
'GCC_ARM': 'GCC_ARM', 'GCC_CR': 'GCC_CR',
|
'GCC_ARM': 'GCC_ARM', 'GCC_CR': 'GCC_CR',
|
||||||
'IAR': 'IAR',
|
'IAR': 'IAR',
|
||||||
|
'ARMC6': 'ARMC6',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1531,24 +1533,24 @@ class mbedToolchain:
|
||||||
to_ret.update(self.config.report)
|
to_ret.update(self.config.report)
|
||||||
return to_ret
|
return to_ret
|
||||||
|
|
||||||
from tools.settings import ARM_PATH
|
from tools.settings import ARM_PATH, ARMC6_PATH, GCC_ARM_PATH, IAR_PATH
|
||||||
from tools.settings import GCC_ARM_PATH
|
|
||||||
from tools.settings import IAR_PATH
|
|
||||||
|
|
||||||
TOOLCHAIN_PATHS = {
|
TOOLCHAIN_PATHS = {
|
||||||
'ARM': ARM_PATH,
|
'ARM': ARM_PATH,
|
||||||
'uARM': ARM_PATH,
|
'uARM': ARM_PATH,
|
||||||
|
'ARMC6': ARMC6_PATH,
|
||||||
'GCC_ARM': GCC_ARM_PATH,
|
'GCC_ARM': GCC_ARM_PATH,
|
||||||
'IAR': IAR_PATH
|
'IAR': IAR_PATH
|
||||||
}
|
}
|
||||||
|
|
||||||
from tools.toolchains.arm import ARM_STD, ARM_MICRO
|
from tools.toolchains.arm import ARM_STD, ARM_MICRO, ARMC6
|
||||||
from tools.toolchains.gcc import GCC_ARM
|
from tools.toolchains.gcc import GCC_ARM
|
||||||
from tools.toolchains.iar import IAR
|
from tools.toolchains.iar import IAR
|
||||||
|
|
||||||
TOOLCHAIN_CLASSES = {
|
TOOLCHAIN_CLASSES = {
|
||||||
'ARM': ARM_STD,
|
'ARM': ARM_STD,
|
||||||
'uARM': ARM_MICRO,
|
'uARM': ARM_MICRO,
|
||||||
|
'ARMC6': ARMC6,
|
||||||
'GCC_ARM': GCC_ARM,
|
'GCC_ARM': GCC_ARM,
|
||||||
'IAR': IAR
|
'IAR': IAR
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
"""
|
"""
|
||||||
import re
|
import re
|
||||||
|
from copy import copy
|
||||||
from os.path import join, dirname, splitext, basename, exists
|
from os.path import join, dirname, splitext, basename, exists
|
||||||
from os import makedirs, write
|
from os import makedirs, write
|
||||||
from tempfile import mkstemp
|
from tempfile import mkstemp
|
||||||
|
@ -31,6 +32,7 @@ class ARM(mbedToolchain):
|
||||||
DIAGNOSTIC_PATTERN = re.compile('"(?P<file>[^"]+)", line (?P<line>\d+)( \(column (?P<column>\d+)\)|): (?P<severity>Warning|Error|Fatal error): (?P<message>.+)')
|
DIAGNOSTIC_PATTERN = re.compile('"(?P<file>[^"]+)", line (?P<line>\d+)( \(column (?P<column>\d+)\)|): (?P<severity>Warning|Error|Fatal error): (?P<message>.+)')
|
||||||
INDEX_PATTERN = re.compile('(?P<col>\s*)\^')
|
INDEX_PATTERN = re.compile('(?P<col>\s*)\^')
|
||||||
DEP_PATTERN = re.compile('\S+:\s(?P<file>.+)\n')
|
DEP_PATTERN = re.compile('\S+:\s(?P<file>.+)\n')
|
||||||
|
SHEBANG = "#! armcc -E"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def check_executable():
|
def check_executable():
|
||||||
|
@ -175,32 +177,52 @@ class ARM(mbedToolchain):
|
||||||
def compile_cpp(self, source, object, includes):
|
def compile_cpp(self, source, object, includes):
|
||||||
return self.compile(self.cppc, source, object, includes)
|
return self.compile(self.cppc, source, object, includes)
|
||||||
|
|
||||||
@hook_tool
|
def correct_scatter_shebang(self, scatter_file):
|
||||||
def link(self, output, objects, libraries, lib_dirs, mem_map):
|
"""Correct the shebang at the top of a scatter file.
|
||||||
map_file = splitext(output)[0] + ".map"
|
|
||||||
if len(lib_dirs):
|
Positional arguments:
|
||||||
args = ["-o", output, "--userlibpath", ",".join(lib_dirs), "--info=totals", "--map", "--list=%s" % map_file]
|
scatter_file -- the scatter file to correct
|
||||||
|
|
||||||
|
Return:
|
||||||
|
The location of the correct scatter file
|
||||||
|
|
||||||
|
Side Effects:
|
||||||
|
This method MAY write a new scatter file to disk
|
||||||
|
"""
|
||||||
|
with open(scatter_file, "rb") as input:
|
||||||
|
lines = input.readlines()
|
||||||
|
if lines[0].startswith(self.SHEBANG):
|
||||||
|
return scatter_file
|
||||||
else:
|
else:
|
||||||
|
new_scatter = join(self.build_dir, ".link_script.sct")
|
||||||
|
if self.need_update(new_scatter, [scatter_file]):
|
||||||
|
with open(new_scatter, "wb") as out:
|
||||||
|
out.write(self.SHEBANG)
|
||||||
|
out.write("\n")
|
||||||
|
out.write("".join(lines[1:]))
|
||||||
|
return new_scatter
|
||||||
|
|
||||||
|
@hook_tool
|
||||||
|
def link(self, output, objects, libraries, lib_dirs, scatter_file):
|
||||||
|
base, _ = splitext(output)
|
||||||
|
map_file = base + ".map"
|
||||||
args = ["-o", output, "--info=totals", "--map", "--list=%s" % map_file]
|
args = ["-o", output, "--info=totals", "--map", "--list=%s" % map_file]
|
||||||
|
args.extend(objects)
|
||||||
|
args.extend(libraries)
|
||||||
|
if lib_dirs:
|
||||||
|
args.extend(["--userlibpath", ",".join(lib_dirs)])
|
||||||
|
if scatter_file:
|
||||||
|
new_scatter = self.correct_scatter_shebang(scatter_file)
|
||||||
|
args.extend(["--scatter", new_scatter])
|
||||||
|
|
||||||
args.extend(self.flags['ld'])
|
cmd_pre = self.ld + args
|
||||||
|
cmd = self.hook.get_cmdline_linker(cmd_pre)
|
||||||
if mem_map:
|
|
||||||
args.extend(["--scatter", mem_map])
|
|
||||||
|
|
||||||
# Build linker command
|
|
||||||
cmd = self.ld + args + objects + libraries + self.sys_libs
|
|
||||||
|
|
||||||
# Call cmdline hook
|
|
||||||
cmd = self.hook.get_cmdline_linker(cmd)
|
|
||||||
|
|
||||||
if self.RESPONSE_FILES:
|
if self.RESPONSE_FILES:
|
||||||
# Split link command to linker executable + response file
|
|
||||||
cmd_linker = cmd[0]
|
cmd_linker = cmd[0]
|
||||||
link_files = self.get_link_file(cmd[1:])
|
link_files = self.get_link_file(cmd[1:])
|
||||||
cmd = [cmd_linker, '--via', link_files]
|
cmd = [cmd_linker, '--via', link_files]
|
||||||
|
|
||||||
# Exec command
|
|
||||||
self.cc_verbose("Link: %s" % ' '.join(cmd))
|
self.cc_verbose("Link: %s" % ' '.join(cmd))
|
||||||
self.default_cmd(cmd)
|
self.default_cmd(cmd)
|
||||||
|
|
||||||
|
@ -210,21 +232,14 @@ class ARM(mbedToolchain):
|
||||||
param = ['--via', self.get_arch_file(objects)]
|
param = ['--via', self.get_arch_file(objects)]
|
||||||
else:
|
else:
|
||||||
param = objects
|
param = objects
|
||||||
|
|
||||||
# Exec command
|
|
||||||
self.default_cmd([self.ar, '-r', lib_path] + param)
|
self.default_cmd([self.ar, '-r', lib_path] + param)
|
||||||
|
|
||||||
@hook_tool
|
@hook_tool
|
||||||
def binary(self, resources, elf, bin):
|
def binary(self, resources, elf, bin):
|
||||||
_, fmt = splitext(bin)
|
_, fmt = splitext(bin)
|
||||||
bin_arg = {".bin": "--bin", ".hex": "--i32"}[fmt]
|
bin_arg = {".bin": "--bin", ".hex": "--i32"}[fmt]
|
||||||
# Build binary command
|
|
||||||
cmd = [self.elf2bin, bin_arg, '-o', bin, elf]
|
cmd = [self.elf2bin, bin_arg, '-o', bin, elf]
|
||||||
|
|
||||||
# Call cmdline hook
|
|
||||||
cmd = self.hook.get_cmdline_binary(cmd)
|
cmd = self.hook.get_cmdline_binary(cmd)
|
||||||
|
|
||||||
# Exec command
|
|
||||||
self.cc_verbose("FromELF: %s" % ' '.join(cmd))
|
self.cc_verbose("FromELF: %s" % ' '.join(cmd))
|
||||||
self.default_cmd(cmd)
|
self.default_cmd(cmd)
|
||||||
|
|
||||||
|
@ -248,6 +263,89 @@ class ARM(mbedToolchain):
|
||||||
class ARM_STD(ARM):
|
class ARM_STD(ARM):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ARM_MICRO(ARM):
|
class ARM_MICRO(ARM):
|
||||||
PATCHED_LIBRARY = False
|
PATCHED_LIBRARY = False
|
||||||
|
|
||||||
|
class ARMC6(ARM_STD):
|
||||||
|
SHEBANG = "#! armclang -E --target=arm-arm-none-eabi -x c"
|
||||||
|
@staticmethod
|
||||||
|
def check_executable():
|
||||||
|
return mbedToolchain.generic_check_executable("ARMC6", "armclang", 1)
|
||||||
|
|
||||||
|
def __init__(self, target, *args, **kwargs):
|
||||||
|
mbedToolchain.__init__(self, target, *args, **kwargs)
|
||||||
|
|
||||||
|
if target.core.lower().endswith("fd"):
|
||||||
|
self.flags['common'].append("-mcpu=%s" % target.core.lower()[:-2])
|
||||||
|
self.flags['ld'].append("--cpu=%s" % target.core.lower()[:-2])
|
||||||
|
elif target.core.lower().endswith("f"):
|
||||||
|
self.flags['common'].append("-mcpu=%s" % target.core.lower()[:-1])
|
||||||
|
self.flags['ld'].append("--cpu=%s" % target.core.lower()[:-1])
|
||||||
|
else:
|
||||||
|
self.flags['common'].append("-mcpu=%s" % target.core.lower())
|
||||||
|
self.flags['ld'].append("--cpu=%s" % target.core.lower())
|
||||||
|
|
||||||
|
if target.core == "Cortex-M4F":
|
||||||
|
self.flags['common'].append("-mfpu=fpv4-sp-d16")
|
||||||
|
self.flags['common'].append("-mfloat-abi=hard")
|
||||||
|
elif target.core == "Cortex-M7F":
|
||||||
|
self.flags['common'].append("-mfpu=fpv5-sp-d16")
|
||||||
|
self.flags['common'].append("-mfloat-abi=softfp")
|
||||||
|
elif target.core == "Cortex-M7FD":
|
||||||
|
self.flags['common'].append("-mfpu=fpv5-d16")
|
||||||
|
self.flags['common'].append("-mfloat-abi=softfp")
|
||||||
|
|
||||||
|
asm_cpu = {
|
||||||
|
"Cortex-M0+": "Cortex-M0",
|
||||||
|
"Cortex-M4F": "Cortex-M4.fp",
|
||||||
|
"Cortex-M7F": "Cortex-M7.fp.sp",
|
||||||
|
"Cortex-M7FD": "Cortex-M7.fp.dp"}.get(target.core, target.core)
|
||||||
|
|
||||||
|
self.flags['asm'].append("--cpu=%s" % asm_cpu)
|
||||||
|
|
||||||
|
self.cc = ([join(TOOLCHAIN_PATHS["ARMC6"], "armclang")] +
|
||||||
|
self.flags['common'] + self.flags['c'])
|
||||||
|
self.cppc = ([join(TOOLCHAIN_PATHS["ARMC6"], "armclang")] +
|
||||||
|
self.flags['common'] + self.flags['cxx'])
|
||||||
|
self.asm = [join(TOOLCHAIN_PATHS["ARMC6"], "armasm")] + self.flags['asm']
|
||||||
|
self.ld = [join(TOOLCHAIN_PATHS["ARMC6"], "armlink")] + self.flags['ld']
|
||||||
|
self.ar = [join(TOOLCHAIN_PATHS["ARMC6"], "armar")]
|
||||||
|
self.elf2bin = join(TOOLCHAIN_PATHS["ARMC6"], "fromelf")
|
||||||
|
|
||||||
|
|
||||||
|
def parse_dependencies(self, dep_path):
|
||||||
|
return []
|
||||||
|
|
||||||
|
def parse_output(self, output):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_config_option(self, config_header):
|
||||||
|
return ["-include", config_header]
|
||||||
|
|
||||||
|
def get_compile_options(self, defines, includes, for_asm=False):
|
||||||
|
opts = ['-D%s' % d for d in defines]
|
||||||
|
opts.extend(["-I%s" % i for i in includes])
|
||||||
|
if for_asm:
|
||||||
|
return ["--cpreproc",
|
||||||
|
"--cpreproc_opts=%s" % ",".join(self.flags['common'] + opts)]
|
||||||
|
else:
|
||||||
|
config_header = self.get_config_header()
|
||||||
|
if config_header:
|
||||||
|
opts.extend(self.get_config_option(config_header))
|
||||||
|
return opts
|
||||||
|
|
||||||
|
@hook_tool
|
||||||
|
def assemble(self, source, object, includes):
|
||||||
|
cmd_pre = copy(self.asm)
|
||||||
|
cmd_pre.extend(self.get_compile_options(
|
||||||
|
self.get_symbols(True), includes, for_asm=True))
|
||||||
|
cmd_pre.extend(["-o", object, source])
|
||||||
|
return [self.hook.get_cmdline_assembler(cmd_pre)]
|
||||||
|
|
||||||
|
@hook_tool
|
||||||
|
def compile(self, cc, source, object, includes):
|
||||||
|
cmd = copy(cc)
|
||||||
|
cmd.extend(self.get_compile_options(self.get_symbols(), includes))
|
||||||
|
cmd.extend(["-o", object, source])
|
||||||
|
cmd = self.hook.get_cmdline_compiler(cmd)
|
||||||
|
return [cmd]
|
||||||
|
|
Loading…
Reference in New Issue