Rtos API example

Committer:
marcozecchini
Date:
Sat Feb 23 12:13:36 2019 +0000
Revision:
0:9fca2b23d0ba
final commit

Who changed what in which revision?

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