init

Dependencies:   mbed

Committer:
Nathan Yonkee
Date:
Fri Mar 02 07:16:49 2018 -0700
Revision:
10:46a4cf51ee38
Parent:
9:d58e77ebd769
remove mbed-os

Who changed what in which revision?

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