Clone of official tools

Committer:
theotherjimmy
Date:
Wed Oct 25 14:46:50 2017 -0500
Revision:
41:2a77626a4c21
Parent:
40:7d3fa6b99b2b
Child:
43:2a7da56ebd24
Update to track Mbed OS 5.6.3

Who changed what in which revision?

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