Clone of official tools

Committer:
Screamer@Y5070-M.virtuoso
Date:
Tue Jun 14 11:07:30 2016 +0100
Revision:
9:2d27d77ada5c
Parent:
8:a8ac6ed29081
Child:
13:ab47a20b66f0
Updated tools based on latest live tools code

Who changed what in which revision?

UserRevisionLine numberNew contents of line
screamer 0:66f3b5499f7f 1 """
screamer 0:66f3b5499f7f 2 mbed SDK
screamer 0:66f3b5499f7f 3 Copyright (c) 2011-2013 ARM Limited
screamer 0:66f3b5499f7f 4
screamer 0:66f3b5499f7f 5 Licensed under the Apache License, Version 2.0 (the "License");
screamer 0:66f3b5499f7f 6 you may not use this file except in compliance with the License.
screamer 0:66f3b5499f7f 7 You may obtain a copy of the License at
screamer 0:66f3b5499f7f 8
screamer 0:66f3b5499f7f 9 http://www.apache.org/licenses/LICENSE-2.0
screamer 0:66f3b5499f7f 10
screamer 0:66f3b5499f7f 11 Unless required by applicable law or agreed to in writing, software
screamer 0:66f3b5499f7f 12 distributed under the License is distributed on an "AS IS" BASIS,
screamer 0:66f3b5499f7f 13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
screamer 0:66f3b5499f7f 14 See the License for the specific language governing permissions and
screamer 0:66f3b5499f7f 15 limitations under the License.
screamer 0:66f3b5499f7f 16 """
screamer 0:66f3b5499f7f 17
screamer 0:66f3b5499f7f 18 import re
screamer 0:66f3b5499f7f 19 import tempfile
screamer 0:66f3b5499f7f 20 import colorama
screamer 0:66f3b5499f7f 21
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 22 from copy import copy
screamer 0:66f3b5499f7f 23 from types import ListType
screamer 0:66f3b5499f7f 24 from shutil import rmtree
screamer 7:5af61d55adbe 25 from os.path import join, exists, basename, abspath, normpath
screamer 8:a8ac6ed29081 26 from os import getcwd, walk
screamer 0:66f3b5499f7f 27 from time import time
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 28 import fnmatch
screamer 0:66f3b5499f7f 29
screamer 7:5af61d55adbe 30 from tools.utils import mkdir, run_cmd, run_cmd_ext, NotSupportedException, ToolException
screamer 0:66f3b5499f7f 31 from tools.paths import MBED_TARGETS_PATH, MBED_LIBRARIES, MBED_API, MBED_HAL, MBED_COMMON
screamer 0:66f3b5499f7f 32 from tools.targets import TARGET_NAMES, TARGET_MAP
screamer 0:66f3b5499f7f 33 from tools.libraries import Library
screamer 7:5af61d55adbe 34 from tools.toolchains import TOOLCHAIN_CLASSES
screamer 0:66f3b5499f7f 35 from jinja2 import FileSystemLoader
screamer 0:66f3b5499f7f 36 from jinja2.environment import Environment
screamer 7:5af61d55adbe 37 from tools.config import Config
screamer 0:66f3b5499f7f 38
screamer 0:66f3b5499f7f 39 def prep_report(report, target_name, toolchain_name, id_name):
screamer 0:66f3b5499f7f 40 # Setup report keys
screamer 0:66f3b5499f7f 41 if not target_name in report:
screamer 0:66f3b5499f7f 42 report[target_name] = {}
screamer 0:66f3b5499f7f 43
screamer 0:66f3b5499f7f 44 if not toolchain_name in report[target_name]:
screamer 0:66f3b5499f7f 45 report[target_name][toolchain_name] = {}
screamer 0:66f3b5499f7f 46
screamer 0:66f3b5499f7f 47 if not id_name in report[target_name][toolchain_name]:
screamer 0:66f3b5499f7f 48 report[target_name][toolchain_name][id_name] = []
screamer 0:66f3b5499f7f 49
screamer 0:66f3b5499f7f 50 def prep_properties(properties, target_name, toolchain_name, vendor_label):
screamer 0:66f3b5499f7f 51 # Setup test properties
screamer 0:66f3b5499f7f 52 if not target_name in properties:
screamer 0:66f3b5499f7f 53 properties[target_name] = {}
screamer 0:66f3b5499f7f 54
screamer 0:66f3b5499f7f 55 if not toolchain_name in properties[target_name]:
screamer 0:66f3b5499f7f 56 properties[target_name][toolchain_name] = {}
screamer 0:66f3b5499f7f 57
screamer 0:66f3b5499f7f 58 properties[target_name][toolchain_name]["target"] = target_name
screamer 0:66f3b5499f7f 59 properties[target_name][toolchain_name]["vendor"] = vendor_label
screamer 0:66f3b5499f7f 60 properties[target_name][toolchain_name]["toolchain"] = toolchain_name
screamer 0:66f3b5499f7f 61
screamer 0:66f3b5499f7f 62 def create_result(target_name, toolchain_name, id_name, description):
screamer 0:66f3b5499f7f 63 cur_result = {}
screamer 0:66f3b5499f7f 64 cur_result["target_name"] = target_name
screamer 0:66f3b5499f7f 65 cur_result["toolchain_name"] = toolchain_name
screamer 0:66f3b5499f7f 66 cur_result["id"] = id_name
screamer 0:66f3b5499f7f 67 cur_result["description"] = description
screamer 0:66f3b5499f7f 68 cur_result["elapsed_time"] = 0
screamer 0:66f3b5499f7f 69 cur_result["output"] = ""
screamer 0:66f3b5499f7f 70
screamer 0:66f3b5499f7f 71 return cur_result
screamer 0:66f3b5499f7f 72
screamer 0:66f3b5499f7f 73 def add_result_to_report(report, result):
screamer 0:66f3b5499f7f 74 target = result["target_name"]
screamer 0:66f3b5499f7f 75 toolchain = result["toolchain_name"]
screamer 0:66f3b5499f7f 76 id_name = result['id']
screamer 0:66f3b5499f7f 77 result_wrap = { 0: result }
screamer 0:66f3b5499f7f 78 report[target][toolchain][id_name].append(result_wrap)
screamer 0:66f3b5499f7f 79
screamer 7:5af61d55adbe 80 def get_config(src_path, target, toolchain_name):
screamer 7:5af61d55adbe 81 # Convert src_path to a list if needed
screamer 1:a99c8e460c5c 82 src_paths = [src_path] if type(src_path) != ListType else src_path
screamer 1:a99c8e460c5c 83 # We need to remove all paths which are repeated to avoid
screamer 1:a99c8e460c5c 84 # multiple compilations and linking with the same objects
screamer 1:a99c8e460c5c 85 src_paths = [src_paths[0]] + list(set(src_paths[1:]))
screamer 7:5af61d55adbe 86
screamer 7:5af61d55adbe 87 # Create configuration object
screamer 7:5af61d55adbe 88 config = Config(target, src_paths)
screamer 1:a99c8e460c5c 89
screamer 7:5af61d55adbe 90 # If the 'target' argument is a string, convert it to a target instance
screamer 7:5af61d55adbe 91 if isinstance(target, str):
screamer 7:5af61d55adbe 92 try:
screamer 7:5af61d55adbe 93 target = TARGET_MAP[target]
screamer 7:5af61d55adbe 94 except KeyError:
screamer 7:5af61d55adbe 95 raise KeyError("Target '%s' not found" % target)
screamer 2:07730b0f452c 96
screamer 0:66f3b5499f7f 97 # Toolchain instance
screamer 0:66f3b5499f7f 98 try:
screamer 7:5af61d55adbe 99 toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options=None, notify=None, macros=None, silent=True, extra_verbose=False)
screamer 7:5af61d55adbe 100 except KeyError as e:
screamer 7:5af61d55adbe 101 raise KeyError("Toolchain %s not supported" % toolchain_name)
screamer 7:5af61d55adbe 102
screamer 7:5af61d55adbe 103 # Scan src_path for config files
screamer 7:5af61d55adbe 104 resources = toolchain.scan_resources(src_paths[0])
screamer 7:5af61d55adbe 105 for path in src_paths[1:]:
screamer 7:5af61d55adbe 106 resources.add(toolchain.scan_resources(path))
screamer 7:5af61d55adbe 107
screamer 7:5af61d55adbe 108 config.add_config_files(resources.json_files)
screamer 7:5af61d55adbe 109 return config.get_config_data()
screamer 7:5af61d55adbe 110
screamer 7:5af61d55adbe 111 def build_project(src_path, build_path, target, toolchain_name,
screamer 7:5af61d55adbe 112 libraries_paths=None, options=None, linker_script=None,
screamer 7:5af61d55adbe 113 clean=False, notify=None, verbose=False, name=None, macros=None, inc_dirs=None,
screamer 7:5af61d55adbe 114 jobs=1, silent=False, report=None, properties=None, project_id=None, project_description=None,
screamer 7:5af61d55adbe 115 extra_verbose=False, config=None):
screamer 7:5af61d55adbe 116 """ This function builds project. Project can be for example one test / UT
screamer 7:5af61d55adbe 117 """
screamer 7:5af61d55adbe 118
screamer 7:5af61d55adbe 119 # Convert src_path to a list if needed
screamer 7:5af61d55adbe 120 src_paths = [src_path] if type(src_path) != ListType else src_path
screamer 7:5af61d55adbe 121
screamer 7:5af61d55adbe 122 # We need to remove all paths which are repeated to avoid
screamer 7:5af61d55adbe 123 # multiple compilations and linking with the same objects
screamer 7:5af61d55adbe 124 src_paths = [src_paths[0]] + list(set(src_paths[1:]))
screamer 7:5af61d55adbe 125 first_src_path = src_paths[0] if src_paths[0] != "." and src_paths[0] != "./" else getcwd()
screamer 7:5af61d55adbe 126 abs_path = abspath(first_src_path)
screamer 7:5af61d55adbe 127 project_name = basename(normpath(abs_path))
screamer 7:5af61d55adbe 128
screamer 8:a8ac6ed29081 129 for path in src_paths:
screamer 8:a8ac6ed29081 130 profile = get_build_profile(path)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 131
screamer 7:5af61d55adbe 132 # If the configuration object was not yet created, create it now
screamer 7:5af61d55adbe 133 config = config or Config(target, src_paths)
screamer 7:5af61d55adbe 134
screamer 7:5af61d55adbe 135 # If the 'target' argument is a string, convert it to a target instance
screamer 7:5af61d55adbe 136 if isinstance(target, str):
screamer 7:5af61d55adbe 137 try:
screamer 7:5af61d55adbe 138 target = TARGET_MAP[target]
screamer 7:5af61d55adbe 139 except KeyError:
screamer 7:5af61d55adbe 140 raise KeyError("Target '%s' not found" % target)
screamer 7:5af61d55adbe 141
screamer 7:5af61d55adbe 142 # Toolchain instance
screamer 7:5af61d55adbe 143 try:
screamer 8:a8ac6ed29081 144 toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options, notify, macros, silent, extra_verbose=extra_verbose, profile=profile)
screamer 0:66f3b5499f7f 145 except KeyError as e:
screamer 0:66f3b5499f7f 146 raise KeyError("Toolchain %s not supported" % toolchain_name)
screamer 0:66f3b5499f7f 147
screamer 0:66f3b5499f7f 148 toolchain.VERBOSE = verbose
screamer 0:66f3b5499f7f 149 toolchain.jobs = jobs
screamer 0:66f3b5499f7f 150 toolchain.build_all = clean
screamer 0:66f3b5499f7f 151
screamer 0:66f3b5499f7f 152 if name is None:
screamer 0:66f3b5499f7f 153 # We will use default project name based on project folder name
screamer 0:66f3b5499f7f 154 name = project_name
screamer 0:66f3b5499f7f 155 toolchain.info("Building project %s (%s, %s)" % (project_name, target.name, toolchain_name))
screamer 0:66f3b5499f7f 156 else:
screamer 0:66f3b5499f7f 157 # User used custom global project name to have the same name for the
screamer 0:66f3b5499f7f 158 toolchain.info("Building project %s to %s (%s, %s)" % (project_name, name, target.name, toolchain_name))
screamer 0:66f3b5499f7f 159
screamer 0:66f3b5499f7f 160
screamer 0:66f3b5499f7f 161 if report != None:
screamer 0:66f3b5499f7f 162 start = time()
screamer 7:5af61d55adbe 163
screamer 7:5af61d55adbe 164 # If project_id is specified, use that over the default name
screamer 7:5af61d55adbe 165 id_name = project_id.upper() if project_id else name.upper()
screamer 7:5af61d55adbe 166 description = project_description if project_description else name
screamer 0:66f3b5499f7f 167 vendor_label = target.extra_labels[0]
screamer 0:66f3b5499f7f 168 cur_result = None
screamer 0:66f3b5499f7f 169 prep_report(report, target.name, toolchain_name, id_name)
screamer 0:66f3b5499f7f 170 cur_result = create_result(target.name, toolchain_name, id_name, description)
screamer 0:66f3b5499f7f 171
screamer 0:66f3b5499f7f 172 if properties != None:
screamer 0:66f3b5499f7f 173 prep_properties(properties, target.name, toolchain_name, vendor_label)
screamer 0:66f3b5499f7f 174
screamer 0:66f3b5499f7f 175 try:
screamer 0:66f3b5499f7f 176 # Scan src_path and libraries_paths for resources
screamer 0:66f3b5499f7f 177 resources = toolchain.scan_resources(src_paths[0])
screamer 0:66f3b5499f7f 178 for path in src_paths[1:]:
screamer 0:66f3b5499f7f 179 resources.add(toolchain.scan_resources(path))
screamer 0:66f3b5499f7f 180 if libraries_paths is not None:
screamer 0:66f3b5499f7f 181 src_paths.extend(libraries_paths)
screamer 0:66f3b5499f7f 182 for path in libraries_paths:
screamer 0:66f3b5499f7f 183 resources.add(toolchain.scan_resources(path))
screamer 0:66f3b5499f7f 184
screamer 0:66f3b5499f7f 185 if linker_script is not None:
screamer 0:66f3b5499f7f 186 resources.linker_script = linker_script
screamer 0:66f3b5499f7f 187
screamer 0:66f3b5499f7f 188 # Build Directory
screamer 0:66f3b5499f7f 189 if clean:
screamer 0:66f3b5499f7f 190 if exists(build_path):
screamer 0:66f3b5499f7f 191 rmtree(build_path)
screamer 0:66f3b5499f7f 192 mkdir(build_path)
screamer 0:66f3b5499f7f 193
screamer 0:66f3b5499f7f 194 # We need to add if necessary additional include directories
screamer 0:66f3b5499f7f 195 if inc_dirs:
screamer 0:66f3b5499f7f 196 if type(inc_dirs) == ListType:
screamer 0:66f3b5499f7f 197 resources.inc_dirs.extend(inc_dirs)
screamer 0:66f3b5499f7f 198 else:
screamer 0:66f3b5499f7f 199 resources.inc_dirs.append(inc_dirs)
screamer 7:5af61d55adbe 200
screamer 7:5af61d55adbe 201 # Update the configuration with any .json files found while scanning
screamer 7:5af61d55adbe 202 config.add_config_files(resources.json_files)
screamer 7:5af61d55adbe 203 # And add the configuration macros to the toolchain
screamer 7:5af61d55adbe 204 toolchain.add_macros(config.get_config_data_macros())
screamer 7:5af61d55adbe 205
screamer 0:66f3b5499f7f 206 # Compile Sources
screamer 0:66f3b5499f7f 207 for path in src_paths:
screamer 0:66f3b5499f7f 208 src = toolchain.scan_resources(path)
screamer 0:66f3b5499f7f 209 objects = toolchain.compile_sources(src, build_path, resources.inc_dirs)
screamer 0:66f3b5499f7f 210 resources.objects.extend(objects)
screamer 0:66f3b5499f7f 211
screamer 0:66f3b5499f7f 212 # Link Program
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 213 res, _ = toolchain.link_program(resources, build_path, name)
screamer 0:66f3b5499f7f 214
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 215 if report != None:
screamer 0:66f3b5499f7f 216 end = time()
screamer 0:66f3b5499f7f 217 cur_result["elapsed_time"] = end - start
screamer 0:66f3b5499f7f 218 cur_result["output"] = toolchain.get_output()
screamer 0:66f3b5499f7f 219 cur_result["result"] = "OK"
screamer 0:66f3b5499f7f 220
screamer 0:66f3b5499f7f 221 add_result_to_report(report, cur_result)
screamer 0:66f3b5499f7f 222
screamer 0:66f3b5499f7f 223 return res
screamer 0:66f3b5499f7f 224
screamer 0:66f3b5499f7f 225 except Exception, e:
screamer 0:66f3b5499f7f 226 if report != None:
screamer 0:66f3b5499f7f 227 end = time()
screamer 0:66f3b5499f7f 228
screamer 0:66f3b5499f7f 229 if isinstance(e, NotSupportedException):
screamer 0:66f3b5499f7f 230 cur_result["result"] = "NOT_SUPPORTED"
screamer 0:66f3b5499f7f 231 else:
screamer 0:66f3b5499f7f 232 cur_result["result"] = "FAIL"
screamer 0:66f3b5499f7f 233
screamer 0:66f3b5499f7f 234 cur_result["elapsed_time"] = end - start
screamer 0:66f3b5499f7f 235
screamer 0:66f3b5499f7f 236 toolchain_output = toolchain.get_output()
screamer 0:66f3b5499f7f 237 if toolchain_output:
screamer 0:66f3b5499f7f 238 cur_result["output"] += toolchain_output
screamer 0:66f3b5499f7f 239
screamer 0:66f3b5499f7f 240 add_result_to_report(report, cur_result)
screamer 0:66f3b5499f7f 241
screamer 0:66f3b5499f7f 242 # Let Exception propagate
screamer 0:66f3b5499f7f 243 raise e
screamer 0:66f3b5499f7f 244
screamer 0:66f3b5499f7f 245 def build_library(src_paths, build_path, target, toolchain_name,
screamer 0:66f3b5499f7f 246 dependencies_paths=None, options=None, name=None, clean=False, archive=True,
screamer 0:66f3b5499f7f 247 notify=None, verbose=False, macros=None, inc_dirs=None, inc_dirs_ext=None,
screamer 7:5af61d55adbe 248 jobs=1, silent=False, report=None, properties=None, extra_verbose=False,
screamer 7:5af61d55adbe 249 project_id=None):
screamer 0:66f3b5499f7f 250 """ src_path: the path of the source directory
screamer 0:66f3b5499f7f 251 build_path: the path of the build directory
screamer 0:66f3b5499f7f 252 target: ['LPC1768', 'LPC11U24', 'LPC2368']
screamer 0:66f3b5499f7f 253 toolchain: ['ARM', 'uARM', 'GCC_ARM', 'GCC_CR']
screamer 0:66f3b5499f7f 254 library_paths: List of paths to additional libraries
screamer 0:66f3b5499f7f 255 clean: Rebuild everything if True
screamer 0:66f3b5499f7f 256 notify: Notify function for logs
screamer 0:66f3b5499f7f 257 verbose: Write the actual tools command lines if True
screamer 0:66f3b5499f7f 258 inc_dirs: additional include directories which should be included in build
screamer 0:66f3b5499f7f 259 inc_dirs_ext: additional include directories which should be copied to library directory
screamer 0:66f3b5499f7f 260 """
screamer 0:66f3b5499f7f 261 if type(src_paths) != ListType:
screamer 0:66f3b5499f7f 262 src_paths = [src_paths]
screamer 0:66f3b5499f7f 263
screamer 0:66f3b5499f7f 264 # The first path will give the name to the library
screamer 7:5af61d55adbe 265 project_name = basename(src_paths[0] if src_paths[0] != "." and src_paths[0] != "./" else getcwd())
screamer 0:66f3b5499f7f 266 if name is None:
screamer 0:66f3b5499f7f 267 # We will use default project name based on project folder name
screamer 0:66f3b5499f7f 268 name = project_name
screamer 0:66f3b5499f7f 269
screamer 0:66f3b5499f7f 270 if report != None:
screamer 0:66f3b5499f7f 271 start = time()
screamer 7:5af61d55adbe 272
screamer 7:5af61d55adbe 273 # If project_id is specified, use that over the default name
screamer 7:5af61d55adbe 274 id_name = project_id.upper() if project_id else name.upper()
screamer 0:66f3b5499f7f 275 description = name
screamer 0:66f3b5499f7f 276 vendor_label = target.extra_labels[0]
screamer 0:66f3b5499f7f 277 cur_result = None
screamer 0:66f3b5499f7f 278 prep_report(report, target.name, toolchain_name, id_name)
screamer 0:66f3b5499f7f 279 cur_result = create_result(target.name, toolchain_name, id_name, description)
screamer 0:66f3b5499f7f 280
screamer 0:66f3b5499f7f 281 if properties != None:
screamer 0:66f3b5499f7f 282 prep_properties(properties, target.name, toolchain_name, vendor_label)
screamer 0:66f3b5499f7f 283
screamer 0:66f3b5499f7f 284 for src_path in src_paths:
screamer 0:66f3b5499f7f 285 if not exists(src_path):
screamer 0:66f3b5499f7f 286 error_msg = "The library source folder does not exist: %s", src_path
screamer 0:66f3b5499f7f 287
screamer 0:66f3b5499f7f 288 if report != None:
screamer 0:66f3b5499f7f 289 cur_result["output"] = error_msg
screamer 0:66f3b5499f7f 290 cur_result["result"] = "FAIL"
screamer 0:66f3b5499f7f 291 add_result_to_report(report, cur_result)
screamer 0:66f3b5499f7f 292
screamer 0:66f3b5499f7f 293 raise Exception(error_msg)
screamer 0:66f3b5499f7f 294
screamer 8:a8ac6ed29081 295 for path in src_paths:
screamer 8:a8ac6ed29081 296 profile = get_build_profile(path)
screamer 8:a8ac6ed29081 297
screamer 0:66f3b5499f7f 298 try:
screamer 0:66f3b5499f7f 299 # Toolchain instance
screamer 8:a8ac6ed29081 300 toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options, macros=macros, notify=notify, silent=silent, extra_verbose=extra_verbose, profile=profile)
screamer 0:66f3b5499f7f 301 toolchain.VERBOSE = verbose
screamer 0:66f3b5499f7f 302 toolchain.jobs = jobs
screamer 0:66f3b5499f7f 303 toolchain.build_all = clean
screamer 0:66f3b5499f7f 304
screamer 0:66f3b5499f7f 305 toolchain.info("Building library %s (%s, %s)" % (name, target.name, toolchain_name))
screamer 0:66f3b5499f7f 306
screamer 0:66f3b5499f7f 307 # Scan Resources
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 308 resources = None
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 309 for path in src_paths:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 310 # Scan resources
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 311 resource = toolchain.scan_resources(path)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 312
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 313 # Copy headers, objects and static libraries - all files needed for static lib
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 314 toolchain.copy_files(resource.headers, build_path, rel_path=resource.base_path)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 315 toolchain.copy_files(resource.objects, build_path, rel_path=resource.base_path)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 316 toolchain.copy_files(resource.libraries, build_path, rel_path=resource.base_path)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 317 if resource.linker_script:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 318 toolchain.copy_files(resource.linker_script, build_path, rel_path=resource.base_path)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 319
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 320 # Extend resources collection
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 321 if not resources:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 322 resources = resource
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 323 else:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 324 resources.add(resource)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 325
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 326 # We need to add if necessary additional include directories
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 327 if inc_dirs:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 328 if type(inc_dirs) == ListType:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 329 resources.inc_dirs.extend(inc_dirs)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 330 else:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 331 resources.inc_dirs.append(inc_dirs)
screamer 0:66f3b5499f7f 332
screamer 0:66f3b5499f7f 333 # Add extra include directories / files which are required by library
screamer 0:66f3b5499f7f 334 # This files usually are not in the same directory as source files so
screamer 0:66f3b5499f7f 335 # previous scan will not include them
screamer 0:66f3b5499f7f 336 if inc_dirs_ext is not None:
screamer 0:66f3b5499f7f 337 for inc_ext in inc_dirs_ext:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 338 resources.add(toolchain.scan_resources(inc_ext))
screamer 0:66f3b5499f7f 339
screamer 0:66f3b5499f7f 340 # Dependencies Include Paths
screamer 0:66f3b5499f7f 341 if dependencies_paths is not None:
screamer 0:66f3b5499f7f 342 for path in dependencies_paths:
screamer 0:66f3b5499f7f 343 lib_resources = toolchain.scan_resources(path)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 344 resources.inc_dirs.extend(lib_resources.inc_dirs)
screamer 0:66f3b5499f7f 345
screamer 0:66f3b5499f7f 346 if archive:
screamer 0:66f3b5499f7f 347 # Use temp path when building archive
screamer 0:66f3b5499f7f 348 tmp_path = join(build_path, '.temp')
screamer 0:66f3b5499f7f 349 mkdir(tmp_path)
screamer 0:66f3b5499f7f 350 else:
screamer 0:66f3b5499f7f 351 tmp_path = build_path
screamer 0:66f3b5499f7f 352
screamer 7:5af61d55adbe 353 # Handle configuration
screamer 7:5af61d55adbe 354 config = Config(target)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 355 # Update the configuration with any .json files found while scanning
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 356 config.add_config_files(resources.json_files)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 357 # And add the configuration macros to the toolchain
screamer 7:5af61d55adbe 358 toolchain.add_macros(config.get_config_data_macros())
screamer 0:66f3b5499f7f 359
screamer 0:66f3b5499f7f 360 # Compile Sources
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 361 for path in src_paths:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 362 src = toolchain.scan_resources(path)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 363 objects = toolchain.compile_sources(src, abspath(tmp_path), resources.inc_dirs)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 364 resources.objects.extend(objects)
screamer 0:66f3b5499f7f 365
screamer 0:66f3b5499f7f 366 if archive:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 367 toolchain.build_library(objects, build_path, name)
screamer 0:66f3b5499f7f 368
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 369 if report != None:
screamer 0:66f3b5499f7f 370 end = time()
screamer 0:66f3b5499f7f 371 cur_result["elapsed_time"] = end - start
screamer 0:66f3b5499f7f 372 cur_result["output"] = toolchain.get_output()
screamer 0:66f3b5499f7f 373 cur_result["result"] = "OK"
screamer 0:66f3b5499f7f 374
screamer 0:66f3b5499f7f 375 add_result_to_report(report, cur_result)
screamer 0:66f3b5499f7f 376
screamer 0:66f3b5499f7f 377 except Exception, e:
screamer 0:66f3b5499f7f 378 if report != None:
screamer 0:66f3b5499f7f 379 end = time()
screamer 7:5af61d55adbe 380
screamer 7:5af61d55adbe 381 if isinstance(e, ToolException):
screamer 7:5af61d55adbe 382 cur_result["result"] = "FAIL"
screamer 7:5af61d55adbe 383 elif isinstance(e, NotSupportedException):
screamer 7:5af61d55adbe 384 cur_result["result"] = "NOT_SUPPORTED"
screamer 7:5af61d55adbe 385
screamer 0:66f3b5499f7f 386 cur_result["elapsed_time"] = end - start
screamer 0:66f3b5499f7f 387
screamer 0:66f3b5499f7f 388 toolchain_output = toolchain.get_output()
screamer 0:66f3b5499f7f 389 if toolchain_output:
screamer 0:66f3b5499f7f 390 cur_result["output"] += toolchain_output
screamer 0:66f3b5499f7f 391
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 392 add_result_to_report(report, cur_result)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 393
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 394 # Let Exception propagate
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 395 raise e
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 396
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 397 ######################
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 398 ### Legacy methods ###
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 399 ######################
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 400
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 401 def build_lib(lib_id, target, toolchain_name, options=None, verbose=False, clean=False, macros=None, notify=None, jobs=1, silent=False, report=None, properties=None, extra_verbose=False):
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 402 """ Legacy method for building mbed libraries
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 403 Function builds library in proper directory using all dependencies and macros defined by user.
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 404 """
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 405 lib = Library(lib_id)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 406 if not lib.is_supported(target, toolchain_name):
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 407 print 'Library "%s" is not yet supported on target %s with toolchain %s' % (lib_id, target.name, toolchain)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 408 return False
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 409
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 410 # We need to combine macros from parameter list with macros from library definition
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 411 MACROS = lib.macros if lib.macros else []
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 412 if macros:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 413 macros.extend(MACROS)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 414 else:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 415 macros = MACROS
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 416
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 417 src_paths = lib.source_dir
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 418 build_path = lib.build_dir
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 419 dependencies_paths = lib.dependencies
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 420 inc_dirs = lib.inc_dirs
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 421 inc_dirs_ext = lib.inc_dirs_ext
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 422
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 423 """ src_path: the path of the source directory
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 424 build_path: the path of the build directory
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 425 target: ['LPC1768', 'LPC11U24', 'LPC2368']
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 426 toolchain: ['ARM', 'uARM', 'GCC_ARM', 'GCC_CR']
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 427 library_paths: List of paths to additional libraries
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 428 clean: Rebuild everything if True
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 429 notify: Notify function for logs
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 430 verbose: Write the actual tools command lines if True
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 431 inc_dirs: additional include directories which should be included in build
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 432 inc_dirs_ext: additional include directories which should be copied to library directory
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 433 """
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 434 if type(src_paths) != ListType:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 435 src_paths = [src_paths]
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 436
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 437 # The first path will give the name to the library
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 438 name = basename(src_paths[0])
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 439
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 440 if report != None:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 441 start = time()
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 442 id_name = name.upper()
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 443 description = name
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 444 vendor_label = target.extra_labels[0]
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 445 cur_result = None
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 446 prep_report(report, target.name, toolchain_name, id_name)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 447 cur_result = create_result(target.name, toolchain_name, id_name, description)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 448
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 449 if properties != None:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 450 prep_properties(properties, target.name, toolchain_name, vendor_label)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 451
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 452 for src_path in src_paths:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 453 if not exists(src_path):
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 454 error_msg = "The library source folder does not exist: %s", src_path
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 455
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 456 if report != None:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 457 cur_result["output"] = error_msg
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 458 cur_result["result"] = "FAIL"
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 459 add_result_to_report(report, cur_result)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 460
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 461 raise Exception(error_msg)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 462
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 463 try:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 464 # Toolchain instance
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 465 toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options, macros=macros, notify=notify, silent=silent, extra_verbose=extra_verbose, profile=profile)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 466 toolchain.VERBOSE = verbose
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 467 toolchain.jobs = jobs
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 468 toolchain.build_all = clean
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 469
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 470 toolchain.info("Building library %s (%s, %s)" % (name.upper(), target.name, toolchain_name))
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 471
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 472 # Scan Resources
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 473 resources = []
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 474 for src_path in src_paths:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 475 resources.append(toolchain.scan_resources(src_path))
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 476
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 477 # Add extra include directories / files which are required by library
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 478 # This files usually are not in the same directory as source files so
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 479 # previous scan will not include them
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 480 if inc_dirs_ext is not None:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 481 for inc_ext in inc_dirs_ext:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 482 resources.append(toolchain.scan_resources(inc_ext))
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 483
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 484 # Dependencies Include Paths
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 485 dependencies_include_dir = []
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 486 if dependencies_paths is not None:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 487 for path in dependencies_paths:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 488 lib_resources = toolchain.scan_resources(path)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 489 dependencies_include_dir.extend(lib_resources.inc_dirs)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 490
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 491 if inc_dirs:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 492 dependencies_include_dir.extend(inc_dirs)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 493
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 494 # Create the desired build directory structure
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 495 bin_path = join(build_path, toolchain.obj_path)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 496 mkdir(bin_path)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 497 tmp_path = join(build_path, '.temp', toolchain.obj_path)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 498 mkdir(tmp_path)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 499
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 500 # Copy Headers
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 501 for resource in resources:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 502 toolchain.copy_files(resource.headers, build_path, rel_path=resource.base_path)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 503 dependencies_include_dir.extend(toolchain.scan_resources(build_path).inc_dirs)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 504
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 505 # Compile Sources
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 506 objects = []
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 507 for resource in resources:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 508 objects.extend(toolchain.compile_sources(resource, tmp_path, dependencies_include_dir))
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 509
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 510 needed_update = toolchain.build_library(objects, bin_path, name)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 511
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 512 if report != None and needed_update:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 513 end = time()
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 514 cur_result["elapsed_time"] = end - start
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 515 cur_result["output"] = toolchain.get_output()
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 516 cur_result["result"] = "OK"
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 517
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 518 add_result_to_report(report, cur_result)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 519
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 520 except Exception, e:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 521 if report != None:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 522 end = time()
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 523 cur_result["result"] = "FAIL"
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 524 cur_result["elapsed_time"] = end - start
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 525
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 526 toolchain_output = toolchain.get_output()
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 527 if toolchain_output:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 528 cur_result["output"] += toolchain_output
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 529
screamer 0:66f3b5499f7f 530 cur_result["output"] += str(e)
screamer 0:66f3b5499f7f 531
screamer 0:66f3b5499f7f 532 add_result_to_report(report, cur_result)
screamer 0:66f3b5499f7f 533
screamer 0:66f3b5499f7f 534 # Let Exception propagate
screamer 0:66f3b5499f7f 535 raise e
screamer 0:66f3b5499f7f 536
screamer 0:66f3b5499f7f 537 # We do have unique legacy conventions about how we build and package the mbed library
screamer 0:66f3b5499f7f 538 def build_mbed_libs(target, toolchain_name, options=None, verbose=False, clean=False, macros=None, notify=None, jobs=1, silent=False, report=None, properties=None, extra_verbose=False):
screamer 0:66f3b5499f7f 539 """ Function returns True is library was built and false if building was skipped """
screamer 0:66f3b5499f7f 540
screamer 0:66f3b5499f7f 541 if report != None:
screamer 0:66f3b5499f7f 542 start = time()
screamer 0:66f3b5499f7f 543 id_name = "MBED"
screamer 0:66f3b5499f7f 544 description = "mbed SDK"
screamer 0:66f3b5499f7f 545 vendor_label = target.extra_labels[0]
screamer 0:66f3b5499f7f 546 cur_result = None
screamer 0:66f3b5499f7f 547 prep_report(report, target.name, toolchain_name, id_name)
screamer 0:66f3b5499f7f 548 cur_result = create_result(target.name, toolchain_name, id_name, description)
screamer 0:66f3b5499f7f 549
screamer 0:66f3b5499f7f 550 if properties != None:
screamer 0:66f3b5499f7f 551 prep_properties(properties, target.name, toolchain_name, vendor_label)
screamer 0:66f3b5499f7f 552
screamer 0:66f3b5499f7f 553 # Check toolchain support
screamer 0:66f3b5499f7f 554 if toolchain_name not in target.supported_toolchains:
screamer 0:66f3b5499f7f 555 supported_toolchains_text = ", ".join(target.supported_toolchains)
screamer 0:66f3b5499f7f 556 print '%s target is not yet supported by toolchain %s' % (target.name, toolchain_name)
screamer 0:66f3b5499f7f 557 print '%s target supports %s toolchain%s' % (target.name, supported_toolchains_text, 's' if len(target.supported_toolchains) > 1 else '')
screamer 0:66f3b5499f7f 558
screamer 0:66f3b5499f7f 559 if report != None:
screamer 0:66f3b5499f7f 560 cur_result["result"] = "SKIP"
screamer 0:66f3b5499f7f 561 add_result_to_report(report, cur_result)
screamer 0:66f3b5499f7f 562
screamer 0:66f3b5499f7f 563 return False
screamer 0:66f3b5499f7f 564
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 565 for path in src_paths:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 566 profile = get_build_profile(path)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 567
screamer 0:66f3b5499f7f 568 try:
screamer 0:66f3b5499f7f 569 # Toolchain
screamer 0:66f3b5499f7f 570 toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options, macros=macros, notify=notify, silent=silent, extra_verbose=extra_verbose)
screamer 0:66f3b5499f7f 571 toolchain.VERBOSE = verbose
screamer 0:66f3b5499f7f 572 toolchain.jobs = jobs
screamer 0:66f3b5499f7f 573 toolchain.build_all = clean
screamer 0:66f3b5499f7f 574
screamer 0:66f3b5499f7f 575 # Source and Build Paths
screamer 0:66f3b5499f7f 576 BUILD_TARGET = join(MBED_LIBRARIES, "TARGET_" + target.name)
screamer 0:66f3b5499f7f 577 BUILD_TOOLCHAIN = join(BUILD_TARGET, "TOOLCHAIN_" + toolchain.name)
screamer 0:66f3b5499f7f 578 mkdir(BUILD_TOOLCHAIN)
screamer 0:66f3b5499f7f 579
screamer 0:66f3b5499f7f 580 TMP_PATH = join(MBED_LIBRARIES, '.temp', toolchain.obj_path)
screamer 0:66f3b5499f7f 581 mkdir(TMP_PATH)
screamer 0:66f3b5499f7f 582
screamer 0:66f3b5499f7f 583 # CMSIS
screamer 0:66f3b5499f7f 584 toolchain.info("Building library %s (%s, %s)"% ('CMSIS', target.name, toolchain_name))
screamer 0:66f3b5499f7f 585 cmsis_src = join(MBED_TARGETS_PATH, "cmsis")
screamer 0:66f3b5499f7f 586 resources = toolchain.scan_resources(cmsis_src)
screamer 0:66f3b5499f7f 587
screamer 0:66f3b5499f7f 588 toolchain.copy_files(resources.headers, BUILD_TARGET)
screamer 0:66f3b5499f7f 589 toolchain.copy_files(resources.linker_script, BUILD_TOOLCHAIN)
screamer 0:66f3b5499f7f 590 toolchain.copy_files(resources.bin_files, BUILD_TOOLCHAIN)
screamer 0:66f3b5499f7f 591
screamer 0:66f3b5499f7f 592 objects = toolchain.compile_sources(resources, TMP_PATH)
screamer 0:66f3b5499f7f 593 toolchain.copy_files(objects, BUILD_TOOLCHAIN)
screamer 0:66f3b5499f7f 594
screamer 0:66f3b5499f7f 595 # mbed
screamer 0:66f3b5499f7f 596 toolchain.info("Building library %s (%s, %s)" % ('MBED', target.name, toolchain_name))
screamer 0:66f3b5499f7f 597
screamer 0:66f3b5499f7f 598 # Common Headers
screamer 0:66f3b5499f7f 599 toolchain.copy_files(toolchain.scan_resources(MBED_API).headers, MBED_LIBRARIES)
screamer 0:66f3b5499f7f 600 toolchain.copy_files(toolchain.scan_resources(MBED_HAL).headers, MBED_LIBRARIES)
screamer 0:66f3b5499f7f 601
screamer 0:66f3b5499f7f 602 # Target specific sources
screamer 0:66f3b5499f7f 603 HAL_SRC = join(MBED_TARGETS_PATH, "hal")
screamer 0:66f3b5499f7f 604 hal_implementation = toolchain.scan_resources(HAL_SRC)
screamer 0:66f3b5499f7f 605 toolchain.copy_files(hal_implementation.headers + hal_implementation.hex_files + hal_implementation.libraries, BUILD_TARGET, HAL_SRC)
screamer 0:66f3b5499f7f 606 incdirs = toolchain.scan_resources(BUILD_TARGET).inc_dirs
screamer 0:66f3b5499f7f 607 objects = toolchain.compile_sources(hal_implementation, TMP_PATH, [MBED_LIBRARIES] + incdirs)
screamer 0:66f3b5499f7f 608
screamer 0:66f3b5499f7f 609 # Common Sources
screamer 0:66f3b5499f7f 610 mbed_resources = toolchain.scan_resources(MBED_COMMON)
screamer 0:66f3b5499f7f 611 objects += toolchain.compile_sources(mbed_resources, TMP_PATH, [MBED_LIBRARIES] + incdirs)
screamer 0:66f3b5499f7f 612
screamer 0:66f3b5499f7f 613 # A number of compiled files need to be copied as objects as opposed to
screamer 0:66f3b5499f7f 614 # being part of the mbed library, for reasons that have to do with the way
screamer 0:66f3b5499f7f 615 # the linker search for symbols in archives. These are:
screamer 0:66f3b5499f7f 616 # - retarget.o: to make sure that the C standard lib symbols get overridden
screamer 0:66f3b5499f7f 617 # - board.o: mbed_die is weak
screamer 0:66f3b5499f7f 618 # - mbed_overrides.o: this contains platform overrides of various weak SDK functions
screamer 0:66f3b5499f7f 619 separate_names, separate_objects = ['retarget.o', 'board.o', 'mbed_overrides.o'], []
screamer 0:66f3b5499f7f 620
screamer 0:66f3b5499f7f 621 for o in objects:
screamer 0:66f3b5499f7f 622 for name in separate_names:
screamer 0:66f3b5499f7f 623 if o.endswith(name):
screamer 0:66f3b5499f7f 624 separate_objects.append(o)
screamer 0:66f3b5499f7f 625
screamer 0:66f3b5499f7f 626 for o in separate_objects:
screamer 0:66f3b5499f7f 627 objects.remove(o)
screamer 0:66f3b5499f7f 628
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 629 toolchain.build_library(objects, BUILD_TOOLCHAIN, "mbed")
screamer 0:66f3b5499f7f 630
screamer 0:66f3b5499f7f 631 for o in separate_objects:
screamer 0:66f3b5499f7f 632 toolchain.copy_files(o, BUILD_TOOLCHAIN)
screamer 0:66f3b5499f7f 633
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 634 if report != None:
screamer 0:66f3b5499f7f 635 end = time()
screamer 0:66f3b5499f7f 636 cur_result["elapsed_time"] = end - start
screamer 0:66f3b5499f7f 637 cur_result["output"] = toolchain.get_output()
screamer 0:66f3b5499f7f 638 cur_result["result"] = "OK"
screamer 0:66f3b5499f7f 639
screamer 0:66f3b5499f7f 640 add_result_to_report(report, cur_result)
screamer 0:66f3b5499f7f 641
screamer 0:66f3b5499f7f 642 return True
screamer 0:66f3b5499f7f 643
screamer 0:66f3b5499f7f 644 except Exception, e:
screamer 0:66f3b5499f7f 645 if report != None:
screamer 0:66f3b5499f7f 646 end = time()
screamer 0:66f3b5499f7f 647 cur_result["result"] = "FAIL"
screamer 0:66f3b5499f7f 648 cur_result["elapsed_time"] = end - start
screamer 0:66f3b5499f7f 649
screamer 0:66f3b5499f7f 650 toolchain_output = toolchain.get_output()
screamer 0:66f3b5499f7f 651 if toolchain_output:
screamer 0:66f3b5499f7f 652 cur_result["output"] += toolchain_output
screamer 0:66f3b5499f7f 653
screamer 0:66f3b5499f7f 654 cur_result["output"] += str(e)
screamer 0:66f3b5499f7f 655
screamer 0:66f3b5499f7f 656 add_result_to_report(report, cur_result)
screamer 0:66f3b5499f7f 657
screamer 0:66f3b5499f7f 658 # Let Exception propagate
screamer 0:66f3b5499f7f 659 raise e
screamer 0:66f3b5499f7f 660
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 661
screamer 0:66f3b5499f7f 662 def get_unique_supported_toolchains():
screamer 0:66f3b5499f7f 663 """ Get list of all unique toolchains supported by targets """
screamer 0:66f3b5499f7f 664 unique_supported_toolchains = []
screamer 0:66f3b5499f7f 665 for target in TARGET_NAMES:
screamer 0:66f3b5499f7f 666 for toolchain in TARGET_MAP[target].supported_toolchains:
screamer 0:66f3b5499f7f 667 if toolchain not in unique_supported_toolchains:
screamer 0:66f3b5499f7f 668 unique_supported_toolchains.append(toolchain)
screamer 0:66f3b5499f7f 669 return unique_supported_toolchains
screamer 0:66f3b5499f7f 670
screamer 0:66f3b5499f7f 671
screamer 0:66f3b5499f7f 672 def mcu_toolchain_matrix(verbose_html=False, platform_filter=None):
screamer 0:66f3b5499f7f 673 """ Shows target map using prettytable """
screamer 0:66f3b5499f7f 674 unique_supported_toolchains = get_unique_supported_toolchains()
screamer 0:66f3b5499f7f 675 from prettytable import PrettyTable # Only use it in this function so building works without extra modules
screamer 0:66f3b5499f7f 676
screamer 0:66f3b5499f7f 677 # All tests status table print
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 678 columns = ["Target"] + unique_supported_toolchains
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 679 pt = PrettyTable(["Target"] + unique_supported_toolchains)
screamer 0:66f3b5499f7f 680 # Align table
screamer 0:66f3b5499f7f 681 for col in columns:
screamer 0:66f3b5499f7f 682 pt.align[col] = "c"
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 683 pt.align["Target"] = "l"
screamer 0:66f3b5499f7f 684
screamer 0:66f3b5499f7f 685 perm_counter = 0
screamer 0:66f3b5499f7f 686 target_counter = 0
screamer 0:66f3b5499f7f 687 for target in sorted(TARGET_NAMES):
screamer 0:66f3b5499f7f 688 if platform_filter is not None:
screamer 0:66f3b5499f7f 689 # FIlter out platforms using regex
screamer 0:66f3b5499f7f 690 if re.search(platform_filter, target) is None:
screamer 0:66f3b5499f7f 691 continue
screamer 0:66f3b5499f7f 692 target_counter += 1
screamer 0:66f3b5499f7f 693
screamer 0:66f3b5499f7f 694 row = [target] # First column is platform name
screamer 0:66f3b5499f7f 695 for unique_toolchain in unique_supported_toolchains:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 696 if unique_toolchain in TARGET_MAP[target].supported_toolchains:
screamer 0:66f3b5499f7f 697 text = "Supported"
screamer 0:66f3b5499f7f 698 perm_counter += 1
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 699 else:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 700 text = "-"
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 701
screamer 0:66f3b5499f7f 702 row.append(text)
screamer 0:66f3b5499f7f 703 pt.add_row(row)
screamer 0:66f3b5499f7f 704
screamer 0:66f3b5499f7f 705 result = pt.get_html_string() if verbose_html else pt.get_string()
screamer 0:66f3b5499f7f 706 result += "\n"
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 707 result += "Supported targets: %d\n"% (target_counter)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 708 if target_counter == 1:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 709 result += "Supported toolchains: %d"% (perm_counter)
screamer 0:66f3b5499f7f 710 return result
screamer 0:66f3b5499f7f 711
screamer 0:66f3b5499f7f 712
screamer 0:66f3b5499f7f 713 def get_target_supported_toolchains(target):
screamer 0:66f3b5499f7f 714 """ Returns target supported toolchains list """
screamer 0:66f3b5499f7f 715 return TARGET_MAP[target].supported_toolchains if target in TARGET_MAP else None
screamer 0:66f3b5499f7f 716
screamer 0:66f3b5499f7f 717
screamer 0:66f3b5499f7f 718 def static_analysis_scan(target, toolchain_name, CPPCHECK_CMD, CPPCHECK_MSG_FORMAT, options=None, verbose=False, clean=False, macros=None, notify=None, jobs=1, extra_verbose=False):
screamer 0:66f3b5499f7f 719 # Toolchain
screamer 0:66f3b5499f7f 720 toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options, macros=macros, notify=notify, extra_verbose=extra_verbose)
screamer 0:66f3b5499f7f 721 toolchain.VERBOSE = verbose
screamer 0:66f3b5499f7f 722 toolchain.jobs = jobs
screamer 0:66f3b5499f7f 723 toolchain.build_all = clean
screamer 0:66f3b5499f7f 724
screamer 0:66f3b5499f7f 725 # Source and Build Paths
screamer 0:66f3b5499f7f 726 BUILD_TARGET = join(MBED_LIBRARIES, "TARGET_" + target.name)
screamer 0:66f3b5499f7f 727 BUILD_TOOLCHAIN = join(BUILD_TARGET, "TOOLCHAIN_" + toolchain.name)
screamer 0:66f3b5499f7f 728 mkdir(BUILD_TOOLCHAIN)
screamer 0:66f3b5499f7f 729
screamer 0:66f3b5499f7f 730 TMP_PATH = join(MBED_LIBRARIES, '.temp', toolchain.obj_path)
screamer 0:66f3b5499f7f 731 mkdir(TMP_PATH)
screamer 0:66f3b5499f7f 732
screamer 0:66f3b5499f7f 733 # CMSIS
screamer 0:66f3b5499f7f 734 toolchain.info("Static analysis for %s (%s, %s)" % ('CMSIS', target.name, toolchain_name))
screamer 0:66f3b5499f7f 735 cmsis_src = join(MBED_TARGETS_PATH, "cmsis")
screamer 0:66f3b5499f7f 736 resources = toolchain.scan_resources(cmsis_src)
screamer 0:66f3b5499f7f 737
screamer 0:66f3b5499f7f 738 # Copy files before analysis
screamer 0:66f3b5499f7f 739 toolchain.copy_files(resources.headers, BUILD_TARGET)
screamer 0:66f3b5499f7f 740 toolchain.copy_files(resources.linker_script, BUILD_TOOLCHAIN)
screamer 0:66f3b5499f7f 741
screamer 0:66f3b5499f7f 742 # Gather include paths, c, cpp sources and macros to transfer to cppcheck command line
screamer 0:66f3b5499f7f 743 includes = ["-I%s"% i for i in resources.inc_dirs]
screamer 0:66f3b5499f7f 744 includes.append("-I%s"% str(BUILD_TARGET))
screamer 0:66f3b5499f7f 745 c_sources = " ".join(resources.c_sources)
screamer 0:66f3b5499f7f 746 cpp_sources = " ".join(resources.cpp_sources)
screamer 0:66f3b5499f7f 747 macros = ["-D%s"% s for s in toolchain.get_symbols() + toolchain.macros]
screamer 0:66f3b5499f7f 748
screamer 0:66f3b5499f7f 749 includes = map(str.strip, includes)
screamer 0:66f3b5499f7f 750 macros = map(str.strip, macros)
screamer 0:66f3b5499f7f 751
screamer 0:66f3b5499f7f 752 check_cmd = CPPCHECK_CMD
screamer 0:66f3b5499f7f 753 check_cmd += CPPCHECK_MSG_FORMAT
screamer 0:66f3b5499f7f 754 check_cmd += includes
screamer 0:66f3b5499f7f 755 check_cmd += macros
screamer 0:66f3b5499f7f 756
screamer 0:66f3b5499f7f 757 # We need to pass some params via file to avoid "command line too long in some OSs"
screamer 0:66f3b5499f7f 758 tmp_file = tempfile.NamedTemporaryFile(delete=False)
screamer 0:66f3b5499f7f 759 tmp_file.writelines(line + '\n' for line in c_sources.split())
screamer 0:66f3b5499f7f 760 tmp_file.writelines(line + '\n' for line in cpp_sources.split())
screamer 0:66f3b5499f7f 761 tmp_file.close()
screamer 0:66f3b5499f7f 762 check_cmd += ["--file-list=%s"% tmp_file.name]
screamer 0:66f3b5499f7f 763
screamer 0:66f3b5499f7f 764 _stdout, _stderr, _rc = run_cmd(check_cmd)
screamer 0:66f3b5499f7f 765 if verbose:
screamer 0:66f3b5499f7f 766 print _stdout
screamer 0:66f3b5499f7f 767 print _stderr
screamer 0:66f3b5499f7f 768
screamer 0:66f3b5499f7f 769 # =========================================================================
screamer 0:66f3b5499f7f 770
screamer 0:66f3b5499f7f 771 # MBED
screamer 0:66f3b5499f7f 772 toolchain.info("Static analysis for %s (%s, %s)" % ('MBED', target.name, toolchain_name))
screamer 0:66f3b5499f7f 773
screamer 0:66f3b5499f7f 774 # Common Headers
screamer 0:66f3b5499f7f 775 toolchain.copy_files(toolchain.scan_resources(MBED_API).headers, MBED_LIBRARIES)
screamer 0:66f3b5499f7f 776 toolchain.copy_files(toolchain.scan_resources(MBED_HAL).headers, MBED_LIBRARIES)
screamer 0:66f3b5499f7f 777
screamer 0:66f3b5499f7f 778 # Target specific sources
screamer 0:66f3b5499f7f 779 HAL_SRC = join(MBED_TARGETS_PATH, "hal")
screamer 0:66f3b5499f7f 780 hal_implementation = toolchain.scan_resources(HAL_SRC)
screamer 0:66f3b5499f7f 781
screamer 0:66f3b5499f7f 782 # Copy files before analysis
screamer 0:66f3b5499f7f 783 toolchain.copy_files(hal_implementation.headers + hal_implementation.hex_files, BUILD_TARGET, HAL_SRC)
screamer 0:66f3b5499f7f 784 incdirs = toolchain.scan_resources(BUILD_TARGET)
screamer 0:66f3b5499f7f 785
screamer 0:66f3b5499f7f 786 target_includes = ["-I%s" % i for i in incdirs.inc_dirs]
screamer 0:66f3b5499f7f 787 target_includes.append("-I%s"% str(BUILD_TARGET))
screamer 0:66f3b5499f7f 788 target_includes.append("-I%s"% str(HAL_SRC))
screamer 0:66f3b5499f7f 789 target_c_sources = " ".join(incdirs.c_sources)
screamer 0:66f3b5499f7f 790 target_cpp_sources = " ".join(incdirs.cpp_sources)
screamer 0:66f3b5499f7f 791 target_macros = ["-D%s"% s for s in toolchain.get_symbols() + toolchain.macros]
screamer 0:66f3b5499f7f 792
screamer 0:66f3b5499f7f 793 # Common Sources
screamer 0:66f3b5499f7f 794 mbed_resources = toolchain.scan_resources(MBED_COMMON)
screamer 0:66f3b5499f7f 795
screamer 0:66f3b5499f7f 796 # Gather include paths, c, cpp sources and macros to transfer to cppcheck command line
screamer 0:66f3b5499f7f 797 mbed_includes = ["-I%s" % i for i in mbed_resources.inc_dirs]
screamer 0:66f3b5499f7f 798 mbed_includes.append("-I%s"% str(BUILD_TARGET))
screamer 0:66f3b5499f7f 799 mbed_includes.append("-I%s"% str(MBED_COMMON))
screamer 0:66f3b5499f7f 800 mbed_includes.append("-I%s"% str(MBED_API))
screamer 0:66f3b5499f7f 801 mbed_includes.append("-I%s"% str(MBED_HAL))
screamer 0:66f3b5499f7f 802 mbed_c_sources = " ".join(mbed_resources.c_sources)
screamer 0:66f3b5499f7f 803 mbed_cpp_sources = " ".join(mbed_resources.cpp_sources)
screamer 0:66f3b5499f7f 804
screamer 0:66f3b5499f7f 805 target_includes = map(str.strip, target_includes)
screamer 0:66f3b5499f7f 806 mbed_includes = map(str.strip, mbed_includes)
screamer 0:66f3b5499f7f 807 target_macros = map(str.strip, target_macros)
screamer 0:66f3b5499f7f 808
screamer 0:66f3b5499f7f 809 check_cmd = CPPCHECK_CMD
screamer 0:66f3b5499f7f 810 check_cmd += CPPCHECK_MSG_FORMAT
screamer 0:66f3b5499f7f 811 check_cmd += target_includes
screamer 0:66f3b5499f7f 812 check_cmd += mbed_includes
screamer 0:66f3b5499f7f 813 check_cmd += target_macros
screamer 0:66f3b5499f7f 814
screamer 0:66f3b5499f7f 815 # We need to pass some parames via file to avoid "command line too long in some OSs"
screamer 0:66f3b5499f7f 816 tmp_file = tempfile.NamedTemporaryFile(delete=False)
screamer 0:66f3b5499f7f 817 tmp_file.writelines(line + '\n' for line in target_c_sources.split())
screamer 0:66f3b5499f7f 818 tmp_file.writelines(line + '\n' for line in target_cpp_sources.split())
screamer 0:66f3b5499f7f 819 tmp_file.writelines(line + '\n' for line in mbed_c_sources.split())
screamer 0:66f3b5499f7f 820 tmp_file.writelines(line + '\n' for line in mbed_cpp_sources.split())
screamer 0:66f3b5499f7f 821 tmp_file.close()
screamer 0:66f3b5499f7f 822 check_cmd += ["--file-list=%s"% tmp_file.name]
screamer 0:66f3b5499f7f 823
screamer 0:66f3b5499f7f 824 _stdout, _stderr, _rc = run_cmd_ext(check_cmd)
screamer 0:66f3b5499f7f 825 if verbose:
screamer 0:66f3b5499f7f 826 print _stdout
screamer 0:66f3b5499f7f 827 print _stderr
screamer 0:66f3b5499f7f 828
screamer 0:66f3b5499f7f 829
screamer 0:66f3b5499f7f 830 def static_analysis_scan_lib(lib_id, target, toolchain, cppcheck_cmd, cppcheck_msg_format,
screamer 0:66f3b5499f7f 831 options=None, verbose=False, clean=False, macros=None, notify=None, jobs=1, extra_verbose=False):
screamer 0:66f3b5499f7f 832 lib = Library(lib_id)
screamer 0:66f3b5499f7f 833 if lib.is_supported(target, toolchain):
screamer 0:66f3b5499f7f 834 static_analysis_scan_library(lib.source_dir, lib.build_dir, target, toolchain, cppcheck_cmd, cppcheck_msg_format,
screamer 0:66f3b5499f7f 835 lib.dependencies, options,
screamer 0:66f3b5499f7f 836 verbose=verbose, clean=clean, macros=macros, notify=notify, jobs=jobs, extra_verbose=extra_verbose)
screamer 0:66f3b5499f7f 837 else:
screamer 0:66f3b5499f7f 838 print 'Library "%s" is not yet supported on target %s with toolchain %s'% (lib_id, target.name, toolchain)
screamer 0:66f3b5499f7f 839
screamer 0:66f3b5499f7f 840
screamer 0:66f3b5499f7f 841 def static_analysis_scan_library(src_paths, build_path, target, toolchain_name, cppcheck_cmd, cppcheck_msg_format,
screamer 0:66f3b5499f7f 842 dependencies_paths=None, options=None, name=None, clean=False,
screamer 0:66f3b5499f7f 843 notify=None, verbose=False, macros=None, jobs=1, extra_verbose=False):
screamer 0:66f3b5499f7f 844 """ Function scans library (or just some set of sources/headers) for staticly detectable defects """
screamer 0:66f3b5499f7f 845 if type(src_paths) != ListType:
screamer 0:66f3b5499f7f 846 src_paths = [src_paths]
screamer 0:66f3b5499f7f 847
screamer 0:66f3b5499f7f 848 for src_path in src_paths:
screamer 0:66f3b5499f7f 849 if not exists(src_path):
screamer 0:66f3b5499f7f 850 raise Exception("The library source folder does not exist: %s", src_path)
screamer 0:66f3b5499f7f 851
screamer 0:66f3b5499f7f 852 # Toolchain instance
screamer 0:66f3b5499f7f 853 toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options, macros=macros, notify=notify, extra_verbose=extra_verbose)
screamer 0:66f3b5499f7f 854 toolchain.VERBOSE = verbose
screamer 0:66f3b5499f7f 855 toolchain.jobs = jobs
screamer 0:66f3b5499f7f 856
screamer 0:66f3b5499f7f 857 # The first path will give the name to the library
screamer 0:66f3b5499f7f 858 name = basename(src_paths[0])
screamer 0:66f3b5499f7f 859 toolchain.info("Static analysis for library %s (%s, %s)" % (name.upper(), target.name, toolchain_name))
screamer 0:66f3b5499f7f 860
screamer 0:66f3b5499f7f 861 # Scan Resources
screamer 0:66f3b5499f7f 862 resources = []
screamer 0:66f3b5499f7f 863 for src_path in src_paths:
screamer 0:66f3b5499f7f 864 resources.append(toolchain.scan_resources(src_path))
screamer 0:66f3b5499f7f 865
screamer 0:66f3b5499f7f 866 # Dependencies Include Paths
screamer 0:66f3b5499f7f 867 dependencies_include_dir = []
screamer 0:66f3b5499f7f 868 if dependencies_paths is not None:
screamer 0:66f3b5499f7f 869 for path in dependencies_paths:
screamer 0:66f3b5499f7f 870 lib_resources = toolchain.scan_resources(path)
screamer 0:66f3b5499f7f 871 dependencies_include_dir.extend(lib_resources.inc_dirs)
screamer 0:66f3b5499f7f 872
screamer 0:66f3b5499f7f 873 # Create the desired build directory structure
screamer 0:66f3b5499f7f 874 bin_path = join(build_path, toolchain.obj_path)
screamer 0:66f3b5499f7f 875 mkdir(bin_path)
screamer 0:66f3b5499f7f 876 tmp_path = join(build_path, '.temp', toolchain.obj_path)
screamer 0:66f3b5499f7f 877 mkdir(tmp_path)
screamer 0:66f3b5499f7f 878
screamer 0:66f3b5499f7f 879 # Gather include paths, c, cpp sources and macros to transfer to cppcheck command line
screamer 0:66f3b5499f7f 880 includes = ["-I%s" % i for i in dependencies_include_dir + src_paths]
screamer 0:66f3b5499f7f 881 c_sources = " "
screamer 0:66f3b5499f7f 882 cpp_sources = " "
screamer 0:66f3b5499f7f 883 macros = ['-D%s' % s for s in toolchain.get_symbols() + toolchain.macros]
screamer 0:66f3b5499f7f 884
screamer 0:66f3b5499f7f 885 # Copy Headers
screamer 0:66f3b5499f7f 886 for resource in resources:
screamer 0:66f3b5499f7f 887 toolchain.copy_files(resource.headers, build_path, rel_path=resource.base_path)
screamer 0:66f3b5499f7f 888 includes += ["-I%s" % i for i in resource.inc_dirs]
screamer 0:66f3b5499f7f 889 c_sources += " ".join(resource.c_sources) + " "
screamer 0:66f3b5499f7f 890 cpp_sources += " ".join(resource.cpp_sources) + " "
screamer 0:66f3b5499f7f 891
screamer 0:66f3b5499f7f 892 dependencies_include_dir.extend(toolchain.scan_resources(build_path).inc_dirs)
screamer 0:66f3b5499f7f 893
screamer 0:66f3b5499f7f 894 includes = map(str.strip, includes)
screamer 0:66f3b5499f7f 895 macros = map(str.strip, macros)
screamer 0:66f3b5499f7f 896
screamer 0:66f3b5499f7f 897 check_cmd = cppcheck_cmd
screamer 0:66f3b5499f7f 898 check_cmd += cppcheck_msg_format
screamer 0:66f3b5499f7f 899 check_cmd += includes
screamer 0:66f3b5499f7f 900 check_cmd += macros
screamer 0:66f3b5499f7f 901
screamer 0:66f3b5499f7f 902 # We need to pass some parameters via file to avoid "command line too long in some OSs"
screamer 0:66f3b5499f7f 903 # Temporary file is created to store e.g. cppcheck list of files for command line
screamer 0:66f3b5499f7f 904 tmp_file = tempfile.NamedTemporaryFile(delete=False)
screamer 0:66f3b5499f7f 905 tmp_file.writelines(line + '\n' for line in c_sources.split())
screamer 0:66f3b5499f7f 906 tmp_file.writelines(line + '\n' for line in cpp_sources.split())
screamer 0:66f3b5499f7f 907 tmp_file.close()
screamer 0:66f3b5499f7f 908 check_cmd += ["--file-list=%s"% tmp_file.name]
screamer 0:66f3b5499f7f 909
screamer 0:66f3b5499f7f 910 # This will allow us to grab result from both stdio and stderr outputs (so we can show them)
screamer 0:66f3b5499f7f 911 # We assume static code analysis tool is outputting defects on STDERR
screamer 0:66f3b5499f7f 912 _stdout, _stderr, _rc = run_cmd_ext(check_cmd)
screamer 0:66f3b5499f7f 913 if verbose:
screamer 0:66f3b5499f7f 914 print _stdout
screamer 0:66f3b5499f7f 915 print _stderr
screamer 0:66f3b5499f7f 916
screamer 0:66f3b5499f7f 917
screamer 0:66f3b5499f7f 918 def print_build_results(result_list, build_name):
screamer 0:66f3b5499f7f 919 """ Generate result string for build results """
screamer 0:66f3b5499f7f 920 result = ""
screamer 0:66f3b5499f7f 921 if len(result_list) > 0:
screamer 0:66f3b5499f7f 922 result += build_name + "\n"
screamer 0:66f3b5499f7f 923 result += "\n".join([" * %s" % f for f in result_list])
screamer 0:66f3b5499f7f 924 result += "\n"
screamer 0:66f3b5499f7f 925 return result
screamer 0:66f3b5499f7f 926
screamer 0:66f3b5499f7f 927 def write_build_report(build_report, template_filename, filename):
screamer 0:66f3b5499f7f 928 build_report_failing = []
screamer 0:66f3b5499f7f 929 build_report_passing = []
screamer 0:66f3b5499f7f 930
screamer 0:66f3b5499f7f 931 for report in build_report:
screamer 0:66f3b5499f7f 932 if len(report["failing"]) > 0:
screamer 0:66f3b5499f7f 933 build_report_failing.append(report)
screamer 0:66f3b5499f7f 934 else:
screamer 0:66f3b5499f7f 935 build_report_passing.append(report)
screamer 0:66f3b5499f7f 936
screamer 0:66f3b5499f7f 937 env = Environment(extensions=['jinja2.ext.with_'])
screamer 0:66f3b5499f7f 938 env.loader = FileSystemLoader('ci_templates')
screamer 0:66f3b5499f7f 939 template = env.get_template(template_filename)
screamer 0:66f3b5499f7f 940
screamer 0:66f3b5499f7f 941 with open(filename, 'w+') as f:
screamer 0:66f3b5499f7f 942 f.write(template.render(failing_builds=build_report_failing, passing_builds=build_report_passing))
screamer 1:a99c8e460c5c 943
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 944
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 945 def scan_for_source_paths(path, exclude_paths=None):
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 946 ignorepatterns = []
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 947 paths = []
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 948
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 949 def is_ignored(file_path):
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 950 for pattern in ignorepatterns:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 951 if fnmatch.fnmatch(file_path, pattern):
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 952 return True
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 953 return False
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 954
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 955
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 956 """ os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]])
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 957 When topdown is True, the caller can modify the dirnames list in-place
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 958 (perhaps using del or slice assignment), and walk() will only recurse into
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 959 the subdirectories whose names remain in dirnames; this can be used to prune
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 960 the search, impose a specific order of visiting, or even to inform walk()
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 961 about directories the caller creates or renames before it resumes walk()
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 962 again. Modifying dirnames when topdown is False is ineffective, because in
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 963 bottom-up mode the directories in dirnames are generated before dirpath
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 964 itself is generated.
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 965 """
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 966 for root, dirs, files in walk(path, followlinks=True):
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 967 # Remove ignored directories
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 968 # Check if folder contains .mbedignore
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 969 if ".mbedignore" in files :
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 970 with open (join(root,".mbedignore"), "r") as f:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 971 lines=f.readlines()
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 972 lines = [l.strip() for l in lines] # Strip whitespaces
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 973 lines = [l for l in lines if l != ""] # Strip empty lines
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 974 lines = [l for l in lines if not re.match("^#",l)] # Strip comment lines
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 975 # Append root path to glob patterns
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 976 # and append patterns to ignorepatterns
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 977 ignorepatterns.extend([join(root,line.strip()) for line in lines])
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 978
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 979 for d in copy(dirs):
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 980 dir_path = join(root, d)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 981
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 982 # Always ignore hidden directories
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 983 if d.startswith('.'):
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 984 dirs.remove(d)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 985
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 986 # Remove dirs that already match the ignorepatterns
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 987 # to avoid travelling into them and to prevent them
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 988 # on appearing in include path.
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 989 if is_ignored(join(dir_path,"")):
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 990 dirs.remove(d)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 991
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 992 if exclude_paths:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 993 for exclude_path in exclude_paths:
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 994 rel_path = relpath(dir_path, exclude_path)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 995 if not (rel_path.startswith('..')):
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 996 dirs.remove(d)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 997 break
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 998
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 999 # Add root to include paths
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 1000 paths.append(root)
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 1001
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 1002 return paths
Screamer@Y5070-M.virtuoso 9:2d27d77ada5c 1003
screamer 2:07730b0f452c 1004 def get_build_profile(path):
screamer 1:a99c8e460c5c 1005 profile = None
screamer 1:a99c8e460c5c 1006 builds = get_build_ids(path)
screamer 1:a99c8e460c5c 1007 for build in builds:
screamer 1:a99c8e460c5c 1008 if MBED_SDK_REV_MAP.has_key(build):
screamer 1:a99c8e460c5c 1009 idx = MBED_SDK_REV_MAP[build]
screamer 1:a99c8e460c5c 1010
screamer 1:a99c8e460c5c 1011 if idx is None:
screamer 1:a99c8e460c5c 1012 profile = 'v5'
screamer 1:a99c8e460c5c 1013 elif idx <= 43:
screamer 1:a99c8e460c5c 1014 profile = 'v1'
screamer 1:a99c8e460c5c 1015 elif idx <= 68:
screamer 2:07730b0f452c 1016 profile = 'v2'
screamer 1:a99c8e460c5c 1017 elif idx <= 76:
screamer 1:a99c8e460c5c 1018 profile = 'v3'
screamer 1:a99c8e460c5c 1019 elif idx <= 105:
screamer 1:a99c8e460c5c 1020 profile = 'v4'
screamer 1:a99c8e460c5c 1021 else:
screamer 1:a99c8e460c5c 1022 profile = 'v5'
screamer 1:a99c8e460c5c 1023
screamer 1:a99c8e460c5c 1024 return profile
screamer 1:a99c8e460c5c 1025
screamer 1:a99c8e460c5c 1026 def get_build_ids(path):
screamer 1:a99c8e460c5c 1027 builds = []
screamer 1:a99c8e460c5c 1028
screamer 1:a99c8e460c5c 1029 for (root, dirs, files) in walk(path):
screamer 1:a99c8e460c5c 1030 for d in copy(dirs):
screamer 1:a99c8e460c5c 1031 if d.startswith('.'):
screamer 1:a99c8e460c5c 1032 dirs.remove(d)
screamer 1:a99c8e460c5c 1033
screamer 1:a99c8e460c5c 1034 for filename in filter(lambda s: s.endswith(".bld"), files):
screamer 1:a99c8e460c5c 1035 try:
screamer 1:a99c8e460c5c 1036 # TODO check user has permission to link against build
screamer 1:a99c8e460c5c 1037 url = open(join(root, filename), 'r').read()
screamer 1:a99c8e460c5c 1038 builds.append(re.sub(r'^.+/(.*?)$', r'\1', url))
screamer 1:a99c8e460c5c 1039 except:
screamer 1:a99c8e460c5c 1040 pass
screamer 1:a99c8e460c5c 1041
screamer 1:a99c8e460c5c 1042 return builds
screamer 1:a99c8e460c5c 1043
screamer 1:a99c8e460c5c 1044 MBED_SDK_REV_MAP = {
screamer 1:a99c8e460c5c 1045 '8ed44a420e5c': 105,
screamer 1:a99c8e460c5c 1046 'b9ad9a133dc7': 104,
screamer 1:a99c8e460c5c 1047 'bad568076d81': 103,
screamer 1:a99c8e460c5c 1048 'da0ca467f8b5': 102,
screamer 1:a99c8e460c5c 1049 '7cff1c4259d7': 101,
screamer 1:a99c8e460c5c 1050 'cbbeb26dbd92': 100,
screamer 1:a99c8e460c5c 1051 'dbbf35b96557': 99,
screamer 1:a99c8e460c5c 1052 '8ab26030e058': 98,
screamer 1:a99c8e460c5c 1053 '433970e64889': 97,
screamer 1:a99c8e460c5c 1054 '487b796308b0': 96,
screamer 1:a99c8e460c5c 1055 '7e07b6fb45cf': 95,
screamer 1:a99c8e460c5c 1056 '9ad691361fac': 94,
screamer 1:a99c8e460c5c 1057 'e188a91d3eaa': 93,
screamer 1:a99c8e460c5c 1058 '4fc01daae5a5': 92,
screamer 1:a99c8e460c5c 1059 '031413cf7a89': 91,
screamer 1:a99c8e460c5c 1060 'cb3d968589d8': 90,
screamer 1:a99c8e460c5c 1061 '552587b429a1': 89,
screamer 1:a99c8e460c5c 1062 '9327015d4013': 88,
screamer 1:a99c8e460c5c 1063 '6213f644d804': 87,
screamer 1:a99c8e460c5c 1064 '04dd9b1680ae': 86,
screamer 1:a99c8e460c5c 1065 '024bf7f99721': 85,
screamer 1:a99c8e460c5c 1066 '0b3ab51c8877': 84,
screamer 1:a99c8e460c5c 1067 '8a40adfe8776': 83,
screamer 1:a99c8e460c5c 1068 '6473597d706e': 82,
screamer 1:a99c8e460c5c 1069 '7d30d6019079': 81,
screamer 1:a99c8e460c5c 1070 '8e73be2a2ac1': 80,
screamer 1:a99c8e460c5c 1071 '0c05e21ae27e': 79,
screamer 1:a99c8e460c5c 1072 'ed8466a608b4': 78,
screamer 1:a99c8e460c5c 1073 '869cf507173a': 77,
screamer 1:a99c8e460c5c 1074 '824293ae5e43': 76,
screamer 1:a99c8e460c5c 1075 'dc225afb6914': 75,
screamer 1:a99c8e460c5c 1076 'a842253909c9': 74,
screamer 1:a99c8e460c5c 1077 '1efda918f0ba': 73,
screamer 1:a99c8e460c5c 1078 '4096f863f923': 72,
screamer 1:a99c8e460c5c 1079 '8fabd470bb6e': 71,
screamer 1:a99c8e460c5c 1080 '673126e12c73': 70,
screamer 1:a99c8e460c5c 1081 '4a7918f48478': 69,
screamer 1:a99c8e460c5c 1082 'f37f3b9c9f0b': 68,
screamer 1:a99c8e460c5c 1083 'a9913a65894f': 67,
screamer 1:a99c8e460c5c 1084 '9c8f0e3462fb': 66,
screamer 1:a99c8e460c5c 1085 '5798e58a58b1': 65,
screamer 1:a99c8e460c5c 1086 'e3affc9e7238': 64,
screamer 1:a99c8e460c5c 1087 'b3110cd2dd17': 63,
screamer 1:a99c8e460c5c 1088 '7e6c9f46b3bd': 62,
screamer 1:a99c8e460c5c 1089 '5e5da4a5990b': 61,
screamer 1:a99c8e460c5c 1090 '3d0ef94e36ec': 60,
screamer 1:a99c8e460c5c 1091 '0883845fe643': 59,
screamer 1:a99c8e460c5c 1092 '0954ebd79f59': 58,
screamer 1:a99c8e460c5c 1093 '0480438fc29c': 57,
screamer 1:a99c8e460c5c 1094 '3753e96f3c8b': 56,
screamer 1:a99c8e460c5c 1095 'd722ed6a4237': 55,
screamer 1:a99c8e460c5c 1096 '71b101360fb9': 54,
screamer 1:a99c8e460c5c 1097 '63cdd78b2dc1': 53,
screamer 1:a99c8e460c5c 1098 '09236a68d21b': 52,
screamer 1:a99c8e460c5c 1099 'a076018f59af': 51,
screamer 1:a99c8e460c5c 1100 'b60934f96c0c': 50,
screamer 1:a99c8e460c5c 1101 'eeb8a2a33ec9': 49,
screamer 1:a99c8e460c5c 1102 '49c296715c73': 48,
screamer 1:a99c8e460c5c 1103 '134def52cfa0': 47,
screamer 1:a99c8e460c5c 1104 '890817bdcffb': 46,
screamer 1:a99c8e460c5c 1105 '3d775a932e1d': 45,
screamer 1:a99c8e460c5c 1106 '24d45a770a51': 44,
screamer 1:a99c8e460c5c 1107 'e2ed12d17f06': 43,
screamer 1:a99c8e460c5c 1108 'cd19af002ccc': 42,
screamer 1:a99c8e460c5c 1109 '10b9abbe79a6': 41,
screamer 1:a99c8e460c5c 1110 '976df7c37ad5': 40,
screamer 1:a99c8e460c5c 1111 '737756e0b479': 39,
screamer 1:a99c8e460c5c 1112 '4c0c40fd0593': 38,
screamer 1:a99c8e460c5c 1113 '14f4805c468c': 37,
screamer 1:a99c8e460c5c 1114 'b4b9f287a47e': 36,
screamer 1:a99c8e460c5c 1115 '5284544d04b6': 35,
screamer 1:a99c8e460c5c 1116 '7495d544864f': 34,
screamer 1:a99c8e460c5c 1117 '5364839841bd': 33,
screamer 1:a99c8e460c5c 1118 '3b05dd009342': 32,
screamer 1:a99c8e460c5c 1119 'a7ef757f598c': 31,
screamer 1:a99c8e460c5c 1120 '3991a86798e3': 30,
screamer 1:a99c8e460c5c 1121 '078e4b97a13e': 29,
screamer 1:a99c8e460c5c 1122 '667d61c9177b': 28,
screamer 1:a99c8e460c5c 1123 '7110ebee3484': 27,
screamer 1:a99c8e460c5c 1124 '63bcd7ba4912': 26,
screamer 1:a99c8e460c5c 1125 '9a9732ce53a1': 25,
screamer 1:a99c8e460c5c 1126 'e2ac27c8e93e': 24,
screamer 1:a99c8e460c5c 1127 '74b8d43b5817': 23,
screamer 1:a99c8e460c5c 1128 '9114680c05da': 22,
screamer 1:a99c8e460c5c 1129 '3944f1e2fa4f': 21,
screamer 1:a99c8e460c5c 1130 '029aa53d7323': 20,
screamer 1:a99c8e460c5c 1131 'e6be4cd80aad': 19,
screamer 1:a99c8e460c5c 1132 'b3c9f16cbb96': 18,
screamer 1:a99c8e460c5c 1133 '49a220cc26e0': 17,
screamer 1:a99c8e460c5c 1134 '32af5db564d4': 16,
screamer 1:a99c8e460c5c 1135 'd1a9de3f4fe0': 15,
screamer 1:a99c8e460c5c 1136 '20a79241b4a0': 14,
screamer 1:a99c8e460c5c 1137 'a0336ede94ce': 13,
screamer 1:a99c8e460c5c 1138 'f63353af7be8': 12,
screamer 1:a99c8e460c5c 1139 '1c1ebd0324fa': 11,
screamer 1:a99c8e460c5c 1140 'fcb9359f0959': 10,
screamer 1:a99c8e460c5c 1141 'cf0d45ce28a6': 9,
screamer 1:a99c8e460c5c 1142 '00a04e5cd407': 8,
screamer 1:a99c8e460c5c 1143 '15d74db76485': 7,
screamer 1:a99c8e460c5c 1144 '3fd6a337c7cc': 6,
screamer 1:a99c8e460c5c 1145 '62573be585e9': 5,
screamer 1:a99c8e460c5c 1146 '5d1359a283bc': 4,
screamer 1:a99c8e460c5c 1147 'aefd12a1f1c5': 3,
screamer 1:a99c8e460c5c 1148 '969fc1867111': 2,
screamer 1:a99c8e460c5c 1149 '6b7f447ca868': 1,
screamer 1:a99c8e460c5c 1150 '82220227f4fa': 0,
screamer 7:5af61d55adbe 1151 }