Color Oled(SSD1331) connect to STMicroelectronics Nucleo-F466

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Wed Oct 10 00:33:53 2018 +0000
Revision:
0:8fdf9a60065b
how to make mbed librry

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kadonotakashi 0:8fdf9a60065b 1 """
kadonotakashi 0:8fdf9a60065b 2 mbed SDK
kadonotakashi 0:8fdf9a60065b 3 Copyright (c) 2011-2013 ARM Limited
kadonotakashi 0:8fdf9a60065b 4
kadonotakashi 0:8fdf9a60065b 5 Licensed under the Apache License, Version 2.0 (the "License");
kadonotakashi 0:8fdf9a60065b 6 you may not use this file except in compliance with the License.
kadonotakashi 0:8fdf9a60065b 7 You may obtain a copy of the License at
kadonotakashi 0:8fdf9a60065b 8
kadonotakashi 0:8fdf9a60065b 9 http://www.apache.org/licenses/LICENSE-2.0
kadonotakashi 0:8fdf9a60065b 10
kadonotakashi 0:8fdf9a60065b 11 Unless required by applicable law or agreed to in writing, software
kadonotakashi 0:8fdf9a60065b 12 distributed under the License is distributed on an "AS IS" BASIS,
kadonotakashi 0:8fdf9a60065b 13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kadonotakashi 0:8fdf9a60065b 14 See the License for the specific language governing permissions and
kadonotakashi 0:8fdf9a60065b 15 limitations under the License.
kadonotakashi 0:8fdf9a60065b 16 """
kadonotakashi 0:8fdf9a60065b 17 from __future__ import print_function, division, absolute_import
kadonotakashi 0:8fdf9a60065b 18
kadonotakashi 0:8fdf9a60065b 19 import re
kadonotakashi 0:8fdf9a60065b 20 import sys
kadonotakashi 0:8fdf9a60065b 21 import json
kadonotakashi 0:8fdf9a60065b 22 from os import stat, walk, getcwd, sep, remove
kadonotakashi 0:8fdf9a60065b 23 from copy import copy
kadonotakashi 0:8fdf9a60065b 24 from time import time, sleep
kadonotakashi 0:8fdf9a60065b 25 from shutil import copyfile
kadonotakashi 0:8fdf9a60065b 26 from os.path import (join, splitext, exists, relpath, dirname, basename, split,
kadonotakashi 0:8fdf9a60065b 27 abspath, isfile, isdir, normcase)
kadonotakashi 0:8fdf9a60065b 28 from inspect import getmro
kadonotakashi 0:8fdf9a60065b 29 from copy import deepcopy
kadonotakashi 0:8fdf9a60065b 30 from collections import namedtuple
kadonotakashi 0:8fdf9a60065b 31 from abc import ABCMeta, abstractmethod
kadonotakashi 0:8fdf9a60065b 32 from distutils.spawn import find_executable
kadonotakashi 0:8fdf9a60065b 33 from multiprocessing import Pool, cpu_count
kadonotakashi 0:8fdf9a60065b 34 from hashlib import md5
kadonotakashi 0:8fdf9a60065b 35
kadonotakashi 0:8fdf9a60065b 36 from ..utils import (run_cmd, mkdir, rel_path, ToolException,
kadonotakashi 0:8fdf9a60065b 37 NotSupportedException, split_path, compile_worker)
kadonotakashi 0:8fdf9a60065b 38 from ..settings import MBED_ORG_USER, PRINT_COMPILER_OUTPUT_AS_LINK
kadonotakashi 0:8fdf9a60065b 39 from .. import hooks
kadonotakashi 0:8fdf9a60065b 40 from ..notifier.term import TerminalNotifier
kadonotakashi 0:8fdf9a60065b 41 from ..resources import FileType
kadonotakashi 0:8fdf9a60065b 42 from ..memap import MemapParser
kadonotakashi 0:8fdf9a60065b 43 from ..config import ConfigException
kadonotakashi 0:8fdf9a60065b 44
kadonotakashi 0:8fdf9a60065b 45
kadonotakashi 0:8fdf9a60065b 46 #Disables multiprocessing if set to higher number than the host machine CPUs
kadonotakashi 0:8fdf9a60065b 47 CPU_COUNT_MIN = 1
kadonotakashi 0:8fdf9a60065b 48 CPU_COEF = 1
kadonotakashi 0:8fdf9a60065b 49
kadonotakashi 0:8fdf9a60065b 50 class mbedToolchain:
kadonotakashi 0:8fdf9a60065b 51 # Verbose logging
kadonotakashi 0:8fdf9a60065b 52 VERBOSE = True
kadonotakashi 0:8fdf9a60065b 53
kadonotakashi 0:8fdf9a60065b 54 # Compile C files as CPP
kadonotakashi 0:8fdf9a60065b 55 COMPILE_C_AS_CPP = False
kadonotakashi 0:8fdf9a60065b 56
kadonotakashi 0:8fdf9a60065b 57 # Response files for compiling, includes, linking and archiving.
kadonotakashi 0:8fdf9a60065b 58 # Not needed on posix systems where the typical arg limit is 2 megabytes
kadonotakashi 0:8fdf9a60065b 59 RESPONSE_FILES = True
kadonotakashi 0:8fdf9a60065b 60
kadonotakashi 0:8fdf9a60065b 61 CORTEX_SYMBOLS = {
kadonotakashi 0:8fdf9a60065b 62 "Cortex-M0" : ["__CORTEX_M0", "ARM_MATH_CM0", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"],
kadonotakashi 0:8fdf9a60065b 63 "Cortex-M0+": ["__CORTEX_M0PLUS", "ARM_MATH_CM0PLUS", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"],
kadonotakashi 0:8fdf9a60065b 64 "Cortex-M1" : ["__CORTEX_M3", "ARM_MATH_CM1", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"],
kadonotakashi 0:8fdf9a60065b 65 "Cortex-M3" : ["__CORTEX_M3", "ARM_MATH_CM3", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"],
kadonotakashi 0:8fdf9a60065b 66 "Cortex-M4" : ["__CORTEX_M4", "ARM_MATH_CM4", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"],
kadonotakashi 0:8fdf9a60065b 67 "Cortex-M4F" : ["__CORTEX_M4", "ARM_MATH_CM4", "__FPU_PRESENT=1", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"],
kadonotakashi 0:8fdf9a60065b 68 "Cortex-M7" : ["__CORTEX_M7", "ARM_MATH_CM7", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"],
kadonotakashi 0:8fdf9a60065b 69 "Cortex-M7F" : ["__CORTEX_M7", "ARM_MATH_CM7", "__FPU_PRESENT=1", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"],
kadonotakashi 0:8fdf9a60065b 70 "Cortex-M7FD" : ["__CORTEX_M7", "ARM_MATH_CM7", "__FPU_PRESENT=1", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"],
kadonotakashi 0:8fdf9a60065b 71 "Cortex-A9" : ["__CORTEX_A9", "ARM_MATH_CA9", "__FPU_PRESENT", "__CMSIS_RTOS", "__EVAL", "__MBED_CMSIS_RTOS_CA9"],
kadonotakashi 0:8fdf9a60065b 72 "Cortex-M23-NS": ["__CORTEX_M23", "ARM_MATH_ARMV8MBL", "DOMAIN_NS=1", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"],
kadonotakashi 0:8fdf9a60065b 73 "Cortex-M23": ["__CORTEX_M23", "ARM_MATH_ARMV8MBL", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"],
kadonotakashi 0:8fdf9a60065b 74 "Cortex-M33-NS": ["__CORTEX_M33", "ARM_MATH_ARMV8MML", "DOMAIN_NS=1", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"],
kadonotakashi 0:8fdf9a60065b 75 "Cortex-M33": ["__CORTEX_M33", "ARM_MATH_ARMV8MML", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"],
kadonotakashi 0:8fdf9a60065b 76 "Cortex-M33F-NS": ["__CORTEX_M33", "ARM_MATH_ARMV8MML", "DOMAIN_NS=1", "__FPU_PRESENT", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"],
kadonotakashi 0:8fdf9a60065b 77 "Cortex-M33F": ["__CORTEX_M33", "ARM_MATH_ARMV8MML", "__FPU_PRESENT", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"],
kadonotakashi 0:8fdf9a60065b 78 }
kadonotakashi 0:8fdf9a60065b 79
kadonotakashi 0:8fdf9a60065b 80 MBED_CONFIG_FILE_NAME="mbed_config.h"
kadonotakashi 0:8fdf9a60065b 81
kadonotakashi 0:8fdf9a60065b 82 PROFILE_FILE_NAME = ".profile"
kadonotakashi 0:8fdf9a60065b 83
kadonotakashi 0:8fdf9a60065b 84 __metaclass__ = ABCMeta
kadonotakashi 0:8fdf9a60065b 85
kadonotakashi 0:8fdf9a60065b 86 profile_template = {'common':[], 'c':[], 'cxx':[], 'asm':[], 'ld':[]}
kadonotakashi 0:8fdf9a60065b 87
kadonotakashi 0:8fdf9a60065b 88 def __init__(self, target, notify=None, macros=None, build_profile=None,
kadonotakashi 0:8fdf9a60065b 89 build_dir=None):
kadonotakashi 0:8fdf9a60065b 90 self.target = target
kadonotakashi 0:8fdf9a60065b 91 self.name = self.__class__.__name__
kadonotakashi 0:8fdf9a60065b 92
kadonotakashi 0:8fdf9a60065b 93 # compile/assemble/link/binary hooks
kadonotakashi 0:8fdf9a60065b 94 self.hook = hooks.Hook(target, self)
kadonotakashi 0:8fdf9a60065b 95
kadonotakashi 0:8fdf9a60065b 96 # Toolchain flags
kadonotakashi 0:8fdf9a60065b 97 self.flags = deepcopy(build_profile or self.profile_template)
kadonotakashi 0:8fdf9a60065b 98
kadonotakashi 0:8fdf9a60065b 99 # System libraries provided by the toolchain
kadonotakashi 0:8fdf9a60065b 100 self.sys_libs = []
kadonotakashi 0:8fdf9a60065b 101
kadonotakashi 0:8fdf9a60065b 102 # User-defined macros
kadonotakashi 0:8fdf9a60065b 103 self.macros = macros or []
kadonotakashi 0:8fdf9a60065b 104
kadonotakashi 0:8fdf9a60065b 105 # Macros generated from toolchain and target rules/features
kadonotakashi 0:8fdf9a60065b 106 self.asm_symbols = None
kadonotakashi 0:8fdf9a60065b 107 self.cxx_symbols = None
kadonotakashi 0:8fdf9a60065b 108
kadonotakashi 0:8fdf9a60065b 109 # Labels generated from toolchain and target rules/features (used for selective build)
kadonotakashi 0:8fdf9a60065b 110 self.labels = None
kadonotakashi 0:8fdf9a60065b 111
kadonotakashi 0:8fdf9a60065b 112 # This will hold the initialized config object
kadonotakashi 0:8fdf9a60065b 113 self.config = None
kadonotakashi 0:8fdf9a60065b 114
kadonotakashi 0:8fdf9a60065b 115 # This will hold the configuration data (as returned by Config.get_config_data())
kadonotakashi 0:8fdf9a60065b 116 self.config_data = None
kadonotakashi 0:8fdf9a60065b 117
kadonotakashi 0:8fdf9a60065b 118 # This will hold the location of the configuration file or None if there's no configuration available
kadonotakashi 0:8fdf9a60065b 119 self.config_file = None
kadonotakashi 0:8fdf9a60065b 120
kadonotakashi 0:8fdf9a60065b 121 # Call guard for "get_config_data" (see the comments of get_config_data for details)
kadonotakashi 0:8fdf9a60065b 122 self.config_processed = False
kadonotakashi 0:8fdf9a60065b 123
kadonotakashi 0:8fdf9a60065b 124 # Non-incremental compile
kadonotakashi 0:8fdf9a60065b 125 self.build_all = False
kadonotakashi 0:8fdf9a60065b 126
kadonotakashi 0:8fdf9a60065b 127 # Build output dir
kadonotakashi 0:8fdf9a60065b 128 self.build_dir = abspath(build_dir) if PRINT_COMPILER_OUTPUT_AS_LINK else build_dir
kadonotakashi 0:8fdf9a60065b 129 self.timestamp = time()
kadonotakashi 0:8fdf9a60065b 130
kadonotakashi 0:8fdf9a60065b 131 # Number of concurrent build jobs. 0 means auto (based on host system cores)
kadonotakashi 0:8fdf9a60065b 132 self.jobs = 0
kadonotakashi 0:8fdf9a60065b 133
kadonotakashi 0:8fdf9a60065b 134
kadonotakashi 0:8fdf9a60065b 135 # Output notify function
kadonotakashi 0:8fdf9a60065b 136 # This function is passed all events, and expected to handle notification of the
kadonotakashi 0:8fdf9a60065b 137 # user, emit the events to a log, etc.
kadonotakashi 0:8fdf9a60065b 138 # The API for all notify methods passed into the notify parameter is as follows:
kadonotakashi 0:8fdf9a60065b 139 # def notify(Event, Silent)
kadonotakashi 0:8fdf9a60065b 140 # Where *Event* is a dict representing the toolchain event that was generated
kadonotakashi 0:8fdf9a60065b 141 # e.g.: a compile succeeded, or a warning was emitted by the compiler
kadonotakashi 0:8fdf9a60065b 142 # or an application was linked
kadonotakashi 0:8fdf9a60065b 143 # *Silent* is a boolean
kadonotakashi 0:8fdf9a60065b 144 if notify:
kadonotakashi 0:8fdf9a60065b 145 self.notify = notify
kadonotakashi 0:8fdf9a60065b 146 else:
kadonotakashi 0:8fdf9a60065b 147 self.notify = TerminalNotifier()
kadonotakashi 0:8fdf9a60065b 148
kadonotakashi 0:8fdf9a60065b 149
kadonotakashi 0:8fdf9a60065b 150 # Stats cache is used to reduce the amount of IO requests to stat
kadonotakashi 0:8fdf9a60065b 151 # header files during dependency change. See need_update()
kadonotakashi 0:8fdf9a60065b 152 self.stat_cache = {}
kadonotakashi 0:8fdf9a60065b 153
kadonotakashi 0:8fdf9a60065b 154 # Used by the mbed Online Build System to build in chrooted environment
kadonotakashi 0:8fdf9a60065b 155 self.CHROOT = None
kadonotakashi 0:8fdf9a60065b 156
kadonotakashi 0:8fdf9a60065b 157 # Call post __init__() hooks before the ARM/GCC_ARM/IAR toolchain __init__() takes over
kadonotakashi 0:8fdf9a60065b 158 self.init()
kadonotakashi 0:8fdf9a60065b 159
kadonotakashi 0:8fdf9a60065b 160 # Used for post __init__() hooks
kadonotakashi 0:8fdf9a60065b 161 # THIS METHOD IS BEING OVERRIDDEN BY THE MBED ONLINE BUILD SYSTEM
kadonotakashi 0:8fdf9a60065b 162 # ANY CHANGE OF PARAMETERS OR RETURN VALUES WILL BREAK COMPATIBILITY
kadonotakashi 0:8fdf9a60065b 163 def init(self):
kadonotakashi 0:8fdf9a60065b 164 return True
kadonotakashi 0:8fdf9a60065b 165
kadonotakashi 0:8fdf9a60065b 166 def get_output(self):
kadonotakashi 0:8fdf9a60065b 167 return self.notifier.get_output()
kadonotakashi 0:8fdf9a60065b 168
kadonotakashi 0:8fdf9a60065b 169 def get_symbols(self, for_asm=False):
kadonotakashi 0:8fdf9a60065b 170 if for_asm:
kadonotakashi 0:8fdf9a60065b 171 if self.asm_symbols is None:
kadonotakashi 0:8fdf9a60065b 172 self.asm_symbols = []
kadonotakashi 0:8fdf9a60065b 173
kadonotakashi 0:8fdf9a60065b 174 # Cortex CPU symbols
kadonotakashi 0:8fdf9a60065b 175 if self.target.core in mbedToolchain.CORTEX_SYMBOLS:
kadonotakashi 0:8fdf9a60065b 176 self.asm_symbols.extend(mbedToolchain.CORTEX_SYMBOLS[self.target.core])
kadonotakashi 0:8fdf9a60065b 177
kadonotakashi 0:8fdf9a60065b 178 # Add target's symbols
kadonotakashi 0:8fdf9a60065b 179 self.asm_symbols += self.target.macros
kadonotakashi 0:8fdf9a60065b 180 # Add extra symbols passed via 'macros' parameter
kadonotakashi 0:8fdf9a60065b 181 self.asm_symbols += self.macros
kadonotakashi 0:8fdf9a60065b 182 return list(set(self.asm_symbols)) # Return only unique symbols
kadonotakashi 0:8fdf9a60065b 183 else:
kadonotakashi 0:8fdf9a60065b 184 if self.cxx_symbols is None:
kadonotakashi 0:8fdf9a60065b 185 # Target and Toolchain symbols
kadonotakashi 0:8fdf9a60065b 186 labels = self.get_labels()
kadonotakashi 0:8fdf9a60065b 187 self.cxx_symbols = ["TARGET_%s" % t for t in labels['TARGET']]
kadonotakashi 0:8fdf9a60065b 188 self.cxx_symbols.extend(["TOOLCHAIN_%s" % t for t in labels['TOOLCHAIN']])
kadonotakashi 0:8fdf9a60065b 189
kadonotakashi 0:8fdf9a60065b 190 # Cortex CPU symbols
kadonotakashi 0:8fdf9a60065b 191 if self.target.core in mbedToolchain.CORTEX_SYMBOLS:
kadonotakashi 0:8fdf9a60065b 192 self.cxx_symbols.extend(mbedToolchain.CORTEX_SYMBOLS[self.target.core])
kadonotakashi 0:8fdf9a60065b 193
kadonotakashi 0:8fdf9a60065b 194 # Symbols defined by the on-line build.system
kadonotakashi 0:8fdf9a60065b 195 self.cxx_symbols.extend(['MBED_BUILD_TIMESTAMP=%s' % self.timestamp, 'TARGET_LIKE_MBED', '__MBED__=1'])
kadonotakashi 0:8fdf9a60065b 196 if MBED_ORG_USER:
kadonotakashi 0:8fdf9a60065b 197 self.cxx_symbols.append('MBED_USERNAME=' + MBED_ORG_USER)
kadonotakashi 0:8fdf9a60065b 198
kadonotakashi 0:8fdf9a60065b 199 # Add target's symbols
kadonotakashi 0:8fdf9a60065b 200 self.cxx_symbols += self.target.macros
kadonotakashi 0:8fdf9a60065b 201 # Add target's hardware
kadonotakashi 0:8fdf9a60065b 202 self.cxx_symbols += ["DEVICE_" + data + "=1" for data in self.target.device_has]
kadonotakashi 0:8fdf9a60065b 203 # Add target's features
kadonotakashi 0:8fdf9a60065b 204 self.cxx_symbols += ["FEATURE_" + data + "=1" for data in self.target.features]
kadonotakashi 0:8fdf9a60065b 205 # Add target's components
kadonotakashi 0:8fdf9a60065b 206 self.cxx_symbols += ["COMPONENT_" + data + "=1" for data in self.target.components]
kadonotakashi 0:8fdf9a60065b 207 # Add extra symbols passed via 'macros' parameter
kadonotakashi 0:8fdf9a60065b 208 self.cxx_symbols += self.macros
kadonotakashi 0:8fdf9a60065b 209
kadonotakashi 0:8fdf9a60065b 210 # Form factor variables
kadonotakashi 0:8fdf9a60065b 211 if hasattr(self.target, 'supported_form_factors'):
kadonotakashi 0:8fdf9a60065b 212 self.cxx_symbols.extend(["TARGET_FF_%s" % t for t in self.target.supported_form_factors])
kadonotakashi 0:8fdf9a60065b 213
kadonotakashi 0:8fdf9a60065b 214 return list(set(self.cxx_symbols)) # Return only unique symbols
kadonotakashi 0:8fdf9a60065b 215
kadonotakashi 0:8fdf9a60065b 216 # Extend the internal list of macros
kadonotakashi 0:8fdf9a60065b 217 def add_macros(self, new_macros):
kadonotakashi 0:8fdf9a60065b 218 self.macros.extend(new_macros)
kadonotakashi 0:8fdf9a60065b 219
kadonotakashi 0:8fdf9a60065b 220 def get_labels(self):
kadonotakashi 0:8fdf9a60065b 221 if self.labels is None:
kadonotakashi 0:8fdf9a60065b 222 toolchain_labels = self._get_toolchain_labels()
kadonotakashi 0:8fdf9a60065b 223 self.labels = {
kadonotakashi 0:8fdf9a60065b 224 'TARGET': self.target.labels,
kadonotakashi 0:8fdf9a60065b 225 'FEATURE': self.target.features,
kadonotakashi 0:8fdf9a60065b 226 'COMPONENT': self.target.components,
kadonotakashi 0:8fdf9a60065b 227 'TOOLCHAIN': toolchain_labels
kadonotakashi 0:8fdf9a60065b 228 }
kadonotakashi 0:8fdf9a60065b 229
kadonotakashi 0:8fdf9a60065b 230 # This is a policy decision and it should /really/ be in the config system
kadonotakashi 0:8fdf9a60065b 231 # ATM it's here for backward compatibility
kadonotakashi 0:8fdf9a60065b 232 if ((("-g" in self.flags['common'] or "-g3" in self.flags['common']) and
kadonotakashi 0:8fdf9a60065b 233 "-O0" in self.flags['common']) or
kadonotakashi 0:8fdf9a60065b 234 ("-r" in self.flags['common'] and
kadonotakashi 0:8fdf9a60065b 235 "-On" in self.flags['common'])):
kadonotakashi 0:8fdf9a60065b 236 self.labels['TARGET'].append("DEBUG")
kadonotakashi 0:8fdf9a60065b 237 else:
kadonotakashi 0:8fdf9a60065b 238 self.labels['TARGET'].append("RELEASE")
kadonotakashi 0:8fdf9a60065b 239 return self.labels
kadonotakashi 0:8fdf9a60065b 240
kadonotakashi 0:8fdf9a60065b 241 def _get_toolchain_labels(self):
kadonotakashi 0:8fdf9a60065b 242 toolchain_labels = [c.__name__ for c in getmro(self.__class__)]
kadonotakashi 0:8fdf9a60065b 243 toolchain_labels.remove('mbedToolchain')
kadonotakashi 0:8fdf9a60065b 244 toolchain_labels.remove('object')
kadonotakashi 0:8fdf9a60065b 245 return toolchain_labels
kadonotakashi 0:8fdf9a60065b 246
kadonotakashi 0:8fdf9a60065b 247
kadonotakashi 0:8fdf9a60065b 248 # Determine whether a source file needs updating/compiling
kadonotakashi 0:8fdf9a60065b 249 def need_update(self, target, dependencies):
kadonotakashi 0:8fdf9a60065b 250 if self.build_all:
kadonotakashi 0:8fdf9a60065b 251 return True
kadonotakashi 0:8fdf9a60065b 252
kadonotakashi 0:8fdf9a60065b 253 if not exists(target):
kadonotakashi 0:8fdf9a60065b 254 return True
kadonotakashi 0:8fdf9a60065b 255
kadonotakashi 0:8fdf9a60065b 256 target_mod_time = stat(target).st_mtime
kadonotakashi 0:8fdf9a60065b 257
kadonotakashi 0:8fdf9a60065b 258 for d in dependencies:
kadonotakashi 0:8fdf9a60065b 259 # Some objects are not provided with full path and here we do not have
kadonotakashi 0:8fdf9a60065b 260 # information about the library paths. Safe option: assume an update
kadonotakashi 0:8fdf9a60065b 261 if not d or not exists(d):
kadonotakashi 0:8fdf9a60065b 262 return True
kadonotakashi 0:8fdf9a60065b 263
kadonotakashi 0:8fdf9a60065b 264 if d not in self.stat_cache:
kadonotakashi 0:8fdf9a60065b 265 self.stat_cache[d] = stat(d).st_mtime
kadonotakashi 0:8fdf9a60065b 266
kadonotakashi 0:8fdf9a60065b 267 if self.stat_cache[d] >= target_mod_time:
kadonotakashi 0:8fdf9a60065b 268 return True
kadonotakashi 0:8fdf9a60065b 269
kadonotakashi 0:8fdf9a60065b 270 return False
kadonotakashi 0:8fdf9a60065b 271
kadonotakashi 0:8fdf9a60065b 272
kadonotakashi 0:8fdf9a60065b 273 def scan_repository(self, path):
kadonotakashi 0:8fdf9a60065b 274 resources = []
kadonotakashi 0:8fdf9a60065b 275
kadonotakashi 0:8fdf9a60065b 276 for root, dirs, files in walk(path):
kadonotakashi 0:8fdf9a60065b 277 # Remove ignored directories
kadonotakashi 0:8fdf9a60065b 278 for d in copy(dirs):
kadonotakashi 0:8fdf9a60065b 279 if d == '.' or d == '..':
kadonotakashi 0:8fdf9a60065b 280 dirs.remove(d)
kadonotakashi 0:8fdf9a60065b 281
kadonotakashi 0:8fdf9a60065b 282 for file in files:
kadonotakashi 0:8fdf9a60065b 283 file_path = join(root, file)
kadonotakashi 0:8fdf9a60065b 284 resources.append(file_path)
kadonotakashi 0:8fdf9a60065b 285
kadonotakashi 0:8fdf9a60065b 286 return resources
kadonotakashi 0:8fdf9a60065b 287
kadonotakashi 0:8fdf9a60065b 288 def copy_files(self, files_paths, trg_path, resources=None):
kadonotakashi 0:8fdf9a60065b 289 # Handle a single file
kadonotakashi 0:8fdf9a60065b 290 if not isinstance(files_paths, list):
kadonotakashi 0:8fdf9a60065b 291 files_paths = [files_paths]
kadonotakashi 0:8fdf9a60065b 292
kadonotakashi 0:8fdf9a60065b 293 for dest, source in files_paths:
kadonotakashi 0:8fdf9a60065b 294 target = join(trg_path, dest)
kadonotakashi 0:8fdf9a60065b 295 if (target != source) and (self.need_update(target, [source])):
kadonotakashi 0:8fdf9a60065b 296 self.progress("copy", dest)
kadonotakashi 0:8fdf9a60065b 297 mkdir(dirname(target))
kadonotakashi 0:8fdf9a60065b 298 copyfile(source, target)
kadonotakashi 0:8fdf9a60065b 299
kadonotakashi 0:8fdf9a60065b 300 # THIS METHOD IS BEING OVERRIDDEN BY THE MBED ONLINE BUILD SYSTEM
kadonotakashi 0:8fdf9a60065b 301 # ANY CHANGE OF PARAMETERS OR RETURN VALUES WILL BREAK COMPATIBILITY
kadonotakashi 0:8fdf9a60065b 302 def relative_object_path(self, build_path, file_ref):
kadonotakashi 0:8fdf9a60065b 303 source_dir, name, _ = split_path(file_ref.name)
kadonotakashi 0:8fdf9a60065b 304
kadonotakashi 0:8fdf9a60065b 305 obj_dir = relpath(join(build_path, source_dir))
kadonotakashi 0:8fdf9a60065b 306 if obj_dir is not self.prev_dir:
kadonotakashi 0:8fdf9a60065b 307 self.prev_dir = obj_dir
kadonotakashi 0:8fdf9a60065b 308 mkdir(obj_dir)
kadonotakashi 0:8fdf9a60065b 309 return join(obj_dir, name + '.o')
kadonotakashi 0:8fdf9a60065b 310
kadonotakashi 0:8fdf9a60065b 311 def make_option_file(self, options, naming=".options_{}.txt"):
kadonotakashi 0:8fdf9a60065b 312 """ Generate a via file for a pile of defines
kadonotakashi 0:8fdf9a60065b 313 ARM, GCC, IAR cross compatible
kadonotakashi 0:8fdf9a60065b 314 """
kadonotakashi 0:8fdf9a60065b 315 to_write = " ".join(options).encode('utf-8')
kadonotakashi 0:8fdf9a60065b 316 new_md5 = md5(to_write).hexdigest()
kadonotakashi 0:8fdf9a60065b 317 via_file = join(self.build_dir, naming.format(new_md5))
kadonotakashi 0:8fdf9a60065b 318 try:
kadonotakashi 0:8fdf9a60065b 319 with open(via_file, "r") as fd:
kadonotakashi 0:8fdf9a60065b 320 old_md5 = md5(fd.read().encode('utf-8')).hexdigest()
kadonotakashi 0:8fdf9a60065b 321 except IOError:
kadonotakashi 0:8fdf9a60065b 322 old_md5 = None
kadonotakashi 0:8fdf9a60065b 323 if old_md5 != new_md5:
kadonotakashi 0:8fdf9a60065b 324 with open(via_file, "wb") as fd:
kadonotakashi 0:8fdf9a60065b 325 fd.write(to_write)
kadonotakashi 0:8fdf9a60065b 326 return via_file
kadonotakashi 0:8fdf9a60065b 327
kadonotakashi 0:8fdf9a60065b 328 def get_inc_file(self, includes):
kadonotakashi 0:8fdf9a60065b 329 """Generate a via file for all includes.
kadonotakashi 0:8fdf9a60065b 330 ARM, GCC, IAR cross compatible
kadonotakashi 0:8fdf9a60065b 331 """
kadonotakashi 0:8fdf9a60065b 332 cmd_list = ("-I{}".format(c.replace("\\", "/")) for c in includes if c)
kadonotakashi 0:8fdf9a60065b 333 if self.CHROOT:
kadonotakashi 0:8fdf9a60065b 334 cmd_list = (c.replace(self.CHROOT, '') for c in cmd_list)
kadonotakashi 0:8fdf9a60065b 335 return self.make_option_file(list(cmd_list), naming=".includes_{}.txt")
kadonotakashi 0:8fdf9a60065b 336
kadonotakashi 0:8fdf9a60065b 337 def get_link_file(self, cmd):
kadonotakashi 0:8fdf9a60065b 338 """Generate a via file for all objects when linking.
kadonotakashi 0:8fdf9a60065b 339 ARM, GCC, IAR cross compatible
kadonotakashi 0:8fdf9a60065b 340 """
kadonotakashi 0:8fdf9a60065b 341 cmd_list = (c.replace("\\", "/") for c in cmd if c)
kadonotakashi 0:8fdf9a60065b 342 if self.CHROOT:
kadonotakashi 0:8fdf9a60065b 343 cmd_list = (c.replace(self.CHROOT, '') for c in cmd_list)
kadonotakashi 0:8fdf9a60065b 344 return self.make_option_file(list(cmd_list), naming=".link_options.txt")
kadonotakashi 0:8fdf9a60065b 345
kadonotakashi 0:8fdf9a60065b 346 def get_arch_file(self, objects):
kadonotakashi 0:8fdf9a60065b 347 """ Generate a via file for all objects when archiving.
kadonotakashi 0:8fdf9a60065b 348 ARM, GCC, IAR cross compatible
kadonotakashi 0:8fdf9a60065b 349 """
kadonotakashi 0:8fdf9a60065b 350 cmd_list = (c.replace("\\", "/") for c in objects if c)
kadonotakashi 0:8fdf9a60065b 351 return self.make_option_file(list(cmd_list), ".archive_files.txt")
kadonotakashi 0:8fdf9a60065b 352
kadonotakashi 0:8fdf9a60065b 353 # THIS METHOD IS BEING CALLED BY THE MBED ONLINE BUILD SYSTEM
kadonotakashi 0:8fdf9a60065b 354 # ANY CHANGE OF PARAMETERS OR RETURN VALUES WILL BREAK COMPATIBILITY
kadonotakashi 0:8fdf9a60065b 355 def compile_sources(self, resources, inc_dirs=None):
kadonotakashi 0:8fdf9a60065b 356 # Web IDE progress bar for project build
kadonotakashi 0:8fdf9a60065b 357 files_to_compile = (
kadonotakashi 0:8fdf9a60065b 358 resources.get_file_refs(FileType.ASM_SRC) +
kadonotakashi 0:8fdf9a60065b 359 resources.get_file_refs(FileType.C_SRC) +
kadonotakashi 0:8fdf9a60065b 360 resources.get_file_refs(FileType.CPP_SRC)
kadonotakashi 0:8fdf9a60065b 361 )
kadonotakashi 0:8fdf9a60065b 362 self.to_be_compiled = len(files_to_compile)
kadonotakashi 0:8fdf9a60065b 363 self.compiled = 0
kadonotakashi 0:8fdf9a60065b 364
kadonotakashi 0:8fdf9a60065b 365 self.notify.cc_verbose("Macros: "+' '.join(['-D%s' % s for s in self.get_symbols()]))
kadonotakashi 0:8fdf9a60065b 366
kadonotakashi 0:8fdf9a60065b 367 inc_paths = resources.get_file_paths(FileType.INC_DIR)
kadonotakashi 0:8fdf9a60065b 368 if inc_dirs is not None:
kadonotakashi 0:8fdf9a60065b 369 if isinstance(inc_dirs, list):
kadonotakashi 0:8fdf9a60065b 370 inc_paths.extend(inc_dirs)
kadonotakashi 0:8fdf9a60065b 371 else:
kadonotakashi 0:8fdf9a60065b 372 inc_paths.append(inc_dirs)
kadonotakashi 0:8fdf9a60065b 373 # De-duplicate include paths
kadonotakashi 0:8fdf9a60065b 374 inc_paths = set(inc_paths)
kadonotakashi 0:8fdf9a60065b 375 # Sort include paths for consistency
kadonotakashi 0:8fdf9a60065b 376 inc_paths = sorted(set(inc_paths))
kadonotakashi 0:8fdf9a60065b 377 # Unique id of all include paths
kadonotakashi 0:8fdf9a60065b 378 self.inc_md5 = md5(' '.join(inc_paths).encode('utf-8')).hexdigest()
kadonotakashi 0:8fdf9a60065b 379
kadonotakashi 0:8fdf9a60065b 380 objects = []
kadonotakashi 0:8fdf9a60065b 381 queue = []
kadonotakashi 0:8fdf9a60065b 382 work_dir = getcwd()
kadonotakashi 0:8fdf9a60065b 383 self.prev_dir = None
kadonotakashi 0:8fdf9a60065b 384
kadonotakashi 0:8fdf9a60065b 385 # Generate configuration header (this will update self.build_all if needed)
kadonotakashi 0:8fdf9a60065b 386 self.get_config_header()
kadonotakashi 0:8fdf9a60065b 387 self.dump_build_profile()
kadonotakashi 0:8fdf9a60065b 388
kadonotakashi 0:8fdf9a60065b 389 # Sort compile queue for consistency
kadonotakashi 0:8fdf9a60065b 390 files_to_compile.sort()
kadonotakashi 0:8fdf9a60065b 391 for source in files_to_compile:
kadonotakashi 0:8fdf9a60065b 392 object = self.relative_object_path(self.build_dir, source)
kadonotakashi 0:8fdf9a60065b 393
kadonotakashi 0:8fdf9a60065b 394 # Queue mode (multiprocessing)
kadonotakashi 0:8fdf9a60065b 395 commands = self.compile_command(source.path, object, inc_paths)
kadonotakashi 0:8fdf9a60065b 396 if commands is not None:
kadonotakashi 0:8fdf9a60065b 397 queue.append({
kadonotakashi 0:8fdf9a60065b 398 'source': source,
kadonotakashi 0:8fdf9a60065b 399 'object': object,
kadonotakashi 0:8fdf9a60065b 400 'commands': commands,
kadonotakashi 0:8fdf9a60065b 401 'work_dir': work_dir,
kadonotakashi 0:8fdf9a60065b 402 'chroot': self.CHROOT
kadonotakashi 0:8fdf9a60065b 403 })
kadonotakashi 0:8fdf9a60065b 404 else:
kadonotakashi 0:8fdf9a60065b 405 self.compiled += 1
kadonotakashi 0:8fdf9a60065b 406 objects.append(object)
kadonotakashi 0:8fdf9a60065b 407
kadonotakashi 0:8fdf9a60065b 408 # Use queues/multiprocessing if cpu count is higher than setting
kadonotakashi 0:8fdf9a60065b 409 jobs = self.jobs if self.jobs else cpu_count()
kadonotakashi 0:8fdf9a60065b 410 if jobs > CPU_COUNT_MIN and len(queue) > jobs:
kadonotakashi 0:8fdf9a60065b 411 return self.compile_queue(queue, objects)
kadonotakashi 0:8fdf9a60065b 412 else:
kadonotakashi 0:8fdf9a60065b 413 return self.compile_seq(queue, objects)
kadonotakashi 0:8fdf9a60065b 414
kadonotakashi 0:8fdf9a60065b 415 # Compile source files queue in sequential order
kadonotakashi 0:8fdf9a60065b 416 def compile_seq(self, queue, objects):
kadonotakashi 0:8fdf9a60065b 417 for item in queue:
kadonotakashi 0:8fdf9a60065b 418 result = compile_worker(item)
kadonotakashi 0:8fdf9a60065b 419
kadonotakashi 0:8fdf9a60065b 420 self.compiled += 1
kadonotakashi 0:8fdf9a60065b 421 self.progress("compile", item['source'].name, build_update=True)
kadonotakashi 0:8fdf9a60065b 422 for res in result['results']:
kadonotakashi 0:8fdf9a60065b 423 self.notify.cc_verbose("Compile: %s" % ' '.join(res['command']), result['source'].name)
kadonotakashi 0:8fdf9a60065b 424 self.compile_output([
kadonotakashi 0:8fdf9a60065b 425 res['code'],
kadonotakashi 0:8fdf9a60065b 426 res['output'],
kadonotakashi 0:8fdf9a60065b 427 res['command']
kadonotakashi 0:8fdf9a60065b 428 ])
kadonotakashi 0:8fdf9a60065b 429 objects.append(result['object'])
kadonotakashi 0:8fdf9a60065b 430 return objects
kadonotakashi 0:8fdf9a60065b 431
kadonotakashi 0:8fdf9a60065b 432 # Compile source files queue in parallel by creating pool of worker threads
kadonotakashi 0:8fdf9a60065b 433 def compile_queue(self, queue, objects):
kadonotakashi 0:8fdf9a60065b 434 jobs_count = int(self.jobs if self.jobs else cpu_count() * CPU_COEF)
kadonotakashi 0:8fdf9a60065b 435 p = Pool(processes=jobs_count)
kadonotakashi 0:8fdf9a60065b 436
kadonotakashi 0:8fdf9a60065b 437 results = []
kadonotakashi 0:8fdf9a60065b 438 for i in range(len(queue)):
kadonotakashi 0:8fdf9a60065b 439 results.append(p.apply_async(compile_worker, [queue[i]]))
kadonotakashi 0:8fdf9a60065b 440 p.close()
kadonotakashi 0:8fdf9a60065b 441
kadonotakashi 0:8fdf9a60065b 442 itr = 0
kadonotakashi 0:8fdf9a60065b 443 while len(results):
kadonotakashi 0:8fdf9a60065b 444 itr += 1
kadonotakashi 0:8fdf9a60065b 445 if itr > 180000:
kadonotakashi 0:8fdf9a60065b 446 p.terminate()
kadonotakashi 0:8fdf9a60065b 447 p.join()
kadonotakashi 0:8fdf9a60065b 448 raise ToolException("Compile did not finish in 5 minutes")
kadonotakashi 0:8fdf9a60065b 449
kadonotakashi 0:8fdf9a60065b 450 sleep(0.01)
kadonotakashi 0:8fdf9a60065b 451 pending = 0
kadonotakashi 0:8fdf9a60065b 452 for r in results:
kadonotakashi 0:8fdf9a60065b 453 if r.ready():
kadonotakashi 0:8fdf9a60065b 454 try:
kadonotakashi 0:8fdf9a60065b 455 result = r.get()
kadonotakashi 0:8fdf9a60065b 456 results.remove(r)
kadonotakashi 0:8fdf9a60065b 457
kadonotakashi 0:8fdf9a60065b 458 self.compiled += 1
kadonotakashi 0:8fdf9a60065b 459 self.progress("compile", result['source'].name, build_update=True)
kadonotakashi 0:8fdf9a60065b 460 for res in result['results']:
kadonotakashi 0:8fdf9a60065b 461 self.notify.cc_verbose("Compile: %s" % ' '.join(res['command']), result['source'].name)
kadonotakashi 0:8fdf9a60065b 462 self.compile_output([
kadonotakashi 0:8fdf9a60065b 463 res['code'],
kadonotakashi 0:8fdf9a60065b 464 res['output'],
kadonotakashi 0:8fdf9a60065b 465 res['command']
kadonotakashi 0:8fdf9a60065b 466 ])
kadonotakashi 0:8fdf9a60065b 467 objects.append(result['object'])
kadonotakashi 0:8fdf9a60065b 468 except ToolException as err:
kadonotakashi 0:8fdf9a60065b 469 if p._taskqueue.queue:
kadonotakashi 0:8fdf9a60065b 470 p._taskqueue.queue.clear()
kadonotakashi 0:8fdf9a60065b 471 sleep(0.5)
kadonotakashi 0:8fdf9a60065b 472 p.terminate()
kadonotakashi 0:8fdf9a60065b 473 p.join()
kadonotakashi 0:8fdf9a60065b 474 raise ToolException(err)
kadonotakashi 0:8fdf9a60065b 475 else:
kadonotakashi 0:8fdf9a60065b 476 pending += 1
kadonotakashi 0:8fdf9a60065b 477 if pending >= jobs_count:
kadonotakashi 0:8fdf9a60065b 478 break
kadonotakashi 0:8fdf9a60065b 479
kadonotakashi 0:8fdf9a60065b 480 results = None
kadonotakashi 0:8fdf9a60065b 481 p.join()
kadonotakashi 0:8fdf9a60065b 482
kadonotakashi 0:8fdf9a60065b 483 return objects
kadonotakashi 0:8fdf9a60065b 484
kadonotakashi 0:8fdf9a60065b 485 # Determine the compile command based on type of source file
kadonotakashi 0:8fdf9a60065b 486 def compile_command(self, source, object, includes):
kadonotakashi 0:8fdf9a60065b 487 # Check dependencies
kadonotakashi 0:8fdf9a60065b 488 _, ext = splitext(source)
kadonotakashi 0:8fdf9a60065b 489 ext = ext.lower()
kadonotakashi 0:8fdf9a60065b 490
kadonotakashi 0:8fdf9a60065b 491 source = abspath(source) if PRINT_COMPILER_OUTPUT_AS_LINK else source
kadonotakashi 0:8fdf9a60065b 492
kadonotakashi 0:8fdf9a60065b 493 if ext == '.c' or ext == '.cpp' or ext == '.cc':
kadonotakashi 0:8fdf9a60065b 494 base, _ = splitext(object)
kadonotakashi 0:8fdf9a60065b 495 dep_path = base + '.d'
kadonotakashi 0:8fdf9a60065b 496 try:
kadonotakashi 0:8fdf9a60065b 497 deps = self.parse_dependencies(dep_path) if (exists(dep_path)) else []
kadonotakashi 0:8fdf9a60065b 498 except (IOError, IndexError):
kadonotakashi 0:8fdf9a60065b 499 deps = []
kadonotakashi 0:8fdf9a60065b 500 config_file = ([self.config.app_config_location]
kadonotakashi 0:8fdf9a60065b 501 if self.config.app_config_location else [])
kadonotakashi 0:8fdf9a60065b 502 deps.extend(config_file)
kadonotakashi 0:8fdf9a60065b 503 if ext != '.c' or self.COMPILE_C_AS_CPP:
kadonotakashi 0:8fdf9a60065b 504 deps.append(join(self.build_dir, self.PROFILE_FILE_NAME + "-cxx"))
kadonotakashi 0:8fdf9a60065b 505 else:
kadonotakashi 0:8fdf9a60065b 506 deps.append(join(self.build_dir, self.PROFILE_FILE_NAME + "-c"))
kadonotakashi 0:8fdf9a60065b 507 if len(deps) == 0 or self.need_update(object, deps):
kadonotakashi 0:8fdf9a60065b 508 if ext != '.c' or self.COMPILE_C_AS_CPP:
kadonotakashi 0:8fdf9a60065b 509 return self.compile_cpp(source, object, includes)
kadonotakashi 0:8fdf9a60065b 510 else:
kadonotakashi 0:8fdf9a60065b 511 return self.compile_c(source, object, includes)
kadonotakashi 0:8fdf9a60065b 512 elif ext == '.s':
kadonotakashi 0:8fdf9a60065b 513 deps = [source]
kadonotakashi 0:8fdf9a60065b 514 deps.append(join(self.build_dir, self.PROFILE_FILE_NAME + "-asm"))
kadonotakashi 0:8fdf9a60065b 515 if self.need_update(object, deps):
kadonotakashi 0:8fdf9a60065b 516 return self.assemble(source, object, includes)
kadonotakashi 0:8fdf9a60065b 517 else:
kadonotakashi 0:8fdf9a60065b 518 return False
kadonotakashi 0:8fdf9a60065b 519
kadonotakashi 0:8fdf9a60065b 520 return None
kadonotakashi 0:8fdf9a60065b 521
kadonotakashi 0:8fdf9a60065b 522 def parse_dependencies(self, dep_path):
kadonotakashi 0:8fdf9a60065b 523 """Parse the dependency information generated by the compiler.
kadonotakashi 0:8fdf9a60065b 524
kadonotakashi 0:8fdf9a60065b 525 Positional arguments:
kadonotakashi 0:8fdf9a60065b 526 dep_path -- the path to a file generated by a previous run of the compiler
kadonotakashi 0:8fdf9a60065b 527
kadonotakashi 0:8fdf9a60065b 528 Return value:
kadonotakashi 0:8fdf9a60065b 529 A list of all source files that the dependency file indicated were dependencies
kadonotakashi 0:8fdf9a60065b 530
kadonotakashi 0:8fdf9a60065b 531 Side effects:
kadonotakashi 0:8fdf9a60065b 532 None
kadonotakashi 0:8fdf9a60065b 533
kadonotakashi 0:8fdf9a60065b 534 Note: A default implementation is provided for make-like file formats
kadonotakashi 0:8fdf9a60065b 535 """
kadonotakashi 0:8fdf9a60065b 536 dependencies = []
kadonotakashi 0:8fdf9a60065b 537 buff = open(dep_path).readlines()
kadonotakashi 0:8fdf9a60065b 538 if buff:
kadonotakashi 0:8fdf9a60065b 539 buff[0] = re.sub('^(.*?)\: ', '', buff[0])
kadonotakashi 0:8fdf9a60065b 540 for line in buff:
kadonotakashi 0:8fdf9a60065b 541 filename = line.replace('\\\n', '').strip()
kadonotakashi 0:8fdf9a60065b 542 if filename:
kadonotakashi 0:8fdf9a60065b 543 filename = filename.replace('\\ ', '\a')
kadonotakashi 0:8fdf9a60065b 544 dependencies.extend(((self.CHROOT if self.CHROOT else '') +
kadonotakashi 0:8fdf9a60065b 545 f.replace('\a', ' '))
kadonotakashi 0:8fdf9a60065b 546 for f in filename.split(" "))
kadonotakashi 0:8fdf9a60065b 547 return list(filter(None, dependencies))
kadonotakashi 0:8fdf9a60065b 548
kadonotakashi 0:8fdf9a60065b 549 def is_not_supported_error(self, output):
kadonotakashi 0:8fdf9a60065b 550 return "#error directive: [NOT_SUPPORTED]" in output
kadonotakashi 0:8fdf9a60065b 551
kadonotakashi 0:8fdf9a60065b 552 @abstractmethod
kadonotakashi 0:8fdf9a60065b 553 def parse_output(self, output):
kadonotakashi 0:8fdf9a60065b 554 """Take in compiler output and extract sinlge line warnings and errors from it.
kadonotakashi 0:8fdf9a60065b 555
kadonotakashi 0:8fdf9a60065b 556 Positional arguments:
kadonotakashi 0:8fdf9a60065b 557 output -- a string of all the messages emitted by a run of the compiler
kadonotakashi 0:8fdf9a60065b 558
kadonotakashi 0:8fdf9a60065b 559 Return value:
kadonotakashi 0:8fdf9a60065b 560 None
kadonotakashi 0:8fdf9a60065b 561
kadonotakashi 0:8fdf9a60065b 562 Side effects:
kadonotakashi 0:8fdf9a60065b 563 call self.cc_info or self.notify with a description of the event generated by the compiler
kadonotakashi 0:8fdf9a60065b 564 """
kadonotakashi 0:8fdf9a60065b 565 raise NotImplemented
kadonotakashi 0:8fdf9a60065b 566
kadonotakashi 0:8fdf9a60065b 567 def compile_output(self, output=[]):
kadonotakashi 0:8fdf9a60065b 568 _rc = output[0]
kadonotakashi 0:8fdf9a60065b 569 _stderr = output[1].decode("utf-8")
kadonotakashi 0:8fdf9a60065b 570 command = output[2]
kadonotakashi 0:8fdf9a60065b 571
kadonotakashi 0:8fdf9a60065b 572 # Parse output for Warnings and Errors
kadonotakashi 0:8fdf9a60065b 573 self.parse_output(_stderr)
kadonotakashi 0:8fdf9a60065b 574 self.notify.debug("Return: %s"% _rc)
kadonotakashi 0:8fdf9a60065b 575 for error_line in _stderr.splitlines():
kadonotakashi 0:8fdf9a60065b 576 self.notify.debug("Output: %s"% error_line)
kadonotakashi 0:8fdf9a60065b 577
kadonotakashi 0:8fdf9a60065b 578 # Check return code
kadonotakashi 0:8fdf9a60065b 579 if _rc != 0:
kadonotakashi 0:8fdf9a60065b 580 if self.is_not_supported_error(_stderr):
kadonotakashi 0:8fdf9a60065b 581 raise NotSupportedException(_stderr)
kadonotakashi 0:8fdf9a60065b 582 else:
kadonotakashi 0:8fdf9a60065b 583 raise ToolException(_stderr)
kadonotakashi 0:8fdf9a60065b 584
kadonotakashi 0:8fdf9a60065b 585 def build_library(self, objects, dir, name):
kadonotakashi 0:8fdf9a60065b 586 needed_update = False
kadonotakashi 0:8fdf9a60065b 587 lib = self.STD_LIB_NAME % name
kadonotakashi 0:8fdf9a60065b 588 fout = join(dir, lib)
kadonotakashi 0:8fdf9a60065b 589 if self.need_update(fout, objects):
kadonotakashi 0:8fdf9a60065b 590 self.notify.info("Library: %s" % lib)
kadonotakashi 0:8fdf9a60065b 591 self.archive(objects, fout)
kadonotakashi 0:8fdf9a60065b 592 needed_update = True
kadonotakashi 0:8fdf9a60065b 593
kadonotakashi 0:8fdf9a60065b 594 return needed_update
kadonotakashi 0:8fdf9a60065b 595
kadonotakashi 0:8fdf9a60065b 596 def link_program(self, r, tmp_path, name):
kadonotakashi 0:8fdf9a60065b 597 needed_update = False
kadonotakashi 0:8fdf9a60065b 598 ext = 'bin'
kadonotakashi 0:8fdf9a60065b 599 if hasattr(self.target, 'OUTPUT_EXT'):
kadonotakashi 0:8fdf9a60065b 600 ext = self.target.OUTPUT_EXT
kadonotakashi 0:8fdf9a60065b 601
kadonotakashi 0:8fdf9a60065b 602 if hasattr(self.target, 'OUTPUT_NAMING'):
kadonotakashi 0:8fdf9a60065b 603 self.notify.var("binary_naming", self.target.OUTPUT_NAMING)
kadonotakashi 0:8fdf9a60065b 604 if self.target.OUTPUT_NAMING == "8.3":
kadonotakashi 0:8fdf9a60065b 605 name = name[0:8]
kadonotakashi 0:8fdf9a60065b 606 ext = ext[0:3]
kadonotakashi 0:8fdf9a60065b 607
kadonotakashi 0:8fdf9a60065b 608 # Create destination directory
kadonotakashi 0:8fdf9a60065b 609 head, tail = split(name)
kadonotakashi 0:8fdf9a60065b 610 new_path = join(tmp_path, head)
kadonotakashi 0:8fdf9a60065b 611 mkdir(new_path)
kadonotakashi 0:8fdf9a60065b 612
kadonotakashi 0:8fdf9a60065b 613 filename = name+'.'+ext
kadonotakashi 0:8fdf9a60065b 614 # Absolute path of the final linked file
kadonotakashi 0:8fdf9a60065b 615 full_path = join(tmp_path, filename)
kadonotakashi 0:8fdf9a60065b 616 elf = join(tmp_path, name + '.elf')
kadonotakashi 0:8fdf9a60065b 617 bin = None if ext == 'elf' else full_path
kadonotakashi 0:8fdf9a60065b 618 map = join(tmp_path, name + '.map')
kadonotakashi 0:8fdf9a60065b 619
kadonotakashi 0:8fdf9a60065b 620 objects = sorted(set(r.get_file_paths(FileType.OBJECT)))
kadonotakashi 0:8fdf9a60065b 621 config_file = ([self.config.app_config_location]
kadonotakashi 0:8fdf9a60065b 622 if self.config.app_config_location else [])
kadonotakashi 0:8fdf9a60065b 623 linker_script = [path for _, path in r.get_file_refs(FileType.LD_SCRIPT)
kadonotakashi 0:8fdf9a60065b 624 if path.endswith(self.LINKER_EXT)][-1]
kadonotakashi 0:8fdf9a60065b 625 lib_dirs = r.get_file_paths(FileType.LIB_DIR)
kadonotakashi 0:8fdf9a60065b 626 libraries = [l for l in r.get_file_paths(FileType.LIB)
kadonotakashi 0:8fdf9a60065b 627 if l.endswith(self.LIBRARY_EXT)]
kadonotakashi 0:8fdf9a60065b 628 dependencies = objects + libraries + [linker_script] + config_file
kadonotakashi 0:8fdf9a60065b 629 dependencies.append(join(self.build_dir, self.PROFILE_FILE_NAME + "-ld"))
kadonotakashi 0:8fdf9a60065b 630 if self.need_update(elf, dependencies):
kadonotakashi 0:8fdf9a60065b 631 needed_update = True
kadonotakashi 0:8fdf9a60065b 632 self.progress("link", name)
kadonotakashi 0:8fdf9a60065b 633 self.link(elf, objects, libraries, lib_dirs, linker_script)
kadonotakashi 0:8fdf9a60065b 634
kadonotakashi 0:8fdf9a60065b 635 if bin and self.need_update(bin, [elf]):
kadonotakashi 0:8fdf9a60065b 636 needed_update = True
kadonotakashi 0:8fdf9a60065b 637 self.progress("elf2bin", name)
kadonotakashi 0:8fdf9a60065b 638 self.binary(r, elf, bin)
kadonotakashi 0:8fdf9a60065b 639
kadonotakashi 0:8fdf9a60065b 640 # Initialize memap and process map file. This doesn't generate output.
kadonotakashi 0:8fdf9a60065b 641 self.mem_stats(map)
kadonotakashi 0:8fdf9a60065b 642
kadonotakashi 0:8fdf9a60065b 643 self.notify.var("compile_succeded", True)
kadonotakashi 0:8fdf9a60065b 644 self.notify.var("binary", filename)
kadonotakashi 0:8fdf9a60065b 645
kadonotakashi 0:8fdf9a60065b 646 return full_path, needed_update
kadonotakashi 0:8fdf9a60065b 647
kadonotakashi 0:8fdf9a60065b 648 # THIS METHOD IS BEING OVERRIDDEN BY THE MBED ONLINE BUILD SYSTEM
kadonotakashi 0:8fdf9a60065b 649 # ANY CHANGE OF PARAMETERS OR RETURN VALUES WILL BREAK COMPATIBILITY
kadonotakashi 0:8fdf9a60065b 650 def default_cmd(self, command):
kadonotakashi 0:8fdf9a60065b 651 _stdout, _stderr, _rc = run_cmd(command, work_dir=getcwd(), chroot=self.CHROOT)
kadonotakashi 0:8fdf9a60065b 652 self.notify.debug("Return: %s"% _rc)
kadonotakashi 0:8fdf9a60065b 653
kadonotakashi 0:8fdf9a60065b 654 for output_line in _stdout.splitlines():
kadonotakashi 0:8fdf9a60065b 655 self.notify.debug("Output: %s"% output_line)
kadonotakashi 0:8fdf9a60065b 656 for error_line in _stderr.splitlines():
kadonotakashi 0:8fdf9a60065b 657 self.notify.debug("Errors: %s"% error_line)
kadonotakashi 0:8fdf9a60065b 658
kadonotakashi 0:8fdf9a60065b 659 if _rc != 0:
kadonotakashi 0:8fdf9a60065b 660 for line in _stderr.splitlines():
kadonotakashi 0:8fdf9a60065b 661 self.notify.tool_error(line)
kadonotakashi 0:8fdf9a60065b 662 raise ToolException(_stderr)
kadonotakashi 0:8fdf9a60065b 663
kadonotakashi 0:8fdf9a60065b 664 def progress(self, action, file, build_update=False):
kadonotakashi 0:8fdf9a60065b 665 if build_update:
kadonotakashi 0:8fdf9a60065b 666 percent = 100. * float(self.compiled) / float(self.to_be_compiled)
kadonotakashi 0:8fdf9a60065b 667 else:
kadonotakashi 0:8fdf9a60065b 668 percent = None
kadonotakashi 0:8fdf9a60065b 669 self.notify.progress(action, file, percent)
kadonotakashi 0:8fdf9a60065b 670
kadonotakashi 0:8fdf9a60065b 671 # THIS METHOD IS BEING OVERRIDDEN BY THE MBED ONLINE BUILD SYSTEM
kadonotakashi 0:8fdf9a60065b 672 # ANY CHANGE OF PARAMETERS OR RETURN VALUES WILL BREAK COMPATIBILITY
kadonotakashi 0:8fdf9a60065b 673 def mem_stats(self, map):
kadonotakashi 0:8fdf9a60065b 674 """! Creates parser object
kadonotakashi 0:8fdf9a60065b 675 @param map Path to linker map file to parse and decode
kadonotakashi 0:8fdf9a60065b 676 @return None
kadonotakashi 0:8fdf9a60065b 677 """
kadonotakashi 0:8fdf9a60065b 678 toolchain = self.__class__.__name__
kadonotakashi 0:8fdf9a60065b 679
kadonotakashi 0:8fdf9a60065b 680 # Create memap object
kadonotakashi 0:8fdf9a60065b 681 memap = MemapParser()
kadonotakashi 0:8fdf9a60065b 682
kadonotakashi 0:8fdf9a60065b 683 # Parse and decode a map file
kadonotakashi 0:8fdf9a60065b 684 if memap.parse(abspath(map), toolchain) is False:
kadonotakashi 0:8fdf9a60065b 685 self.notify.info("Unknown toolchain for memory statistics %s" % toolchain)
kadonotakashi 0:8fdf9a60065b 686 return None
kadonotakashi 0:8fdf9a60065b 687
kadonotakashi 0:8fdf9a60065b 688 # Store the memap instance for later use
kadonotakashi 0:8fdf9a60065b 689 self.memap_instance = memap
kadonotakashi 0:8fdf9a60065b 690
kadonotakashi 0:8fdf9a60065b 691 # Note: memory statistics are not returned.
kadonotakashi 0:8fdf9a60065b 692 # Need call to generate_output later (depends on depth & output format)
kadonotakashi 0:8fdf9a60065b 693
kadonotakashi 0:8fdf9a60065b 694 return None
kadonotakashi 0:8fdf9a60065b 695
kadonotakashi 0:8fdf9a60065b 696 def _add_defines_from_region(self, region, suffixes=['_ADDR', '_SIZE']):
kadonotakashi 0:8fdf9a60065b 697 for define in [(region.name.upper() + suffixes[0], region.start),
kadonotakashi 0:8fdf9a60065b 698 (region.name.upper() + suffixes[1], region.size)]:
kadonotakashi 0:8fdf9a60065b 699 define_string = "-D%s=0x%x" % define
kadonotakashi 0:8fdf9a60065b 700 self.cc.append(define_string)
kadonotakashi 0:8fdf9a60065b 701 self.cppc.append(define_string)
kadonotakashi 0:8fdf9a60065b 702 self.flags["common"].append(define_string)
kadonotakashi 0:8fdf9a60065b 703
kadonotakashi 0:8fdf9a60065b 704 def _add_all_regions(self, region_list, active_region_name):
kadonotakashi 0:8fdf9a60065b 705 for region in region_list:
kadonotakashi 0:8fdf9a60065b 706 self._add_defines_from_region(region)
kadonotakashi 0:8fdf9a60065b 707 if region.active:
kadonotakashi 0:8fdf9a60065b 708 for define in [
kadonotakashi 0:8fdf9a60065b 709 ("%s_START" % active_region_name, "0x%x" % region.start),
kadonotakashi 0:8fdf9a60065b 710 ("%s_SIZE" % active_region_name, "0x%x" % region.size)
kadonotakashi 0:8fdf9a60065b 711 ]:
kadonotakashi 0:8fdf9a60065b 712 define_string = self.make_ld_define(*define)
kadonotakashi 0:8fdf9a60065b 713 self.ld.append(define_string)
kadonotakashi 0:8fdf9a60065b 714 self.flags["ld"].append(define_string)
kadonotakashi 0:8fdf9a60065b 715 self.notify.info(" Region %s: size 0x%x, offset 0x%x"
kadonotakashi 0:8fdf9a60065b 716 % (region.name, region.size, region.start))
kadonotakashi 0:8fdf9a60065b 717
kadonotakashi 0:8fdf9a60065b 718 def add_regions(self):
kadonotakashi 0:8fdf9a60065b 719 """Add regions to the build profile, if there are any.
kadonotakashi 0:8fdf9a60065b 720 """
kadonotakashi 0:8fdf9a60065b 721 if self.config.has_regions:
kadonotakashi 0:8fdf9a60065b 722 regions = list(self.config.regions)
kadonotakashi 0:8fdf9a60065b 723 self.notify.info("Using ROM region%s %s in this build." % (
kadonotakashi 0:8fdf9a60065b 724 "s" if len(regions) > 1 else "",
kadonotakashi 0:8fdf9a60065b 725 ", ".join(r.name for r in regions)
kadonotakashi 0:8fdf9a60065b 726 ))
kadonotakashi 0:8fdf9a60065b 727 self._add_all_regions(regions, "MBED_APP")
kadonotakashi 0:8fdf9a60065b 728 if self.config.has_ram_regions:
kadonotakashi 0:8fdf9a60065b 729 regions = list(self.config.ram_regions)
kadonotakashi 0:8fdf9a60065b 730 self.notify.info("Using RAM region%s %s in this build." % (
kadonotakashi 0:8fdf9a60065b 731 "s" if len(regions) > 1 else "",
kadonotakashi 0:8fdf9a60065b 732 ", ".join(r.name for r in regions)
kadonotakashi 0:8fdf9a60065b 733 ))
kadonotakashi 0:8fdf9a60065b 734 self._add_all_regions(regions, "MBED_RAM")
kadonotakashi 0:8fdf9a60065b 735 try:
kadonotakashi 0:8fdf9a60065b 736 rom_start, rom_size = self.config.rom
kadonotakashi 0:8fdf9a60065b 737 Region = namedtuple("Region", "name start size")
kadonotakashi 0:8fdf9a60065b 738 self._add_defines_from_region(
kadonotakashi 0:8fdf9a60065b 739 Region("MBED_ROM", rom_start, rom_size),
kadonotakashi 0:8fdf9a60065b 740 suffixes=["_START", "_SIZE"]
kadonotakashi 0:8fdf9a60065b 741 )
kadonotakashi 0:8fdf9a60065b 742 except ConfigException:
kadonotakashi 0:8fdf9a60065b 743 pass
kadonotakashi 0:8fdf9a60065b 744
kadonotakashi 0:8fdf9a60065b 745 def add_linker_defines(self):
kadonotakashi 0:8fdf9a60065b 746 stack_param = "target.boot-stack-size"
kadonotakashi 0:8fdf9a60065b 747 params, _ = self.config_data
kadonotakashi 0:8fdf9a60065b 748
kadonotakashi 0:8fdf9a60065b 749 if stack_param in params:
kadonotakashi 0:8fdf9a60065b 750 define_string = self.make_ld_define("MBED_BOOT_STACK_SIZE", int(params[stack_param].value, 0))
kadonotakashi 0:8fdf9a60065b 751 self.ld.append(define_string)
kadonotakashi 0:8fdf9a60065b 752 self.flags["ld"].append(define_string)
kadonotakashi 0:8fdf9a60065b 753
kadonotakashi 0:8fdf9a60065b 754 # Set the configuration data
kadonotakashi 0:8fdf9a60065b 755 def set_config_data(self, config_data):
kadonotakashi 0:8fdf9a60065b 756 self.config_data = config_data
kadonotakashi 0:8fdf9a60065b 757 # new configuration data can change labels, so clear the cache
kadonotakashi 0:8fdf9a60065b 758 self.labels = None
kadonotakashi 0:8fdf9a60065b 759 # pass info about softdevice presence to linker (see NRF52)
kadonotakashi 0:8fdf9a60065b 760 if "SOFTDEVICE_PRESENT" in config_data[1]:
kadonotakashi 0:8fdf9a60065b 761 define_string = self.make_ld_define("SOFTDEVICE_PRESENT", config_data[1]["SOFTDEVICE_PRESENT"].macro_value)
kadonotakashi 0:8fdf9a60065b 762 self.ld.append(define_string)
kadonotakashi 0:8fdf9a60065b 763 self.flags["ld"].append(define_string)
kadonotakashi 0:8fdf9a60065b 764 self.add_regions()
kadonotakashi 0:8fdf9a60065b 765 self.add_linker_defines()
kadonotakashi 0:8fdf9a60065b 766
kadonotakashi 0:8fdf9a60065b 767 # Creates the configuration header if needed:
kadonotakashi 0:8fdf9a60065b 768 # - if there is no configuration data, "mbed_config.h" is not create (or deleted if it exists).
kadonotakashi 0:8fdf9a60065b 769 # - if there is configuration data and "mbed_config.h" does not exist, it is created.
kadonotakashi 0:8fdf9a60065b 770 # - if there is configuration data similar to the previous configuration data,
kadonotakashi 0:8fdf9a60065b 771 # "mbed_config.h" is left untouched.
kadonotakashi 0:8fdf9a60065b 772 # - if there is new configuration data, "mbed_config.h" is overriden.
kadonotakashi 0:8fdf9a60065b 773 # The function needs to be called exactly once for the lifetime of this toolchain instance.
kadonotakashi 0:8fdf9a60065b 774 # The "config_processed" variable (below) ensures this behaviour.
kadonotakashi 0:8fdf9a60065b 775 # The function returns the location of the configuration file, or None if there is no
kadonotakashi 0:8fdf9a60065b 776 # configuration data available (and thus no configuration file)
kadonotakashi 0:8fdf9a60065b 777 def get_config_header(self):
kadonotakashi 0:8fdf9a60065b 778 if self.config_processed: # this function was already called, return its result
kadonotakashi 0:8fdf9a60065b 779 return self.config_file
kadonotakashi 0:8fdf9a60065b 780 # The config file is located in the build directory
kadonotakashi 0:8fdf9a60065b 781 self.config_file = join(self.build_dir, self.MBED_CONFIG_FILE_NAME)
kadonotakashi 0:8fdf9a60065b 782 # If the file exists, read its current content in prev_data
kadonotakashi 0:8fdf9a60065b 783 if exists(self.config_file):
kadonotakashi 0:8fdf9a60065b 784 with open(self.config_file, "r") as f:
kadonotakashi 0:8fdf9a60065b 785 prev_data = f.read()
kadonotakashi 0:8fdf9a60065b 786 else:
kadonotakashi 0:8fdf9a60065b 787 prev_data = None
kadonotakashi 0:8fdf9a60065b 788 # Get the current configuration data
kadonotakashi 0:8fdf9a60065b 789 crt_data = self.config.config_to_header(self.config_data) if self.config_data else None
kadonotakashi 0:8fdf9a60065b 790 # "changed" indicates if a configuration change was detected
kadonotakashi 0:8fdf9a60065b 791 changed = False
kadonotakashi 0:8fdf9a60065b 792 if prev_data is not None: # a previous mbed_config.h exists
kadonotakashi 0:8fdf9a60065b 793 if crt_data is None: # no configuration data, so "mbed_config.h" needs to be removed
kadonotakashi 0:8fdf9a60065b 794 remove(self.config_file)
kadonotakashi 0:8fdf9a60065b 795 self.config_file = None # this means "config file not present"
kadonotakashi 0:8fdf9a60065b 796 changed = True
kadonotakashi 0:8fdf9a60065b 797 elif crt_data != prev_data: # different content of config file
kadonotakashi 0:8fdf9a60065b 798 with open(self.config_file, "w") as f:
kadonotakashi 0:8fdf9a60065b 799 f.write(crt_data)
kadonotakashi 0:8fdf9a60065b 800 changed = True
kadonotakashi 0:8fdf9a60065b 801 else: # a previous mbed_config.h does not exist
kadonotakashi 0:8fdf9a60065b 802 if crt_data is not None: # there's configuration data available
kadonotakashi 0:8fdf9a60065b 803 with open(self.config_file, "w") as f:
kadonotakashi 0:8fdf9a60065b 804 f.write(crt_data)
kadonotakashi 0:8fdf9a60065b 805 changed = True
kadonotakashi 0:8fdf9a60065b 806 else:
kadonotakashi 0:8fdf9a60065b 807 self.config_file = None # this means "config file not present"
kadonotakashi 0:8fdf9a60065b 808 # If there was a change in configuration, rebuild everything
kadonotakashi 0:8fdf9a60065b 809 self.build_all = changed
kadonotakashi 0:8fdf9a60065b 810 # Make sure that this function will only return the location of the configuration
kadonotakashi 0:8fdf9a60065b 811 # file for subsequent calls, without trying to manipulate its content in any way.
kadonotakashi 0:8fdf9a60065b 812 self.config_processed = True
kadonotakashi 0:8fdf9a60065b 813 return self.config_file
kadonotakashi 0:8fdf9a60065b 814
kadonotakashi 0:8fdf9a60065b 815 def dump_build_profile(self):
kadonotakashi 0:8fdf9a60065b 816 """Dump the current build profile and macros into the `.profile` file
kadonotakashi 0:8fdf9a60065b 817 in the build directory"""
kadonotakashi 0:8fdf9a60065b 818 for key in ["cxx", "c", "asm", "ld"]:
kadonotakashi 0:8fdf9a60065b 819 to_dump = {
kadonotakashi 0:8fdf9a60065b 820 "flags": sorted(self.flags[key]),
kadonotakashi 0:8fdf9a60065b 821 "macros": sorted(self.macros),
kadonotakashi 0:8fdf9a60065b 822 "symbols": sorted(self.get_symbols(for_asm=(key == "asm"))),
kadonotakashi 0:8fdf9a60065b 823 }
kadonotakashi 0:8fdf9a60065b 824 if key in ["cxx", "c"]:
kadonotakashi 0:8fdf9a60065b 825 to_dump["symbols"].remove('MBED_BUILD_TIMESTAMP=%s' % self.timestamp)
kadonotakashi 0:8fdf9a60065b 826 to_dump["flags"].extend(sorted(self.flags['common']))
kadonotakashi 0:8fdf9a60065b 827 where = join(self.build_dir, self.PROFILE_FILE_NAME + "-" + key)
kadonotakashi 0:8fdf9a60065b 828 self._overwrite_when_not_equal(where, json.dumps(
kadonotakashi 0:8fdf9a60065b 829 to_dump, sort_keys=True, indent=4))
kadonotakashi 0:8fdf9a60065b 830
kadonotakashi 0:8fdf9a60065b 831 @staticmethod
kadonotakashi 0:8fdf9a60065b 832 def _overwrite_when_not_equal(filename, content):
kadonotakashi 0:8fdf9a60065b 833 if not exists(filename) or content != open(filename).read():
kadonotakashi 0:8fdf9a60065b 834 with open(filename, "w") as out:
kadonotakashi 0:8fdf9a60065b 835 out.write(content)
kadonotakashi 0:8fdf9a60065b 836
kadonotakashi 0:8fdf9a60065b 837 @staticmethod
kadonotakashi 0:8fdf9a60065b 838 def generic_check_executable(tool_key, executable_name, levels_up,
kadonotakashi 0:8fdf9a60065b 839 nested_dir=None):
kadonotakashi 0:8fdf9a60065b 840 """
kadonotakashi 0:8fdf9a60065b 841 Positional args:
kadonotakashi 0:8fdf9a60065b 842 tool_key: the key to index TOOLCHAIN_PATHS
kadonotakashi 0:8fdf9a60065b 843 executable_name: the toolchain's named executable (ex. armcc)
kadonotakashi 0:8fdf9a60065b 844 levels_up: each toolchain joins the toolchain_path, some
kadonotakashi 0:8fdf9a60065b 845 variable directories (bin, include), and the executable name,
kadonotakashi 0:8fdf9a60065b 846 so the TOOLCHAIN_PATH value must be appropriately distanced
kadonotakashi 0:8fdf9a60065b 847
kadonotakashi 0:8fdf9a60065b 848 Keyword args:
kadonotakashi 0:8fdf9a60065b 849 nested_dir: the directory within TOOLCHAIN_PATHS where the executable
kadonotakashi 0:8fdf9a60065b 850 is found (ex: 'bin' for ARM\bin\armcc (necessary to check for path
kadonotakashi 0:8fdf9a60065b 851 that will be used by toolchain's compile)
kadonotakashi 0:8fdf9a60065b 852
kadonotakashi 0:8fdf9a60065b 853 Returns True if the executable location specified by the user
kadonotakashi 0:8fdf9a60065b 854 exists and is valid OR the executable can be found on the PATH.
kadonotakashi 0:8fdf9a60065b 855 Returns False otherwise.
kadonotakashi 0:8fdf9a60065b 856 """
kadonotakashi 0:8fdf9a60065b 857 # Search PATH if user did not specify a path or specified path doesn't
kadonotakashi 0:8fdf9a60065b 858 # exist.
kadonotakashi 0:8fdf9a60065b 859 if not TOOLCHAIN_PATHS[tool_key] or not exists(TOOLCHAIN_PATHS[tool_key]):
kadonotakashi 0:8fdf9a60065b 860 exe = find_executable(executable_name)
kadonotakashi 0:8fdf9a60065b 861 if not exe:
kadonotakashi 0:8fdf9a60065b 862 return False
kadonotakashi 0:8fdf9a60065b 863 for level in range(levels_up):
kadonotakashi 0:8fdf9a60065b 864 # move up the specified number of directories
kadonotakashi 0:8fdf9a60065b 865 exe = dirname(exe)
kadonotakashi 0:8fdf9a60065b 866 TOOLCHAIN_PATHS[tool_key] = exe
kadonotakashi 0:8fdf9a60065b 867 if nested_dir:
kadonotakashi 0:8fdf9a60065b 868 subdir = join(TOOLCHAIN_PATHS[tool_key], nested_dir,
kadonotakashi 0:8fdf9a60065b 869 executable_name)
kadonotakashi 0:8fdf9a60065b 870 else:
kadonotakashi 0:8fdf9a60065b 871 subdir = join(TOOLCHAIN_PATHS[tool_key],executable_name)
kadonotakashi 0:8fdf9a60065b 872 # User could have specified a path that exists but does not contain exe
kadonotakashi 0:8fdf9a60065b 873 return exists(subdir) or exists(subdir +'.exe')
kadonotakashi 0:8fdf9a60065b 874
kadonotakashi 0:8fdf9a60065b 875 @abstractmethod
kadonotakashi 0:8fdf9a60065b 876 def check_executable(self):
kadonotakashi 0:8fdf9a60065b 877 """Returns True if the executable (armcc) location specified by the
kadonotakashi 0:8fdf9a60065b 878 user exists OR the executable can be found on the PATH.
kadonotakashi 0:8fdf9a60065b 879 Returns False otherwise."""
kadonotakashi 0:8fdf9a60065b 880 raise NotImplemented
kadonotakashi 0:8fdf9a60065b 881
kadonotakashi 0:8fdf9a60065b 882 @abstractmethod
kadonotakashi 0:8fdf9a60065b 883 def get_config_option(self, config_header):
kadonotakashi 0:8fdf9a60065b 884 """Generate the compiler option that forces the inclusion of the configuration
kadonotakashi 0:8fdf9a60065b 885 header file.
kadonotakashi 0:8fdf9a60065b 886
kadonotakashi 0:8fdf9a60065b 887 Positional arguments:
kadonotakashi 0:8fdf9a60065b 888 config_header -- The configuration header that will be included within all source files
kadonotakashi 0:8fdf9a60065b 889
kadonotakashi 0:8fdf9a60065b 890 Return value:
kadonotakashi 0:8fdf9a60065b 891 A list of the command line arguments that will force the inclusion the specified header
kadonotakashi 0:8fdf9a60065b 892
kadonotakashi 0:8fdf9a60065b 893 Side effects:
kadonotakashi 0:8fdf9a60065b 894 None
kadonotakashi 0:8fdf9a60065b 895 """
kadonotakashi 0:8fdf9a60065b 896 raise NotImplemented
kadonotakashi 0:8fdf9a60065b 897
kadonotakashi 0:8fdf9a60065b 898 @abstractmethod
kadonotakashi 0:8fdf9a60065b 899 def get_compile_options(self, defines, includes, for_asm=False):
kadonotakashi 0:8fdf9a60065b 900 """Generate the compiler options from the defines and includes
kadonotakashi 0:8fdf9a60065b 901
kadonotakashi 0:8fdf9a60065b 902 Positional arguments:
kadonotakashi 0:8fdf9a60065b 903 defines -- The preprocessor macros defined on the command line
kadonotakashi 0:8fdf9a60065b 904 includes -- The include file search paths
kadonotakashi 0:8fdf9a60065b 905
kadonotakashi 0:8fdf9a60065b 906 Keyword arguments:
kadonotakashi 0:8fdf9a60065b 907 for_asm -- generate the assembler options instead of the compiler options
kadonotakashi 0:8fdf9a60065b 908
kadonotakashi 0:8fdf9a60065b 909 Return value:
kadonotakashi 0:8fdf9a60065b 910 A list of the command line arguments that will force the inclusion the specified header
kadonotakashi 0:8fdf9a60065b 911
kadonotakashi 0:8fdf9a60065b 912 Side effects:
kadonotakashi 0:8fdf9a60065b 913 None
kadonotakashi 0:8fdf9a60065b 914 """
kadonotakashi 0:8fdf9a60065b 915 raise NotImplemented
kadonotakashi 0:8fdf9a60065b 916
kadonotakashi 0:8fdf9a60065b 917 @abstractmethod
kadonotakashi 0:8fdf9a60065b 918 def assemble(self, source, object, includes):
kadonotakashi 0:8fdf9a60065b 919 """Generate the command line that assembles.
kadonotakashi 0:8fdf9a60065b 920
kadonotakashi 0:8fdf9a60065b 921 Positional arguments:
kadonotakashi 0:8fdf9a60065b 922 source -- a file path that is the file to assemble
kadonotakashi 0:8fdf9a60065b 923 object -- a file path that is the destination object
kadonotakashi 0:8fdf9a60065b 924 includes -- a list of all directories where header files may be found
kadonotakashi 0:8fdf9a60065b 925
kadonotakashi 0:8fdf9a60065b 926 Return value:
kadonotakashi 0:8fdf9a60065b 927 The complete command line, as a list, that would invoke the assembler
kadonotakashi 0:8fdf9a60065b 928 on the source file, include all the include paths, and generate
kadonotakashi 0:8fdf9a60065b 929 the specified object file.
kadonotakashi 0:8fdf9a60065b 930
kadonotakashi 0:8fdf9a60065b 931 Side effects:
kadonotakashi 0:8fdf9a60065b 932 None
kadonotakashi 0:8fdf9a60065b 933
kadonotakashi 0:8fdf9a60065b 934 Note:
kadonotakashi 0:8fdf9a60065b 935 This method should be decorated with @hook_tool.
kadonotakashi 0:8fdf9a60065b 936 """
kadonotakashi 0:8fdf9a60065b 937 raise NotImplemented
kadonotakashi 0:8fdf9a60065b 938
kadonotakashi 0:8fdf9a60065b 939 @abstractmethod
kadonotakashi 0:8fdf9a60065b 940 def compile_c(self, source, object, includes):
kadonotakashi 0:8fdf9a60065b 941 """Generate the command line that compiles a C source file.
kadonotakashi 0:8fdf9a60065b 942
kadonotakashi 0:8fdf9a60065b 943 Positional arguments:
kadonotakashi 0:8fdf9a60065b 944 source -- the C source file to compile
kadonotakashi 0:8fdf9a60065b 945 object -- the destination object file
kadonotakashi 0:8fdf9a60065b 946 includes -- a list of all the directories where header files may be found
kadonotakashi 0:8fdf9a60065b 947
kadonotakashi 0:8fdf9a60065b 948 Return value:
kadonotakashi 0:8fdf9a60065b 949 The complete command line, as a list, that would invoke the C compiler
kadonotakashi 0:8fdf9a60065b 950 on the source file, include all the include paths, and generate the
kadonotakashi 0:8fdf9a60065b 951 specified object file.
kadonotakashi 0:8fdf9a60065b 952
kadonotakashi 0:8fdf9a60065b 953 Side effects:
kadonotakashi 0:8fdf9a60065b 954 None
kadonotakashi 0:8fdf9a60065b 955
kadonotakashi 0:8fdf9a60065b 956 Note:
kadonotakashi 0:8fdf9a60065b 957 This method should be decorated with @hook_tool.
kadonotakashi 0:8fdf9a60065b 958 """
kadonotakashi 0:8fdf9a60065b 959 raise NotImplemented
kadonotakashi 0:8fdf9a60065b 960
kadonotakashi 0:8fdf9a60065b 961 @abstractmethod
kadonotakashi 0:8fdf9a60065b 962 def compile_cpp(self, source, object, includes):
kadonotakashi 0:8fdf9a60065b 963 """Generate the command line that compiles a C++ source file.
kadonotakashi 0:8fdf9a60065b 964
kadonotakashi 0:8fdf9a60065b 965 Positional arguments:
kadonotakashi 0:8fdf9a60065b 966 source -- the C++ source file to compile
kadonotakashi 0:8fdf9a60065b 967 object -- the destination object file
kadonotakashi 0:8fdf9a60065b 968 includes -- a list of all the directories where header files may be found
kadonotakashi 0:8fdf9a60065b 969
kadonotakashi 0:8fdf9a60065b 970 Return value:
kadonotakashi 0:8fdf9a60065b 971 The complete command line, as a list, that would invoke the C++ compiler
kadonotakashi 0:8fdf9a60065b 972 on the source file, include all the include paths, and generate the
kadonotakashi 0:8fdf9a60065b 973 specified object file.
kadonotakashi 0:8fdf9a60065b 974
kadonotakashi 0:8fdf9a60065b 975 Side effects:
kadonotakashi 0:8fdf9a60065b 976 None
kadonotakashi 0:8fdf9a60065b 977
kadonotakashi 0:8fdf9a60065b 978 Note:
kadonotakashi 0:8fdf9a60065b 979 This method should be decorated with @hook_tool.
kadonotakashi 0:8fdf9a60065b 980 """
kadonotakashi 0:8fdf9a60065b 981 raise NotImplemented
kadonotakashi 0:8fdf9a60065b 982
kadonotakashi 0:8fdf9a60065b 983 @abstractmethod
kadonotakashi 0:8fdf9a60065b 984 def link(self, output, objects, libraries, lib_dirs, mem_map):
kadonotakashi 0:8fdf9a60065b 985 """Run the linker to create an executable and memory map.
kadonotakashi 0:8fdf9a60065b 986
kadonotakashi 0:8fdf9a60065b 987 Positional arguments:
kadonotakashi 0:8fdf9a60065b 988 output -- the file name to place the executable in
kadonotakashi 0:8fdf9a60065b 989 objects -- all of the object files to link
kadonotakashi 0:8fdf9a60065b 990 libraries -- all of the required libraries
kadonotakashi 0:8fdf9a60065b 991 lib_dirs -- where the required libraries are located
kadonotakashi 0:8fdf9a60065b 992 mem_map -- the location where the memory map file should be stored
kadonotakashi 0:8fdf9a60065b 993
kadonotakashi 0:8fdf9a60065b 994 Return value:
kadonotakashi 0:8fdf9a60065b 995 None
kadonotakashi 0:8fdf9a60065b 996
kadonotakashi 0:8fdf9a60065b 997 Side effect:
kadonotakashi 0:8fdf9a60065b 998 Runs the linker to produce the executable.
kadonotakashi 0:8fdf9a60065b 999
kadonotakashi 0:8fdf9a60065b 1000 Note:
kadonotakashi 0:8fdf9a60065b 1001 This method should be decorated with @hook_tool.
kadonotakashi 0:8fdf9a60065b 1002 """
kadonotakashi 0:8fdf9a60065b 1003 raise NotImplemented
kadonotakashi 0:8fdf9a60065b 1004
kadonotakashi 0:8fdf9a60065b 1005 @abstractmethod
kadonotakashi 0:8fdf9a60065b 1006 def archive(self, objects, lib_path):
kadonotakashi 0:8fdf9a60065b 1007 """Run the command line that creates an archive.
kadonotakashi 0:8fdf9a60065b 1008
kadonotakashi 0:8fdf9a60065b 1009 Positional arguhments:
kadonotakashi 0:8fdf9a60065b 1010 objects -- a list of all the object files that should be archived
kadonotakashi 0:8fdf9a60065b 1011 lib_path -- the file name of the resulting library file
kadonotakashi 0:8fdf9a60065b 1012
kadonotakashi 0:8fdf9a60065b 1013 Return value:
kadonotakashi 0:8fdf9a60065b 1014 None
kadonotakashi 0:8fdf9a60065b 1015
kadonotakashi 0:8fdf9a60065b 1016 Side effect:
kadonotakashi 0:8fdf9a60065b 1017 Runs the archiving tool to produce the library file.
kadonotakashi 0:8fdf9a60065b 1018
kadonotakashi 0:8fdf9a60065b 1019 Note:
kadonotakashi 0:8fdf9a60065b 1020 This method should be decorated with @hook_tool.
kadonotakashi 0:8fdf9a60065b 1021 """
kadonotakashi 0:8fdf9a60065b 1022 raise NotImplemented
kadonotakashi 0:8fdf9a60065b 1023
kadonotakashi 0:8fdf9a60065b 1024 @abstractmethod
kadonotakashi 0:8fdf9a60065b 1025 def binary(self, resources, elf, bin):
kadonotakashi 0:8fdf9a60065b 1026 """Run the command line that will Extract a simplified binary file.
kadonotakashi 0:8fdf9a60065b 1027
kadonotakashi 0:8fdf9a60065b 1028 Positional arguments:
kadonotakashi 0:8fdf9a60065b 1029 resources -- A resources object (Is not used in any of the toolchains)
kadonotakashi 0:8fdf9a60065b 1030 elf -- the executable file that is to be converted
kadonotakashi 0:8fdf9a60065b 1031 bin -- the file name of the to be created simplified binary file
kadonotakashi 0:8fdf9a60065b 1032
kadonotakashi 0:8fdf9a60065b 1033 Return value:
kadonotakashi 0:8fdf9a60065b 1034 None
kadonotakashi 0:8fdf9a60065b 1035
kadonotakashi 0:8fdf9a60065b 1036 Side effect:
kadonotakashi 0:8fdf9a60065b 1037 Runs the elf2bin tool to produce the simplified binary file.
kadonotakashi 0:8fdf9a60065b 1038
kadonotakashi 0:8fdf9a60065b 1039 Note:
kadonotakashi 0:8fdf9a60065b 1040 This method should be decorated with @hook_tool.
kadonotakashi 0:8fdf9a60065b 1041 """
kadonotakashi 0:8fdf9a60065b 1042 raise NotImplemented
kadonotakashi 0:8fdf9a60065b 1043
kadonotakashi 0:8fdf9a60065b 1044 @staticmethod
kadonotakashi 0:8fdf9a60065b 1045 @abstractmethod
kadonotakashi 0:8fdf9a60065b 1046 def name_mangle(name):
kadonotakashi 0:8fdf9a60065b 1047 """Mangle a name based on the conventional name mangling of this toolchain
kadonotakashi 0:8fdf9a60065b 1048
kadonotakashi 0:8fdf9a60065b 1049 Positional arguments:
kadonotakashi 0:8fdf9a60065b 1050 name -- the name to mangle
kadonotakashi 0:8fdf9a60065b 1051
kadonotakashi 0:8fdf9a60065b 1052 Return:
kadonotakashi 0:8fdf9a60065b 1053 the mangled name as a string
kadonotakashi 0:8fdf9a60065b 1054 """
kadonotakashi 0:8fdf9a60065b 1055 raise NotImplemented
kadonotakashi 0:8fdf9a60065b 1056
kadonotakashi 0:8fdf9a60065b 1057 @staticmethod
kadonotakashi 0:8fdf9a60065b 1058 @abstractmethod
kadonotakashi 0:8fdf9a60065b 1059 def make_ld_define(name, value):
kadonotakashi 0:8fdf9a60065b 1060 """Create an argument to the linker that would define a symbol
kadonotakashi 0:8fdf9a60065b 1061
kadonotakashi 0:8fdf9a60065b 1062 Positional arguments:
kadonotakashi 0:8fdf9a60065b 1063 name -- the symbol to define
kadonotakashi 0:8fdf9a60065b 1064 value -- the value to give the symbol
kadonotakashi 0:8fdf9a60065b 1065
kadonotakashi 0:8fdf9a60065b 1066 Return:
kadonotakashi 0:8fdf9a60065b 1067 The linker flag as a string
kadonotakashi 0:8fdf9a60065b 1068 """
kadonotakashi 0:8fdf9a60065b 1069 raise NotImplemented
kadonotakashi 0:8fdf9a60065b 1070
kadonotakashi 0:8fdf9a60065b 1071 @staticmethod
kadonotakashi 0:8fdf9a60065b 1072 @abstractmethod
kadonotakashi 0:8fdf9a60065b 1073 def redirect_symbol(source, sync, build_dir):
kadonotakashi 0:8fdf9a60065b 1074 """Redirect a symbol at link time to point at somewhere else
kadonotakashi 0:8fdf9a60065b 1075
kadonotakashi 0:8fdf9a60065b 1076 Positional arguments:
kadonotakashi 0:8fdf9a60065b 1077 source -- the symbol doing the pointing
kadonotakashi 0:8fdf9a60065b 1078 sync -- the symbol being pointed to
kadonotakashi 0:8fdf9a60065b 1079 build_dir -- the directory to put "response files" if needed by the toolchain
kadonotakashi 0:8fdf9a60065b 1080
kadonotakashi 0:8fdf9a60065b 1081 Side Effects:
kadonotakashi 0:8fdf9a60065b 1082 Possibly create a file in the build directory
kadonotakashi 0:8fdf9a60065b 1083
kadonotakashi 0:8fdf9a60065b 1084 Return:
kadonotakashi 0:8fdf9a60065b 1085 The linker flag to redirect the symbol, as a string
kadonotakashi 0:8fdf9a60065b 1086 """
kadonotakashi 0:8fdf9a60065b 1087 raise NotImplemented
kadonotakashi 0:8fdf9a60065b 1088
kadonotakashi 0:8fdf9a60065b 1089 # Return the list of macros geenrated by the build system
kadonotakashi 0:8fdf9a60065b 1090 def get_config_macros(self):
kadonotakashi 0:8fdf9a60065b 1091 return self.config.config_to_macros(self.config_data) if self.config_data else []
kadonotakashi 0:8fdf9a60065b 1092
kadonotakashi 0:8fdf9a60065b 1093 @abstractmethod
kadonotakashi 0:8fdf9a60065b 1094 def version_check(self):
kadonotakashi 0:8fdf9a60065b 1095 """Check the version of a compiler being used and raise a
kadonotakashi 0:8fdf9a60065b 1096 NotSupportedException when it's incorrect.
kadonotakashi 0:8fdf9a60065b 1097 """
kadonotakashi 0:8fdf9a60065b 1098 raise NotImplemented
kadonotakashi 0:8fdf9a60065b 1099
kadonotakashi 0:8fdf9a60065b 1100 @property
kadonotakashi 0:8fdf9a60065b 1101 def report(self):
kadonotakashi 0:8fdf9a60065b 1102 to_ret = {}
kadonotakashi 0:8fdf9a60065b 1103 to_ret['c_compiler'] = {'flags': copy(self.flags['c']),
kadonotakashi 0:8fdf9a60065b 1104 'symbols': self.get_symbols()}
kadonotakashi 0:8fdf9a60065b 1105 to_ret['cxx_compiler'] = {'flags': copy(self.flags['cxx']),
kadonotakashi 0:8fdf9a60065b 1106 'symbols': self.get_symbols()}
kadonotakashi 0:8fdf9a60065b 1107 to_ret['assembler'] = {'flags': copy(self.flags['asm']),
kadonotakashi 0:8fdf9a60065b 1108 'symbols': self.get_symbols(True)}
kadonotakashi 0:8fdf9a60065b 1109 to_ret['linker'] = {'flags': copy(self.flags['ld'])}
kadonotakashi 0:8fdf9a60065b 1110 to_ret.update(self.config.report)
kadonotakashi 0:8fdf9a60065b 1111 return to_ret
kadonotakashi 0:8fdf9a60065b 1112
kadonotakashi 0:8fdf9a60065b 1113 from tools.settings import ARM_PATH, ARMC6_PATH, GCC_ARM_PATH, IAR_PATH
kadonotakashi 0:8fdf9a60065b 1114
kadonotakashi 0:8fdf9a60065b 1115 TOOLCHAIN_PATHS = {
kadonotakashi 0:8fdf9a60065b 1116 'ARM': ARM_PATH,
kadonotakashi 0:8fdf9a60065b 1117 'uARM': ARM_PATH,
kadonotakashi 0:8fdf9a60065b 1118 'ARMC6': ARMC6_PATH,
kadonotakashi 0:8fdf9a60065b 1119 'GCC_ARM': GCC_ARM_PATH,
kadonotakashi 0:8fdf9a60065b 1120 'IAR': IAR_PATH
kadonotakashi 0:8fdf9a60065b 1121 }
kadonotakashi 0:8fdf9a60065b 1122
kadonotakashi 0:8fdf9a60065b 1123 from tools.toolchains.arm import ARM_STD, ARM_MICRO, ARMC6
kadonotakashi 0:8fdf9a60065b 1124 from tools.toolchains.gcc import GCC_ARM
kadonotakashi 0:8fdf9a60065b 1125 from tools.toolchains.iar import IAR
kadonotakashi 0:8fdf9a60065b 1126
kadonotakashi 0:8fdf9a60065b 1127 TOOLCHAIN_CLASSES = {
kadonotakashi 0:8fdf9a60065b 1128 u'ARM': ARM_STD,
kadonotakashi 0:8fdf9a60065b 1129 u'uARM': ARM_MICRO,
kadonotakashi 0:8fdf9a60065b 1130 u'ARMC6': ARMC6,
kadonotakashi 0:8fdf9a60065b 1131 u'GCC_ARM': GCC_ARM,
kadonotakashi 0:8fdf9a60065b 1132 u'IAR': IAR
kadonotakashi 0:8fdf9a60065b 1133 }
kadonotakashi 0:8fdf9a60065b 1134
kadonotakashi 0:8fdf9a60065b 1135 TOOLCHAINS = set(TOOLCHAIN_CLASSES.keys())