Clone of official tools

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