Clone of official tools

Committer:
theotherjimmy
Date:
Tue Oct 10 16:56:30 2017 -0500
Revision:
40:7d3fa6b99b2b
Parent:
36:96847d42f010
Child:
41:2a77626a4c21
Update to tools release 5.6.1

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
screamer 24:25bff2709c20 442 return resources
screamer 24:25bff2709c20 443
screamer 24:25bff2709c20 444 def build_project(src_paths, build_path, target, toolchain_name,
The Other Jimmy 31:8ea194f6145b 445 libraries_paths=None, linker_script=None,
screamer 29:1210849dba19 446 clean=False, notify=None, verbose=False, name=None,
screamer 29:1210849dba19 447 macros=None, inc_dirs=None, jobs=1, silent=False,
screamer 29:1210849dba19 448 report=None, properties=None, project_id=None,
The Other Jimmy 31:8ea194f6145b 449 project_description=None, extra_verbose=False, config=None,
theotherjimmy 40:7d3fa6b99b2b 450 app_config=None, build_profile=None, stats_depth=None):
screamer 29:1210849dba19 451 """ Build a project. A project may be a test or a user program.
screamer 29:1210849dba19 452
screamer 29:1210849dba19 453 Positional arguments:
screamer 29:1210849dba19 454 src_paths - a path or list of paths that contain all files needed to build
screamer 29:1210849dba19 455 the project
screamer 29:1210849dba19 456 build_path - the directory where all of the object files will be placed
screamer 29:1210849dba19 457 target - the MCU or board that the project will compile for
screamer 29:1210849dba19 458 toolchain_name - the name of the build tools
screamer 29:1210849dba19 459
screamer 29:1210849dba19 460 Keyword arguments:
screamer 29:1210849dba19 461 libraries_paths - The location of libraries to include when linking
screamer 29:1210849dba19 462 linker_script - the file that drives the linker to do it's job
screamer 29:1210849dba19 463 clean - Rebuild everything if True
screamer 29:1210849dba19 464 notify - Notify function for logs
screamer 29:1210849dba19 465 verbose - Write the actual tools command lines used if True
screamer 29:1210849dba19 466 name - the name of the project
screamer 29:1210849dba19 467 macros - additional macros
screamer 29:1210849dba19 468 inc_dirs - additional directories where include files may be found
screamer 29:1210849dba19 469 jobs - how many compilers we can run at once
screamer 29:1210849dba19 470 silent - suppress printing of progress indicators
screamer 29:1210849dba19 471 report - a dict where a result may be appended
screamer 29:1210849dba19 472 properties - UUUUHHHHH beats me
screamer 29:1210849dba19 473 project_id - the name put in the report
screamer 29:1210849dba19 474 project_description - the human-readable version of what this thing does
screamer 29:1210849dba19 475 extra_verbose - even more output!
screamer 29:1210849dba19 476 config - a Config object to use instead of creating one
The Other Jimmy 31:8ea194f6145b 477 app_config - location of a chosen mbed_app.json file
The Other Jimmy 31:8ea194f6145b 478 build_profile - a dict of flags that will be passed to the compiler
theotherjimmy 40:7d3fa6b99b2b 479 stats_depth - depth level for memap to display file/dirs
screamer 24:25bff2709c20 480 """
screamer 24:25bff2709c20 481
screamer 24:25bff2709c20 482 # Convert src_path to a list if needed
screamer 24:25bff2709c20 483 if type(src_paths) != ListType:
screamer 24:25bff2709c20 484 src_paths = [src_paths]
screamer 24:25bff2709c20 485 # Extend src_paths wiht libraries_paths
screamer 24:25bff2709c20 486 if libraries_paths is not None:
screamer 24:25bff2709c20 487 src_paths.extend(libraries_paths)
The Other Jimmy 31:8ea194f6145b 488 inc_dirs.extend(map(dirname, libraries_paths))
screamer 24:25bff2709c20 489
screamer 29:1210849dba19 490 if clean and exists(build_path):
screamer 29:1210849dba19 491 rmtree(build_path)
screamer 24:25bff2709c20 492 mkdir(build_path)
screamer 24:25bff2709c20 493
screamer 24:25bff2709c20 494 ###################################
screamer 24:25bff2709c20 495 # mbed Classic/2.0/libary support #
screamer 24:25bff2709c20 496
screamer 14:ee1b877e6839 497 # Find build system profile
screamer 14:ee1b877e6839 498 profile = None
screamer 24:25bff2709c20 499 targets_json = None
screamer 14:ee1b877e6839 500 for path in src_paths:
screamer 14:ee1b877e6839 501 profile = find_build_profile(path) or profile
screamer 27:5461402c33f8 502 if profile:
screamer 29:1210849dba19 503 targets_json = join(dirname(abspath(__file__)), 'legacy_targets.json')
screamer 27:5461402c33f8 504 else:
screamer 27:5461402c33f8 505 targets_json = find_targets_json(path) or targets_json
screamer 14:ee1b877e6839 506
screamer 24:25bff2709c20 507 # Apply targets.json to active targets
screamer 24:25bff2709c20 508 if targets_json:
screamer 24:25bff2709c20 509 if verbose:
screamer 24:25bff2709c20 510 print("Using targets from %s" % targets_json)
screamer 24:25bff2709c20 511 set_targets_json_location(targets_json)
screamer 24:25bff2709c20 512
screamer 24:25bff2709c20 513 # Apply profile to toolchains
screamer 14:ee1b877e6839 514 if profile:
screamer 14:ee1b877e6839 515 def init_hook(self):
screamer 14:ee1b877e6839 516 profile_data = get_toolchain_profile(self.name, profile)
screamer 14:ee1b877e6839 517 if not profile_data:
screamer 14:ee1b877e6839 518 return
screamer 24:25bff2709c20 519 if verbose:
screamer 24:25bff2709c20 520 self.info("Using toolchain %s profile %s" % (self.name, profile))
screamer 14:ee1b877e6839 521
screamer 14:ee1b877e6839 522 for k,v in profile_data.items():
screamer 14:ee1b877e6839 523 if self.flags.has_key(k):
screamer 14:ee1b877e6839 524 self.flags[k] = v
screamer 14:ee1b877e6839 525 else:
screamer 14:ee1b877e6839 526 setattr(self, k, v)
screamer 14:ee1b877e6839 527
screamer 14:ee1b877e6839 528 mbedToolchain.init = init_hook
screamer 14:ee1b877e6839 529
The Other Jimmy 31:8ea194f6145b 530 # mbed Classic/2.0/libary support #
The Other Jimmy 31:8ea194f6145b 531 ###################################
The Other Jimmy 31:8ea194f6145b 532
screamer 29:1210849dba19 533 toolchain = prepare_toolchain(
The Other Jimmy 36:96847d42f010 534 src_paths, build_path, target, toolchain_name, macros=macros,
The Other Jimmy 36:96847d42f010 535 clean=clean, jobs=jobs, notify=notify, silent=silent, verbose=verbose,
The Other Jimmy 31:8ea194f6145b 536 extra_verbose=extra_verbose, config=config, app_config=app_config,
The Other Jimmy 31:8ea194f6145b 537 build_profile=build_profile)
screamer 0:66f3b5499f7f 538
screamer 24:25bff2709c20 539 # The first path will give the name to the library
The Other Jimmy 36:96847d42f010 540 name = (name or toolchain.config.name or
The Other Jimmy 36:96847d42f010 541 basename(normpath(abspath(src_paths[0]))))
screamer 29:1210849dba19 542 toolchain.info("Building project %s (%s, %s)" %
screamer 29:1210849dba19 543 (name, toolchain.target.name, toolchain_name))
screamer 0:66f3b5499f7f 544
screamer 24:25bff2709c20 545 # Initialize reporting
screamer 0:66f3b5499f7f 546 if report != None:
screamer 0:66f3b5499f7f 547 start = time()
screamer 7:5af61d55adbe 548 # If project_id is specified, use that over the default name
screamer 7:5af61d55adbe 549 id_name = project_id.upper() if project_id else name.upper()
screamer 7:5af61d55adbe 550 description = project_description if project_description else name
screamer 24:25bff2709c20 551 vendor_label = toolchain.target.extra_labels[0]
screamer 24:25bff2709c20 552 prep_report(report, toolchain.target.name, toolchain_name, id_name)
screamer 29:1210849dba19 553 cur_result = create_result(toolchain.target.name, toolchain_name,
screamer 29:1210849dba19 554 id_name, description)
screamer 0:66f3b5499f7f 555 if properties != None:
screamer 29:1210849dba19 556 prep_properties(properties, toolchain.target.name, toolchain_name,
screamer 29:1210849dba19 557 vendor_label)
screamer 0:66f3b5499f7f 558
screamer 0:66f3b5499f7f 559 try:
screamer 24:25bff2709c20 560 # Call unified scan_resources
screamer 24:25bff2709c20 561 resources = scan_resources(src_paths, toolchain, inc_dirs=inc_dirs)
The Other Jimmy 36:96847d42f010 562 if (hasattr(toolchain.target, "release_versions") and
The Other Jimmy 36:96847d42f010 563 "5" not in toolchain.target.release_versions and
The Other Jimmy 36:96847d42f010 564 "rtos" in toolchain.config.lib_config_data):
The Other Jimmy 36:96847d42f010 565 if "Cortex-A" in toolchain.target.core:
The Other Jimmy 36:96847d42f010 566 raise NotSupportedException(
The Other Jimmy 36:96847d42f010 567 ("%s Will be supported in mbed OS 5.6. "
The Other Jimmy 36:96847d42f010 568 "To use the %s, please checkout the mbed OS 5.4 release branch. "
The Other Jimmy 36:96847d42f010 569 "See https://developer.mbed.org/platforms/Renesas-GR-PEACH/#important-notice "
The Other Jimmy 36:96847d42f010 570 "for more information") % (toolchain.target.name, toolchain.target.name))
The Other Jimmy 36:96847d42f010 571 else:
The Other Jimmy 36:96847d42f010 572 raise NotSupportedException("Target does not support mbed OS 5")
screamer 0:66f3b5499f7f 573
screamer 24:25bff2709c20 574 # Change linker script if specified
screamer 0:66f3b5499f7f 575 if linker_script is not None:
screamer 0:66f3b5499f7f 576 resources.linker_script = linker_script
screamer 0:66f3b5499f7f 577
screamer 0:66f3b5499f7f 578 # Compile Sources
The Other Jimmy 36:96847d42f010 579 objects = toolchain.compile_sources(resources, resources.inc_dirs)
screamer 13:ab47a20b66f0 580 resources.objects.extend(objects)
screamer 0:66f3b5499f7f 581
screamer 0:66f3b5499f7f 582 # Link Program
The Other Jimmy 36:96847d42f010 583 if toolchain.config.has_regions:
The Other Jimmy 36:96847d42f010 584 res, _ = toolchain.link_program(resources, build_path, name + "_application")
The Other Jimmy 36:96847d42f010 585 region_list = list(toolchain.config.regions)
The Other Jimmy 36:96847d42f010 586 region_list = [r._replace(filename=res) if r.active else r
The Other Jimmy 36:96847d42f010 587 for r in region_list]
The Other Jimmy 36:96847d42f010 588 res = join(build_path, name) + ".bin"
The Other Jimmy 36:96847d42f010 589 merge_region_list(region_list, res)
The Other Jimmy 36:96847d42f010 590 else:
The Other Jimmy 36:96847d42f010 591 res, _ = toolchain.link_program(resources, build_path, name)
screamer 0:66f3b5499f7f 592
The Other Jimmy 31:8ea194f6145b 593 memap_instance = getattr(toolchain, 'memap_instance', None)
The Other Jimmy 31:8ea194f6145b 594 memap_table = ''
The Other Jimmy 31:8ea194f6145b 595 if memap_instance:
The Other Jimmy 31:8ea194f6145b 596 # Write output to stdout in text (pretty table) format
theotherjimmy 40:7d3fa6b99b2b 597 memap_table = memap_instance.generate_output('table', stats_depth)
The Other Jimmy 31:8ea194f6145b 598
The Other Jimmy 31:8ea194f6145b 599 if not silent:
The Other Jimmy 31:8ea194f6145b 600 print memap_table
The Other Jimmy 31:8ea194f6145b 601
The Other Jimmy 31:8ea194f6145b 602 # Write output to file in JSON format
The Other Jimmy 31:8ea194f6145b 603 map_out = join(build_path, name + "_map.json")
theotherjimmy 40:7d3fa6b99b2b 604 memap_instance.generate_output('json', stats_depth, map_out)
The Other Jimmy 31:8ea194f6145b 605
The Other Jimmy 31:8ea194f6145b 606 # Write output to file in CSV format for the CI
The Other Jimmy 31:8ea194f6145b 607 map_csv = join(build_path, name + "_map.csv")
theotherjimmy 40:7d3fa6b99b2b 608 memap_instance.generate_output('csv-ci', stats_depth, map_csv)
The Other Jimmy 31:8ea194f6145b 609
The Other Jimmy 31:8ea194f6145b 610 resources.detect_duplicates(toolchain)
The Other Jimmy 31:8ea194f6145b 611
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 612 if report != None:
screamer 0:66f3b5499f7f 613 end = time()
screamer 0:66f3b5499f7f 614 cur_result["elapsed_time"] = end - start
The Other Jimmy 31:8ea194f6145b 615 cur_result["output"] = toolchain.get_output() + memap_table
screamer 0:66f3b5499f7f 616 cur_result["result"] = "OK"
theotherjimmy 40:7d3fa6b99b2b 617 cur_result["memory_usage"] = memap_instance.mem_report
The Other Jimmy 36:96847d42f010 618 cur_result["bin"] = res
The Other Jimmy 36:96847d42f010 619 cur_result["elf"] = splitext(res)[0] + ".elf"
The Other Jimmy 36:96847d42f010 620 cur_result.update(toolchain.report)
screamer 0:66f3b5499f7f 621
screamer 0:66f3b5499f7f 622 add_result_to_report(report, cur_result)
screamer 0:66f3b5499f7f 623
screamer 0:66f3b5499f7f 624 return res
screamer 0:66f3b5499f7f 625
screamer 29:1210849dba19 626 except Exception as exc:
screamer 0:66f3b5499f7f 627 if report != None:
screamer 0:66f3b5499f7f 628 end = time()
screamer 0:66f3b5499f7f 629
screamer 29:1210849dba19 630 if isinstance(exc, NotSupportedException):
screamer 0:66f3b5499f7f 631 cur_result["result"] = "NOT_SUPPORTED"
screamer 0:66f3b5499f7f 632 else:
screamer 0:66f3b5499f7f 633 cur_result["result"] = "FAIL"
screamer 0:66f3b5499f7f 634
screamer 0:66f3b5499f7f 635 cur_result["elapsed_time"] = end - start
screamer 0:66f3b5499f7f 636
screamer 0:66f3b5499f7f 637 toolchain_output = toolchain.get_output()
screamer 0:66f3b5499f7f 638 if toolchain_output:
screamer 0:66f3b5499f7f 639 cur_result["output"] += toolchain_output
screamer 0:66f3b5499f7f 640
screamer 0:66f3b5499f7f 641 add_result_to_report(report, cur_result)
screamer 0:66f3b5499f7f 642
screamer 0:66f3b5499f7f 643 # Let Exception propagate
screamer 13:ab47a20b66f0 644 raise
screamer 0:66f3b5499f7f 645
screamer 0:66f3b5499f7f 646 def build_library(src_paths, build_path, target, toolchain_name,
The Other Jimmy 31:8ea194f6145b 647 dependencies_paths=None, name=None, clean=False,
screamer 29:1210849dba19 648 archive=True, notify=None, verbose=False, macros=None,
screamer 29:1210849dba19 649 inc_dirs=None, jobs=1, silent=False, report=None,
The Other Jimmy 31:8ea194f6145b 650 properties=None, extra_verbose=False, project_id=None,
The Other Jimmy 31:8ea194f6145b 651 remove_config_header_file=False, app_config=None,
The Other Jimmy 31:8ea194f6145b 652 build_profile=None):
screamer 29:1210849dba19 653 """ Build a library
screamer 29:1210849dba19 654
screamer 29:1210849dba19 655 Positional arguments:
screamer 29:1210849dba19 656 src_paths - a path or list of paths that contain all files needed to build
screamer 29:1210849dba19 657 the library
screamer 29:1210849dba19 658 build_path - the directory where all of the object files will be placed
screamer 29:1210849dba19 659 target - the MCU or board that the project will compile for
screamer 29:1210849dba19 660 toolchain_name - the name of the build tools
screamer 29:1210849dba19 661
screamer 29:1210849dba19 662 Keyword arguments:
screamer 29:1210849dba19 663 dependencies_paths - The location of libraries to include when linking
screamer 29:1210849dba19 664 name - the name of the library
screamer 29:1210849dba19 665 clean - Rebuild everything if True
screamer 29:1210849dba19 666 archive - whether the library will create an archive file
screamer 29:1210849dba19 667 notify - Notify function for logs
screamer 29:1210849dba19 668 verbose - Write the actual tools command lines used if True
screamer 29:1210849dba19 669 macros - additional macros
screamer 29:1210849dba19 670 inc_dirs - additional directories where include files may be found
screamer 29:1210849dba19 671 jobs - how many compilers we can run at once
screamer 29:1210849dba19 672 silent - suppress printing of progress indicators
screamer 29:1210849dba19 673 report - a dict where a result may be appended
screamer 29:1210849dba19 674 properties - UUUUHHHHH beats me
screamer 29:1210849dba19 675 extra_verbose - even more output!
screamer 29:1210849dba19 676 project_id - the name that goes in the report
The Other Jimmy 31:8ea194f6145b 677 remove_config_header_file - delete config header file when done building
The Other Jimmy 31:8ea194f6145b 678 app_config - location of a chosen mbed_app.json file
The Other Jimmy 31:8ea194f6145b 679 build_profile - a dict of flags that will be passed to the compiler
screamer 0:66f3b5499f7f 680 """
screamer 24:25bff2709c20 681
screamer 24:25bff2709c20 682 # Convert src_path to a list if needed
screamer 0:66f3b5499f7f 683 if type(src_paths) != ListType:
screamer 0:66f3b5499f7f 684 src_paths = [src_paths]
screamer 0:66f3b5499f7f 685
screamer 24:25bff2709c20 686 # Build path
screamer 24:25bff2709c20 687 if archive:
screamer 24:25bff2709c20 688 # Use temp path when building archive
screamer 24:25bff2709c20 689 tmp_path = join(build_path, '.temp')
screamer 24:25bff2709c20 690 mkdir(tmp_path)
screamer 24:25bff2709c20 691 else:
screamer 24:25bff2709c20 692 tmp_path = build_path
screamer 0:66f3b5499f7f 693
screamer 29:1210849dba19 694 # Clean the build directory
screamer 29:1210849dba19 695 if clean and exists(tmp_path):
screamer 29:1210849dba19 696 rmtree(tmp_path)
screamer 29:1210849dba19 697 mkdir(tmp_path)
screamer 29:1210849dba19 698
screamer 24:25bff2709c20 699 # Pass all params to the unified prepare_toolchain()
screamer 29:1210849dba19 700 toolchain = prepare_toolchain(
The Other Jimmy 36:96847d42f010 701 src_paths, build_path, target, toolchain_name, macros=macros,
The Other Jimmy 36:96847d42f010 702 clean=clean, jobs=jobs, notify=notify, silent=silent,
The Other Jimmy 36:96847d42f010 703 verbose=verbose, extra_verbose=extra_verbose, app_config=app_config,
The Other Jimmy 31:8ea194f6145b 704 build_profile=build_profile)
screamer 13:ab47a20b66f0 705
screamer 24:25bff2709c20 706 # The first path will give the name to the library
screamer 24:25bff2709c20 707 if name is None:
screamer 24:25bff2709c20 708 name = basename(normpath(abspath(src_paths[0])))
screamer 29:1210849dba19 709 toolchain.info("Building library %s (%s, %s)" %
screamer 29:1210849dba19 710 (name, toolchain.target.name, toolchain_name))
screamer 13:ab47a20b66f0 711
screamer 24:25bff2709c20 712 # Initialize reporting
screamer 0:66f3b5499f7f 713 if report != None:
screamer 0:66f3b5499f7f 714 start = time()
screamer 7:5af61d55adbe 715 # If project_id is specified, use that over the default name
screamer 7:5af61d55adbe 716 id_name = project_id.upper() if project_id else name.upper()
screamer 0:66f3b5499f7f 717 description = name
screamer 24:25bff2709c20 718 vendor_label = toolchain.target.extra_labels[0]
screamer 24:25bff2709c20 719 prep_report(report, toolchain.target.name, toolchain_name, id_name)
screamer 29:1210849dba19 720 cur_result = create_result(toolchain.target.name, toolchain_name,
screamer 29:1210849dba19 721 id_name, description)
The Other Jimmy 36:96847d42f010 722 cur_result['type'] = 'library'
screamer 0:66f3b5499f7f 723 if properties != None:
screamer 29:1210849dba19 724 prep_properties(properties, toolchain.target.name, toolchain_name,
screamer 29:1210849dba19 725 vendor_label)
screamer 0:66f3b5499f7f 726
screamer 0:66f3b5499f7f 727 for src_path in src_paths:
screamer 0:66f3b5499f7f 728 if not exists(src_path):
screamer 0:66f3b5499f7f 729 error_msg = "The library source folder does not exist: %s", src_path
screamer 0:66f3b5499f7f 730 if report != None:
screamer 0:66f3b5499f7f 731 cur_result["output"] = error_msg
screamer 0:66f3b5499f7f 732 cur_result["result"] = "FAIL"
screamer 0:66f3b5499f7f 733 add_result_to_report(report, cur_result)
screamer 0:66f3b5499f7f 734 raise Exception(error_msg)
screamer 0:66f3b5499f7f 735
screamer 0:66f3b5499f7f 736 try:
screamer 24:25bff2709c20 737 # Call unified scan_resources
screamer 29:1210849dba19 738 resources = scan_resources(src_paths, toolchain,
screamer 29:1210849dba19 739 dependencies_paths=dependencies_paths,
screamer 29:1210849dba19 740 inc_dirs=inc_dirs)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 741
screamer 13:ab47a20b66f0 742
screamer 29:1210849dba19 743 # Copy headers, objects and static libraries - all files needed for
screamer 29:1210849dba19 744 # static lib
screamer 13:ab47a20b66f0 745 toolchain.copy_files(resources.headers, build_path, resources=resources)
screamer 13:ab47a20b66f0 746 toolchain.copy_files(resources.objects, build_path, resources=resources)
screamer 29:1210849dba19 747 toolchain.copy_files(resources.libraries, build_path,
screamer 29:1210849dba19 748 resources=resources)
The Other Jimmy 31:8ea194f6145b 749 toolchain.copy_files(resources.json_files, build_path,
The Other Jimmy 31:8ea194f6145b 750 resources=resources)
screamer 13:ab47a20b66f0 751 if resources.linker_script:
screamer 29:1210849dba19 752 toolchain.copy_files(resources.linker_script, build_path,
screamer 29:1210849dba19 753 resources=resources)
screamer 22:9e85236d8716 754
screamer 24:25bff2709c20 755 if resources.hex_files:
screamer 29:1210849dba19 756 toolchain.copy_files(resources.hex_files, build_path,
screamer 29:1210849dba19 757 resources=resources)
screamer 0:66f3b5499f7f 758
screamer 0:66f3b5499f7f 759 # Compile Sources
The Other Jimmy 36:96847d42f010 760 objects = toolchain.compile_sources(resources, resources.inc_dirs)
screamer 13:ab47a20b66f0 761 resources.objects.extend(objects)
screamer 0:66f3b5499f7f 762
screamer 0:66f3b5499f7f 763 if archive:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 764 toolchain.build_library(objects, build_path, name)
screamer 0:66f3b5499f7f 765
The Other Jimmy 31:8ea194f6145b 766 if remove_config_header_file:
The Other Jimmy 31:8ea194f6145b 767 config_header_path = toolchain.get_config_header()
The Other Jimmy 31:8ea194f6145b 768 if config_header_path:
The Other Jimmy 31:8ea194f6145b 769 remove(config_header_path)
The Other Jimmy 31:8ea194f6145b 770
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 771 if report != None:
screamer 0:66f3b5499f7f 772 end = time()
screamer 0:66f3b5499f7f 773 cur_result["elapsed_time"] = end - start
screamer 0:66f3b5499f7f 774 cur_result["output"] = toolchain.get_output()
screamer 0:66f3b5499f7f 775 cur_result["result"] = "OK"
screamer 0:66f3b5499f7f 776
screamer 29:1210849dba19 777
screamer 0:66f3b5499f7f 778 add_result_to_report(report, cur_result)
screamer 22:9e85236d8716 779 return True
screamer 0:66f3b5499f7f 780
screamer 29:1210849dba19 781 except Exception as exc:
screamer 0:66f3b5499f7f 782 if report != None:
screamer 0:66f3b5499f7f 783 end = time()
screamer 22:9e85236d8716 784
screamer 29:1210849dba19 785 if isinstance(exc, ToolException):
screamer 7:5af61d55adbe 786 cur_result["result"] = "FAIL"
screamer 29:1210849dba19 787 elif isinstance(exc, NotSupportedException):
screamer 7:5af61d55adbe 788 cur_result["result"] = "NOT_SUPPORTED"
screamer 22:9e85236d8716 789
screamer 0:66f3b5499f7f 790 cur_result["elapsed_time"] = end - start
screamer 0:66f3b5499f7f 791
screamer 0:66f3b5499f7f 792 toolchain_output = toolchain.get_output()
screamer 0:66f3b5499f7f 793 if toolchain_output:
screamer 0:66f3b5499f7f 794 cur_result["output"] += toolchain_output
screamer 0:66f3b5499f7f 795
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 796 add_result_to_report(report, cur_result)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 797
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 798 # Let Exception propagate
screamer 29:1210849dba19 799 raise
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 800
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 801 ######################
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 802 ### Legacy methods ###
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 803 ######################
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 804
The Other Jimmy 36:96847d42f010 805 def mbed2_obj_path(target_name, toolchain_name):
The Other Jimmy 36:96847d42f010 806 real_tc_name = TOOLCHAIN_CLASSES[toolchain_name].__name__
The Other Jimmy 36:96847d42f010 807 return join("TARGET_" + target_name, "TOOLCHAIN_" + real_tc_name)
The Other Jimmy 36:96847d42f010 808
The Other Jimmy 31:8ea194f6145b 809 def build_lib(lib_id, target, toolchain_name, verbose=False,
screamer 29:1210849dba19 810 clean=False, macros=None, notify=None, jobs=1, silent=False,
The Other Jimmy 31:8ea194f6145b 811 report=None, properties=None, extra_verbose=False,
The Other Jimmy 31:8ea194f6145b 812 build_profile=None):
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 813 """ Legacy method for building mbed libraries
screamer 29:1210849dba19 814
screamer 29:1210849dba19 815 Positional arguments:
screamer 29:1210849dba19 816 lib_id - the library's unique identifier
screamer 29:1210849dba19 817 target - the MCU or board that the project will compile for
screamer 29:1210849dba19 818 toolchain_name - the name of the build tools
screamer 29:1210849dba19 819
screamer 29:1210849dba19 820 Keyword arguments:
screamer 29:1210849dba19 821 clean - Rebuild everything if True
screamer 29:1210849dba19 822 verbose - Write the actual tools command lines used if True
screamer 29:1210849dba19 823 macros - additional macros
screamer 29:1210849dba19 824 notify - Notify function for logs
screamer 29:1210849dba19 825 jobs - how many compilers we can run at once
screamer 29:1210849dba19 826 silent - suppress printing of progress indicators
screamer 29:1210849dba19 827 report - a dict where a result may be appended
screamer 29:1210849dba19 828 properties - UUUUHHHHH beats me
screamer 29:1210849dba19 829 extra_verbose - even more output!
The Other Jimmy 31:8ea194f6145b 830 build_profile - a dict of flags that will be passed to the compiler
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 831 """
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 832 lib = Library(lib_id)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 833 if not lib.is_supported(target, toolchain_name):
screamer 29:1210849dba19 834 print('Library "%s" is not yet supported on target %s with toolchain %s'
screamer 29:1210849dba19 835 % (lib_id, target.name, toolchain_name))
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 836 return False
screamer 22:9e85236d8716 837
screamer 29:1210849dba19 838 # We need to combine macros from parameter list with macros from library
screamer 29:1210849dba19 839 # definition
screamer 29:1210849dba19 840 lib_macros = lib.macros if lib.macros else []
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 841 if macros:
screamer 29:1210849dba19 842 macros.extend(lib_macros)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 843 else:
screamer 29:1210849dba19 844 macros = lib_macros
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 845
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 846 src_paths = lib.source_dir
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 847 build_path = lib.build_dir
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 848 dependencies_paths = lib.dependencies
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 849 inc_dirs = lib.inc_dirs
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 850 inc_dirs_ext = lib.inc_dirs_ext
screamer 22:9e85236d8716 851
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 852 if type(src_paths) != ListType:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 853 src_paths = [src_paths]
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 854
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 855 # The first path will give the name to the library
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 856 name = basename(src_paths[0])
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 857
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 858 if report != None:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 859 start = time()
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 860 id_name = name.upper()
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 861 description = name
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 862 vendor_label = target.extra_labels[0]
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 863 cur_result = None
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 864 prep_report(report, target.name, toolchain_name, id_name)
screamer 29:1210849dba19 865 cur_result = create_result(target.name, toolchain_name, id_name,
screamer 29:1210849dba19 866 description)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 867
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 868 if properties != None:
screamer 29:1210849dba19 869 prep_properties(properties, target.name, toolchain_name,
screamer 29:1210849dba19 870 vendor_label)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 871
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 872 for src_path in src_paths:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 873 if not exists(src_path):
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 874 error_msg = "The library source folder does not exist: %s", src_path
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 875
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 876 if report != None:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 877 cur_result["output"] = error_msg
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 878 cur_result["result"] = "FAIL"
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 879 add_result_to_report(report, cur_result)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 880
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 881 raise Exception(error_msg)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 882
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 883 try:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 884 # Toolchain instance
The Other Jimmy 36:96847d42f010 885 # Create the desired build directory structure
The Other Jimmy 36:96847d42f010 886 bin_path = join(build_path, mbed2_obj_path(target.name, toolchain_name))
The Other Jimmy 36:96847d42f010 887 mkdir(bin_path)
The Other Jimmy 36:96847d42f010 888 tmp_path = join(build_path, '.temp', mbed2_obj_path(target.name,
The Other Jimmy 36:96847d42f010 889 toolchain_name))
The Other Jimmy 36:96847d42f010 890 mkdir(tmp_path)
The Other Jimmy 36:96847d42f010 891
The Other Jimmy 36:96847d42f010 892 toolchain = prepare_toolchain(
The Other Jimmy 36:96847d42f010 893 src_paths, tmp_path, target, toolchain_name, macros=macros,
The Other Jimmy 36:96847d42f010 894 notify=notify, silent=silent, extra_verbose=extra_verbose,
The Other Jimmy 36:96847d42f010 895 build_profile=build_profile, jobs=jobs, clean=clean)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 896
screamer 29:1210849dba19 897 toolchain.info("Building library %s (%s, %s)" %
screamer 29:1210849dba19 898 (name.upper(), target.name, toolchain_name))
screamer 29:1210849dba19 899
screamer 29:1210849dba19 900 # Take into account the library configuration (MBED_CONFIG_FILE)
The Other Jimmy 36:96847d42f010 901 config = toolchain.config
screamer 29:1210849dba19 902 config.add_config_files([MBED_CONFIG_FILE])
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 903
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 904 # Scan Resources
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 905 resources = []
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 906 for src_path in src_paths:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 907 resources.append(toolchain.scan_resources(src_path))
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 908
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 909 # Add extra include directories / files which are required by library
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 910 # This files usually are not in the same directory as source files so
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 911 # previous scan will not include them
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 912 if inc_dirs_ext is not None:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 913 for inc_ext in inc_dirs_ext:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 914 resources.append(toolchain.scan_resources(inc_ext))
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 915
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 916 # Dependencies Include Paths
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 917 dependencies_include_dir = []
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 918 if dependencies_paths is not None:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 919 for path in dependencies_paths:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 920 lib_resources = toolchain.scan_resources(path)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 921 dependencies_include_dir.extend(lib_resources.inc_dirs)
The Other Jimmy 31:8ea194f6145b 922 dependencies_include_dir.extend(map(dirname, lib_resources.inc_dirs))
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 923
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 924 if inc_dirs:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 925 dependencies_include_dir.extend(inc_dirs)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 926
screamer 29:1210849dba19 927 # Add other discovered configuration data to the configuration object
screamer 29:1210849dba19 928 for res in resources:
screamer 29:1210849dba19 929 config.load_resources(res)
screamer 29:1210849dba19 930 toolchain.set_config_data(toolchain.config.get_config_data())
screamer 29:1210849dba19 931
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 932
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 933 # Copy Headers
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 934 for resource in resources:
screamer 29:1210849dba19 935 toolchain.copy_files(resource.headers, build_path,
screamer 29:1210849dba19 936 resources=resource)
screamer 22:9e85236d8716 937
screamer 29:1210849dba19 938 dependencies_include_dir.extend(
screamer 29:1210849dba19 939 toolchain.scan_resources(build_path).inc_dirs)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 940
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 941 # Compile Sources
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 942 objects = []
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 943 for resource in resources:
The Other Jimmy 36:96847d42f010 944 objects.extend(toolchain.compile_sources(resource, dependencies_include_dir))
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 945
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 946 needed_update = toolchain.build_library(objects, bin_path, name)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 947
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 948 if report != None and needed_update:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 949 end = time()
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 950 cur_result["elapsed_time"] = end - start
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 951 cur_result["output"] = toolchain.get_output()
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 952 cur_result["result"] = "OK"
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 953
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 954 add_result_to_report(report, cur_result)
screamer 22:9e85236d8716 955 return True
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 956
screamer 29:1210849dba19 957 except Exception:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 958 if report != None:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 959 end = time()
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 960 cur_result["result"] = "FAIL"
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 961 cur_result["elapsed_time"] = end - start
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 962
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 963 toolchain_output = toolchain.get_output()
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 964 if toolchain_output:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 965 cur_result["output"] += toolchain_output
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 966
screamer 0:66f3b5499f7f 967 add_result_to_report(report, cur_result)
screamer 0:66f3b5499f7f 968
screamer 0:66f3b5499f7f 969 # Let Exception propagate
screamer 29:1210849dba19 970 raise
screamer 29:1210849dba19 971
screamer 29:1210849dba19 972 # We do have unique legacy conventions about how we build and package the mbed
screamer 29:1210849dba19 973 # library
The Other Jimmy 31:8ea194f6145b 974 def build_mbed_libs(target, toolchain_name, verbose=False,
screamer 29:1210849dba19 975 clean=False, macros=None, notify=None, jobs=1, silent=False,
The Other Jimmy 31:8ea194f6145b 976 report=None, properties=None, extra_verbose=False,
The Other Jimmy 31:8ea194f6145b 977 build_profile=None):
screamer 29:1210849dba19 978 """ Function returns True is library was built and false if building was
screamer 29:1210849dba19 979 skipped
screamer 0:66f3b5499f7f 980
screamer 29:1210849dba19 981 Positional arguments:
screamer 29:1210849dba19 982 target - the MCU or board that the project will compile for
screamer 29:1210849dba19 983 toolchain_name - the name of the build tools
screamer 29:1210849dba19 984
screamer 29:1210849dba19 985 Keyword arguments:
screamer 29:1210849dba19 986 verbose - Write the actual tools command lines used if True
screamer 29:1210849dba19 987 clean - Rebuild everything if True
screamer 29:1210849dba19 988 macros - additional macros
screamer 29:1210849dba19 989 notify - Notify function for logs
screamer 29:1210849dba19 990 jobs - how many compilers we can run at once
screamer 29:1210849dba19 991 silent - suppress printing of progress indicators
screamer 29:1210849dba19 992 report - a dict where a result may be appended
screamer 29:1210849dba19 993 properties - UUUUHHHHH beats me
screamer 29:1210849dba19 994 extra_verbose - even more output!
The Other Jimmy 31:8ea194f6145b 995 build_profile - a dict of flags that will be passed to the compiler
screamer 29:1210849dba19 996 """
screamer 0:66f3b5499f7f 997
screamer 0:66f3b5499f7f 998 if report != None:
screamer 0:66f3b5499f7f 999 start = time()
screamer 0:66f3b5499f7f 1000 id_name = "MBED"
screamer 0:66f3b5499f7f 1001 description = "mbed SDK"
screamer 0:66f3b5499f7f 1002 vendor_label = target.extra_labels[0]
screamer 0:66f3b5499f7f 1003 cur_result = None
screamer 0:66f3b5499f7f 1004 prep_report(report, target.name, toolchain_name, id_name)
screamer 29:1210849dba19 1005 cur_result = create_result(target.name, toolchain_name, id_name,
screamer 29:1210849dba19 1006 description)
screamer 0:66f3b5499f7f 1007
screamer 0:66f3b5499f7f 1008 if properties != None:
screamer 29:1210849dba19 1009 prep_properties(properties, target.name, toolchain_name,
screamer 29:1210849dba19 1010 vendor_label)
screamer 0:66f3b5499f7f 1011
screamer 0:66f3b5499f7f 1012 # Check toolchain support
screamer 0:66f3b5499f7f 1013 if toolchain_name not in target.supported_toolchains:
screamer 0:66f3b5499f7f 1014 supported_toolchains_text = ", ".join(target.supported_toolchains)
screamer 29:1210849dba19 1015 print('%s target is not yet supported by toolchain %s' %
screamer 29:1210849dba19 1016 (target.name, toolchain_name))
screamer 29:1210849dba19 1017 print('%s target supports %s toolchain%s' %
screamer 29:1210849dba19 1018 (target.name, supported_toolchains_text, 's'
screamer 29:1210849dba19 1019 if len(target.supported_toolchains) > 1 else ''))
screamer 0:66f3b5499f7f 1020
screamer 0:66f3b5499f7f 1021 if report != None:
screamer 0:66f3b5499f7f 1022 cur_result["result"] = "SKIP"
screamer 0:66f3b5499f7f 1023 add_result_to_report(report, cur_result)
screamer 0:66f3b5499f7f 1024
screamer 0:66f3b5499f7f 1025 return False
screamer 0:66f3b5499f7f 1026
screamer 0:66f3b5499f7f 1027 try:
The Other Jimmy 36:96847d42f010 1028 # Source and Build Paths
The Other Jimmy 36:96847d42f010 1029 build_target = join(MBED_LIBRARIES, "TARGET_" + target.name)
The Other Jimmy 36:96847d42f010 1030 build_toolchain = join(MBED_LIBRARIES, mbed2_obj_path(target.name, toolchain_name))
The Other Jimmy 36:96847d42f010 1031 mkdir(build_toolchain)
The Other Jimmy 36:96847d42f010 1032
screamer 0:66f3b5499f7f 1033 # Toolchain
The Other Jimmy 36:96847d42f010 1034 tmp_path = join(MBED_LIBRARIES, '.temp', mbed2_obj_path(target.name, toolchain_name))
The Other Jimmy 36:96847d42f010 1035 mkdir(tmp_path)
The Other Jimmy 36:96847d42f010 1036
The Other Jimmy 36:96847d42f010 1037 toolchain = prepare_toolchain(
theotherjimmy 40:7d3fa6b99b2b 1038 [""], tmp_path, target, toolchain_name, macros=macros,verbose=verbose,
The Other Jimmy 36:96847d42f010 1039 notify=notify, silent=silent, extra_verbose=extra_verbose,
The Other Jimmy 36:96847d42f010 1040 build_profile=build_profile, jobs=jobs, clean=clean)
screamer 0:66f3b5499f7f 1041
screamer 29:1210849dba19 1042 # Take into account the library configuration (MBED_CONFIG_FILE)
The Other Jimmy 36:96847d42f010 1043 config = toolchain.config
screamer 29:1210849dba19 1044 config.add_config_files([MBED_CONFIG_FILE])
screamer 29:1210849dba19 1045 toolchain.set_config_data(toolchain.config.get_config_data())
screamer 29:1210849dba19 1046
screamer 0:66f3b5499f7f 1047 # CMSIS
screamer 29:1210849dba19 1048 toolchain.info("Building library %s (%s, %s)" %
screamer 29:1210849dba19 1049 ('CMSIS', target.name, toolchain_name))
The Other Jimmy 31:8ea194f6145b 1050 cmsis_src = MBED_CMSIS_PATH
screamer 0:66f3b5499f7f 1051 resources = toolchain.scan_resources(cmsis_src)
screamer 0:66f3b5499f7f 1052
screamer 29:1210849dba19 1053 toolchain.copy_files(resources.headers, build_target)
screamer 29:1210849dba19 1054 toolchain.copy_files(resources.linker_script, build_toolchain)
screamer 29:1210849dba19 1055 toolchain.copy_files(resources.bin_files, build_toolchain)
screamer 0:66f3b5499f7f 1056
screamer 29:1210849dba19 1057 objects = toolchain.compile_sources(resources, tmp_path)
screamer 29:1210849dba19 1058 toolchain.copy_files(objects, build_toolchain)
screamer 0:66f3b5499f7f 1059
screamer 0:66f3b5499f7f 1060 # mbed
screamer 29:1210849dba19 1061 toolchain.info("Building library %s (%s, %s)" %
screamer 29:1210849dba19 1062 ('MBED', target.name, toolchain_name))
screamer 0:66f3b5499f7f 1063
screamer 0:66f3b5499f7f 1064 # Common Headers
The Other Jimmy 31:8ea194f6145b 1065 toolchain.copy_files([MBED_HEADER], MBED_LIBRARIES)
The Other Jimmy 31:8ea194f6145b 1066 library_incdirs = [dirname(MBED_LIBRARIES), MBED_LIBRARIES]
The Other Jimmy 31:8ea194f6145b 1067
The Other Jimmy 31:8ea194f6145b 1068 for dir, dest in [(MBED_DRIVERS, MBED_LIBRARIES_DRIVERS),
The Other Jimmy 31:8ea194f6145b 1069 (MBED_PLATFORM, MBED_LIBRARIES_PLATFORM),
The Other Jimmy 31:8ea194f6145b 1070 (MBED_HAL, MBED_LIBRARIES_HAL)]:
The Other Jimmy 31:8ea194f6145b 1071 resources = toolchain.scan_resources(dir)
The Other Jimmy 31:8ea194f6145b 1072 toolchain.copy_files(resources.headers, dest)
The Other Jimmy 31:8ea194f6145b 1073 library_incdirs.append(dest)
screamer 0:66f3b5499f7f 1074
screamer 0:66f3b5499f7f 1075 # Target specific sources
The Other Jimmy 31:8ea194f6145b 1076 hal_src = MBED_TARGETS_PATH
screamer 29:1210849dba19 1077 hal_implementation = toolchain.scan_resources(hal_src)
screamer 29:1210849dba19 1078 toolchain.copy_files(hal_implementation.headers +
screamer 29:1210849dba19 1079 hal_implementation.hex_files +
The Other Jimmy 31:8ea194f6145b 1080 hal_implementation.libraries +
The Other Jimmy 31:8ea194f6145b 1081 [MBED_CONFIG_FILE],
screamer 29:1210849dba19 1082 build_target, resources=hal_implementation)
The Other Jimmy 31:8ea194f6145b 1083 toolchain.copy_files(hal_implementation.linker_script, build_toolchain)
The Other Jimmy 31:8ea194f6145b 1084 toolchain.copy_files(hal_implementation.bin_files, build_toolchain)
screamer 29:1210849dba19 1085 incdirs = toolchain.scan_resources(build_target).inc_dirs
The Other Jimmy 36:96847d42f010 1086 objects = toolchain.compile_sources(hal_implementation,
The Other Jimmy 31:8ea194f6145b 1087 library_incdirs + incdirs)
The Other Jimmy 31:8ea194f6145b 1088 toolchain.copy_files(objects, build_toolchain)
screamer 0:66f3b5499f7f 1089
screamer 0:66f3b5499f7f 1090 # Common Sources
The Other Jimmy 31:8ea194f6145b 1091 mbed_resources = None
The Other Jimmy 31:8ea194f6145b 1092 for dir in [MBED_DRIVERS, MBED_PLATFORM, MBED_HAL]:
The Other Jimmy 31:8ea194f6145b 1093 mbed_resources += toolchain.scan_resources(dir)
The Other Jimmy 31:8ea194f6145b 1094
The Other Jimmy 36:96847d42f010 1095 objects = toolchain.compile_sources(mbed_resources,
The Other Jimmy 31:8ea194f6145b 1096 library_incdirs + incdirs)
screamer 0:66f3b5499f7f 1097
screamer 0:66f3b5499f7f 1098 # A number of compiled files need to be copied as objects as opposed to
screamer 29:1210849dba19 1099 # way the linker search for symbols in archives. These are:
The Other Jimmy 36:96847d42f010 1100 # - mbed_retarget.o: to make sure that the C standard lib symbols get
screamer 29:1210849dba19 1101 # overridden
The Other Jimmy 36:96847d42f010 1102 # - mbed_board.o: mbed_die is weak
screamer 29:1210849dba19 1103 # - mbed_overrides.o: this contains platform overrides of various
screamer 29:1210849dba19 1104 # weak SDK functions
The Other Jimmy 36:96847d42f010 1105 # - mbed_main.o: this contains main redirection
The Other Jimmy 36:96847d42f010 1106 separate_names, separate_objects = ['mbed_retarget.o', 'mbed_board.o',
The Other Jimmy 36:96847d42f010 1107 'mbed_overrides.o', 'mbed_main.o', 'mbed_sdk_boot.o'], []
screamer 0:66f3b5499f7f 1108
screamer 29:1210849dba19 1109 for obj in objects:
screamer 0:66f3b5499f7f 1110 for name in separate_names:
screamer 29:1210849dba19 1111 if obj.endswith(name):
screamer 29:1210849dba19 1112 separate_objects.append(obj)
screamer 0:66f3b5499f7f 1113
screamer 29:1210849dba19 1114 for obj in separate_objects:
screamer 29:1210849dba19 1115 objects.remove(obj)
screamer 0:66f3b5499f7f 1116
screamer 29:1210849dba19 1117 toolchain.build_library(objects, build_toolchain, "mbed")
screamer 0:66f3b5499f7f 1118
screamer 29:1210849dba19 1119 for obj in separate_objects:
screamer 29:1210849dba19 1120 toolchain.copy_files(obj, build_toolchain)
screamer 0:66f3b5499f7f 1121
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 1122 if report != None:
screamer 0:66f3b5499f7f 1123 end = time()
screamer 0:66f3b5499f7f 1124 cur_result["elapsed_time"] = end - start
screamer 0:66f3b5499f7f 1125 cur_result["output"] = toolchain.get_output()
screamer 0:66f3b5499f7f 1126 cur_result["result"] = "OK"
screamer 0:66f3b5499f7f 1127
screamer 0:66f3b5499f7f 1128 add_result_to_report(report, cur_result)
screamer 0:66f3b5499f7f 1129
screamer 0:66f3b5499f7f 1130 return True
screamer 0:66f3b5499f7f 1131
screamer 29:1210849dba19 1132 except Exception as exc:
screamer 0:66f3b5499f7f 1133 if report != None:
screamer 0:66f3b5499f7f 1134 end = time()
screamer 0:66f3b5499f7f 1135 cur_result["result"] = "FAIL"
screamer 0:66f3b5499f7f 1136 cur_result["elapsed_time"] = end - start
screamer 0:66f3b5499f7f 1137
screamer 0:66f3b5499f7f 1138 toolchain_output = toolchain.get_output()
screamer 0:66f3b5499f7f 1139 if toolchain_output:
screamer 0:66f3b5499f7f 1140 cur_result["output"] += toolchain_output
screamer 0:66f3b5499f7f 1141
screamer 29:1210849dba19 1142 cur_result["output"] += str(exc)
screamer 0:66f3b5499f7f 1143
screamer 0:66f3b5499f7f 1144 add_result_to_report(report, cur_result)
screamer 0:66f3b5499f7f 1145
screamer 0:66f3b5499f7f 1146 # Let Exception propagate
screamer 29:1210849dba19 1147 raise
screamer 0:66f3b5499f7f 1148
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 1149
screamer 24:25bff2709c20 1150 def get_unique_supported_toolchains(release_targets=None):
screamer 24:25bff2709c20 1151 """ Get list of all unique toolchains supported by targets
screamer 29:1210849dba19 1152
screamer 29:1210849dba19 1153 Keyword arguments:
screamer 29:1210849dba19 1154 release_targets - tuple structure returned from get_mbed_official_release().
screamer 29:1210849dba19 1155 If release_targets is not specified, then it queries all
screamer 29:1210849dba19 1156 known targets
screamer 24:25bff2709c20 1157 """
screamer 0:66f3b5499f7f 1158 unique_supported_toolchains = []
screamer 24:25bff2709c20 1159
screamer 24:25bff2709c20 1160 if not release_targets:
screamer 24:25bff2709c20 1161 for target in TARGET_NAMES:
screamer 24:25bff2709c20 1162 for toolchain in TARGET_MAP[target].supported_toolchains:
screamer 24:25bff2709c20 1163 if toolchain not in unique_supported_toolchains:
screamer 24:25bff2709c20 1164 unique_supported_toolchains.append(toolchain)
screamer 24:25bff2709c20 1165 else:
screamer 24:25bff2709c20 1166 for target in release_targets:
screamer 24:25bff2709c20 1167 for toolchain in target[1]:
screamer 24:25bff2709c20 1168 if toolchain not in unique_supported_toolchains:
screamer 24:25bff2709c20 1169 unique_supported_toolchains.append(toolchain)
screamer 24:25bff2709c20 1170
theotherjimmy 40:7d3fa6b99b2b 1171 if "ARM" in unique_supported_toolchains:
theotherjimmy 40:7d3fa6b99b2b 1172 unique_supported_toolchains.append("ARMC6")
theotherjimmy 40:7d3fa6b99b2b 1173
screamer 0:66f3b5499f7f 1174 return unique_supported_toolchains
screamer 0:66f3b5499f7f 1175
The Other Jimmy 36:96847d42f010 1176 def mcu_toolchain_list(release_version='5'):
The Other Jimmy 36:96847d42f010 1177 """ Shows list of toolchains
The Other Jimmy 36:96847d42f010 1178
The Other Jimmy 36:96847d42f010 1179 """
The Other Jimmy 36:96847d42f010 1180
The Other Jimmy 36:96847d42f010 1181 if isinstance(release_version, basestring):
The Other Jimmy 36:96847d42f010 1182 # Force release_version to lowercase if it is a string
The Other Jimmy 36:96847d42f010 1183 release_version = release_version.lower()
The Other Jimmy 36:96847d42f010 1184 else:
The Other Jimmy 36:96847d42f010 1185 # Otherwise default to printing all known targets and toolchains
The Other Jimmy 36:96847d42f010 1186 release_version = 'all'
The Other Jimmy 36:96847d42f010 1187
The Other Jimmy 36:96847d42f010 1188
The Other Jimmy 36:96847d42f010 1189 version_release_targets = {}
The Other Jimmy 36:96847d42f010 1190 version_release_target_names = {}
The Other Jimmy 36:96847d42f010 1191
The Other Jimmy 36:96847d42f010 1192 for version in RELEASE_VERSIONS:
The Other Jimmy 36:96847d42f010 1193 version_release_targets[version] = get_mbed_official_release(version)
The Other Jimmy 36:96847d42f010 1194 version_release_target_names[version] = [x[0] for x in
The Other Jimmy 36:96847d42f010 1195 version_release_targets[
The Other Jimmy 36:96847d42f010 1196 version]]
The Other Jimmy 36:96847d42f010 1197
The Other Jimmy 36:96847d42f010 1198 if release_version in RELEASE_VERSIONS:
The Other Jimmy 36:96847d42f010 1199 release_targets = version_release_targets[release_version]
The Other Jimmy 36:96847d42f010 1200 else:
The Other Jimmy 36:96847d42f010 1201 release_targets = None
The Other Jimmy 36:96847d42f010 1202
The Other Jimmy 36:96847d42f010 1203 unique_supported_toolchains = get_unique_supported_toolchains(
The Other Jimmy 36:96847d42f010 1204 release_targets)
The Other Jimmy 36:96847d42f010 1205 columns = ["mbed OS %s" % x for x in RELEASE_VERSIONS] + unique_supported_toolchains
The Other Jimmy 36:96847d42f010 1206 return "\n".join(columns)
The Other Jimmy 36:96847d42f010 1207
The Other Jimmy 36:96847d42f010 1208
The Other Jimmy 36:96847d42f010 1209 def mcu_target_list(release_version='5'):
theotherjimmy 40:7d3fa6b99b2b 1210 """ Shows target list
The Other Jimmy 36:96847d42f010 1211
The Other Jimmy 36:96847d42f010 1212 """
The Other Jimmy 36:96847d42f010 1213
The Other Jimmy 36:96847d42f010 1214 if isinstance(release_version, basestring):
The Other Jimmy 36:96847d42f010 1215 # Force release_version to lowercase if it is a string
The Other Jimmy 36:96847d42f010 1216 release_version = release_version.lower()
The Other Jimmy 36:96847d42f010 1217 else:
The Other Jimmy 36:96847d42f010 1218 # Otherwise default to printing all known targets and toolchains
The Other Jimmy 36:96847d42f010 1219 release_version = 'all'
The Other Jimmy 36:96847d42f010 1220
The Other Jimmy 36:96847d42f010 1221
The Other Jimmy 36:96847d42f010 1222 version_release_targets = {}
The Other Jimmy 36:96847d42f010 1223 version_release_target_names = {}
The Other Jimmy 36:96847d42f010 1224
The Other Jimmy 36:96847d42f010 1225 for version in RELEASE_VERSIONS:
The Other Jimmy 36:96847d42f010 1226 version_release_targets[version] = get_mbed_official_release(version)
The Other Jimmy 36:96847d42f010 1227 version_release_target_names[version] = [x[0] for x in
The Other Jimmy 36:96847d42f010 1228 version_release_targets[
The Other Jimmy 36:96847d42f010 1229 version]]
The Other Jimmy 36:96847d42f010 1230
The Other Jimmy 36:96847d42f010 1231 if release_version in RELEASE_VERSIONS:
The Other Jimmy 36:96847d42f010 1232 release_targets = version_release_targets[release_version]
The Other Jimmy 36:96847d42f010 1233 else:
The Other Jimmy 36:96847d42f010 1234 release_targets = None
The Other Jimmy 36:96847d42f010 1235
The Other Jimmy 36:96847d42f010 1236 target_names = []
The Other Jimmy 36:96847d42f010 1237
The Other Jimmy 36:96847d42f010 1238 if release_targets:
The Other Jimmy 36:96847d42f010 1239 target_names = [x[0] for x in release_targets]
The Other Jimmy 36:96847d42f010 1240 else:
The Other Jimmy 36:96847d42f010 1241 target_names = TARGET_NAMES
The Other Jimmy 36:96847d42f010 1242
The Other Jimmy 36:96847d42f010 1243 return "\n".join(target_names)
The Other Jimmy 36:96847d42f010 1244
screamer 0:66f3b5499f7f 1245
screamer 29:1210849dba19 1246 def mcu_toolchain_matrix(verbose_html=False, platform_filter=None,
screamer 29:1210849dba19 1247 release_version='5'):
screamer 29:1210849dba19 1248 """ Shows target map using prettytable
screamer 29:1210849dba19 1249
screamer 29:1210849dba19 1250 Keyword arguments:
screamer 29:1210849dba19 1251 verbose_html - emit html instead of a simple table
screamer 29:1210849dba19 1252 platform_filter - remove results that match the string
screamer 29:1210849dba19 1253 release_version - get the matrix for this major version number
screamer 29:1210849dba19 1254 """
screamer 29:1210849dba19 1255 # Only use it in this function so building works without extra modules
screamer 29:1210849dba19 1256 from prettytable import PrettyTable
screamer 0:66f3b5499f7f 1257
screamer 24:25bff2709c20 1258 if isinstance(release_version, basestring):
screamer 24:25bff2709c20 1259 # Force release_version to lowercase if it is a string
screamer 24:25bff2709c20 1260 release_version = release_version.lower()
screamer 24:25bff2709c20 1261 else:
screamer 24:25bff2709c20 1262 # Otherwise default to printing all known targets and toolchains
screamer 24:25bff2709c20 1263 release_version = 'all'
screamer 24:25bff2709c20 1264
screamer 24:25bff2709c20 1265
screamer 24:25bff2709c20 1266 version_release_targets = {}
screamer 24:25bff2709c20 1267 version_release_target_names = {}
screamer 24:25bff2709c20 1268
screamer 24:25bff2709c20 1269 for version in RELEASE_VERSIONS:
screamer 24:25bff2709c20 1270 version_release_targets[version] = get_mbed_official_release(version)
screamer 29:1210849dba19 1271 version_release_target_names[version] = [x[0] for x in
screamer 29:1210849dba19 1272 version_release_targets[
screamer 29:1210849dba19 1273 version]]
screamer 24:25bff2709c20 1274
screamer 24:25bff2709c20 1275 if release_version in RELEASE_VERSIONS:
screamer 24:25bff2709c20 1276 release_targets = version_release_targets[release_version]
screamer 24:25bff2709c20 1277 else:
screamer 24:25bff2709c20 1278 release_targets = None
screamer 24:25bff2709c20 1279
screamer 29:1210849dba19 1280 unique_supported_toolchains = get_unique_supported_toolchains(
screamer 29:1210849dba19 1281 release_targets)
screamer 24:25bff2709c20 1282 prepend_columns = ["Target"] + ["mbed OS %s" % x for x in RELEASE_VERSIONS]
screamer 24:25bff2709c20 1283
screamer 0:66f3b5499f7f 1284 # All tests status table print
screamer 24:25bff2709c20 1285 columns = prepend_columns + unique_supported_toolchains
screamer 29:1210849dba19 1286 table_printer = PrettyTable(columns)
screamer 0:66f3b5499f7f 1287 # Align table
screamer 0:66f3b5499f7f 1288 for col in columns:
screamer 29:1210849dba19 1289 table_printer.align[col] = "c"
screamer 29:1210849dba19 1290 table_printer.align["Target"] = "l"
screamer 0:66f3b5499f7f 1291
screamer 0:66f3b5499f7f 1292 perm_counter = 0
screamer 0:66f3b5499f7f 1293 target_counter = 0
screamer 24:25bff2709c20 1294
screamer 24:25bff2709c20 1295 target_names = []
screamer 24:25bff2709c20 1296
screamer 24:25bff2709c20 1297 if release_targets:
screamer 24:25bff2709c20 1298 target_names = [x[0] for x in release_targets]
screamer 24:25bff2709c20 1299 else:
screamer 24:25bff2709c20 1300 target_names = TARGET_NAMES
screamer 24:25bff2709c20 1301
screamer 24:25bff2709c20 1302 for target in sorted(target_names):
screamer 0:66f3b5499f7f 1303 if platform_filter is not None:
screamer 0:66f3b5499f7f 1304 # FIlter out platforms using regex
screamer 0:66f3b5499f7f 1305 if re.search(platform_filter, target) is None:
screamer 0:66f3b5499f7f 1306 continue
screamer 0:66f3b5499f7f 1307 target_counter += 1
screamer 0:66f3b5499f7f 1308
screamer 0:66f3b5499f7f 1309 row = [target] # First column is platform name
screamer 24:25bff2709c20 1310
screamer 24:25bff2709c20 1311 for version in RELEASE_VERSIONS:
screamer 24:25bff2709c20 1312 if target in version_release_target_names[version]:
screamer 24:25bff2709c20 1313 text = "Supported"
screamer 24:25bff2709c20 1314 else:
screamer 24:25bff2709c20 1315 text = "-"
screamer 24:25bff2709c20 1316 row.append(text)
screamer 24:25bff2709c20 1317
screamer 0:66f3b5499f7f 1318 for unique_toolchain in unique_supported_toolchains:
theotherjimmy 40:7d3fa6b99b2b 1319 if (unique_toolchain in TARGET_MAP[target].supported_toolchains or
theotherjimmy 40:7d3fa6b99b2b 1320 (unique_toolchain == "ARMC6" and
theotherjimmy 40:7d3fa6b99b2b 1321 "ARM" in TARGET_MAP[target].supported_toolchains)):
screamer 0:66f3b5499f7f 1322 text = "Supported"
screamer 0:66f3b5499f7f 1323 perm_counter += 1
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 1324 else:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 1325 text = "-"
screamer 22:9e85236d8716 1326
screamer 0:66f3b5499f7f 1327 row.append(text)
screamer 29:1210849dba19 1328 table_printer.add_row(row)
screamer 0:66f3b5499f7f 1329
screamer 29:1210849dba19 1330 result = table_printer.get_html_string() if verbose_html \
screamer 29:1210849dba19 1331 else table_printer.get_string()
screamer 0:66f3b5499f7f 1332 result += "\n"
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 1333 result += "Supported targets: %d\n"% (target_counter)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 1334 if target_counter == 1:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 1335 result += "Supported toolchains: %d"% (perm_counter)
screamer 0:66f3b5499f7f 1336 return result
screamer 0:66f3b5499f7f 1337
screamer 0:66f3b5499f7f 1338
screamer 0:66f3b5499f7f 1339 def get_target_supported_toolchains(target):
screamer 29:1210849dba19 1340 """ Returns target supported toolchains list
screamer 29:1210849dba19 1341
screamer 29:1210849dba19 1342 Positional arguments:
screamer 29:1210849dba19 1343 target - the target to get the supported toolchains of
screamer 29:1210849dba19 1344 """
screamer 29:1210849dba19 1345 return TARGET_MAP[target].supported_toolchains if target in TARGET_MAP \
screamer 29:1210849dba19 1346 else None
screamer 0:66f3b5499f7f 1347
screamer 0:66f3b5499f7f 1348
screamer 0:66f3b5499f7f 1349 def print_build_results(result_list, build_name):
screamer 29:1210849dba19 1350 """ Generate result string for build results
screamer 29:1210849dba19 1351
screamer 29:1210849dba19 1352 Positional arguments:
screamer 29:1210849dba19 1353 result_list - the list of results to print
screamer 29:1210849dba19 1354 build_name - the name of the build we are printing result for
screamer 29:1210849dba19 1355 """
screamer 0:66f3b5499f7f 1356 result = ""
screamer 0:66f3b5499f7f 1357 if len(result_list) > 0:
screamer 0:66f3b5499f7f 1358 result += build_name + "\n"
screamer 0:66f3b5499f7f 1359 result += "\n".join([" * %s" % f for f in result_list])
screamer 0:66f3b5499f7f 1360 result += "\n"
screamer 0:66f3b5499f7f 1361 return result
screamer 0:66f3b5499f7f 1362
screamer 29:1210849dba19 1363 def print_build_memory_usage(report):
screamer 22:9e85236d8716 1364 """ Generate result table with memory usage values for build results
screamer 29:1210849dba19 1365 Aggregates (puts together) reports obtained from self.get_memory_summary()
screamer 29:1210849dba19 1366
screamer 29:1210849dba19 1367 Positional arguments:
screamer 29:1210849dba19 1368 report - Report generated during build procedure.
screamer 22:9e85236d8716 1369 """
screamer 22:9e85236d8716 1370 from prettytable import PrettyTable
screamer 22:9e85236d8716 1371 columns_text = ['name', 'target', 'toolchain']
theotherjimmy 40:7d3fa6b99b2b 1372 columns_int = ['static_ram', 'total_flash']
screamer 22:9e85236d8716 1373 table = PrettyTable(columns_text + columns_int)
screamer 22:9e85236d8716 1374
screamer 22:9e85236d8716 1375 for col in columns_text:
screamer 22:9e85236d8716 1376 table.align[col] = 'l'
screamer 22:9e85236d8716 1377
screamer 22:9e85236d8716 1378 for col in columns_int:
screamer 22:9e85236d8716 1379 table.align[col] = 'r'
screamer 22:9e85236d8716 1380
screamer 22:9e85236d8716 1381 for target in report:
screamer 22:9e85236d8716 1382 for toolchain in report[target]:
screamer 22:9e85236d8716 1383 for name in report[target][toolchain]:
screamer 22:9e85236d8716 1384 for dlist in report[target][toolchain][name]:
screamer 22:9e85236d8716 1385 for dlistelem in dlist:
screamer 29:1210849dba19 1386 # Get 'memory_usage' record and build table with
screamer 29:1210849dba19 1387 # statistics
screamer 22:9e85236d8716 1388 record = dlist[dlistelem]
screamer 22:9e85236d8716 1389 if 'memory_usage' in record and record['memory_usage']:
screamer 22:9e85236d8716 1390 # Note that summary should be in the last record of
screamer 29:1210849dba19 1391 # 'memory_usage' section. This is why we are
screamer 29:1210849dba19 1392 # grabbing last "[-1]" record.
screamer 22:9e85236d8716 1393 row = [
screamer 22:9e85236d8716 1394 record['description'],
screamer 22:9e85236d8716 1395 record['target_name'],
screamer 22:9e85236d8716 1396 record['toolchain_name'],
screamer 29:1210849dba19 1397 record['memory_usage'][-1]['summary'][
screamer 29:1210849dba19 1398 'static_ram'],
screamer 29:1210849dba19 1399 record['memory_usage'][-1]['summary'][
screamer 29:1210849dba19 1400 'total_flash'],
screamer 22:9e85236d8716 1401 ]
screamer 22:9e85236d8716 1402 table.add_row(row)
screamer 22:9e85236d8716 1403
screamer 22:9e85236d8716 1404 result = "Memory map breakdown for built projects (values in Bytes):\n"
screamer 22:9e85236d8716 1405 result += table.get_string(sortby='name')
screamer 22:9e85236d8716 1406 return result
screamer 22:9e85236d8716 1407
screamer 0:66f3b5499f7f 1408 def write_build_report(build_report, template_filename, filename):
screamer 29:1210849dba19 1409 """Write a build report to disk using a template file
screamer 29:1210849dba19 1410
screamer 29:1210849dba19 1411 Positional arguments:
screamer 29:1210849dba19 1412 build_report - a report generated by the build system
screamer 29:1210849dba19 1413 template_filename - a file that contains the template for the style of build
screamer 29:1210849dba19 1414 report
screamer 29:1210849dba19 1415 filename - the location on disk to write the file to
screamer 29:1210849dba19 1416 """
screamer 0:66f3b5499f7f 1417 build_report_failing = []
screamer 0:66f3b5499f7f 1418 build_report_passing = []
screamer 0:66f3b5499f7f 1419
screamer 0:66f3b5499f7f 1420 for report in build_report:
screamer 0:66f3b5499f7f 1421 if len(report["failing"]) > 0:
screamer 0:66f3b5499f7f 1422 build_report_failing.append(report)
screamer 0:66f3b5499f7f 1423 else:
screamer 0:66f3b5499f7f 1424 build_report_passing.append(report)
screamer 0:66f3b5499f7f 1425
screamer 0:66f3b5499f7f 1426 env = Environment(extensions=['jinja2.ext.with_'])
screamer 0:66f3b5499f7f 1427 env.loader = FileSystemLoader('ci_templates')
screamer 0:66f3b5499f7f 1428 template = env.get_template(template_filename)
screamer 0:66f3b5499f7f 1429
screamer 29:1210849dba19 1430 with open(filename, 'w+') as placeholder:
screamer 29:1210849dba19 1431 placeholder.write(template.render(
screamer 29:1210849dba19 1432 failing_builds=build_report_failing,
screamer 29:1210849dba19 1433 passing_builds=build_report_passing))
The Other Jimmy 36:96847d42f010 1434
The Other Jimmy 36:96847d42f010 1435
The Other Jimmy 36:96847d42f010 1436 def merge_build_data(filename, toolchain_report, app_type):
The Other Jimmy 36:96847d42f010 1437 path_to_file = dirname(abspath(filename))
The Other Jimmy 36:96847d42f010 1438 try:
The Other Jimmy 36:96847d42f010 1439 build_data = load(open(filename))
The Other Jimmy 36:96847d42f010 1440 except (IOError, ValueError):
The Other Jimmy 36:96847d42f010 1441 build_data = {'builds': []}
The Other Jimmy 36:96847d42f010 1442 for tgt in toolchain_report.values():
The Other Jimmy 36:96847d42f010 1443 for tc in tgt.values():
The Other Jimmy 36:96847d42f010 1444 for project in tc.values():
The Other Jimmy 36:96847d42f010 1445 for build in project:
The Other Jimmy 36:96847d42f010 1446 try:
The Other Jimmy 36:96847d42f010 1447 build[0]['elf'] = relpath(build[0]['elf'], path_to_file)
The Other Jimmy 36:96847d42f010 1448 build[0]['bin'] = relpath(build[0]['bin'], path_to_file)
The Other Jimmy 36:96847d42f010 1449 except KeyError:
The Other Jimmy 36:96847d42f010 1450 pass
The Other Jimmy 36:96847d42f010 1451 if 'type' not in build[0]:
The Other Jimmy 36:96847d42f010 1452 build[0]['type'] = app_type
The Other Jimmy 36:96847d42f010 1453 build_data['builds'].append(build[0])
The Other Jimmy 36:96847d42f010 1454 dump(build_data, open(filename, "wb"), indent=4, separators=(',', ': '))