Color Oled(SSD1331) connect to STMicroelectronics Nucleo-F466

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Thu Oct 11 02:27:46 2018 +0000
Revision:
3:f3764f852aa8
Parent:
0:8fdf9a60065b
Nucreo 446 + SSD1331 test version;

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-2016 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 tempfile
kadonotakashi 0:8fdf9a60065b 21 import datetime
kadonotakashi 0:8fdf9a60065b 22 import uuid
kadonotakashi 0:8fdf9a60065b 23 import struct
kadonotakashi 0:8fdf9a60065b 24 import zlib
kadonotakashi 0:8fdf9a60065b 25 import hashlib
kadonotakashi 0:8fdf9a60065b 26 from shutil import rmtree
kadonotakashi 0:8fdf9a60065b 27 from os.path import join, exists, dirname, basename, abspath, normpath, splitext
kadonotakashi 0:8fdf9a60065b 28 from os.path import relpath
kadonotakashi 0:8fdf9a60065b 29 from os import linesep, remove, makedirs
kadonotakashi 0:8fdf9a60065b 30 from time import time
kadonotakashi 0:8fdf9a60065b 31 from intelhex import IntelHex
kadonotakashi 0:8fdf9a60065b 32 from json import load, dump
kadonotakashi 0:8fdf9a60065b 33 from jinja2 import FileSystemLoader
kadonotakashi 0:8fdf9a60065b 34 from jinja2.environment import Environment
kadonotakashi 0:8fdf9a60065b 35
kadonotakashi 0:8fdf9a60065b 36 from .arm_pack_manager import Cache
kadonotakashi 0:8fdf9a60065b 37 from .utils import (mkdir, run_cmd, run_cmd_ext, NotSupportedException,
kadonotakashi 0:8fdf9a60065b 38 ToolException, InvalidReleaseTargetException,
kadonotakashi 0:8fdf9a60065b 39 intelhex_offset, integer, generate_update_filename)
kadonotakashi 0:8fdf9a60065b 40 from .paths import (MBED_CMSIS_PATH, MBED_TARGETS_PATH, MBED_LIBRARIES,
kadonotakashi 0:8fdf9a60065b 41 MBED_HEADER, MBED_DRIVERS, MBED_PLATFORM, MBED_HAL,
kadonotakashi 0:8fdf9a60065b 42 MBED_CONFIG_FILE, MBED_LIBRARIES_DRIVERS,
kadonotakashi 0:8fdf9a60065b 43 MBED_LIBRARIES_PLATFORM, MBED_LIBRARIES_HAL,
kadonotakashi 0:8fdf9a60065b 44 BUILD_DIR)
kadonotakashi 0:8fdf9a60065b 45 from .resources import Resources, FileType, FileRef
kadonotakashi 0:8fdf9a60065b 46 from .notifier.mock import MockNotifier
kadonotakashi 0:8fdf9a60065b 47 from .targets import TARGET_NAMES, TARGET_MAP, CORE_ARCH
kadonotakashi 0:8fdf9a60065b 48 from .libraries import Library
kadonotakashi 0:8fdf9a60065b 49 from .toolchains import TOOLCHAIN_CLASSES
kadonotakashi 0:8fdf9a60065b 50 from .config import Config
kadonotakashi 0:8fdf9a60065b 51
kadonotakashi 0:8fdf9a60065b 52 RELEASE_VERSIONS = ['2', '5']
kadonotakashi 0:8fdf9a60065b 53
kadonotakashi 0:8fdf9a60065b 54 def prep_report(report, target_name, toolchain_name, id_name):
kadonotakashi 0:8fdf9a60065b 55 """Setup report keys
kadonotakashi 0:8fdf9a60065b 56
kadonotakashi 0:8fdf9a60065b 57 Positional arguments:
kadonotakashi 0:8fdf9a60065b 58 report - the report to fill
kadonotakashi 0:8fdf9a60065b 59 target_name - the target being used
kadonotakashi 0:8fdf9a60065b 60 toolchain_name - the toolchain being used
kadonotakashi 0:8fdf9a60065b 61 id_name - the name of the executable or library being built
kadonotakashi 0:8fdf9a60065b 62 """
kadonotakashi 0:8fdf9a60065b 63 if not target_name in report:
kadonotakashi 0:8fdf9a60065b 64 report[target_name] = {}
kadonotakashi 0:8fdf9a60065b 65
kadonotakashi 0:8fdf9a60065b 66 if not toolchain_name in report[target_name]:
kadonotakashi 0:8fdf9a60065b 67 report[target_name][toolchain_name] = {}
kadonotakashi 0:8fdf9a60065b 68
kadonotakashi 0:8fdf9a60065b 69 if not id_name in report[target_name][toolchain_name]:
kadonotakashi 0:8fdf9a60065b 70 report[target_name][toolchain_name][id_name] = []
kadonotakashi 0:8fdf9a60065b 71
kadonotakashi 0:8fdf9a60065b 72 def prep_properties(properties, target_name, toolchain_name, vendor_label):
kadonotakashi 0:8fdf9a60065b 73 """Setup test properties
kadonotakashi 0:8fdf9a60065b 74
kadonotakashi 0:8fdf9a60065b 75 Positional arguments:
kadonotakashi 0:8fdf9a60065b 76 properties - the dict to fill
kadonotakashi 0:8fdf9a60065b 77 target_name - the target the test is targeting
kadonotakashi 0:8fdf9a60065b 78 toolchain_name - the toolchain that will compile the test
kadonotakashi 0:8fdf9a60065b 79 vendor_label - the vendor
kadonotakashi 0:8fdf9a60065b 80 """
kadonotakashi 0:8fdf9a60065b 81 if not target_name in properties:
kadonotakashi 0:8fdf9a60065b 82 properties[target_name] = {}
kadonotakashi 0:8fdf9a60065b 83
kadonotakashi 0:8fdf9a60065b 84 if not toolchain_name in properties[target_name]:
kadonotakashi 0:8fdf9a60065b 85 properties[target_name][toolchain_name] = {}
kadonotakashi 0:8fdf9a60065b 86
kadonotakashi 0:8fdf9a60065b 87 properties[target_name][toolchain_name]["target"] = target_name
kadonotakashi 0:8fdf9a60065b 88 properties[target_name][toolchain_name]["vendor"] = vendor_label
kadonotakashi 0:8fdf9a60065b 89 properties[target_name][toolchain_name]["toolchain"] = toolchain_name
kadonotakashi 0:8fdf9a60065b 90
kadonotakashi 0:8fdf9a60065b 91 def create_result(target_name, toolchain_name, id_name, description):
kadonotakashi 0:8fdf9a60065b 92 """Create a result dictionary
kadonotakashi 0:8fdf9a60065b 93
kadonotakashi 0:8fdf9a60065b 94 Positional arguments:
kadonotakashi 0:8fdf9a60065b 95 target_name - the target being built for
kadonotakashi 0:8fdf9a60065b 96 toolchain_name - the toolchain doing the building
kadonotakashi 0:8fdf9a60065b 97 id_name - the name of the executable or library being built
kadonotakashi 0:8fdf9a60065b 98 description - a human readable description of what's going on
kadonotakashi 0:8fdf9a60065b 99 """
kadonotakashi 0:8fdf9a60065b 100 cur_result = {}
kadonotakashi 0:8fdf9a60065b 101 cur_result["target_name"] = target_name
kadonotakashi 0:8fdf9a60065b 102 cur_result["toolchain_name"] = toolchain_name
kadonotakashi 0:8fdf9a60065b 103 cur_result["id"] = id_name
kadonotakashi 0:8fdf9a60065b 104 cur_result["description"] = description
kadonotakashi 0:8fdf9a60065b 105 cur_result["elapsed_time"] = 0
kadonotakashi 0:8fdf9a60065b 106 cur_result["output"] = ""
kadonotakashi 0:8fdf9a60065b 107
kadonotakashi 0:8fdf9a60065b 108 return cur_result
kadonotakashi 0:8fdf9a60065b 109
kadonotakashi 0:8fdf9a60065b 110 def add_result_to_report(report, result):
kadonotakashi 0:8fdf9a60065b 111 """Add a single result to a report dictionary
kadonotakashi 0:8fdf9a60065b 112
kadonotakashi 0:8fdf9a60065b 113 Positional arguments:
kadonotakashi 0:8fdf9a60065b 114 report - the report to append to
kadonotakashi 0:8fdf9a60065b 115 result - the result to append
kadonotakashi 0:8fdf9a60065b 116 """
kadonotakashi 0:8fdf9a60065b 117 result["date"] = datetime.datetime.utcnow().isoformat()
kadonotakashi 0:8fdf9a60065b 118 result["uuid"] = str(uuid.uuid1())
kadonotakashi 0:8fdf9a60065b 119 target = result["target_name"]
kadonotakashi 0:8fdf9a60065b 120 toolchain = result["toolchain_name"]
kadonotakashi 0:8fdf9a60065b 121 id_name = result['id']
kadonotakashi 0:8fdf9a60065b 122 result_wrap = {0: result}
kadonotakashi 0:8fdf9a60065b 123 report[target][toolchain][id_name].append(result_wrap)
kadonotakashi 0:8fdf9a60065b 124
kadonotakashi 0:8fdf9a60065b 125 def get_config(src_paths, target, toolchain_name=None, app_config=None):
kadonotakashi 0:8fdf9a60065b 126 """Get the configuration object for a target-toolchain combination
kadonotakashi 0:8fdf9a60065b 127
kadonotakashi 0:8fdf9a60065b 128 Positional arguments:
kadonotakashi 0:8fdf9a60065b 129 src_paths - paths to scan for the configuration files
kadonotakashi 0:8fdf9a60065b 130 target - the device we are building for
kadonotakashi 0:8fdf9a60065b 131 toolchain_name - the string that identifies the build tools
kadonotakashi 0:8fdf9a60065b 132 """
kadonotakashi 0:8fdf9a60065b 133 # Convert src_paths to a list if needed
kadonotakashi 0:8fdf9a60065b 134 if not isinstance(src_paths, list):
kadonotakashi 0:8fdf9a60065b 135 src_paths = [src_paths]
kadonotakashi 0:8fdf9a60065b 136
kadonotakashi 0:8fdf9a60065b 137 res = Resources(MockNotifier())
kadonotakashi 0:8fdf9a60065b 138 if toolchain_name:
kadonotakashi 0:8fdf9a60065b 139 toolchain = prepare_toolchain(src_paths, None, target, toolchain_name,
kadonotakashi 0:8fdf9a60065b 140 app_config=app_config)
kadonotakashi 0:8fdf9a60065b 141 config = toolchain.config
kadonotakashi 0:8fdf9a60065b 142 res.scan_with_toolchain(src_paths, toolchain, exclude=False)
kadonotakashi 0:8fdf9a60065b 143 else:
kadonotakashi 0:8fdf9a60065b 144 config = Config(target, src_paths, app_config=app_config)
kadonotakashi 0:8fdf9a60065b 145 res.scan_with_config(src_paths, config)
kadonotakashi 0:8fdf9a60065b 146 if config.has_regions:
kadonotakashi 0:8fdf9a60065b 147 _ = list(config.regions)
kadonotakashi 0:8fdf9a60065b 148
kadonotakashi 0:8fdf9a60065b 149 cfg, macros = config.get_config_data()
kadonotakashi 0:8fdf9a60065b 150 features = config.get_features()
kadonotakashi 0:8fdf9a60065b 151 return cfg, macros, features
kadonotakashi 0:8fdf9a60065b 152
kadonotakashi 0:8fdf9a60065b 153 def is_official_target(target_name, version):
kadonotakashi 0:8fdf9a60065b 154 """ Returns True, None if a target is part of the official release for the
kadonotakashi 0:8fdf9a60065b 155 given version. Return False, 'reason' if a target is not part of the
kadonotakashi 0:8fdf9a60065b 156 official release for the given version.
kadonotakashi 0:8fdf9a60065b 157
kadonotakashi 0:8fdf9a60065b 158 Positional arguments:
kadonotakashi 0:8fdf9a60065b 159 target_name - Name if the target (ex. 'K64F')
kadonotakashi 0:8fdf9a60065b 160 version - The release version string. Should be a string contained within
kadonotakashi 0:8fdf9a60065b 161 RELEASE_VERSIONS
kadonotakashi 0:8fdf9a60065b 162 """
kadonotakashi 0:8fdf9a60065b 163
kadonotakashi 0:8fdf9a60065b 164 result = True
kadonotakashi 0:8fdf9a60065b 165 reason = None
kadonotakashi 0:8fdf9a60065b 166 target = TARGET_MAP[target_name]
kadonotakashi 0:8fdf9a60065b 167
kadonotakashi 0:8fdf9a60065b 168 if hasattr(target, 'release_versions') \
kadonotakashi 0:8fdf9a60065b 169 and version in target.release_versions:
kadonotakashi 0:8fdf9a60065b 170 if version == '2':
kadonotakashi 0:8fdf9a60065b 171 # For version 2, either ARM or uARM toolchain support is required
kadonotakashi 0:8fdf9a60065b 172 required_toolchains = set(['ARM', 'uARM'])
kadonotakashi 0:8fdf9a60065b 173
kadonotakashi 0:8fdf9a60065b 174 if not len(required_toolchains.intersection(
kadonotakashi 0:8fdf9a60065b 175 set(target.supported_toolchains))) > 0:
kadonotakashi 0:8fdf9a60065b 176 result = False
kadonotakashi 0:8fdf9a60065b 177 reason = ("Target '%s' must support " % target.name) + \
kadonotakashi 0:8fdf9a60065b 178 ("one of the folowing toolchains to be included in the") + \
kadonotakashi 0:8fdf9a60065b 179 ((" mbed 2.0 official release: %s" + linesep) %
kadonotakashi 0:8fdf9a60065b 180 ", ".join(required_toolchains)) + \
kadonotakashi 0:8fdf9a60065b 181 ("Currently it is only configured to support the ") + \
kadonotakashi 0:8fdf9a60065b 182 ("following toolchains: %s" %
kadonotakashi 0:8fdf9a60065b 183 ", ".join(target.supported_toolchains))
kadonotakashi 0:8fdf9a60065b 184
kadonotakashi 0:8fdf9a60065b 185 elif version == '5':
kadonotakashi 0:8fdf9a60065b 186 # For version 5, ARM, GCC_ARM, and IAR toolchain support is required
kadonotakashi 0:8fdf9a60065b 187 required_toolchains = [
kadonotakashi 0:8fdf9a60065b 188 set(['ARM', 'GCC_ARM', 'IAR']),
kadonotakashi 0:8fdf9a60065b 189 set(['ARMC6'])
kadonotakashi 0:8fdf9a60065b 190 ]
kadonotakashi 0:8fdf9a60065b 191 supported_toolchains = set(target.supported_toolchains)
kadonotakashi 0:8fdf9a60065b 192
kadonotakashi 0:8fdf9a60065b 193 if not any(r.issubset(supported_toolchains)
kadonotakashi 0:8fdf9a60065b 194 for r in required_toolchains):
kadonotakashi 0:8fdf9a60065b 195 result = False
kadonotakashi 0:8fdf9a60065b 196 reason = ("Target '%s' must support " % target.name) + \
kadonotakashi 0:8fdf9a60065b 197 ("ALL of the folowing toolchains to be included in the") + \
kadonotakashi 0:8fdf9a60065b 198 ((" mbed OS 5.0 official release: %s" + linesep) %
kadonotakashi 0:8fdf9a60065b 199 ", ".join(sorted(required_toolchains[0]))) + \
kadonotakashi 0:8fdf9a60065b 200 ("Currently it is only configured to support the ") + \
kadonotakashi 0:8fdf9a60065b 201 ("following toolchains: %s" %
kadonotakashi 0:8fdf9a60065b 202 ", ".join(sorted(supported_toolchains)))
kadonotakashi 0:8fdf9a60065b 203
kadonotakashi 0:8fdf9a60065b 204 elif not target.default_lib == 'std':
kadonotakashi 0:8fdf9a60065b 205 result = False
kadonotakashi 0:8fdf9a60065b 206 reason = ("Target '%s' must set the " % target.name) + \
kadonotakashi 0:8fdf9a60065b 207 ("'default_lib' to 'std' to be included in the ") + \
kadonotakashi 0:8fdf9a60065b 208 ("mbed OS 5.0 official release." + linesep) + \
kadonotakashi 0:8fdf9a60065b 209 ("Currently it is set to '%s'" % target.default_lib)
kadonotakashi 0:8fdf9a60065b 210
kadonotakashi 0:8fdf9a60065b 211 else:
kadonotakashi 0:8fdf9a60065b 212 result = False
kadonotakashi 0:8fdf9a60065b 213 reason = ("Target '%s' has set an invalid release version of '%s'" %
kadonotakashi 0:8fdf9a60065b 214 version) + \
kadonotakashi 0:8fdf9a60065b 215 ("Please choose from the following release versions: %s" %
kadonotakashi 0:8fdf9a60065b 216 ', '.join(RELEASE_VERSIONS))
kadonotakashi 0:8fdf9a60065b 217
kadonotakashi 0:8fdf9a60065b 218 else:
kadonotakashi 0:8fdf9a60065b 219 result = False
kadonotakashi 0:8fdf9a60065b 220 if not hasattr(target, 'release_versions'):
kadonotakashi 0:8fdf9a60065b 221 reason = "Target '%s' " % target.name
kadonotakashi 0:8fdf9a60065b 222 reason += "does not have the 'release_versions' key set"
kadonotakashi 0:8fdf9a60065b 223 elif not version in target.release_versions:
kadonotakashi 0:8fdf9a60065b 224 reason = "Target '%s' does not contain the version '%s' " % \
kadonotakashi 0:8fdf9a60065b 225 (target.name, version)
kadonotakashi 0:8fdf9a60065b 226 reason += "in its 'release_versions' key"
kadonotakashi 0:8fdf9a60065b 227
kadonotakashi 0:8fdf9a60065b 228 return result, reason
kadonotakashi 0:8fdf9a60065b 229
kadonotakashi 0:8fdf9a60065b 230 def transform_release_toolchains(toolchains, version):
kadonotakashi 0:8fdf9a60065b 231 """ Given a list of toolchains and a release version, return a list of
kadonotakashi 0:8fdf9a60065b 232 only the supported toolchains for that release
kadonotakashi 0:8fdf9a60065b 233
kadonotakashi 0:8fdf9a60065b 234 Positional arguments:
kadonotakashi 0:8fdf9a60065b 235 toolchains - The list of toolchains
kadonotakashi 0:8fdf9a60065b 236 version - The release version string. Should be a string contained within
kadonotakashi 0:8fdf9a60065b 237 RELEASE_VERSIONS
kadonotakashi 0:8fdf9a60065b 238 """
kadonotakashi 0:8fdf9a60065b 239 if version == '5':
kadonotakashi 0:8fdf9a60065b 240 return ['ARM', 'GCC_ARM', 'IAR']
kadonotakashi 0:8fdf9a60065b 241 else:
kadonotakashi 0:8fdf9a60065b 242 return toolchains
kadonotakashi 0:8fdf9a60065b 243
kadonotakashi 0:8fdf9a60065b 244
kadonotakashi 0:8fdf9a60065b 245 def get_mbed_official_release(version):
kadonotakashi 0:8fdf9a60065b 246 """ Given a release version string, return a tuple that contains a target
kadonotakashi 0:8fdf9a60065b 247 and the supported toolchains for that release.
kadonotakashi 0:8fdf9a60065b 248 Ex. Given '2', return (('LPC1768', ('ARM', 'GCC_ARM')),
kadonotakashi 0:8fdf9a60065b 249 ('K64F', ('ARM', 'GCC_ARM')), ...)
kadonotakashi 0:8fdf9a60065b 250
kadonotakashi 0:8fdf9a60065b 251 Positional arguments:
kadonotakashi 0:8fdf9a60065b 252 version - The version string. Should be a string contained within
kadonotakashi 0:8fdf9a60065b 253 RELEASE_VERSIONS
kadonotakashi 0:8fdf9a60065b 254 """
kadonotakashi 0:8fdf9a60065b 255
kadonotakashi 0:8fdf9a60065b 256 mbed_official_release = (
kadonotakashi 0:8fdf9a60065b 257 tuple(
kadonotakashi 0:8fdf9a60065b 258 tuple(
kadonotakashi 0:8fdf9a60065b 259 [
kadonotakashi 0:8fdf9a60065b 260 TARGET_MAP[target].name,
kadonotakashi 0:8fdf9a60065b 261 tuple(transform_release_toolchains(
kadonotakashi 0:8fdf9a60065b 262 TARGET_MAP[target].supported_toolchains, version))
kadonotakashi 0:8fdf9a60065b 263 ]
kadonotakashi 0:8fdf9a60065b 264 ) for target in TARGET_NAMES \
kadonotakashi 0:8fdf9a60065b 265 if (hasattr(TARGET_MAP[target], 'release_versions')
kadonotakashi 0:8fdf9a60065b 266 and version in TARGET_MAP[target].release_versions)
kadonotakashi 0:8fdf9a60065b 267 )
kadonotakashi 0:8fdf9a60065b 268 )
kadonotakashi 0:8fdf9a60065b 269
kadonotakashi 0:8fdf9a60065b 270 for target in mbed_official_release:
kadonotakashi 0:8fdf9a60065b 271 is_official, reason = is_official_target(target[0], version)
kadonotakashi 0:8fdf9a60065b 272
kadonotakashi 0:8fdf9a60065b 273 if not is_official:
kadonotakashi 0:8fdf9a60065b 274 raise InvalidReleaseTargetException(reason)
kadonotakashi 0:8fdf9a60065b 275
kadonotakashi 0:8fdf9a60065b 276 return mbed_official_release
kadonotakashi 0:8fdf9a60065b 277
kadonotakashi 0:8fdf9a60065b 278 ARM_COMPILERS = ("ARM", "ARMC6", "uARM")
kadonotakashi 0:8fdf9a60065b 279 def target_supports_toolchain(target, toolchain_name):
kadonotakashi 0:8fdf9a60065b 280 if toolchain_name in ARM_COMPILERS:
kadonotakashi 0:8fdf9a60065b 281 return any(tc in target.supported_toolchains for tc in ARM_COMPILERS)
kadonotakashi 0:8fdf9a60065b 282 else:
kadonotakashi 0:8fdf9a60065b 283 return toolchain_name in target.supported_toolchains
kadonotakashi 0:8fdf9a60065b 284
kadonotakashi 0:8fdf9a60065b 285
kadonotakashi 0:8fdf9a60065b 286 def prepare_toolchain(src_paths, build_dir, target, toolchain_name,
kadonotakashi 0:8fdf9a60065b 287 macros=None, clean=False, jobs=1,
kadonotakashi 0:8fdf9a60065b 288 notify=None, config=None, app_config=None,
kadonotakashi 0:8fdf9a60065b 289 build_profile=None, ignore=None):
kadonotakashi 0:8fdf9a60065b 290 """ Prepares resource related objects - toolchain, target, config
kadonotakashi 0:8fdf9a60065b 291
kadonotakashi 0:8fdf9a60065b 292 Positional arguments:
kadonotakashi 0:8fdf9a60065b 293 src_paths - the paths to source directories
kadonotakashi 0:8fdf9a60065b 294 target - ['LPC1768', 'LPC11U24', etc.]
kadonotakashi 0:8fdf9a60065b 295 toolchain_name - ['ARM', 'uARM', 'GCC_ARM', 'GCC_CR']
kadonotakashi 0:8fdf9a60065b 296
kadonotakashi 0:8fdf9a60065b 297 Keyword arguments:
kadonotakashi 0:8fdf9a60065b 298 macros - additional macros
kadonotakashi 0:8fdf9a60065b 299 clean - Rebuild everything if True
kadonotakashi 0:8fdf9a60065b 300 jobs - how many compilers we can run at once
kadonotakashi 0:8fdf9a60065b 301 notify - Notify function for logs
kadonotakashi 0:8fdf9a60065b 302 config - a Config object to use instead of creating one
kadonotakashi 0:8fdf9a60065b 303 app_config - location of a chosen mbed_app.json file
kadonotakashi 0:8fdf9a60065b 304 build_profile - a list of mergeable build profiles
kadonotakashi 0:8fdf9a60065b 305 ignore - list of paths to add to mbedignore
kadonotakashi 0:8fdf9a60065b 306 """
kadonotakashi 0:8fdf9a60065b 307
kadonotakashi 0:8fdf9a60065b 308 # We need to remove all paths which are repeated to avoid
kadonotakashi 0:8fdf9a60065b 309 # multiple compilations and linking with the same objects
kadonotakashi 0:8fdf9a60065b 310 src_paths = [src_paths[0]] + list(set(src_paths[1:]))
kadonotakashi 0:8fdf9a60065b 311
kadonotakashi 0:8fdf9a60065b 312 # If the configuration object was not yet created, create it now
kadonotakashi 0:8fdf9a60065b 313 config = config or Config(target, src_paths, app_config=app_config)
kadonotakashi 0:8fdf9a60065b 314 target = config.target
kadonotakashi 0:8fdf9a60065b 315 if not target_supports_toolchain(target, toolchain_name):
kadonotakashi 0:8fdf9a60065b 316 raise NotSupportedException(
kadonotakashi 0:8fdf9a60065b 317 "Target {} is not supported by toolchain {}".format(
kadonotakashi 0:8fdf9a60065b 318 target.name, toolchain_name))
kadonotakashi 0:8fdf9a60065b 319 if (toolchain_name == "ARM" and CORE_ARCH[target.core] == 8):
kadonotakashi 0:8fdf9a60065b 320 toolchain_name = "ARMC6"
kadonotakashi 0:8fdf9a60065b 321
kadonotakashi 0:8fdf9a60065b 322 try:
kadonotakashi 0:8fdf9a60065b 323 cur_tc = TOOLCHAIN_CLASSES[toolchain_name]
kadonotakashi 0:8fdf9a60065b 324 except KeyError:
kadonotakashi 0:8fdf9a60065b 325 raise KeyError("Toolchain %s not supported" % toolchain_name)
kadonotakashi 0:8fdf9a60065b 326
kadonotakashi 0:8fdf9a60065b 327 profile = {'c': [], 'cxx': [], 'common': [], 'asm': [], 'ld': []}
kadonotakashi 0:8fdf9a60065b 328 for contents in build_profile or []:
kadonotakashi 0:8fdf9a60065b 329 for key in profile:
kadonotakashi 0:8fdf9a60065b 330 profile[key].extend(contents[toolchain_name].get(key, []))
kadonotakashi 0:8fdf9a60065b 331
kadonotakashi 0:8fdf9a60065b 332 toolchain = cur_tc(
kadonotakashi 0:8fdf9a60065b 333 target, notify, macros, build_dir=build_dir, build_profile=profile)
kadonotakashi 0:8fdf9a60065b 334
kadonotakashi 0:8fdf9a60065b 335 toolchain.config = config
kadonotakashi 0:8fdf9a60065b 336 toolchain.jobs = jobs
kadonotakashi 0:8fdf9a60065b 337 toolchain.build_all = clean
kadonotakashi 0:8fdf9a60065b 338
kadonotakashi 0:8fdf9a60065b 339 if ignore:
kadonotakashi 0:8fdf9a60065b 340 toolchain.add_ignore_patterns(root=".", base_path=".", patterns=ignore)
kadonotakashi 0:8fdf9a60065b 341
kadonotakashi 0:8fdf9a60065b 342 return toolchain
kadonotakashi 0:8fdf9a60065b 343
kadonotakashi 0:8fdf9a60065b 344 def _printihex(ihex):
kadonotakashi 0:8fdf9a60065b 345 import pprint
kadonotakashi 0:8fdf9a60065b 346 pprint.PrettyPrinter().pprint(ihex.todict())
kadonotakashi 0:8fdf9a60065b 347
kadonotakashi 0:8fdf9a60065b 348 def _real_region_size(region):
kadonotakashi 0:8fdf9a60065b 349 try:
kadonotakashi 0:8fdf9a60065b 350 part = intelhex_offset(region.filename, offset=region.start)
kadonotakashi 0:8fdf9a60065b 351 return (part.maxaddr() - part.minaddr()) + 1
kadonotakashi 0:8fdf9a60065b 352 except AttributeError:
kadonotakashi 0:8fdf9a60065b 353 return region.size
kadonotakashi 0:8fdf9a60065b 354
kadonotakashi 0:8fdf9a60065b 355
kadonotakashi 0:8fdf9a60065b 356 def _fill_header(region_list, current_region):
kadonotakashi 0:8fdf9a60065b 357 """Fill an application header region
kadonotakashi 0:8fdf9a60065b 358
kadonotakashi 0:8fdf9a60065b 359 This is done it three steps:
kadonotakashi 0:8fdf9a60065b 360 * Fill the whole region with zeros
kadonotakashi 0:8fdf9a60065b 361 * Fill const, timestamp and size entries with their data
kadonotakashi 0:8fdf9a60065b 362 * Fill the digests using this header as the header region
kadonotakashi 0:8fdf9a60065b 363 """
kadonotakashi 0:8fdf9a60065b 364 region_dict = {r.name: r for r in region_list}
kadonotakashi 0:8fdf9a60065b 365 header = IntelHex()
kadonotakashi 0:8fdf9a60065b 366 header.puts(current_region.start, b'\x00' * current_region.size)
kadonotakashi 0:8fdf9a60065b 367 start = current_region.start
kadonotakashi 0:8fdf9a60065b 368 for member in current_region.filename:
kadonotakashi 0:8fdf9a60065b 369 _, type, subtype, data = member
kadonotakashi 0:8fdf9a60065b 370 member_size = Config.header_member_size(member)
kadonotakashi 0:8fdf9a60065b 371 if type == "const":
kadonotakashi 0:8fdf9a60065b 372 fmt = {
kadonotakashi 0:8fdf9a60065b 373 "8le": ">B", "16le": "<H", "32le": "<L", "64le": "<Q",
kadonotakashi 0:8fdf9a60065b 374 "8be": "<B", "16be": ">H", "32be": ">L", "64be": ">Q"
kadonotakashi 0:8fdf9a60065b 375 }[subtype]
kadonotakashi 0:8fdf9a60065b 376 header.puts(start, struct.pack(fmt, integer(data, 0)))
kadonotakashi 0:8fdf9a60065b 377 elif type == "timestamp":
kadonotakashi 0:8fdf9a60065b 378 fmt = {"32le": "<L", "64le": "<Q",
kadonotakashi 0:8fdf9a60065b 379 "32be": ">L", "64be": ">Q"}[subtype]
kadonotakashi 0:8fdf9a60065b 380 header.puts(start, struct.pack(fmt, int(time())))
kadonotakashi 0:8fdf9a60065b 381 elif type == "size":
kadonotakashi 0:8fdf9a60065b 382 fmt = {"32le": "<L", "64le": "<Q",
kadonotakashi 0:8fdf9a60065b 383 "32be": ">L", "64be": ">Q"}[subtype]
kadonotakashi 0:8fdf9a60065b 384 size = sum(_real_region_size(region_dict[r]) for r in data)
kadonotakashi 0:8fdf9a60065b 385 header.puts(start, struct.pack(fmt, size))
kadonotakashi 0:8fdf9a60065b 386 elif type == "digest":
kadonotakashi 0:8fdf9a60065b 387 if data == "header":
kadonotakashi 0:8fdf9a60065b 388 ih = header[:start]
kadonotakashi 0:8fdf9a60065b 389 else:
kadonotakashi 0:8fdf9a60065b 390 ih = intelhex_offset(region_dict[data].filename, offset=region_dict[data].start)
kadonotakashi 0:8fdf9a60065b 391 if subtype.startswith("CRCITT32"):
kadonotakashi 0:8fdf9a60065b 392 fmt = {"CRCITT32be": ">l", "CRCITT32le": "<l"}[subtype]
kadonotakashi 0:8fdf9a60065b 393 header.puts(start, struct.pack(fmt, zlib.crc32(ih.tobinarray())))
kadonotakashi 0:8fdf9a60065b 394 elif subtype.startswith("SHA"):
kadonotakashi 0:8fdf9a60065b 395 if subtype == "SHA256":
kadonotakashi 0:8fdf9a60065b 396 hash = hashlib.sha256()
kadonotakashi 0:8fdf9a60065b 397 elif subtype == "SHA512":
kadonotakashi 0:8fdf9a60065b 398 hash = hashlib.sha512()
kadonotakashi 0:8fdf9a60065b 399 hash.update(ih.tobinarray())
kadonotakashi 0:8fdf9a60065b 400 header.puts(start, hash.digest())
kadonotakashi 0:8fdf9a60065b 401 start += Config.header_member_size(member)
kadonotakashi 0:8fdf9a60065b 402 return header
kadonotakashi 0:8fdf9a60065b 403
kadonotakashi 0:8fdf9a60065b 404 def merge_region_list(region_list, destination, notify, padding=b'\xFF'):
kadonotakashi 0:8fdf9a60065b 405 """Merge the region_list into a single image
kadonotakashi 0:8fdf9a60065b 406
kadonotakashi 0:8fdf9a60065b 407 Positional Arguments:
kadonotakashi 0:8fdf9a60065b 408 region_list - list of regions, which should contain filenames
kadonotakashi 0:8fdf9a60065b 409 destination - file name to write all regions to
kadonotakashi 0:8fdf9a60065b 410 padding - bytes to fill gapps with
kadonotakashi 0:8fdf9a60065b 411 """
kadonotakashi 0:8fdf9a60065b 412 merged = IntelHex()
kadonotakashi 0:8fdf9a60065b 413 _, format = splitext(destination)
kadonotakashi 0:8fdf9a60065b 414
kadonotakashi 0:8fdf9a60065b 415 notify.info("Merging Regions")
kadonotakashi 0:8fdf9a60065b 416
kadonotakashi 0:8fdf9a60065b 417 for region in region_list:
kadonotakashi 0:8fdf9a60065b 418 if region.active and not region.filename:
kadonotakashi 0:8fdf9a60065b 419 raise ToolException("Active region has no contents: No file found.")
kadonotakashi 0:8fdf9a60065b 420 if isinstance(region.filename, list):
kadonotakashi 0:8fdf9a60065b 421 header_basename, _ = splitext(destination)
kadonotakashi 0:8fdf9a60065b 422 header_filename = header_basename + "_header.hex"
kadonotakashi 0:8fdf9a60065b 423 _fill_header(region_list, region).tofile(header_filename, format='hex')
kadonotakashi 0:8fdf9a60065b 424 region = region._replace(filename=header_filename)
kadonotakashi 0:8fdf9a60065b 425 if region.filename:
kadonotakashi 0:8fdf9a60065b 426 notify.info(" Filling region %s with %s" % (region.name, region.filename))
kadonotakashi 0:8fdf9a60065b 427 part = intelhex_offset(region.filename, offset=region.start)
kadonotakashi 0:8fdf9a60065b 428 part.start_addr = None
kadonotakashi 0:8fdf9a60065b 429 part_size = (part.maxaddr() - part.minaddr()) + 1
kadonotakashi 0:8fdf9a60065b 430 if part_size > region.size:
kadonotakashi 0:8fdf9a60065b 431 raise ToolException("Contents of region %s does not fit"
kadonotakashi 0:8fdf9a60065b 432 % region.name)
kadonotakashi 0:8fdf9a60065b 433 merged.merge(part)
kadonotakashi 0:8fdf9a60065b 434 pad_size = region.size - part_size
kadonotakashi 0:8fdf9a60065b 435 if pad_size > 0 and region != region_list[-1]:
kadonotakashi 0:8fdf9a60065b 436 notify.info(" Padding region %s with 0x%x bytes" %
kadonotakashi 0:8fdf9a60065b 437 (region.name, pad_size))
kadonotakashi 0:8fdf9a60065b 438 if format is ".hex":
kadonotakashi 0:8fdf9a60065b 439 """The offset will be in the hex file generated when we're done,
kadonotakashi 0:8fdf9a60065b 440 so we can skip padding here"""
kadonotakashi 0:8fdf9a60065b 441 else:
kadonotakashi 0:8fdf9a60065b 442 merged.puts(merged.maxaddr() + 1, padding * pad_size)
kadonotakashi 0:8fdf9a60065b 443
kadonotakashi 0:8fdf9a60065b 444 if not exists(dirname(destination)):
kadonotakashi 0:8fdf9a60065b 445 makedirs(dirname(destination))
kadonotakashi 0:8fdf9a60065b 446 notify.info("Space used after regions merged: 0x%x" %
kadonotakashi 0:8fdf9a60065b 447 (merged.maxaddr() - merged.minaddr() + 1))
kadonotakashi 0:8fdf9a60065b 448 merged.tofile(destination, format=format.strip("."))
kadonotakashi 0:8fdf9a60065b 449
kadonotakashi 0:8fdf9a60065b 450
kadonotakashi 0:8fdf9a60065b 451 UPDATE_WHITELIST = (
kadonotakashi 0:8fdf9a60065b 452 "application",
kadonotakashi 0:8fdf9a60065b 453 )
kadonotakashi 0:8fdf9a60065b 454
kadonotakashi 0:8fdf9a60065b 455
kadonotakashi 0:8fdf9a60065b 456 def build_project(src_paths, build_path, target, toolchain_name,
kadonotakashi 0:8fdf9a60065b 457 libraries_paths=None, linker_script=None, clean=False,
kadonotakashi 0:8fdf9a60065b 458 notify=None, name=None, macros=None, inc_dirs=None, jobs=1,
kadonotakashi 0:8fdf9a60065b 459 report=None, properties=None, project_id=None,
kadonotakashi 0:8fdf9a60065b 460 project_description=None, config=None,
kadonotakashi 0:8fdf9a60065b 461 app_config=None, build_profile=None, stats_depth=None, ignore=None):
kadonotakashi 0:8fdf9a60065b 462 """ Build a project. A project may be a test or a user program.
kadonotakashi 0:8fdf9a60065b 463
kadonotakashi 0:8fdf9a60065b 464 Positional arguments:
kadonotakashi 0:8fdf9a60065b 465 src_paths - a path or list of paths that contain all files needed to build
kadonotakashi 0:8fdf9a60065b 466 the project
kadonotakashi 0:8fdf9a60065b 467 build_path - the directory where all of the object files will be placed
kadonotakashi 0:8fdf9a60065b 468 target - the MCU or board that the project will compile for
kadonotakashi 0:8fdf9a60065b 469 toolchain_name - the name of the build tools
kadonotakashi 0:8fdf9a60065b 470
kadonotakashi 0:8fdf9a60065b 471 Keyword arguments:
kadonotakashi 0:8fdf9a60065b 472 libraries_paths - The location of libraries to include when linking
kadonotakashi 0:8fdf9a60065b 473 linker_script - the file that drives the linker to do it's job
kadonotakashi 0:8fdf9a60065b 474 clean - Rebuild everything if True
kadonotakashi 0:8fdf9a60065b 475 notify - Notify function for logs
kadonotakashi 0:8fdf9a60065b 476 name - the name of the project
kadonotakashi 0:8fdf9a60065b 477 macros - additional macros
kadonotakashi 0:8fdf9a60065b 478 inc_dirs - additional directories where include files may be found
kadonotakashi 0:8fdf9a60065b 479 jobs - how many compilers we can run at once
kadonotakashi 0:8fdf9a60065b 480 report - a dict where a result may be appended
kadonotakashi 0:8fdf9a60065b 481 properties - UUUUHHHHH beats me
kadonotakashi 0:8fdf9a60065b 482 project_id - the name put in the report
kadonotakashi 0:8fdf9a60065b 483 project_description - the human-readable version of what this thing does
kadonotakashi 0:8fdf9a60065b 484 config - a Config object to use instead of creating one
kadonotakashi 0:8fdf9a60065b 485 app_config - location of a chosen mbed_app.json file
kadonotakashi 0:8fdf9a60065b 486 build_profile - a dict of flags that will be passed to the compiler
kadonotakashi 0:8fdf9a60065b 487 stats_depth - depth level for memap to display file/dirs
kadonotakashi 0:8fdf9a60065b 488 ignore - list of paths to add to mbedignore
kadonotakashi 0:8fdf9a60065b 489 """
kadonotakashi 0:8fdf9a60065b 490 # Convert src_path to a list if needed
kadonotakashi 0:8fdf9a60065b 491 if not isinstance(src_paths, list):
kadonotakashi 0:8fdf9a60065b 492 src_paths = [src_paths]
kadonotakashi 0:8fdf9a60065b 493 # Extend src_paths wiht libraries_paths
kadonotakashi 0:8fdf9a60065b 494 if libraries_paths is not None:
kadonotakashi 0:8fdf9a60065b 495 src_paths.extend(libraries_paths)
kadonotakashi 0:8fdf9a60065b 496 inc_dirs.extend(map(dirname, libraries_paths))
kadonotakashi 0:8fdf9a60065b 497
kadonotakashi 0:8fdf9a60065b 498 if clean and exists(build_path):
kadonotakashi 0:8fdf9a60065b 499 rmtree(build_path)
kadonotakashi 0:8fdf9a60065b 500 mkdir(build_path)
kadonotakashi 0:8fdf9a60065b 501
kadonotakashi 0:8fdf9a60065b 502 toolchain = prepare_toolchain(
kadonotakashi 0:8fdf9a60065b 503 src_paths, build_path, target, toolchain_name, macros=macros,
kadonotakashi 0:8fdf9a60065b 504 clean=clean, jobs=jobs, notify=notify, config=config,
kadonotakashi 0:8fdf9a60065b 505 app_config=app_config, build_profile=build_profile, ignore=ignore)
kadonotakashi 0:8fdf9a60065b 506 toolchain.version_check()
kadonotakashi 0:8fdf9a60065b 507
kadonotakashi 0:8fdf9a60065b 508 # The first path will give the name to the library
kadonotakashi 0:8fdf9a60065b 509 name = (name or toolchain.config.name or
kadonotakashi 0:8fdf9a60065b 510 basename(normpath(abspath(src_paths[0]))))
kadonotakashi 0:8fdf9a60065b 511 notify.info("Building project %s (%s, %s)" %
kadonotakashi 0:8fdf9a60065b 512 (name, toolchain.target.name, toolchain_name))
kadonotakashi 0:8fdf9a60065b 513
kadonotakashi 0:8fdf9a60065b 514 # Initialize reporting
kadonotakashi 0:8fdf9a60065b 515 if report != None:
kadonotakashi 0:8fdf9a60065b 516 start = time()
kadonotakashi 0:8fdf9a60065b 517 # If project_id is specified, use that over the default name
kadonotakashi 0:8fdf9a60065b 518 id_name = project_id.upper() if project_id else name.upper()
kadonotakashi 0:8fdf9a60065b 519 description = project_description if project_description else name
kadonotakashi 0:8fdf9a60065b 520 vendor_label = toolchain.target.extra_labels[0]
kadonotakashi 0:8fdf9a60065b 521 prep_report(report, toolchain.target.name, toolchain_name, id_name)
kadonotakashi 0:8fdf9a60065b 522 cur_result = create_result(toolchain.target.name, toolchain_name,
kadonotakashi 0:8fdf9a60065b 523 id_name, description)
kadonotakashi 0:8fdf9a60065b 524 if properties != None:
kadonotakashi 0:8fdf9a60065b 525 prep_properties(properties, toolchain.target.name, toolchain_name,
kadonotakashi 0:8fdf9a60065b 526 vendor_label)
kadonotakashi 0:8fdf9a60065b 527
kadonotakashi 0:8fdf9a60065b 528 try:
kadonotakashi 0:8fdf9a60065b 529 resources = Resources(notify).scan_with_toolchain(
kadonotakashi 0:8fdf9a60065b 530 src_paths, toolchain, inc_dirs=inc_dirs)
kadonotakashi 0:8fdf9a60065b 531
kadonotakashi 0:8fdf9a60065b 532 # Change linker script if specified
kadonotakashi 0:8fdf9a60065b 533 if linker_script is not None:
kadonotakashi 0:8fdf9a60065b 534 resources.add_file_ref(linker_script, linker_script)
kadonotakashi 0:8fdf9a60065b 535
kadonotakashi 0:8fdf9a60065b 536 # Compile Sources
kadonotakashi 0:8fdf9a60065b 537 objects = toolchain.compile_sources(resources, sorted(resources.get_file_paths(FileType.INC_DIR)))
kadonotakashi 0:8fdf9a60065b 538 resources.add_files_to_type(FileType.OBJECT, objects)
kadonotakashi 0:8fdf9a60065b 539
kadonotakashi 0:8fdf9a60065b 540 # Link Program
kadonotakashi 0:8fdf9a60065b 541 if toolchain.config.has_regions:
kadonotakashi 0:8fdf9a60065b 542 binary, _ = toolchain.link_program(resources, build_path, name + "_application")
kadonotakashi 0:8fdf9a60065b 543 region_list = list(toolchain.config.regions)
kadonotakashi 0:8fdf9a60065b 544 region_list = [r._replace(filename=binary) if r.active else r
kadonotakashi 0:8fdf9a60065b 545 for r in region_list]
kadonotakashi 0:8fdf9a60065b 546 res = "%s.%s" % (join(build_path, name),
kadonotakashi 0:8fdf9a60065b 547 getattr(toolchain.target, "OUTPUT_EXT", "bin"))
kadonotakashi 0:8fdf9a60065b 548 merge_region_list(region_list, res, notify)
kadonotakashi 0:8fdf9a60065b 549 update_regions = [
kadonotakashi 0:8fdf9a60065b 550 r for r in region_list if r.name in UPDATE_WHITELIST
kadonotakashi 0:8fdf9a60065b 551 ]
kadonotakashi 0:8fdf9a60065b 552 if update_regions:
kadonotakashi 0:8fdf9a60065b 553 update_res = join(build_path, generate_update_filename(name, toolchain.target))
kadonotakashi 0:8fdf9a60065b 554 merge_region_list(update_regions, update_res, notify)
kadonotakashi 0:8fdf9a60065b 555 res = (res, update_res)
kadonotakashi 0:8fdf9a60065b 556 else:
kadonotakashi 0:8fdf9a60065b 557 res = (res, None)
kadonotakashi 0:8fdf9a60065b 558 else:
kadonotakashi 0:8fdf9a60065b 559 res, _ = toolchain.link_program(resources, build_path, name)
kadonotakashi 0:8fdf9a60065b 560 res = (res, None)
kadonotakashi 0:8fdf9a60065b 561
kadonotakashi 0:8fdf9a60065b 562 memap_instance = getattr(toolchain, 'memap_instance', None)
kadonotakashi 0:8fdf9a60065b 563 memap_table = ''
kadonotakashi 0:8fdf9a60065b 564 if memap_instance:
kadonotakashi 0:8fdf9a60065b 565 # Write output to stdout in text (pretty table) format
kadonotakashi 0:8fdf9a60065b 566 memap_table = memap_instance.generate_output('table', stats_depth)
kadonotakashi 0:8fdf9a60065b 567 notify.info(memap_table)
kadonotakashi 0:8fdf9a60065b 568
kadonotakashi 0:8fdf9a60065b 569 # Write output to file in JSON format
kadonotakashi 0:8fdf9a60065b 570 map_out = join(build_path, name + "_map.json")
kadonotakashi 0:8fdf9a60065b 571 memap_instance.generate_output('json', stats_depth, map_out)
kadonotakashi 0:8fdf9a60065b 572
kadonotakashi 0:8fdf9a60065b 573 # Write output to file in CSV format for the CI
kadonotakashi 0:8fdf9a60065b 574 map_csv = join(build_path, name + "_map.csv")
kadonotakashi 0:8fdf9a60065b 575 memap_instance.generate_output('csv-ci', stats_depth, map_csv)
kadonotakashi 0:8fdf9a60065b 576
kadonotakashi 0:8fdf9a60065b 577 map_html = join(build_path, name + "_map.html")
kadonotakashi 0:8fdf9a60065b 578 memap_instance.generate_output('html', stats_depth, map_html)
kadonotakashi 0:8fdf9a60065b 579
kadonotakashi 0:8fdf9a60065b 580 resources.detect_duplicates()
kadonotakashi 0:8fdf9a60065b 581
kadonotakashi 0:8fdf9a60065b 582 if report != None:
kadonotakashi 0:8fdf9a60065b 583 end = time()
kadonotakashi 0:8fdf9a60065b 584 cur_result["elapsed_time"] = end - start
kadonotakashi 0:8fdf9a60065b 585 cur_result["result"] = "OK"
kadonotakashi 0:8fdf9a60065b 586 cur_result["memory_usage"] = (memap_instance.mem_report
kadonotakashi 0:8fdf9a60065b 587 if memap_instance is not None else None)
kadonotakashi 0:8fdf9a60065b 588 cur_result["bin"] = res[0]
kadonotakashi 0:8fdf9a60065b 589 cur_result["elf"] = splitext(res[0])[0] + ".elf"
kadonotakashi 0:8fdf9a60065b 590 cur_result.update(toolchain.report)
kadonotakashi 0:8fdf9a60065b 591
kadonotakashi 0:8fdf9a60065b 592 add_result_to_report(report, cur_result)
kadonotakashi 0:8fdf9a60065b 593
kadonotakashi 0:8fdf9a60065b 594 return res
kadonotakashi 0:8fdf9a60065b 595
kadonotakashi 0:8fdf9a60065b 596 except Exception as exc:
kadonotakashi 0:8fdf9a60065b 597 if report != None:
kadonotakashi 0:8fdf9a60065b 598 end = time()
kadonotakashi 0:8fdf9a60065b 599
kadonotakashi 0:8fdf9a60065b 600 if isinstance(exc, NotSupportedException):
kadonotakashi 0:8fdf9a60065b 601 cur_result["result"] = "NOT_SUPPORTED"
kadonotakashi 0:8fdf9a60065b 602 else:
kadonotakashi 0:8fdf9a60065b 603 cur_result["result"] = "FAIL"
kadonotakashi 0:8fdf9a60065b 604
kadonotakashi 0:8fdf9a60065b 605 cur_result["elapsed_time"] = end - start
kadonotakashi 0:8fdf9a60065b 606
kadonotakashi 0:8fdf9a60065b 607 add_result_to_report(report, cur_result)
kadonotakashi 0:8fdf9a60065b 608 # Let Exception propagate
kadonotakashi 0:8fdf9a60065b 609 raise
kadonotakashi 0:8fdf9a60065b 610
kadonotakashi 0:8fdf9a60065b 611 def build_library(src_paths, build_path, target, toolchain_name,
kadonotakashi 0:8fdf9a60065b 612 dependencies_paths=None, name=None, clean=False,
kadonotakashi 0:8fdf9a60065b 613 archive=True, notify=None, macros=None, inc_dirs=None, jobs=1,
kadonotakashi 0:8fdf9a60065b 614 report=None, properties=None, project_id=None,
kadonotakashi 0:8fdf9a60065b 615 remove_config_header_file=False, app_config=None,
kadonotakashi 0:8fdf9a60065b 616 build_profile=None, ignore=None):
kadonotakashi 0:8fdf9a60065b 617 """ Build a library
kadonotakashi 0:8fdf9a60065b 618
kadonotakashi 0:8fdf9a60065b 619 Positional arguments:
kadonotakashi 0:8fdf9a60065b 620 src_paths - a path or list of paths that contain all files needed to build
kadonotakashi 0:8fdf9a60065b 621 the library
kadonotakashi 0:8fdf9a60065b 622 build_path - the directory where all of the object files will be placed
kadonotakashi 0:8fdf9a60065b 623 target - the MCU or board that the project will compile for
kadonotakashi 0:8fdf9a60065b 624 toolchain_name - the name of the build tools
kadonotakashi 0:8fdf9a60065b 625
kadonotakashi 0:8fdf9a60065b 626 Keyword arguments:
kadonotakashi 0:8fdf9a60065b 627 dependencies_paths - The location of libraries to include when linking
kadonotakashi 0:8fdf9a60065b 628 name - the name of the library
kadonotakashi 0:8fdf9a60065b 629 clean - Rebuild everything if True
kadonotakashi 0:8fdf9a60065b 630 archive - whether the library will create an archive file
kadonotakashi 0:8fdf9a60065b 631 notify - Notify function for logs
kadonotakashi 0:8fdf9a60065b 632 macros - additional macros
kadonotakashi 0:8fdf9a60065b 633 inc_dirs - additional directories where include files may be found
kadonotakashi 0:8fdf9a60065b 634 jobs - how many compilers we can run at once
kadonotakashi 0:8fdf9a60065b 635 report - a dict where a result may be appended
kadonotakashi 0:8fdf9a60065b 636 properties - UUUUHHHHH beats me
kadonotakashi 0:8fdf9a60065b 637 project_id - the name that goes in the report
kadonotakashi 0:8fdf9a60065b 638 remove_config_header_file - delete config header file when done building
kadonotakashi 0:8fdf9a60065b 639 app_config - location of a chosen mbed_app.json file
kadonotakashi 0:8fdf9a60065b 640 build_profile - a dict of flags that will be passed to the compiler
kadonotakashi 0:8fdf9a60065b 641 ignore - list of paths to add to mbedignore
kadonotakashi 0:8fdf9a60065b 642 """
kadonotakashi 0:8fdf9a60065b 643
kadonotakashi 0:8fdf9a60065b 644 # Convert src_path to a list if needed
kadonotakashi 0:8fdf9a60065b 645 if not isinstance(src_paths, list):
kadonotakashi 0:8fdf9a60065b 646 src_paths = [src_paths]
kadonotakashi 0:8fdf9a60065b 647 src_paths = [relpath(s) for s in src_paths]
kadonotakashi 0:8fdf9a60065b 648
kadonotakashi 0:8fdf9a60065b 649 # Build path
kadonotakashi 0:8fdf9a60065b 650 if archive:
kadonotakashi 0:8fdf9a60065b 651 # Use temp path when building archive
kadonotakashi 0:8fdf9a60065b 652 tmp_path = join(build_path, '.temp')
kadonotakashi 0:8fdf9a60065b 653 mkdir(tmp_path)
kadonotakashi 0:8fdf9a60065b 654 else:
kadonotakashi 0:8fdf9a60065b 655 tmp_path = build_path
kadonotakashi 0:8fdf9a60065b 656
kadonotakashi 0:8fdf9a60065b 657 # Clean the build directory
kadonotakashi 0:8fdf9a60065b 658 if clean and exists(tmp_path):
kadonotakashi 0:8fdf9a60065b 659 rmtree(tmp_path)
kadonotakashi 0:8fdf9a60065b 660 mkdir(tmp_path)
kadonotakashi 0:8fdf9a60065b 661
kadonotakashi 0:8fdf9a60065b 662 # Pass all params to the unified prepare_toolchain()
kadonotakashi 0:8fdf9a60065b 663 toolchain = prepare_toolchain(
kadonotakashi 0:8fdf9a60065b 664 src_paths, build_path, target, toolchain_name, macros=macros,
kadonotakashi 0:8fdf9a60065b 665 clean=clean, jobs=jobs, notify=notify, app_config=app_config,
kadonotakashi 0:8fdf9a60065b 666 build_profile=build_profile, ignore=ignore)
kadonotakashi 0:8fdf9a60065b 667
kadonotakashi 0:8fdf9a60065b 668 # The first path will give the name to the library
kadonotakashi 0:8fdf9a60065b 669 if name is None:
kadonotakashi 0:8fdf9a60065b 670 name = basename(normpath(abspath(src_paths[0])))
kadonotakashi 0:8fdf9a60065b 671 notify.info("Building library %s (%s, %s)" %
kadonotakashi 0:8fdf9a60065b 672 (name, toolchain.target.name, toolchain_name))
kadonotakashi 0:8fdf9a60065b 673
kadonotakashi 0:8fdf9a60065b 674 # Initialize reporting
kadonotakashi 0:8fdf9a60065b 675 if report != None:
kadonotakashi 0:8fdf9a60065b 676 start = time()
kadonotakashi 0:8fdf9a60065b 677 # If project_id is specified, use that over the default name
kadonotakashi 0:8fdf9a60065b 678 id_name = project_id.upper() if project_id else name.upper()
kadonotakashi 0:8fdf9a60065b 679 description = name
kadonotakashi 0:8fdf9a60065b 680 vendor_label = toolchain.target.extra_labels[0]
kadonotakashi 0:8fdf9a60065b 681 prep_report(report, toolchain.target.name, toolchain_name, id_name)
kadonotakashi 0:8fdf9a60065b 682 cur_result = create_result(toolchain.target.name, toolchain_name,
kadonotakashi 0:8fdf9a60065b 683 id_name, description)
kadonotakashi 0:8fdf9a60065b 684 cur_result['type'] = 'library'
kadonotakashi 0:8fdf9a60065b 685 if properties != None:
kadonotakashi 0:8fdf9a60065b 686 prep_properties(properties, toolchain.target.name, toolchain_name,
kadonotakashi 0:8fdf9a60065b 687 vendor_label)
kadonotakashi 0:8fdf9a60065b 688
kadonotakashi 0:8fdf9a60065b 689 for src_path in src_paths:
kadonotakashi 0:8fdf9a60065b 690 if not exists(src_path):
kadonotakashi 0:8fdf9a60065b 691 error_msg = "The library source folder does not exist: %s", src_path
kadonotakashi 0:8fdf9a60065b 692 if report != None:
kadonotakashi 0:8fdf9a60065b 693 cur_result["output"] = error_msg
kadonotakashi 0:8fdf9a60065b 694 cur_result["result"] = "FAIL"
kadonotakashi 0:8fdf9a60065b 695 add_result_to_report(report, cur_result)
kadonotakashi 0:8fdf9a60065b 696 raise Exception(error_msg)
kadonotakashi 0:8fdf9a60065b 697
kadonotakashi 0:8fdf9a60065b 698 try:
kadonotakashi 0:8fdf9a60065b 699 res = Resources(notify).scan_with_toolchain(
kadonotakashi 0:8fdf9a60065b 700 src_paths, toolchain, dependencies_paths, inc_dirs=inc_dirs)
kadonotakashi 0:8fdf9a60065b 701
kadonotakashi 0:8fdf9a60065b 702 # Copy headers, objects and static libraries - all files needed for
kadonotakashi 0:8fdf9a60065b 703 # static lib
kadonotakashi 0:8fdf9a60065b 704 to_copy = (
kadonotakashi 0:8fdf9a60065b 705 res.get_file_refs(FileType.HEADER) +
kadonotakashi 0:8fdf9a60065b 706 res.get_file_refs(FileType.OBJECT) +
kadonotakashi 0:8fdf9a60065b 707 res.get_file_refs(FileType.LIB) +
kadonotakashi 0:8fdf9a60065b 708 res.get_file_refs(FileType.JSON) +
kadonotakashi 0:8fdf9a60065b 709 res.get_file_refs(FileType.LD_SCRIPT) +
kadonotakashi 0:8fdf9a60065b 710 res.get_file_refs(FileType.HEX) +
kadonotakashi 0:8fdf9a60065b 711 res.get_file_refs(FileType.BIN)
kadonotakashi 0:8fdf9a60065b 712 )
kadonotakashi 0:8fdf9a60065b 713 toolchain.copy_files(to_copy, build_path)
kadonotakashi 0:8fdf9a60065b 714 # Compile Sources
kadonotakashi 0:8fdf9a60065b 715 objects = toolchain.compile_sources(
kadonotakashi 0:8fdf9a60065b 716 res, res.get_file_paths(FileType.INC_DIR))
kadonotakashi 0:8fdf9a60065b 717 res.add_files_to_type(FileType.OBJECT, objects)
kadonotakashi 0:8fdf9a60065b 718
kadonotakashi 0:8fdf9a60065b 719 if archive:
kadonotakashi 0:8fdf9a60065b 720 toolchain.build_library(objects, build_path, name)
kadonotakashi 0:8fdf9a60065b 721
kadonotakashi 0:8fdf9a60065b 722 if remove_config_header_file:
kadonotakashi 0:8fdf9a60065b 723 config_header_path = toolchain.get_config_header()
kadonotakashi 0:8fdf9a60065b 724 if config_header_path:
kadonotakashi 0:8fdf9a60065b 725 remove(config_header_path)
kadonotakashi 0:8fdf9a60065b 726
kadonotakashi 0:8fdf9a60065b 727 if report != None:
kadonotakashi 0:8fdf9a60065b 728 end = time()
kadonotakashi 0:8fdf9a60065b 729 cur_result["elapsed_time"] = end - start
kadonotakashi 0:8fdf9a60065b 730 cur_result["result"] = "OK"
kadonotakashi 0:8fdf9a60065b 731 add_result_to_report(report, cur_result)
kadonotakashi 0:8fdf9a60065b 732 return True
kadonotakashi 0:8fdf9a60065b 733
kadonotakashi 0:8fdf9a60065b 734 except Exception as exc:
kadonotakashi 0:8fdf9a60065b 735 if report != None:
kadonotakashi 0:8fdf9a60065b 736 end = time()
kadonotakashi 0:8fdf9a60065b 737
kadonotakashi 0:8fdf9a60065b 738 if isinstance(exc, ToolException):
kadonotakashi 0:8fdf9a60065b 739 cur_result["result"] = "FAIL"
kadonotakashi 0:8fdf9a60065b 740 elif isinstance(exc, NotSupportedException):
kadonotakashi 0:8fdf9a60065b 741 cur_result["result"] = "NOT_SUPPORTED"
kadonotakashi 0:8fdf9a60065b 742
kadonotakashi 0:8fdf9a60065b 743 cur_result["elapsed_time"] = end - start
kadonotakashi 0:8fdf9a60065b 744
kadonotakashi 0:8fdf9a60065b 745 add_result_to_report(report, cur_result)
kadonotakashi 0:8fdf9a60065b 746
kadonotakashi 0:8fdf9a60065b 747 # Let Exception propagate
kadonotakashi 0:8fdf9a60065b 748 raise
kadonotakashi 0:8fdf9a60065b 749
kadonotakashi 0:8fdf9a60065b 750 ######################
kadonotakashi 0:8fdf9a60065b 751 ### Legacy methods ###
kadonotakashi 0:8fdf9a60065b 752 ######################
kadonotakashi 0:8fdf9a60065b 753
kadonotakashi 0:8fdf9a60065b 754 def mbed2_obj_path(target_name, toolchain_name):
kadonotakashi 0:8fdf9a60065b 755 real_tc_name = TOOLCHAIN_CLASSES[toolchain_name].__name__
kadonotakashi 0:8fdf9a60065b 756 return join("TARGET_" + target_name, "TOOLCHAIN_" + real_tc_name)
kadonotakashi 0:8fdf9a60065b 757
kadonotakashi 0:8fdf9a60065b 758 def build_lib(lib_id, target, toolchain_name, clean=False, macros=None,
kadonotakashi 0:8fdf9a60065b 759 notify=None, jobs=1, report=None, properties=None,
kadonotakashi 0:8fdf9a60065b 760 build_profile=None, ignore=None):
kadonotakashi 0:8fdf9a60065b 761 """ Legacy method for building mbed libraries
kadonotakashi 0:8fdf9a60065b 762
kadonotakashi 0:8fdf9a60065b 763 Positional arguments:
kadonotakashi 0:8fdf9a60065b 764 lib_id - the library's unique identifier
kadonotakashi 0:8fdf9a60065b 765 target - the MCU or board that the project will compile for
kadonotakashi 0:8fdf9a60065b 766 toolchain_name - the name of the build tools
kadonotakashi 0:8fdf9a60065b 767
kadonotakashi 0:8fdf9a60065b 768 Keyword arguments:
kadonotakashi 0:8fdf9a60065b 769 clean - Rebuild everything if True
kadonotakashi 0:8fdf9a60065b 770 macros - additional macros
kadonotakashi 0:8fdf9a60065b 771 notify - Notify function for logs
kadonotakashi 0:8fdf9a60065b 772 jobs - how many compilers we can run at once
kadonotakashi 0:8fdf9a60065b 773 report - a dict where a result may be appended
kadonotakashi 0:8fdf9a60065b 774 properties - UUUUHHHHH beats me
kadonotakashi 0:8fdf9a60065b 775 build_profile - a dict of flags that will be passed to the compiler
kadonotakashi 0:8fdf9a60065b 776 ignore - list of paths to add to mbedignore
kadonotakashi 0:8fdf9a60065b 777 """
kadonotakashi 0:8fdf9a60065b 778 lib = Library(lib_id)
kadonotakashi 0:8fdf9a60065b 779 if not lib.is_supported(target, toolchain_name):
kadonotakashi 0:8fdf9a60065b 780 print('Library "%s" is not yet supported on target %s with toolchain %s'
kadonotakashi 0:8fdf9a60065b 781 % (lib_id, target.name, toolchain_name))
kadonotakashi 0:8fdf9a60065b 782 return False
kadonotakashi 0:8fdf9a60065b 783
kadonotakashi 0:8fdf9a60065b 784 # We need to combine macros from parameter list with macros from library
kadonotakashi 0:8fdf9a60065b 785 # definition
kadonotakashi 0:8fdf9a60065b 786 lib_macros = lib.macros if lib.macros else []
kadonotakashi 0:8fdf9a60065b 787 if macros:
kadonotakashi 0:8fdf9a60065b 788 macros.extend(lib_macros)
kadonotakashi 0:8fdf9a60065b 789 else:
kadonotakashi 0:8fdf9a60065b 790 macros = lib_macros
kadonotakashi 0:8fdf9a60065b 791
kadonotakashi 0:8fdf9a60065b 792 src_paths = lib.source_dir
kadonotakashi 0:8fdf9a60065b 793 build_path = lib.build_dir
kadonotakashi 0:8fdf9a60065b 794 dependencies_paths = lib.dependencies
kadonotakashi 0:8fdf9a60065b 795 inc_dirs = lib.inc_dirs
kadonotakashi 0:8fdf9a60065b 796
kadonotakashi 0:8fdf9a60065b 797 if not isinstance(src_paths, list):
kadonotakashi 0:8fdf9a60065b 798 src_paths = [src_paths]
kadonotakashi 0:8fdf9a60065b 799
kadonotakashi 0:8fdf9a60065b 800 # The first path will give the name to the library
kadonotakashi 0:8fdf9a60065b 801 name = basename(src_paths[0])
kadonotakashi 0:8fdf9a60065b 802
kadonotakashi 0:8fdf9a60065b 803 if report is not None:
kadonotakashi 0:8fdf9a60065b 804 start = time()
kadonotakashi 0:8fdf9a60065b 805 id_name = name.upper()
kadonotakashi 0:8fdf9a60065b 806 description = name
kadonotakashi 0:8fdf9a60065b 807 vendor_label = target.extra_labels[0]
kadonotakashi 0:8fdf9a60065b 808 cur_result = None
kadonotakashi 0:8fdf9a60065b 809 prep_report(report, target.name, toolchain_name, id_name)
kadonotakashi 0:8fdf9a60065b 810 cur_result = create_result(target.name, toolchain_name, id_name,
kadonotakashi 0:8fdf9a60065b 811 description)
kadonotakashi 0:8fdf9a60065b 812
kadonotakashi 0:8fdf9a60065b 813 if properties != None:
kadonotakashi 0:8fdf9a60065b 814 prep_properties(properties, target.name, toolchain_name,
kadonotakashi 0:8fdf9a60065b 815 vendor_label)
kadonotakashi 0:8fdf9a60065b 816
kadonotakashi 0:8fdf9a60065b 817 for src_path in src_paths:
kadonotakashi 0:8fdf9a60065b 818 if not exists(src_path):
kadonotakashi 0:8fdf9a60065b 819 error_msg = "The library source folder does not exist: %s", src_path
kadonotakashi 0:8fdf9a60065b 820
kadonotakashi 0:8fdf9a60065b 821 if report != None:
kadonotakashi 0:8fdf9a60065b 822 cur_result["output"] = error_msg
kadonotakashi 0:8fdf9a60065b 823 cur_result["result"] = "FAIL"
kadonotakashi 0:8fdf9a60065b 824 add_result_to_report(report, cur_result)
kadonotakashi 0:8fdf9a60065b 825
kadonotakashi 0:8fdf9a60065b 826 raise Exception(error_msg)
kadonotakashi 0:8fdf9a60065b 827
kadonotakashi 0:8fdf9a60065b 828 try:
kadonotakashi 0:8fdf9a60065b 829 # Toolchain instance
kadonotakashi 0:8fdf9a60065b 830 # Create the desired build directory structure
kadonotakashi 0:8fdf9a60065b 831 bin_path = join(build_path, mbed2_obj_path(target.name, toolchain_name))
kadonotakashi 0:8fdf9a60065b 832 mkdir(bin_path)
kadonotakashi 0:8fdf9a60065b 833 tmp_path = join(build_path, '.temp', mbed2_obj_path(target.name,
kadonotakashi 0:8fdf9a60065b 834 toolchain_name))
kadonotakashi 0:8fdf9a60065b 835 mkdir(tmp_path)
kadonotakashi 0:8fdf9a60065b 836
kadonotakashi 0:8fdf9a60065b 837 toolchain = prepare_toolchain(
kadonotakashi 0:8fdf9a60065b 838 src_paths, tmp_path, target, toolchain_name, macros=macros,
kadonotakashi 0:8fdf9a60065b 839 notify=notify, build_profile=build_profile, jobs=jobs, clean=clean,
kadonotakashi 0:8fdf9a60065b 840 ignore=ignore)
kadonotakashi 0:8fdf9a60065b 841
kadonotakashi 0:8fdf9a60065b 842 notify.info("Building library %s (%s, %s)" %
kadonotakashi 0:8fdf9a60065b 843 (name.upper(), target.name, toolchain_name))
kadonotakashi 0:8fdf9a60065b 844
kadonotakashi 0:8fdf9a60065b 845 # Take into account the library configuration (MBED_CONFIG_FILE)
kadonotakashi 0:8fdf9a60065b 846 config = toolchain.config
kadonotakashi 0:8fdf9a60065b 847 config.add_config_files([MBED_CONFIG_FILE])
kadonotakashi 0:8fdf9a60065b 848
kadonotakashi 0:8fdf9a60065b 849 # Scan Resources
kadonotakashi 0:8fdf9a60065b 850 resources = Resources(notify).scan_with_toolchain(
kadonotakashi 0:8fdf9a60065b 851 src_paths + (lib.inc_dirs_ext or []), toolchain,
kadonotakashi 0:8fdf9a60065b 852 inc_dirs=inc_dirs, dependencies_paths=dependencies_paths)
kadonotakashi 0:8fdf9a60065b 853
kadonotakashi 0:8fdf9a60065b 854 # Copy Headers
kadonotakashi 0:8fdf9a60065b 855 toolchain.copy_files(
kadonotakashi 0:8fdf9a60065b 856 resources.get_file_refs(FileType.HEADER), build_path)
kadonotakashi 0:8fdf9a60065b 857
kadonotakashi 0:8fdf9a60065b 858 dependencies_include_dir = Resources(notify).sacn_with_toolchain([build_path], toolchain).inc_dirs
kadonotakashi 0:8fdf9a60065b 859
kadonotakashi 0:8fdf9a60065b 860 # Compile Sources
kadonotakashi 0:8fdf9a60065b 861 objects = []
kadonotakashi 0:8fdf9a60065b 862 for resource in resources:
kadonotakashi 0:8fdf9a60065b 863 objects.extend(toolchain.compile_sources(resource, dependencies_include_dir))
kadonotakashi 0:8fdf9a60065b 864
kadonotakashi 0:8fdf9a60065b 865 needed_update = toolchain.build_library(objects, bin_path, name)
kadonotakashi 0:8fdf9a60065b 866
kadonotakashi 0:8fdf9a60065b 867 if report != None and needed_update:
kadonotakashi 0:8fdf9a60065b 868 end = time()
kadonotakashi 0:8fdf9a60065b 869 cur_result["elapsed_time"] = end - start
kadonotakashi 0:8fdf9a60065b 870 cur_result["result"] = "OK"
kadonotakashi 0:8fdf9a60065b 871
kadonotakashi 0:8fdf9a60065b 872 add_result_to_report(report, cur_result)
kadonotakashi 0:8fdf9a60065b 873 return True
kadonotakashi 0:8fdf9a60065b 874
kadonotakashi 0:8fdf9a60065b 875 except Exception:
kadonotakashi 0:8fdf9a60065b 876 if report != None:
kadonotakashi 0:8fdf9a60065b 877 end = time()
kadonotakashi 0:8fdf9a60065b 878 cur_result["result"] = "FAIL"
kadonotakashi 0:8fdf9a60065b 879 cur_result["elapsed_time"] = end - start
kadonotakashi 0:8fdf9a60065b 880
kadonotakashi 0:8fdf9a60065b 881 add_result_to_report(report, cur_result)
kadonotakashi 0:8fdf9a60065b 882
kadonotakashi 0:8fdf9a60065b 883 # Let Exception propagate
kadonotakashi 0:8fdf9a60065b 884 raise
kadonotakashi 0:8fdf9a60065b 885
kadonotakashi 0:8fdf9a60065b 886
kadonotakashi 0:8fdf9a60065b 887 # A number of compiled files need to be copied as objects as the linker
kadonotakashi 0:8fdf9a60065b 888 # will not search for weak symbol overrides in archives. These are:
kadonotakashi 0:8fdf9a60065b 889 # - mbed_retarget.o: to make sure that the C standard lib symbols get
kadonotakashi 0:8fdf9a60065b 890 # overridden
kadonotakashi 0:8fdf9a60065b 891 # - mbed_board.o: `mbed_die` is weak
kadonotakashi 0:8fdf9a60065b 892 # - mbed_overrides.o: this contains platform overrides of various
kadonotakashi 0:8fdf9a60065b 893 # weak SDK functions
kadonotakashi 0:8fdf9a60065b 894 # - mbed_main.o: this contains main redirection
kadonotakashi 0:8fdf9a60065b 895 # - mbed_sdk_boot.o: this contains the main boot code in
kadonotakashi 0:8fdf9a60065b 896 # - PeripheralPins.o: PinMap can be weak
kadonotakashi 0:8fdf9a60065b 897 SEPARATE_NAMES = [
kadonotakashi 0:8fdf9a60065b 898 'PeripheralPins.o',
kadonotakashi 0:8fdf9a60065b 899 'mbed_retarget.o',
kadonotakashi 0:8fdf9a60065b 900 'mbed_board.o',
kadonotakashi 0:8fdf9a60065b 901 'mbed_overrides.o',
kadonotakashi 0:8fdf9a60065b 902 'mbed_main.o',
kadonotakashi 0:8fdf9a60065b 903 'mbed_sdk_boot.o',
kadonotakashi 0:8fdf9a60065b 904 ]
kadonotakashi 0:8fdf9a60065b 905
kadonotakashi 0:8fdf9a60065b 906
kadonotakashi 0:8fdf9a60065b 907 def build_mbed_libs(target, toolchain_name, clean=False, macros=None,
kadonotakashi 0:8fdf9a60065b 908 notify=None, jobs=1, report=None, properties=None,
kadonotakashi 0:8fdf9a60065b 909 build_profile=None, ignore=None):
kadonotakashi 0:8fdf9a60065b 910 """ Build legacy libraries for a target and toolchain pair
kadonotakashi 0:8fdf9a60065b 911
kadonotakashi 0:8fdf9a60065b 912 Positional arguments:
kadonotakashi 0:8fdf9a60065b 913 target - the MCU or board that the project will compile for
kadonotakashi 0:8fdf9a60065b 914 toolchain_name - the name of the build tools
kadonotakashi 0:8fdf9a60065b 915
kadonotakashi 0:8fdf9a60065b 916 Keyword arguments:
kadonotakashi 0:8fdf9a60065b 917 clean - Rebuild everything if True
kadonotakashi 0:8fdf9a60065b 918 macros - additional macros
kadonotakashi 0:8fdf9a60065b 919 notify - Notify function for logs
kadonotakashi 0:8fdf9a60065b 920 jobs - how many compilers we can run at once
kadonotakashi 0:8fdf9a60065b 921 report - a dict where a result may be appended
kadonotakashi 0:8fdf9a60065b 922 properties - UUUUHHHHH beats me
kadonotakashi 0:8fdf9a60065b 923 build_profile - a dict of flags that will be passed to the compiler
kadonotakashi 0:8fdf9a60065b 924 ignore - list of paths to add to mbedignore
kadonotakashi 0:8fdf9a60065b 925
kadonotakashi 0:8fdf9a60065b 926 Return - True if target + toolchain built correctly, False if not supported
kadonotakashi 0:8fdf9a60065b 927 """
kadonotakashi 0:8fdf9a60065b 928
kadonotakashi 0:8fdf9a60065b 929 if report is not None:
kadonotakashi 0:8fdf9a60065b 930 start = time()
kadonotakashi 0:8fdf9a60065b 931 id_name = "MBED"
kadonotakashi 0:8fdf9a60065b 932 description = "mbed SDK"
kadonotakashi 0:8fdf9a60065b 933 vendor_label = target.extra_labels[0]
kadonotakashi 0:8fdf9a60065b 934 cur_result = None
kadonotakashi 0:8fdf9a60065b 935 prep_report(report, target.name, toolchain_name, id_name)
kadonotakashi 0:8fdf9a60065b 936 cur_result = create_result(
kadonotakashi 0:8fdf9a60065b 937 target.name, toolchain_name, id_name, description)
kadonotakashi 0:8fdf9a60065b 938 if properties is not None:
kadonotakashi 0:8fdf9a60065b 939 prep_properties(
kadonotakashi 0:8fdf9a60065b 940 properties, target.name, toolchain_name, vendor_label)
kadonotakashi 0:8fdf9a60065b 941
kadonotakashi 0:8fdf9a60065b 942 if toolchain_name not in target.supported_toolchains:
kadonotakashi 0:8fdf9a60065b 943 supported_toolchains_text = ", ".join(target.supported_toolchains)
kadonotakashi 0:8fdf9a60065b 944 notify.info('The target {} does not support the toolchain {}'.format(
kadonotakashi 0:8fdf9a60065b 945 target.name,
kadonotakashi 0:8fdf9a60065b 946 toolchain_name
kadonotakashi 0:8fdf9a60065b 947 ))
kadonotakashi 0:8fdf9a60065b 948 notify.info('{} supports {} toolchain{}'.format(
kadonotakashi 0:8fdf9a60065b 949 target.name,
kadonotakashi 0:8fdf9a60065b 950 supported_toolchains_text,
kadonotakashi 0:8fdf9a60065b 951 's' if len(target.supported_toolchains) > 1 else ''
kadonotakashi 0:8fdf9a60065b 952 ))
kadonotakashi 0:8fdf9a60065b 953
kadonotakashi 0:8fdf9a60065b 954 if report is not None:
kadonotakashi 0:8fdf9a60065b 955 cur_result["result"] = "SKIP"
kadonotakashi 0:8fdf9a60065b 956 add_result_to_report(report, cur_result)
kadonotakashi 0:8fdf9a60065b 957
kadonotakashi 0:8fdf9a60065b 958 return False
kadonotakashi 0:8fdf9a60065b 959
kadonotakashi 0:8fdf9a60065b 960 try:
kadonotakashi 0:8fdf9a60065b 961 # Source and Build Paths
kadonotakashi 0:8fdf9a60065b 962 build_toolchain = join(
kadonotakashi 0:8fdf9a60065b 963 MBED_LIBRARIES, mbed2_obj_path(target.name, toolchain_name))
kadonotakashi 0:8fdf9a60065b 964 mkdir(build_toolchain)
kadonotakashi 0:8fdf9a60065b 965
kadonotakashi 0:8fdf9a60065b 966 tmp_path = join(
kadonotakashi 0:8fdf9a60065b 967 MBED_LIBRARIES,
kadonotakashi 0:8fdf9a60065b 968 '.temp',
kadonotakashi 0:8fdf9a60065b 969 mbed2_obj_path(target.name, toolchain_name)
kadonotakashi 0:8fdf9a60065b 970 )
kadonotakashi 0:8fdf9a60065b 971 mkdir(tmp_path)
kadonotakashi 0:8fdf9a60065b 972
kadonotakashi 0:8fdf9a60065b 973 # Toolchain and config
kadonotakashi 0:8fdf9a60065b 974 toolchain = prepare_toolchain(
kadonotakashi 0:8fdf9a60065b 975 [""], tmp_path, target, toolchain_name, macros=macros, notify=notify,
kadonotakashi 0:8fdf9a60065b 976 build_profile=build_profile, jobs=jobs, clean=clean, ignore=ignore)
kadonotakashi 0:8fdf9a60065b 977
kadonotakashi 0:8fdf9a60065b 978 config = toolchain.config
kadonotakashi 0:8fdf9a60065b 979 config.add_config_files([MBED_CONFIG_FILE])
kadonotakashi 0:8fdf9a60065b 980 toolchain.set_config_data(toolchain.config.get_config_data())
kadonotakashi 0:8fdf9a60065b 981
kadonotakashi 0:8fdf9a60065b 982 # distribute header files
kadonotakashi 0:8fdf9a60065b 983 toolchain.copy_files(
kadonotakashi 0:8fdf9a60065b 984 [FileRef(basename(MBED_HEADER),MBED_HEADER)], MBED_LIBRARIES)
kadonotakashi 0:8fdf9a60065b 985 library_incdirs = [dirname(MBED_LIBRARIES), MBED_LIBRARIES]
kadonotakashi 0:8fdf9a60065b 986
kadonotakashi 0:8fdf9a60065b 987 for dir, dest in [(MBED_DRIVERS, MBED_LIBRARIES_DRIVERS),
kadonotakashi 0:8fdf9a60065b 988 (MBED_PLATFORM, MBED_LIBRARIES_PLATFORM),
kadonotakashi 0:8fdf9a60065b 989 (MBED_HAL, MBED_LIBRARIES_HAL)]:
kadonotakashi 0:8fdf9a60065b 990 resources = Resources(notify).scan_with_toolchain([dir], toolchain)
kadonotakashi 0:8fdf9a60065b 991 toolchain.copy_files(
kadonotakashi 0:8fdf9a60065b 992 [FileRef(basename(p), p) for p
kadonotakashi 0:8fdf9a60065b 993 in resources.get_file_paths(FileType.HEADER)] ,
kadonotakashi 0:8fdf9a60065b 994 dest)
kadonotakashi 0:8fdf9a60065b 995 library_incdirs.append(dest)
kadonotakashi 0:8fdf9a60065b 996
kadonotakashi 0:8fdf9a60065b 997 # collect resources of the libs to compile
kadonotakashi 0:8fdf9a60065b 998 cmsis_res = Resources(notify).scan_with_toolchain(
kadonotakashi 0:8fdf9a60065b 999 [MBED_CMSIS_PATH], toolchain)
kadonotakashi 0:8fdf9a60065b 1000 hal_res = Resources(notify).scan_with_toolchain(
kadonotakashi 0:8fdf9a60065b 1001 [MBED_TARGETS_PATH], toolchain)
kadonotakashi 0:8fdf9a60065b 1002 mbed_resources = Resources(notify).scan_with_toolchain(
kadonotakashi 0:8fdf9a60065b 1003 [MBED_DRIVERS, MBED_PLATFORM, MBED_HAL], toolchain)
kadonotakashi 0:8fdf9a60065b 1004
kadonotakashi 0:8fdf9a60065b 1005 incdirs = cmsis_res.inc_dirs + hal_res.inc_dirs + library_incdirs
kadonotakashi 0:8fdf9a60065b 1006
kadonotakashi 0:8fdf9a60065b 1007 # Build Things
kadonotakashi 0:8fdf9a60065b 1008 notify.info("Building library %s (%s, %s)" %
kadonotakashi 0:8fdf9a60065b 1009 ('MBED', target.name, toolchain_name))
kadonotakashi 0:8fdf9a60065b 1010 objects = toolchain.compile_sources(mbed_resources, incdirs)
kadonotakashi 0:8fdf9a60065b 1011 separate_objects = []
kadonotakashi 0:8fdf9a60065b 1012
kadonotakashi 0:8fdf9a60065b 1013 for obj in objects:
kadonotakashi 0:8fdf9a60065b 1014 for name in SEPARATE_NAMES:
kadonotakashi 0:8fdf9a60065b 1015 if obj.endswith(name):
kadonotakashi 0:8fdf9a60065b 1016 separate_objects.append(obj)
kadonotakashi 0:8fdf9a60065b 1017
kadonotakashi 0:8fdf9a60065b 1018 for obj in separate_objects:
kadonotakashi 0:8fdf9a60065b 1019 objects.remove(obj)
kadonotakashi 0:8fdf9a60065b 1020
kadonotakashi 0:8fdf9a60065b 1021 toolchain.build_library(objects, build_toolchain, "mbed")
kadonotakashi 0:8fdf9a60065b 1022 notify.info("Building library %s (%s, %s)" %
kadonotakashi 0:8fdf9a60065b 1023 ('CMSIS', target.name, toolchain_name))
kadonotakashi 0:8fdf9a60065b 1024 cmsis_objects = toolchain.compile_sources(cmsis_res, incdirs + [tmp_path])
kadonotakashi 0:8fdf9a60065b 1025 notify.info("Building library %s (%s, %s)" %
kadonotakashi 0:8fdf9a60065b 1026 ('HAL', target.name, toolchain_name))
kadonotakashi 0:8fdf9a60065b 1027 hal_objects = toolchain.compile_sources(hal_res, incdirs + [tmp_path])
kadonotakashi 0:8fdf9a60065b 1028
kadonotakashi 0:8fdf9a60065b 1029 # Copy everything into the build directory
kadonotakashi 0:8fdf9a60065b 1030 to_copy_paths = [
kadonotakashi 0:8fdf9a60065b 1031 hal_res.get_file_paths(FileType.HEADER),
kadonotakashi 0:8fdf9a60065b 1032 hal_res.get_file_paths(FileType.HEX),
kadonotakashi 0:8fdf9a60065b 1033 hal_res.get_file_paths(FileType.BIN),
kadonotakashi 0:8fdf9a60065b 1034 hal_res.get_file_paths(FileType.LIB),
kadonotakashi 0:8fdf9a60065b 1035 cmsis_res.get_file_paths(FileType.HEADER),
kadonotakashi 0:8fdf9a60065b 1036 cmsis_res.get_file_paths(FileType.BIN),
kadonotakashi 0:8fdf9a60065b 1037 cmsis_res.get_file_paths(FileType.LD_SCRIPT),
kadonotakashi 0:8fdf9a60065b 1038 hal_res.get_file_paths(FileType.LD_SCRIPT),
kadonotakashi 0:8fdf9a60065b 1039 [MBED_CONFIG_FILE],
kadonotakashi 0:8fdf9a60065b 1040 cmsis_objects,
kadonotakashi 0:8fdf9a60065b 1041 hal_objects,
kadonotakashi 0:8fdf9a60065b 1042 separate_objects,
kadonotakashi 0:8fdf9a60065b 1043 ]
kadonotakashi 0:8fdf9a60065b 1044 to_copy = [FileRef(basename(p), p) for p in sum(to_copy_paths, [])]
kadonotakashi 0:8fdf9a60065b 1045 toolchain.copy_files(to_copy, build_toolchain)
kadonotakashi 0:8fdf9a60065b 1046
kadonotakashi 0:8fdf9a60065b 1047 if report is not None:
kadonotakashi 0:8fdf9a60065b 1048 end = time()
kadonotakashi 0:8fdf9a60065b 1049 cur_result["elapsed_time"] = end - start
kadonotakashi 0:8fdf9a60065b 1050 cur_result["result"] = "OK"
kadonotakashi 0:8fdf9a60065b 1051 add_result_to_report(report, cur_result)
kadonotakashi 0:8fdf9a60065b 1052
kadonotakashi 0:8fdf9a60065b 1053 return True
kadonotakashi 0:8fdf9a60065b 1054
kadonotakashi 0:8fdf9a60065b 1055 except Exception as exc:
kadonotakashi 0:8fdf9a60065b 1056 if report is not None:
kadonotakashi 0:8fdf9a60065b 1057 end = time()
kadonotakashi 0:8fdf9a60065b 1058 cur_result["result"] = "FAIL"
kadonotakashi 0:8fdf9a60065b 1059 cur_result["elapsed_time"] = end - start
kadonotakashi 0:8fdf9a60065b 1060
kadonotakashi 0:8fdf9a60065b 1061 cur_result["output"] += str(exc)
kadonotakashi 0:8fdf9a60065b 1062
kadonotakashi 0:8fdf9a60065b 1063 add_result_to_report(report, cur_result)
kadonotakashi 0:8fdf9a60065b 1064 raise
kadonotakashi 0:8fdf9a60065b 1065
kadonotakashi 0:8fdf9a60065b 1066
kadonotakashi 0:8fdf9a60065b 1067 def get_unique_supported_toolchains(release_targets=None):
kadonotakashi 0:8fdf9a60065b 1068 """ Get list of all unique toolchains supported by targets
kadonotakashi 0:8fdf9a60065b 1069
kadonotakashi 0:8fdf9a60065b 1070 Keyword arguments:
kadonotakashi 0:8fdf9a60065b 1071 release_targets - tuple structure returned from get_mbed_official_release().
kadonotakashi 0:8fdf9a60065b 1072 If release_targets is not specified, then it queries all
kadonotakashi 0:8fdf9a60065b 1073 known targets
kadonotakashi 0:8fdf9a60065b 1074 """
kadonotakashi 0:8fdf9a60065b 1075 unique_supported_toolchains = []
kadonotakashi 0:8fdf9a60065b 1076
kadonotakashi 0:8fdf9a60065b 1077 if not release_targets:
kadonotakashi 0:8fdf9a60065b 1078 for target in TARGET_NAMES:
kadonotakashi 0:8fdf9a60065b 1079 for toolchain in TARGET_MAP[target].supported_toolchains:
kadonotakashi 0:8fdf9a60065b 1080 if toolchain not in unique_supported_toolchains:
kadonotakashi 0:8fdf9a60065b 1081 unique_supported_toolchains.append(toolchain)
kadonotakashi 0:8fdf9a60065b 1082 else:
kadonotakashi 0:8fdf9a60065b 1083 for target in release_targets:
kadonotakashi 0:8fdf9a60065b 1084 for toolchain in target[1]:
kadonotakashi 0:8fdf9a60065b 1085 if toolchain not in unique_supported_toolchains:
kadonotakashi 0:8fdf9a60065b 1086 unique_supported_toolchains.append(toolchain)
kadonotakashi 0:8fdf9a60065b 1087
kadonotakashi 0:8fdf9a60065b 1088 return unique_supported_toolchains
kadonotakashi 0:8fdf9a60065b 1089
kadonotakashi 0:8fdf9a60065b 1090
kadonotakashi 0:8fdf9a60065b 1091 def _lowercase_release_version(release_version):
kadonotakashi 0:8fdf9a60065b 1092 try:
kadonotakashi 0:8fdf9a60065b 1093 return release_version.lower()
kadonotakashi 0:8fdf9a60065b 1094 except AttributeError:
kadonotakashi 0:8fdf9a60065b 1095 return 'all'
kadonotakashi 0:8fdf9a60065b 1096
kadonotakashi 0:8fdf9a60065b 1097 def mcu_toolchain_list(release_version='5'):
kadonotakashi 0:8fdf9a60065b 1098 """ Shows list of toolchains
kadonotakashi 0:8fdf9a60065b 1099
kadonotakashi 0:8fdf9a60065b 1100 """
kadonotakashi 0:8fdf9a60065b 1101 release_version = _lowercase_release_version(release_version)
kadonotakashi 0:8fdf9a60065b 1102 version_release_targets = {}
kadonotakashi 0:8fdf9a60065b 1103 version_release_target_names = {}
kadonotakashi 0:8fdf9a60065b 1104
kadonotakashi 0:8fdf9a60065b 1105 for version in RELEASE_VERSIONS:
kadonotakashi 0:8fdf9a60065b 1106 version_release_targets[version] = get_mbed_official_release(version)
kadonotakashi 0:8fdf9a60065b 1107 version_release_target_names[version] = [x[0] for x in
kadonotakashi 0:8fdf9a60065b 1108 version_release_targets[
kadonotakashi 0:8fdf9a60065b 1109 version]]
kadonotakashi 0:8fdf9a60065b 1110
kadonotakashi 0:8fdf9a60065b 1111 if release_version in RELEASE_VERSIONS:
kadonotakashi 0:8fdf9a60065b 1112 release_targets = version_release_targets[release_version]
kadonotakashi 0:8fdf9a60065b 1113 else:
kadonotakashi 0:8fdf9a60065b 1114 release_targets = None
kadonotakashi 0:8fdf9a60065b 1115
kadonotakashi 0:8fdf9a60065b 1116 unique_supported_toolchains = get_unique_supported_toolchains(
kadonotakashi 0:8fdf9a60065b 1117 release_targets)
kadonotakashi 0:8fdf9a60065b 1118 columns = ["mbed OS %s" % x for x in RELEASE_VERSIONS] + unique_supported_toolchains
kadonotakashi 0:8fdf9a60065b 1119 return "\n".join(columns)
kadonotakashi 0:8fdf9a60065b 1120
kadonotakashi 0:8fdf9a60065b 1121
kadonotakashi 0:8fdf9a60065b 1122 def mcu_target_list(release_version='5'):
kadonotakashi 0:8fdf9a60065b 1123 """ Shows target list
kadonotakashi 0:8fdf9a60065b 1124
kadonotakashi 0:8fdf9a60065b 1125 """
kadonotakashi 0:8fdf9a60065b 1126 release_version = _lowercase_release_version(release_version)
kadonotakashi 0:8fdf9a60065b 1127 version_release_targets = {}
kadonotakashi 0:8fdf9a60065b 1128 version_release_target_names = {}
kadonotakashi 0:8fdf9a60065b 1129
kadonotakashi 0:8fdf9a60065b 1130 for version in RELEASE_VERSIONS:
kadonotakashi 0:8fdf9a60065b 1131 version_release_targets[version] = get_mbed_official_release(version)
kadonotakashi 0:8fdf9a60065b 1132 version_release_target_names[version] = [x[0] for x in
kadonotakashi 0:8fdf9a60065b 1133 version_release_targets[
kadonotakashi 0:8fdf9a60065b 1134 version]]
kadonotakashi 0:8fdf9a60065b 1135
kadonotakashi 0:8fdf9a60065b 1136 if release_version in RELEASE_VERSIONS:
kadonotakashi 0:8fdf9a60065b 1137 release_targets = version_release_targets[release_version]
kadonotakashi 0:8fdf9a60065b 1138 else:
kadonotakashi 0:8fdf9a60065b 1139 release_targets = None
kadonotakashi 0:8fdf9a60065b 1140
kadonotakashi 0:8fdf9a60065b 1141 target_names = []
kadonotakashi 0:8fdf9a60065b 1142
kadonotakashi 0:8fdf9a60065b 1143 if release_targets:
kadonotakashi 0:8fdf9a60065b 1144 target_names = [x[0] for x in release_targets]
kadonotakashi 0:8fdf9a60065b 1145 else:
kadonotakashi 0:8fdf9a60065b 1146 target_names = TARGET_NAMES
kadonotakashi 0:8fdf9a60065b 1147
kadonotakashi 0:8fdf9a60065b 1148 return "\n".join(target_names)
kadonotakashi 0:8fdf9a60065b 1149
kadonotakashi 0:8fdf9a60065b 1150
kadonotakashi 0:8fdf9a60065b 1151 def mcu_toolchain_matrix(verbose_html=False, platform_filter=None,
kadonotakashi 0:8fdf9a60065b 1152 release_version='5'):
kadonotakashi 0:8fdf9a60065b 1153 """ Shows target map using prettytable
kadonotakashi 0:8fdf9a60065b 1154
kadonotakashi 0:8fdf9a60065b 1155 Keyword arguments:
kadonotakashi 0:8fdf9a60065b 1156 verbose_html - emit html instead of a simple table
kadonotakashi 0:8fdf9a60065b 1157 platform_filter - remove results that match the string
kadonotakashi 0:8fdf9a60065b 1158 release_version - get the matrix for this major version number
kadonotakashi 0:8fdf9a60065b 1159 """
kadonotakashi 0:8fdf9a60065b 1160 # Only use it in this function so building works without extra modules
kadonotakashi 0:8fdf9a60065b 1161 from prettytable import PrettyTable, HEADER
kadonotakashi 0:8fdf9a60065b 1162 release_version = _lowercase_release_version(release_version)
kadonotakashi 0:8fdf9a60065b 1163 version_release_targets = {}
kadonotakashi 0:8fdf9a60065b 1164 version_release_target_names = {}
kadonotakashi 0:8fdf9a60065b 1165
kadonotakashi 0:8fdf9a60065b 1166 for version in RELEASE_VERSIONS:
kadonotakashi 0:8fdf9a60065b 1167 version_release_targets[version] = get_mbed_official_release(version)
kadonotakashi 0:8fdf9a60065b 1168 version_release_target_names[version] = [x[0] for x in
kadonotakashi 0:8fdf9a60065b 1169 version_release_targets[
kadonotakashi 0:8fdf9a60065b 1170 version]]
kadonotakashi 0:8fdf9a60065b 1171
kadonotakashi 0:8fdf9a60065b 1172 if release_version in RELEASE_VERSIONS:
kadonotakashi 0:8fdf9a60065b 1173 release_targets = version_release_targets[release_version]
kadonotakashi 0:8fdf9a60065b 1174 else:
kadonotakashi 0:8fdf9a60065b 1175 release_targets = None
kadonotakashi 0:8fdf9a60065b 1176
kadonotakashi 0:8fdf9a60065b 1177 unique_supported_toolchains = get_unique_supported_toolchains(
kadonotakashi 0:8fdf9a60065b 1178 release_targets)
kadonotakashi 0:8fdf9a60065b 1179 prepend_columns = ["Target"] + ["mbed OS %s" % x for x in RELEASE_VERSIONS]
kadonotakashi 0:8fdf9a60065b 1180
kadonotakashi 0:8fdf9a60065b 1181 # All tests status table print
kadonotakashi 0:8fdf9a60065b 1182 columns = prepend_columns + unique_supported_toolchains
kadonotakashi 0:8fdf9a60065b 1183 table_printer = PrettyTable(columns, junction_char="|", hrules=HEADER)
kadonotakashi 0:8fdf9a60065b 1184 # Align table
kadonotakashi 0:8fdf9a60065b 1185 for col in columns:
kadonotakashi 0:8fdf9a60065b 1186 table_printer.align[col] = "c"
kadonotakashi 0:8fdf9a60065b 1187 table_printer.align["Target"] = "l"
kadonotakashi 0:8fdf9a60065b 1188
kadonotakashi 0:8fdf9a60065b 1189 perm_counter = 0
kadonotakashi 0:8fdf9a60065b 1190 target_counter = 0
kadonotakashi 0:8fdf9a60065b 1191
kadonotakashi 0:8fdf9a60065b 1192 target_names = []
kadonotakashi 0:8fdf9a60065b 1193
kadonotakashi 0:8fdf9a60065b 1194 if release_targets:
kadonotakashi 0:8fdf9a60065b 1195 target_names = [x[0] for x in release_targets]
kadonotakashi 0:8fdf9a60065b 1196 else:
kadonotakashi 0:8fdf9a60065b 1197 target_names = TARGET_NAMES
kadonotakashi 0:8fdf9a60065b 1198
kadonotakashi 0:8fdf9a60065b 1199 for target in sorted(target_names):
kadonotakashi 0:8fdf9a60065b 1200 if platform_filter is not None:
kadonotakashi 0:8fdf9a60065b 1201 # FIlter out platforms using regex
kadonotakashi 0:8fdf9a60065b 1202 if re.search(platform_filter, target) is None:
kadonotakashi 0:8fdf9a60065b 1203 continue
kadonotakashi 0:8fdf9a60065b 1204 target_counter += 1
kadonotakashi 0:8fdf9a60065b 1205
kadonotakashi 0:8fdf9a60065b 1206 row = [target] # First column is platform name
kadonotakashi 0:8fdf9a60065b 1207
kadonotakashi 0:8fdf9a60065b 1208 for version in RELEASE_VERSIONS:
kadonotakashi 0:8fdf9a60065b 1209 if target in version_release_target_names[version]:
kadonotakashi 0:8fdf9a60065b 1210 text = "Supported"
kadonotakashi 0:8fdf9a60065b 1211 else:
kadonotakashi 0:8fdf9a60065b 1212 text = "-"
kadonotakashi 0:8fdf9a60065b 1213 row.append(text)
kadonotakashi 0:8fdf9a60065b 1214
kadonotakashi 0:8fdf9a60065b 1215 for unique_toolchain in unique_supported_toolchains:
kadonotakashi 0:8fdf9a60065b 1216 tgt_obj = TARGET_MAP[target]
kadonotakashi 0:8fdf9a60065b 1217 if (unique_toolchain in tgt_obj.supported_toolchains or
kadonotakashi 0:8fdf9a60065b 1218 (unique_toolchain == "ARMC6" and
kadonotakashi 0:8fdf9a60065b 1219 "ARM" in tgt_obj.supported_toolchains) or
kadonotakashi 0:8fdf9a60065b 1220 (unique_toolchain == "ARM" and
kadonotakashi 0:8fdf9a60065b 1221 "ARMC6" in tgt_obj.supported_toolchains and
kadonotakashi 0:8fdf9a60065b 1222 CORE_ARCH[tgt_obj.core] == 8)):
kadonotakashi 0:8fdf9a60065b 1223 text = "Supported"
kadonotakashi 0:8fdf9a60065b 1224 perm_counter += 1
kadonotakashi 0:8fdf9a60065b 1225 else:
kadonotakashi 0:8fdf9a60065b 1226 text = "-"
kadonotakashi 0:8fdf9a60065b 1227
kadonotakashi 0:8fdf9a60065b 1228 row.append(text)
kadonotakashi 0:8fdf9a60065b 1229 table_printer.add_row(row)
kadonotakashi 0:8fdf9a60065b 1230
kadonotakashi 0:8fdf9a60065b 1231 result = table_printer.get_html_string() if verbose_html \
kadonotakashi 0:8fdf9a60065b 1232 else table_printer.get_string()
kadonotakashi 0:8fdf9a60065b 1233 result += "\n"
kadonotakashi 0:8fdf9a60065b 1234 result += "Supported targets: %d\n"% (target_counter)
kadonotakashi 0:8fdf9a60065b 1235 if target_counter == 1:
kadonotakashi 0:8fdf9a60065b 1236 result += "Supported toolchains: %d"% (perm_counter)
kadonotakashi 0:8fdf9a60065b 1237 return result
kadonotakashi 0:8fdf9a60065b 1238
kadonotakashi 0:8fdf9a60065b 1239
kadonotakashi 0:8fdf9a60065b 1240 def get_target_supported_toolchains(target):
kadonotakashi 0:8fdf9a60065b 1241 """ Returns target supported toolchains list
kadonotakashi 0:8fdf9a60065b 1242
kadonotakashi 0:8fdf9a60065b 1243 Positional arguments:
kadonotakashi 0:8fdf9a60065b 1244 target - the target to get the supported toolchains of
kadonotakashi 0:8fdf9a60065b 1245 """
kadonotakashi 0:8fdf9a60065b 1246 return TARGET_MAP[target].supported_toolchains if target in TARGET_MAP \
kadonotakashi 0:8fdf9a60065b 1247 else None
kadonotakashi 0:8fdf9a60065b 1248
kadonotakashi 0:8fdf9a60065b 1249
kadonotakashi 0:8fdf9a60065b 1250 def print_build_results(result_list, build_name):
kadonotakashi 0:8fdf9a60065b 1251 """ Generate result string for build results
kadonotakashi 0:8fdf9a60065b 1252
kadonotakashi 0:8fdf9a60065b 1253 Positional arguments:
kadonotakashi 0:8fdf9a60065b 1254 result_list - the list of results to print
kadonotakashi 0:8fdf9a60065b 1255 build_name - the name of the build we are printing result for
kadonotakashi 0:8fdf9a60065b 1256 """
kadonotakashi 0:8fdf9a60065b 1257 result = ""
kadonotakashi 0:8fdf9a60065b 1258 if len(result_list) > 0:
kadonotakashi 0:8fdf9a60065b 1259 result += build_name + "\n"
kadonotakashi 0:8fdf9a60065b 1260 result += "\n".join([" * %s" % f for f in result_list])
kadonotakashi 0:8fdf9a60065b 1261 result += "\n"
kadonotakashi 0:8fdf9a60065b 1262 return result
kadonotakashi 0:8fdf9a60065b 1263
kadonotakashi 0:8fdf9a60065b 1264 def print_build_memory_usage(report):
kadonotakashi 0:8fdf9a60065b 1265 """ Generate result table with memory usage values for build results
kadonotakashi 0:8fdf9a60065b 1266 Aggregates (puts together) reports obtained from self.get_memory_summary()
kadonotakashi 0:8fdf9a60065b 1267
kadonotakashi 0:8fdf9a60065b 1268 Positional arguments:
kadonotakashi 0:8fdf9a60065b 1269 report - Report generated during build procedure.
kadonotakashi 0:8fdf9a60065b 1270 """
kadonotakashi 0:8fdf9a60065b 1271 from prettytable import PrettyTable, HEADER
kadonotakashi 0:8fdf9a60065b 1272 columns_text = ['name', 'target', 'toolchain']
kadonotakashi 0:8fdf9a60065b 1273 columns_int = ['static_ram', 'total_flash']
kadonotakashi 0:8fdf9a60065b 1274 table = PrettyTable(columns_text + columns_int, junction_char="|", hrules=HEADER)
kadonotakashi 0:8fdf9a60065b 1275
kadonotakashi 0:8fdf9a60065b 1276 for col in columns_text:
kadonotakashi 0:8fdf9a60065b 1277 table.align[col] = 'l'
kadonotakashi 0:8fdf9a60065b 1278
kadonotakashi 0:8fdf9a60065b 1279 for col in columns_int:
kadonotakashi 0:8fdf9a60065b 1280 table.align[col] = 'r'
kadonotakashi 0:8fdf9a60065b 1281
kadonotakashi 0:8fdf9a60065b 1282 for target in report:
kadonotakashi 0:8fdf9a60065b 1283 for toolchain in report[target]:
kadonotakashi 0:8fdf9a60065b 1284 for name in report[target][toolchain]:
kadonotakashi 0:8fdf9a60065b 1285 for dlist in report[target][toolchain][name]:
kadonotakashi 0:8fdf9a60065b 1286 for dlistelem in dlist:
kadonotakashi 0:8fdf9a60065b 1287 # Get 'memory_usage' record and build table with
kadonotakashi 0:8fdf9a60065b 1288 # statistics
kadonotakashi 0:8fdf9a60065b 1289 record = dlist[dlistelem]
kadonotakashi 0:8fdf9a60065b 1290 if 'memory_usage' in record and record['memory_usage']:
kadonotakashi 0:8fdf9a60065b 1291 # Note that summary should be in the last record of
kadonotakashi 0:8fdf9a60065b 1292 # 'memory_usage' section. This is why we are
kadonotakashi 0:8fdf9a60065b 1293 # grabbing last "[-1]" record.
kadonotakashi 0:8fdf9a60065b 1294 row = [
kadonotakashi 0:8fdf9a60065b 1295 record['description'],
kadonotakashi 0:8fdf9a60065b 1296 record['target_name'],
kadonotakashi 0:8fdf9a60065b 1297 record['toolchain_name'],
kadonotakashi 0:8fdf9a60065b 1298 record['memory_usage'][-1]['summary'][
kadonotakashi 0:8fdf9a60065b 1299 'static_ram'],
kadonotakashi 0:8fdf9a60065b 1300 record['memory_usage'][-1]['summary'][
kadonotakashi 0:8fdf9a60065b 1301 'total_flash'],
kadonotakashi 0:8fdf9a60065b 1302 ]
kadonotakashi 0:8fdf9a60065b 1303 table.add_row(row)
kadonotakashi 0:8fdf9a60065b 1304
kadonotakashi 0:8fdf9a60065b 1305 result = "Memory map breakdown for built projects (values in Bytes):\n"
kadonotakashi 0:8fdf9a60065b 1306 result += table.get_string(sortby='name')
kadonotakashi 0:8fdf9a60065b 1307 return result
kadonotakashi 0:8fdf9a60065b 1308
kadonotakashi 0:8fdf9a60065b 1309 def write_build_report(build_report, template_filename, filename):
kadonotakashi 0:8fdf9a60065b 1310 """Write a build report to disk using a template file
kadonotakashi 0:8fdf9a60065b 1311
kadonotakashi 0:8fdf9a60065b 1312 Positional arguments:
kadonotakashi 0:8fdf9a60065b 1313 build_report - a report generated by the build system
kadonotakashi 0:8fdf9a60065b 1314 template_filename - a file that contains the template for the style of build
kadonotakashi 0:8fdf9a60065b 1315 report
kadonotakashi 0:8fdf9a60065b 1316 filename - the location on disk to write the file to
kadonotakashi 0:8fdf9a60065b 1317 """
kadonotakashi 0:8fdf9a60065b 1318 build_report_failing = []
kadonotakashi 0:8fdf9a60065b 1319 build_report_passing = []
kadonotakashi 0:8fdf9a60065b 1320
kadonotakashi 0:8fdf9a60065b 1321 for report in build_report:
kadonotakashi 0:8fdf9a60065b 1322 if len(report["failing"]) > 0:
kadonotakashi 0:8fdf9a60065b 1323 build_report_failing.append(report)
kadonotakashi 0:8fdf9a60065b 1324 else:
kadonotakashi 0:8fdf9a60065b 1325 build_report_passing.append(report)
kadonotakashi 0:8fdf9a60065b 1326
kadonotakashi 0:8fdf9a60065b 1327 env = Environment(extensions=['jinja2.ext.with_'])
kadonotakashi 0:8fdf9a60065b 1328 env.loader = FileSystemLoader('ci_templates')
kadonotakashi 0:8fdf9a60065b 1329 template = env.get_template(template_filename)
kadonotakashi 0:8fdf9a60065b 1330
kadonotakashi 0:8fdf9a60065b 1331 with open(filename, 'w+') as placeholder:
kadonotakashi 0:8fdf9a60065b 1332 placeholder.write(template.render(
kadonotakashi 0:8fdf9a60065b 1333 failing_builds=build_report_failing,
kadonotakashi 0:8fdf9a60065b 1334 passing_builds=build_report_passing))
kadonotakashi 0:8fdf9a60065b 1335
kadonotakashi 0:8fdf9a60065b 1336
kadonotakashi 0:8fdf9a60065b 1337 def merge_build_data(filename, toolchain_report, app_type):
kadonotakashi 0:8fdf9a60065b 1338 path_to_file = dirname(abspath(filename))
kadonotakashi 0:8fdf9a60065b 1339 try:
kadonotakashi 0:8fdf9a60065b 1340 build_data = load(open(filename))
kadonotakashi 0:8fdf9a60065b 1341 except (IOError, ValueError):
kadonotakashi 0:8fdf9a60065b 1342 build_data = {'builds': []}
kadonotakashi 0:8fdf9a60065b 1343 for tgt in toolchain_report.values():
kadonotakashi 0:8fdf9a60065b 1344 for tc in tgt.values():
kadonotakashi 0:8fdf9a60065b 1345 for project in tc.values():
kadonotakashi 0:8fdf9a60065b 1346 for build in project:
kadonotakashi 0:8fdf9a60065b 1347 try:
kadonotakashi 0:8fdf9a60065b 1348 build[0]['bin_fullpath'] = build[0]['bin']
kadonotakashi 0:8fdf9a60065b 1349 build[0]['elf_fullpath'] = build[0]['elf']
kadonotakashi 0:8fdf9a60065b 1350 build[0]['elf'] = relpath(build[0]['elf'], path_to_file)
kadonotakashi 0:8fdf9a60065b 1351 build[0]['bin'] = relpath(build[0]['bin'], path_to_file)
kadonotakashi 0:8fdf9a60065b 1352 except KeyError:
kadonotakashi 0:8fdf9a60065b 1353 pass
kadonotakashi 0:8fdf9a60065b 1354 if 'type' not in build[0]:
kadonotakashi 0:8fdf9a60065b 1355 build[0]['type'] = app_type
kadonotakashi 0:8fdf9a60065b 1356 build_data['builds'].insert(0, build[0])
kadonotakashi 0:8fdf9a60065b 1357 dump(build_data, open(filename, "w"), indent=4, separators=(',', ': '))