Clone of official tools

Committer:
screamer
Date:
Mon Aug 29 11:56:59 2016 +0100
Revision:
30:f12ce67666d0
Parent:
29:1210849dba19
Child:
31:8ea194f6145b
Update tools from the mbed OS 5.1.2 release (instead of master)

Who changed what in which revision?

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