nkjnm

Dependencies:   MAX44000 nexpaq_mdk

Fork of LED_Demo by Maxim nexpaq

Committer:
nexpaq
Date:
Sat Sep 17 16:32:05 2016 +0000
Revision:
1:55a6170b404f
checking in for sharing

Who changed what in which revision?

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