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
 | 
			
		||||
                self.list_dir_obj(os.path.abspath(mapfile))
 | 
			
		||||
 | 
			
		||||
                if toolchain == "ARM" or toolchain == "ARM_STD" or\
 | 
			
		||||
                  toolchain == "ARM_MICRO":
 | 
			
		||||
                if toolchain in ("ARM", "ARM_STD", "ARM_MICRO", "ARMC6"):
 | 
			
		||||
                    self.parse_map_file_armcc(file_input)
 | 
			
		||||
                elif toolchain == "GCC_ARM" or toolchain == "GCC_CR":
 | 
			
		||||
                    self.parse_map_file_gcc(file_input)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,6 +15,15 @@
 | 
			
		|||
               "-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit",
 | 
			
		||||
               "-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": {
 | 
			
		||||
        "common": ["-c", "--gnu", "-Otime", "--split_sections",
 | 
			
		||||
                   "--apcs=interwork", "--brief_diagnostics", "--restrict",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,6 +14,14 @@
 | 
			
		|||
               "-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit",
 | 
			
		||||
               "-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": {
 | 
			
		||||
        "common": ["-c", "--gnu", "-Otime", "--split_sections",
 | 
			
		||||
                   "--apcs=interwork", "--brief_diagnostics", "--restrict",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,6 +14,14 @@
 | 
			
		|||
               "-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit",
 | 
			
		||||
               "-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": {
 | 
			
		||||
        "common": ["-c", "--gnu", "-Ospace", "--split_sections",
 | 
			
		||||
                   "--apcs=interwork", "--brief_diagnostics", "--restrict",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,6 +30,9 @@ BUILD_DIR = abspath(join(ROOT, "BUILD"))
 | 
			
		|||
# ARM Compiler 5
 | 
			
		||||
ARM_PATH = ""
 | 
			
		||||
 | 
			
		||||
# ARM Compiler 6
 | 
			
		||||
ARMC6_PATH = ""
 | 
			
		||||
 | 
			
		||||
# GCC ARM
 | 
			
		||||
GCC_ARM_PATH = ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -70,7 +73,8 @@ except ImportError:
 | 
			
		|||
##############################################################################
 | 
			
		||||
# 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:
 | 
			
		||||
    if getenv('MBED_'+_n):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -302,11 +302,13 @@ LEGACY_IGNORE_DIRS = set([
 | 
			
		|||
    'LPC11U24', 'LPC1768', 'LPC2368', 'LPC4088', 'LPC812', 'KL25Z',
 | 
			
		||||
    'ARM', 'uARM', 'IAR',
 | 
			
		||||
    'GCC_ARM', 'GCC_CS', 'GCC_CR', 'GCC_CW', 'GCC_CW_EWL', 'GCC_CW_NEWLIB',
 | 
			
		||||
    'ARMC6'
 | 
			
		||||
])
 | 
			
		||||
LEGACY_TOOLCHAIN_NAMES = {
 | 
			
		||||
    'ARM_STD':'ARM', 'ARM_MICRO': 'uARM',
 | 
			
		||||
    'GCC_ARM': 'GCC_ARM', 'GCC_CR': 'GCC_CR',
 | 
			
		||||
    'IAR': 'IAR',
 | 
			
		||||
    'ARMC6': 'ARMC6',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1531,24 +1533,24 @@ class mbedToolchain:
 | 
			
		|||
        to_ret.update(self.config.report)
 | 
			
		||||
        return to_ret
 | 
			
		||||
 | 
			
		||||
from tools.settings import ARM_PATH
 | 
			
		||||
from tools.settings import GCC_ARM_PATH
 | 
			
		||||
from tools.settings import IAR_PATH
 | 
			
		||||
from tools.settings import ARM_PATH, ARMC6_PATH, GCC_ARM_PATH, IAR_PATH
 | 
			
		||||
 | 
			
		||||
TOOLCHAIN_PATHS = {
 | 
			
		||||
    'ARM': ARM_PATH,
 | 
			
		||||
    'uARM': ARM_PATH,
 | 
			
		||||
    'ARMC6': ARMC6_PATH,
 | 
			
		||||
    'GCC_ARM': GCC_ARM_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.iar import IAR
 | 
			
		||||
 | 
			
		||||
TOOLCHAIN_CLASSES = {
 | 
			
		||||
    'ARM': ARM_STD,
 | 
			
		||||
    'uARM': ARM_MICRO,
 | 
			
		||||
    'ARMC6': ARMC6,
 | 
			
		||||
    'GCC_ARM': GCC_ARM,
 | 
			
		||||
    'IAR': IAR
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,6 +15,7 @@ See the License for the specific language governing permissions and
 | 
			
		|||
limitations under the License.
 | 
			
		||||
"""
 | 
			
		||||
import re
 | 
			
		||||
from copy import copy
 | 
			
		||||
from os.path import join, dirname, splitext, basename, exists
 | 
			
		||||
from os import makedirs, write
 | 
			
		||||
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>.+)')
 | 
			
		||||
    INDEX_PATTERN  = re.compile('(?P<col>\s*)\^')
 | 
			
		||||
    DEP_PATTERN = re.compile('\S+:\s(?P<file>.+)\n')
 | 
			
		||||
    SHEBANG = "#! armcc -E"
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def check_executable():
 | 
			
		||||
| 
						 | 
				
			
			@ -175,32 +177,52 @@ class ARM(mbedToolchain):
 | 
			
		|||
    def compile_cpp(self, source, object, includes):
 | 
			
		||||
        return self.compile(self.cppc, source, object, includes)
 | 
			
		||||
 | 
			
		||||
    def correct_scatter_shebang(self, scatter_file):
 | 
			
		||||
        """Correct the shebang at the top of a scatter file.
 | 
			
		||||
 | 
			
		||||
        Positional arguments:
 | 
			
		||||
        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:
 | 
			
		||||
                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, mem_map):
 | 
			
		||||
        map_file = splitext(output)[0] + ".map"
 | 
			
		||||
        if len(lib_dirs):
 | 
			
		||||
            args = ["-o", output, "--userlibpath", ",".join(lib_dirs), "--info=totals", "--map", "--list=%s" % map_file]
 | 
			
		||||
        else:
 | 
			
		||||
            args = ["-o", output, "--info=totals", "--map", "--list=%s" % map_file]
 | 
			
		||||
    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.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'])
 | 
			
		||||
 | 
			
		||||
        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)
 | 
			
		||||
        cmd_pre = self.ld + args
 | 
			
		||||
        cmd = self.hook.get_cmdline_linker(cmd_pre)
 | 
			
		||||
 | 
			
		||||
        if self.RESPONSE_FILES:
 | 
			
		||||
            # Split link command to linker executable + response file
 | 
			
		||||
            cmd_linker = cmd[0]
 | 
			
		||||
            link_files = self.get_link_file(cmd[1:])
 | 
			
		||||
            cmd = [cmd_linker, '--via', link_files]
 | 
			
		||||
 | 
			
		||||
        # Exec command
 | 
			
		||||
        self.cc_verbose("Link: %s" % ' '.join(cmd))
 | 
			
		||||
        self.default_cmd(cmd)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -210,21 +232,14 @@ class ARM(mbedToolchain):
 | 
			
		|||
            param = ['--via', self.get_arch_file(objects)]
 | 
			
		||||
        else:
 | 
			
		||||
            param = objects
 | 
			
		||||
 | 
			
		||||
        # Exec command
 | 
			
		||||
        self.default_cmd([self.ar, '-r', lib_path] + param)
 | 
			
		||||
 | 
			
		||||
    @hook_tool
 | 
			
		||||
    def binary(self, resources, elf, bin):
 | 
			
		||||
        _, fmt = splitext(bin)
 | 
			
		||||
        bin_arg = {".bin": "--bin", ".hex": "--i32"}[fmt]
 | 
			
		||||
        # Build binary command
 | 
			
		||||
        cmd = [self.elf2bin, bin_arg, '-o', bin, elf]
 | 
			
		||||
 | 
			
		||||
        # Call cmdline hook
 | 
			
		||||
        cmd = self.hook.get_cmdline_binary(cmd)
 | 
			
		||||
 | 
			
		||||
        # Exec command
 | 
			
		||||
        self.cc_verbose("FromELF: %s" % ' '.join(cmd))
 | 
			
		||||
        self.default_cmd(cmd)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -248,6 +263,89 @@ class ARM(mbedToolchain):
 | 
			
		|||
class ARM_STD(ARM):
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ARM_MICRO(ARM):
 | 
			
		||||
    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