mbed-os

Dependents:   cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more

Committer:
be_bryan
Date:
Mon Dec 11 17:54:04 2017 +0000
Revision:
0:b74591d5ab33
motor ++

Who changed what in which revision?

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