Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: build_api.py
- Revision:
- 29:1210849dba19
- Parent:
- 27:5461402c33f8
- Child:
- 30:f12ce67666d0
--- a/build_api.py Mon Aug 29 10:55:42 2016 +0100
+++ b/build_api.py Mon Aug 29 11:18:36 2016 +0100
@@ -17,18 +17,16 @@
import re
import tempfile
-import colorama
-
-from copy import copy
from types import ListType
from shutil import rmtree
-from os.path import join, exists, basename, abspath, normpath
-from os import getcwd, walk, linesep
+from os.path import join, exists, basename, abspath, normpath, dirname
+from os import linesep, remove
from time import time
-import fnmatch
-from tools.utils import mkdir, run_cmd, run_cmd_ext, NotSupportedException, ToolException, InvalidReleaseTargetException
-from tools.paths import MBED_TARGETS_PATH, MBED_LIBRARIES, MBED_API, MBED_HAL, MBED_COMMON
+from tools.utils import mkdir, run_cmd, run_cmd_ext, NotSupportedException,\
+ ToolException, InvalidReleaseTargetException
+from tools.paths import MBED_TARGETS_PATH, MBED_LIBRARIES, MBED_API, MBED_HAL,\
+ MBED_COMMON, MBED_CONFIG_FILE
from tools.targets import TARGET_NAMES, TARGET_MAP, set_targets_json_location
from tools.libraries import Library
from tools.toolchains import TOOLCHAIN_CLASSES, mbedToolchain
@@ -40,7 +38,14 @@
RELEASE_VERSIONS = ['2', '5']
def prep_report(report, target_name, toolchain_name, id_name):
- # Setup report keys
+ """Setup report keys
+
+ Positional arguments:
+ report - the report to fill
+ target_name - the target being used
+ toolchain_name - the toolchain being used
+ id_name - the name of the executable or library being built
+ """
if not target_name in report:
report[target_name] = {}
@@ -51,7 +56,14 @@
report[target_name][toolchain_name][id_name] = []
def prep_properties(properties, target_name, toolchain_name, vendor_label):
- # Setup test properties
+ """Setup test properties
+
+ Positional arguments:
+ properties - the dict to fill
+ target_name - the target the test is targeting
+ toolchain_name - the toolchain that will compile the test
+ vendor_label - the vendor
+ """
if not target_name in properties:
properties[target_name] = {}
@@ -63,6 +75,14 @@
properties[target_name][toolchain_name]["toolchain"] = toolchain_name
def create_result(target_name, toolchain_name, id_name, description):
+ """Create a result dictionary
+
+ Positional arguments:
+ target_name - the target being built for
+ toolchain_name - the toolchain doing the building
+ id_name - the name of the executable or library being built
+ description - a human readable description of what's going on
+ """
cur_result = {}
cur_result["target_name"] = target_name
cur_result["toolchain_name"] = toolchain_name
@@ -74,13 +94,26 @@
return cur_result
def add_result_to_report(report, result):
+ """Add a single result to a report dictionary
+
+ Positional arguments:
+ report - the report to append to
+ result - the result to append
+ """
target = result["target_name"]
toolchain = result["toolchain_name"]
id_name = result['id']
- result_wrap = { 0: result }
+ result_wrap = {0: result}
report[target][toolchain][id_name].append(result_wrap)
def get_config(src_paths, target, toolchain_name):
+ """Get the configuration object for a target-toolchain combination
+
+ Positional arguments:
+ src_paths - paths to scan for the configuration files
+ target - the device we are building for
+ toolchain_name - the string that identifies the build tools
+ """
# Convert src_paths to a list if needed
if type(src_paths) != ListType:
src_paths = [src_paths]
@@ -120,27 +153,33 @@
given version. Return False, 'reason' if a target is not part of the
official release for the given version.
- target_name: Name if the target (ex. 'K64F')
- version: The release version string. Should be a string contained within RELEASE_VERSIONS
+ Positional arguments:
+ target_name - Name if the target (ex. 'K64F')
+ version - The release version string. Should be a string contained within
+ RELEASE_VERSIONS
"""
-
+
result = True
reason = None
target = TARGET_MAP[target_name]
-
- if hasattr(target, 'release_versions') and version in target.release_versions:
+
+ if hasattr(target, 'release_versions') \
+ and version in target.release_versions:
if version == '2':
# For version 2, either ARM or uARM toolchain support is required
required_toolchains = set(['ARM', 'uARM'])
-
- if not len(required_toolchains.intersection(set(target.supported_toolchains))) > 0:
- result = False
+
+ if not len(required_toolchains.intersection(
+ set(target.supported_toolchains))) > 0:
+ result = False
reason = ("Target '%s' must support " % target.name) + \
- ("one of the folowing toolchains to be included in the mbed 2.0 ") + \
- (("official release: %s" + linesep) % ", ".join(required_toolchains)) + \
+ ("one of the folowing toolchains to be included in the") + \
+ ((" mbed 2.0 official release: %s" + linesep) %
+ ", ".join(required_toolchains)) + \
("Currently it is only configured to support the ") + \
- ("following toolchains: %s" % ", ".join(target.supported_toolchains))
-
+ ("following toolchains: %s" %
+ ", ".join(target.supported_toolchains))
+
elif version == '5':
# For version 5, ARM, GCC_ARM, and IAR toolchain support is required
required_toolchains = set(['ARM', 'GCC_ARM', 'IAR'])
@@ -149,45 +188,52 @@
supported_toolchains = set(target.supported_toolchains)
supported_toolchains_sorted = list(supported_toolchains)
supported_toolchains_sorted.sort()
-
+
if not required_toolchains.issubset(supported_toolchains):
result = False
reason = ("Target '%s' must support " % target.name) + \
- ("ALL of the folowing toolchains to be included in the mbed OS 5.0 ") + \
- (("official release: %s" + linesep) % ", ".join(required_toolchains_sorted)) + \
+ ("ALL of the folowing toolchains to be included in the") + \
+ ((" mbed OS 5.0 official release: %s" + linesep) %
+ ", ".join(required_toolchains_sorted)) + \
("Currently it is only configured to support the ") + \
- ("following toolchains: %s" % ", ".join(supported_toolchains_sorted))
+ ("following toolchains: %s" %
+ ", ".join(supported_toolchains_sorted))
- elif not target.default_build == 'standard':
+ elif not target.default_lib == 'std':
result = False
- reason = ("Target '%s' must set the 'default_build' " % target.name) + \
- ("to 'standard' to be included in the mbed OS 5.0 ") + \
- ("official release." + linesep) + \
- ("Currently it is set to '%s'" % target.default_build)
+ reason = ("Target '%s' must set the " % target.name) + \
+ ("'default_lib' to 'std' to be included in the ") + \
+ ("mbed OS 5.0 official release." + linesep) + \
+ ("Currently it is set to '%s'" % target.default_lib)
else:
result = False
- reason = ("Target '%s' has set an invalid release version of '%s'" % version) + \
- ("Please choose from the following release versions: %s" + ', '.join(RELEASE_VERSIONS))
+ reason = ("Target '%s' has set an invalid release version of '%s'" %
+ version) + \
+ ("Please choose from the following release versions: %s" %
+ ', '.join(RELEASE_VERSIONS))
else:
result = False
if not hasattr(target, 'release_versions'):
- reason = "Target '%s' does not have the 'release_versions' key set" % target.name
+ reason = "Target '%s' " % target.name
+ reason += "does not have the 'release_versions' key set"
elif not version in target.release_versions:
- reason = "Target '%s' does not contain the version '%s' in its 'release_versions' key" % (target.name, version)
-
+ reason = "Target '%s' does not contain the version '%s' " % \
+ (target.name, version)
+ reason += "in its 'release_versions' key"
+
return result, reason
def transform_release_toolchains(toolchains, version):
""" Given a list of toolchains and a release version, return a list of
only the supported toolchains for that release
- toolchains: The list of toolchains
- version: The release version string. Should be a string contained within RELEASE_VERSIONS
+ Positional arguments:
+ toolchains - The list of toolchains
+ version - The release version string. Should be a string contained within
+ RELEASE_VERSIONS
"""
- toolchains_set = set(toolchains)
-
if version == '5':
return ['ARM', 'GCC_ARM', 'IAR']
else:
@@ -197,41 +243,58 @@
def get_mbed_official_release(version):
""" Given a release version string, return a tuple that contains a target
and the supported toolchains for that release.
- Ex. Given '2', return (('LPC1768', ('ARM', 'GCC_ARM')), ('K64F', ('ARM', 'GCC_ARM')), ...)
+ Ex. Given '2', return (('LPC1768', ('ARM', 'GCC_ARM')),
+ ('K64F', ('ARM', 'GCC_ARM')), ...)
- version: The version string. Should be a string contained within RELEASE_VERSIONS
+ Positional arguments:
+ version - The version string. Should be a string contained within
+ RELEASE_VERSIONS
"""
- MBED_OFFICIAL_RELEASE = (
+ mbed_official_release = (
tuple(
tuple(
[
TARGET_MAP[target].name,
- tuple(transform_release_toolchains(TARGET_MAP[target].supported_toolchains, version))
+ tuple(transform_release_toolchains(
+ TARGET_MAP[target].supported_toolchains, version))
]
- ) for target in TARGET_NAMES if (hasattr(TARGET_MAP[target], 'release_versions') and version in TARGET_MAP[target].release_versions)
+ ) for target in TARGET_NAMES \
+ if (hasattr(TARGET_MAP[target], 'release_versions')
+ and version in TARGET_MAP[target].release_versions)
)
)
-
- for target in MBED_OFFICIAL_RELEASE:
+
+ for target in mbed_official_release:
is_official, reason = is_official_target(target[0], version)
-
+
if not is_official:
raise InvalidReleaseTargetException(reason)
-
- return MBED_OFFICIAL_RELEASE
+
+ return mbed_official_release
def prepare_toolchain(src_paths, target, toolchain_name,
- macros=None, options=None, clean=False, jobs=1,
- notify=None, silent=False, verbose=False, extra_verbose=False, config=None):
+ macros=None, options=None, clean=False, jobs=1,
+ notify=None, silent=False, verbose=False,
+ extra_verbose=False, config=None):
""" Prepares resource related objects - toolchain, target, config
- src_paths: the paths to source directories
- target: ['LPC1768', 'LPC11U24', 'LPC2368']
- toolchain_name: ['ARM', 'uARM', 'GCC_ARM', 'GCC_CR']
- clean: Rebuild everything if True
- notify: Notify function for logs
- verbose: Write the actual tools command lines if True
+
+ Positional arguments:
+ src_paths - the paths to source directories
+ target - ['LPC1768', 'LPC11U24', 'LPC2368', etc.]
+ toolchain_name - ['ARM', 'uARM', 'GCC_ARM', 'GCC_CR']
+
+ Keyword arguments:
+ macros - additional macros
+ options - general compiler options like debug-symbols or small-build
+ clean - Rebuild everything if True
+ jobs - how many compilers we can run at once
+ notify - Notify function for logs
+ silent - suppress printing of progress indicators
+ verbose - Write the actual tools command lines used if True
+ extra_verbose - even more output!
+ config - a Config object to use instead of creating one
"""
# We need to remove all paths which are repeated to avoid
@@ -250,8 +313,10 @@
# Toolchain instance
try:
- toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options, notify, macros, silent, extra_verbose=extra_verbose)
- except KeyError as e:
+ toolchain = TOOLCHAIN_CLASSES[toolchain_name](
+ target, options, notify, macros, silent,
+ extra_verbose=extra_verbose)
+ except KeyError:
raise KeyError("Toolchain %s not supported" % toolchain_name)
toolchain.config = config
@@ -261,12 +326,16 @@
return toolchain
-def scan_resources(src_paths, toolchain, dependencies_paths=None, inc_dirs=None):
+def scan_resources(src_paths, toolchain, dependencies_paths=None,
+ inc_dirs=None):
""" Scan resources using initialized toolcain
- src_paths: the paths to source directories
- toolchain: valid toolchain object
- dependencies_paths: dependency paths that we should scan for include dirs
- inc_dirs: additional include directories which should be added to thescanner resources
+
+ Positional arguments
+ src_paths - the paths to source directories
+ toolchain - valid toolchain object
+ dependencies_paths - dependency paths that we should scan for include dirs
+ inc_dirs - additional include directories which should be added to
+ the scanner resources
"""
# Scan src_path
@@ -287,7 +356,8 @@
else:
resources.inc_dirs.append(inc_dirs)
- # Load resources into the config system which might expand/modify resources based on config data
+ # Load resources into the config system which might expand/modify resources
+ # based on config data
resources = toolchain.config.load_resources(resources)
# Set the toolchain's configuration data
@@ -296,11 +366,38 @@
return resources
def build_project(src_paths, build_path, target, toolchain_name,
- libraries_paths=None, options=None, linker_script=None,
- clean=False, notify=None, verbose=False, name=None, macros=None, inc_dirs=None,
- jobs=1, silent=False, report=None, properties=None, project_id=None, project_description=None,
- extra_verbose=False, config=None):
- """ This function builds project. Project can be for example one test / UT
+ libraries_paths=None, options=None, linker_script=None,
+ clean=False, notify=None, verbose=False, name=None,
+ macros=None, inc_dirs=None, jobs=1, silent=False,
+ report=None, properties=None, project_id=None,
+ project_description=None, extra_verbose=False, config=None):
+ """ Build a project. A project may be a test or a user program.
+
+ Positional arguments:
+ src_paths - a path or list of paths that contain all files needed to build
+ the project
+ build_path - the directory where all of the object files will be placed
+ target - the MCU or board that the project will compile for
+ toolchain_name - the name of the build tools
+
+ Keyword arguments:
+ libraries_paths - The location of libraries to include when linking
+ options - general compiler options like debug-symbols or small-build
+ linker_script - the file that drives the linker to do it's job
+ clean - Rebuild everything if True
+ notify - Notify function for logs
+ verbose - Write the actual tools command lines used if True
+ name - the name of the project
+ macros - additional macros
+ inc_dirs - additional directories where include files may be found
+ jobs - how many compilers we can run at once
+ silent - suppress printing of progress indicators
+ report - a dict where a result may be appended
+ properties - UUUUHHHHH beats me
+ project_id - the name put in the report
+ project_description - the human-readable version of what this thing does
+ extra_verbose - even more output!
+ config - a Config object to use instead of creating one
"""
# Convert src_path to a list if needed
@@ -311,9 +408,8 @@
src_paths.extend(libraries_paths)
# Build Directory
- if clean:
- if exists(build_path):
- rmtree(build_path)
+ if clean and exists(build_path):
+ rmtree(build_path)
mkdir(build_path)
@@ -327,7 +423,7 @@
for path in src_paths:
profile = find_build_profile(path) or profile
if profile:
- targets_json = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'legacy_targets.json')
+ targets_json = join(dirname(abspath(__file__)), 'legacy_targets.json')
else:
targets_json = find_targets_json(path) or targets_json
@@ -355,14 +451,16 @@
mbedToolchain.init = init_hook
# Pass all params to the unified prepare_toolchain()
- toolchain = prepare_toolchain(src_paths, target, toolchain_name,
- macros=macros, options=options, clean=clean, jobs=jobs,
- notify=notify, silent=silent, verbose=verbose, extra_verbose=extra_verbose, config=config)
+ toolchain = prepare_toolchain(
+ src_paths, target, toolchain_name, macros=macros, options=options,
+ clean=clean, jobs=jobs, notify=notify, silent=silent, verbose=verbose,
+ extra_verbose=extra_verbose, config=config)
# The first path will give the name to the library
if name is None:
name = basename(normpath(abspath(src_paths[0])))
- toolchain.info("Building project %s (%s, %s)" % (name, toolchain.target.name, toolchain_name))
+ toolchain.info("Building project %s (%s, %s)" %
+ (name, toolchain.target.name, toolchain_name))
# Initialize reporting
if report != None:
@@ -372,9 +470,11 @@
description = project_description if project_description else name
vendor_label = toolchain.target.extra_labels[0]
prep_report(report, toolchain.target.name, toolchain_name, id_name)
- cur_result = create_result(toolchain.target.name, toolchain_name, id_name, description)
+ cur_result = create_result(toolchain.target.name, toolchain_name,
+ id_name, description)
if properties != None:
- prep_properties(properties, toolchain.target.name, toolchain_name, vendor_label)
+ prep_properties(properties, toolchain.target.name, toolchain_name,
+ vendor_label)
try:
# Call unified scan_resources
@@ -385,7 +485,8 @@
resources.linker_script = linker_script
# Compile Sources
- objects = toolchain.compile_sources(resources, build_path, resources.inc_dirs)
+ objects = toolchain.compile_sources(resources, build_path,
+ resources.inc_dirs)
resources.objects.extend(objects)
# Link Program
@@ -402,11 +503,11 @@
return res
- except Exception, e:
+ except Exception as exc:
if report != None:
end = time()
- if isinstance(e, NotSupportedException):
+ if isinstance(exc, NotSupportedException):
cur_result["result"] = "NOT_SUPPORTED"
else:
cur_result["result"] = "FAIL"
@@ -423,19 +524,37 @@
raise
def build_library(src_paths, build_path, target, toolchain_name,
- dependencies_paths=None, options=None, name=None, clean=False, archive=True,
- notify=None, verbose=False, macros=None, inc_dirs=None,
- jobs=1, silent=False, report=None, properties=None, extra_verbose=False,
- project_id=None):
- """ Prepares resource related objects - toolchain, target, config
- src_paths: the paths to source directories
- build_path: the path of the build directory
- target: ['LPC1768', 'LPC11U24', 'LPC2368']
- toolchain_name: ['ARM', 'uARM', 'GCC_ARM', 'GCC_CR']
- clean: Rebuild everything if True
- notify: Notify function for logs
- verbose: Write the actual tools command lines if True
- inc_dirs: additional include directories which should be included in build
+ dependencies_paths=None, options=None, name=None, clean=False,
+ archive=True, notify=None, verbose=False, macros=None,
+ inc_dirs=None, jobs=1, silent=False, report=None,
+ properties=None, extra_verbose=False, project_id=None,
+ remove_config_header_file=False):
+ """ Build a library
+
+ Positional arguments:
+ src_paths - a path or list of paths that contain all files needed to build
+ the library
+ build_path - the directory where all of the object files will be placed
+ target - the MCU or board that the project will compile for
+ toolchain_name - the name of the build tools
+
+ Keyword arguments:
+ dependencies_paths - The location of libraries to include when linking
+ options - general compiler options like debug-symbols or small-build
+ name - the name of the library
+ clean - Rebuild everything if True
+ archive - whether the library will create an archive file
+ notify - Notify function for logs
+ verbose - Write the actual tools command lines used if True
+ macros - additional macros
+ inc_dirs - additional directories where include files may be found
+ jobs - how many compilers we can run at once
+ silent - suppress printing of progress indicators
+ report - a dict where a result may be appended
+ properties - UUUUHHHHH beats me
+ extra_verbose - even more output!
+ project_id - the name that goes in the report
+ remove_config_header_file - delete config header file when done building
"""
# Convert src_path to a list if needed
@@ -450,15 +569,22 @@
else:
tmp_path = build_path
+ # Clean the build directory
+ if clean and exists(tmp_path):
+ rmtree(tmp_path)
+ mkdir(tmp_path)
+
# Pass all params to the unified prepare_toolchain()
- toolchain = prepare_toolchain(src_paths, target, toolchain_name,
- macros=macros, options=options, clean=clean, jobs=jobs,
- notify=notify, silent=silent, verbose=verbose, extra_verbose=extra_verbose)
+ toolchain = prepare_toolchain(
+ src_paths, target, toolchain_name, macros=macros, options=options,
+ clean=clean, jobs=jobs, notify=notify, silent=silent, verbose=verbose,
+ extra_verbose=extra_verbose)
# The first path will give the name to the library
if name is None:
name = basename(normpath(abspath(src_paths[0])))
- toolchain.info("Building library %s (%s, %s)" % (name, toolchain.target.name, toolchain_name))
+ toolchain.info("Building library %s (%s, %s)" %
+ (name, toolchain.target.name, toolchain_name))
# Initialize reporting
if report != None:
@@ -468,9 +594,11 @@
description = name
vendor_label = toolchain.target.extra_labels[0]
prep_report(report, toolchain.target.name, toolchain_name, id_name)
- cur_result = create_result(toolchain.target.name, toolchain_name, id_name, description)
+ cur_result = create_result(toolchain.target.name, toolchain_name,
+ id_name, description)
if properties != None:
- prep_properties(properties, toolchain.target.name, toolchain_name, vendor_label)
+ prep_properties(properties, toolchain.target.name, toolchain_name,
+ vendor_label)
for src_path in src_paths:
if not exists(src_path):
@@ -483,42 +611,57 @@
try:
# Call unified scan_resources
- resources = scan_resources(src_paths, toolchain, dependencies_paths=dependencies_paths, inc_dirs=inc_dirs)
+ resources = scan_resources(src_paths, toolchain,
+ dependencies_paths=dependencies_paths,
+ inc_dirs=inc_dirs)
- # Copy headers, objects and static libraries - all files needed for static lib
+ # Copy headers, objects and static libraries - all files needed for
+ # static lib
toolchain.copy_files(resources.headers, build_path, resources=resources)
toolchain.copy_files(resources.objects, build_path, resources=resources)
- toolchain.copy_files(resources.libraries, build_path, resources=resources)
+ toolchain.copy_files(resources.libraries, build_path,
+ resources=resources)
+ toolchain.copy_files(resources.json_files, build_path,
+ resources=resources)
if resources.linker_script:
- toolchain.copy_files(resources.linker_script, build_path, resources=resources)
+ toolchain.copy_files(resources.linker_script, build_path,
+ resources=resources)
if resources.hex_files:
- toolchain.copy_files(resources.hex_files, build_path, resources=resources)
+ toolchain.copy_files(resources.hex_files, build_path,
+ resources=resources)
# Compile Sources
- objects = toolchain.compile_sources(resources, abspath(tmp_path), resources.inc_dirs)
+ objects = toolchain.compile_sources(resources, abspath(tmp_path),
+ resources.inc_dirs)
resources.objects.extend(objects)
if archive:
toolchain.build_library(objects, build_path, name)
+ if remove_config_header_file:
+ config_header_path = toolchain.get_config_header()
+ if config_header_path:
+ remove(config_header_path)
+
if report != None:
end = time()
cur_result["elapsed_time"] = end - start
cur_result["output"] = toolchain.get_output()
cur_result["result"] = "OK"
+
add_result_to_report(report, cur_result)
return True
- except Exception, e:
+ except Exception as exc:
if report != None:
end = time()
- if isinstance(e, ToolException):
+ if isinstance(exc, ToolException):
cur_result["result"] = "FAIL"
- elif isinstance(e, NotSupportedException):
+ elif isinstance(exc, NotSupportedException):
cur_result["result"] = "NOT_SUPPORTED"
cur_result["elapsed_time"] = end - start
@@ -530,27 +673,47 @@
add_result_to_report(report, cur_result)
# Let Exception propagate
- raise e
+ raise
######################
### Legacy methods ###
######################
-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):
+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):
""" Legacy method for building mbed libraries
- Function builds library in proper directory using all dependencies and macros defined by user.
+
+ Positional arguments:
+ lib_id - the library's unique identifier
+ target - the MCU or board that the project will compile for
+ toolchain_name - the name of the build tools
+
+ Keyword arguments:
+ options - general compiler options like debug-symbols or small-build
+ clean - Rebuild everything if True
+ verbose - Write the actual tools command lines used if True
+ macros - additional macros
+ notify - Notify function for logs
+ jobs - how many compilers we can run at once
+ silent - suppress printing of progress indicators
+ report - a dict where a result may be appended
+ properties - UUUUHHHHH beats me
+ extra_verbose - even more output!
"""
lib = Library(lib_id)
if not lib.is_supported(target, toolchain_name):
- print 'Library "%s" is not yet supported on target %s with toolchain %s' % (lib_id, target.name, toolchain)
+ print('Library "%s" is not yet supported on target %s with toolchain %s'
+ % (lib_id, target.name, toolchain_name))
return False
- # We need to combine macros from parameter list with macros from library definition
- MACROS = lib.macros if lib.macros else []
+ # We need to combine macros from parameter list with macros from library
+ # definition
+ lib_macros = lib.macros if lib.macros else []
if macros:
- macros.extend(MACROS)
+ macros.extend(lib_macros)
else:
- macros = MACROS
+ macros = lib_macros
src_paths = lib.source_dir
build_path = lib.build_dir
@@ -558,17 +721,6 @@
inc_dirs = lib.inc_dirs
inc_dirs_ext = lib.inc_dirs_ext
- """ src_path: the path of the source directory
- build_path: the path of the build directory
- target: ['LPC1768', 'LPC11U24', 'LPC2368']
- toolchain: ['ARM', 'uARM', 'GCC_ARM', 'GCC_CR']
- library_paths: List of paths to additional libraries
- clean: Rebuild everything if True
- notify: Notify function for logs
- verbose: Write the actual tools command lines if True
- inc_dirs: additional include directories which should be included in build
- inc_dirs_ext: additional include directories which should be copied to library directory
- """
if type(src_paths) != ListType:
src_paths = [src_paths]
@@ -582,10 +734,12 @@
vendor_label = target.extra_labels[0]
cur_result = None
prep_report(report, target.name, toolchain_name, id_name)
- cur_result = create_result(target.name, toolchain_name, id_name, description)
+ cur_result = create_result(target.name, toolchain_name, id_name,
+ description)
if properties != None:
- prep_properties(properties, target.name, toolchain_name, vendor_label)
+ prep_properties(properties, target.name, toolchain_name,
+ vendor_label)
for src_path in src_paths:
if not exists(src_path):
@@ -600,12 +754,20 @@
try:
# Toolchain instance
- toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options, macros=macros, notify=notify, silent=silent, extra_verbose=extra_verbose)
+ toolchain = TOOLCHAIN_CLASSES[toolchain_name](
+ target, options, macros=macros, notify=notify, silent=silent,
+ extra_verbose=extra_verbose)
toolchain.VERBOSE = verbose
toolchain.jobs = jobs
toolchain.build_all = clean
- toolchain.info("Building library %s (%s, %s)" % (name.upper(), target.name, toolchain_name))
+ toolchain.info("Building library %s (%s, %s)" %
+ (name.upper(), target.name, toolchain_name))
+
+ # Take into account the library configuration (MBED_CONFIG_FILE)
+ config = Config(target)
+ toolchain.config = config
+ config.add_config_files([MBED_CONFIG_FILE])
# Scan Resources
resources = []
@@ -629,6 +791,11 @@
if inc_dirs:
dependencies_include_dir.extend(inc_dirs)
+ # Add other discovered configuration data to the configuration object
+ for res in resources:
+ config.load_resources(res)
+ toolchain.set_config_data(toolchain.config.get_config_data())
+
# Create the desired build directory structure
bin_path = join(build_path, toolchain.obj_path)
mkdir(bin_path)
@@ -637,14 +804,17 @@
# Copy Headers
for resource in resources:
- toolchain.copy_files(resource.headers, build_path, resources=resource)
+ toolchain.copy_files(resource.headers, build_path,
+ resources=resource)
- dependencies_include_dir.extend(toolchain.scan_resources(build_path).inc_dirs)
+ dependencies_include_dir.extend(
+ toolchain.scan_resources(build_path).inc_dirs)
# Compile Sources
objects = []
for resource in resources:
- objects.extend(toolchain.compile_sources(resource, tmp_path, dependencies_include_dir))
+ objects.extend(toolchain.compile_sources(resource, tmp_path,
+ dependencies_include_dir))
needed_update = toolchain.build_library(objects, bin_path, name)
@@ -657,7 +827,7 @@
add_result_to_report(report, cur_result)
return True
- except Exception, e:
+ except Exception:
if report != None:
end = time()
cur_result["result"] = "FAIL"
@@ -670,11 +840,32 @@
add_result_to_report(report, cur_result)
# Let Exception propagate
- raise e
+ raise
+
+# We do have unique legacy conventions about how we build and package the mbed
+# library
+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):
+ """ Function returns True is library was built and false if building was
+ skipped
-# We do have unique legacy conventions about how we build and package the mbed library
-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):
- """ Function returns True is library was built and false if building was skipped """
+ Positional arguments:
+ target - the MCU or board that the project will compile for
+ toolchain_name - the name of the build tools
+
+ Keyword arguments:
+ options - general compiler options like debug-symbols or small-build
+ verbose - Write the actual tools command lines used if True
+ clean - Rebuild everything if True
+ macros - additional macros
+ notify - Notify function for logs
+ jobs - how many compilers we can run at once
+ silent - suppress printing of progress indicators
+ report - a dict where a result may be appended
+ properties - UUUUHHHHH beats me
+ extra_verbose - even more output!
+ """
if report != None:
start = time()
@@ -683,16 +874,21 @@
vendor_label = target.extra_labels[0]
cur_result = None
prep_report(report, target.name, toolchain_name, id_name)
- cur_result = create_result(target.name, toolchain_name, id_name, description)
+ cur_result = create_result(target.name, toolchain_name, id_name,
+ description)
if properties != None:
- prep_properties(properties, target.name, toolchain_name, vendor_label)
+ prep_properties(properties, target.name, toolchain_name,
+ vendor_label)
# Check toolchain support
if toolchain_name not in target.supported_toolchains:
supported_toolchains_text = ", ".join(target.supported_toolchains)
- print '%s target is not yet supported by toolchain %s' % (target.name, toolchain_name)
- print '%s target supports %s toolchain%s' % (target.name, supported_toolchains_text, 's' if len(target.supported_toolchains) > 1 else '')
+ print('%s target is not yet supported by toolchain %s' %
+ (target.name, toolchain_name))
+ print('%s target supports %s toolchain%s' %
+ (target.name, supported_toolchains_text, 's'
+ if len(target.supported_toolchains) > 1 else ''))
if report != None:
cur_result["result"] = "SKIP"
@@ -702,69 +898,89 @@
try:
# Toolchain
- toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options, macros=macros, notify=notify, silent=silent, extra_verbose=extra_verbose)
+ toolchain = TOOLCHAIN_CLASSES[toolchain_name](
+ target, options, macros=macros, notify=notify, silent=silent,
+ extra_verbose=extra_verbose)
toolchain.VERBOSE = verbose
toolchain.jobs = jobs
toolchain.build_all = clean
+ # Take into account the library configuration (MBED_CONFIG_FILE)
+ config = Config(target)
+ toolchain.config = config
+ config.add_config_files([MBED_CONFIG_FILE])
+ toolchain.set_config_data(toolchain.config.get_config_data())
+
# Source and Build Paths
- BUILD_TARGET = join(MBED_LIBRARIES, "TARGET_" + target.name)
- BUILD_TOOLCHAIN = join(BUILD_TARGET, "TOOLCHAIN_" + toolchain.name)
- mkdir(BUILD_TOOLCHAIN)
+ build_target = join(MBED_LIBRARIES, "TARGET_" + target.name)
+ build_toolchain = join(build_target, "TOOLCHAIN_" + toolchain.name)
+ mkdir(build_toolchain)
- TMP_PATH = join(MBED_LIBRARIES, '.temp', toolchain.obj_path)
- mkdir(TMP_PATH)
+ tmp_path = join(MBED_LIBRARIES, '.temp', toolchain.obj_path)
+ mkdir(tmp_path)
# CMSIS
- toolchain.info("Building library %s (%s, %s)"% ('CMSIS', target.name, toolchain_name))
+ toolchain.info("Building library %s (%s, %s)" %
+ ('CMSIS', target.name, toolchain_name))
cmsis_src = join(MBED_TARGETS_PATH, "cmsis")
resources = toolchain.scan_resources(cmsis_src)
- toolchain.copy_files(resources.headers, BUILD_TARGET)
- toolchain.copy_files(resources.linker_script, BUILD_TOOLCHAIN)
- toolchain.copy_files(resources.bin_files, BUILD_TOOLCHAIN)
+ toolchain.copy_files(resources.headers, build_target)
+ toolchain.copy_files(resources.linker_script, build_toolchain)
+ toolchain.copy_files(resources.bin_files, build_toolchain)
- objects = toolchain.compile_sources(resources, TMP_PATH)
- toolchain.copy_files(objects, BUILD_TOOLCHAIN)
+ objects = toolchain.compile_sources(resources, tmp_path)
+ toolchain.copy_files(objects, build_toolchain)
# mbed
- toolchain.info("Building library %s (%s, %s)" % ('MBED', target.name, toolchain_name))
+ toolchain.info("Building library %s (%s, %s)" %
+ ('MBED', target.name, toolchain_name))
# Common Headers
- toolchain.copy_files(toolchain.scan_resources(MBED_API).headers, MBED_LIBRARIES)
- toolchain.copy_files(toolchain.scan_resources(MBED_HAL).headers, MBED_LIBRARIES)
+ toolchain.copy_files(toolchain.scan_resources(MBED_API).headers,
+ MBED_LIBRARIES)
+ toolchain.copy_files(toolchain.scan_resources(MBED_HAL).headers,
+ MBED_LIBRARIES)
# Target specific sources
- HAL_SRC = join(MBED_TARGETS_PATH, "hal")
- hal_implementation = toolchain.scan_resources(HAL_SRC)
- toolchain.copy_files(hal_implementation.headers + hal_implementation.hex_files + hal_implementation.libraries, BUILD_TARGET, resources=hal_implementation)
- incdirs = toolchain.scan_resources(BUILD_TARGET).inc_dirs
- objects = toolchain.compile_sources(hal_implementation, TMP_PATH, [MBED_LIBRARIES] + incdirs)
+ hal_src = join(MBED_TARGETS_PATH, "hal")
+ hal_implementation = toolchain.scan_resources(hal_src)
+ toolchain.copy_files(hal_implementation.headers +
+ hal_implementation.hex_files +
+ hal_implementation.libraries,
+ build_target, resources=hal_implementation)
+ incdirs = toolchain.scan_resources(build_target).inc_dirs
+ objects = toolchain.compile_sources(hal_implementation, tmp_path,
+ [MBED_LIBRARIES] + incdirs)
# Common Sources
mbed_resources = toolchain.scan_resources(MBED_COMMON)
- objects += toolchain.compile_sources(mbed_resources, TMP_PATH, [MBED_LIBRARIES] + incdirs)
+ objects += toolchain.compile_sources(mbed_resources, tmp_path,
+ [MBED_LIBRARIES] + incdirs)
# A number of compiled files need to be copied as objects as opposed to
- # being part of the mbed library, for reasons that have to do with the way
- # the linker search for symbols in archives. These are:
- # - retarget.o: to make sure that the C standard lib symbols get overridden
+ # being part of the mbed library, for reasons that have to do with the
+ # way the linker search for symbols in archives. These are:
+ # - retarget.o: to make sure that the C standard lib symbols get
+ # overridden
# - board.o: mbed_die is weak
- # - mbed_overrides.o: this contains platform overrides of various weak SDK functions
- separate_names, separate_objects = ['retarget.o', 'board.o', 'mbed_overrides.o'], []
+ # - mbed_overrides.o: this contains platform overrides of various
+ # weak SDK functions
+ separate_names, separate_objects = ['retarget.o', 'board.o',
+ 'mbed_overrides.o'], []
- for o in objects:
+ for obj in objects:
for name in separate_names:
- if o.endswith(name):
- separate_objects.append(o)
+ if obj.endswith(name):
+ separate_objects.append(obj)
- for o in separate_objects:
- objects.remove(o)
+ for obj in separate_objects:
+ objects.remove(obj)
- toolchain.build_library(objects, BUILD_TOOLCHAIN, "mbed")
+ toolchain.build_library(objects, build_toolchain, "mbed")
- for o in separate_objects:
- toolchain.copy_files(o, BUILD_TOOLCHAIN)
+ for obj in separate_objects:
+ toolchain.copy_files(obj, build_toolchain)
if report != None:
end = time()
@@ -776,7 +992,7 @@
return True
- except Exception, e:
+ except Exception as exc:
if report != None:
end = time()
cur_result["result"] = "FAIL"
@@ -786,18 +1002,21 @@
if toolchain_output:
cur_result["output"] += toolchain_output
- cur_result["output"] += str(e)
+ cur_result["output"] += str(exc)
add_result_to_report(report, cur_result)
# Let Exception propagate
- raise e
+ raise
def get_unique_supported_toolchains(release_targets=None):
""" Get list of all unique toolchains supported by targets
- If release_targets is not specified, then it queries all known targets
- release_targets: tuple structure returned from get_mbed_official_release()
+
+ Keyword arguments:
+ release_targets - tuple structure returned from get_mbed_official_release().
+ If release_targets is not specified, then it queries all
+ known targets
"""
unique_supported_toolchains = []
@@ -815,9 +1034,17 @@
return unique_supported_toolchains
-def mcu_toolchain_matrix(verbose_html=False, platform_filter=None, release_version='5'):
- """ Shows target map using prettytable """
- from prettytable import PrettyTable # Only use it in this function so building works without extra modules
+def mcu_toolchain_matrix(verbose_html=False, platform_filter=None,
+ release_version='5'):
+ """ Shows target map using prettytable
+
+ Keyword arguments:
+ verbose_html - emit html instead of a simple table
+ platform_filter - remove results that match the string
+ release_version - get the matrix for this major version number
+ """
+ # Only use it in this function so building works without extra modules
+ from prettytable import PrettyTable
if isinstance(release_version, basestring):
# Force release_version to lowercase if it is a string
@@ -832,23 +1059,26 @@
for version in RELEASE_VERSIONS:
version_release_targets[version] = get_mbed_official_release(version)
- version_release_target_names[version] = [x[0] for x in version_release_targets[version]]
+ version_release_target_names[version] = [x[0] for x in
+ version_release_targets[
+ version]]
if release_version in RELEASE_VERSIONS:
release_targets = version_release_targets[release_version]
else:
release_targets = None
- unique_supported_toolchains = get_unique_supported_toolchains(release_targets)
+ unique_supported_toolchains = get_unique_supported_toolchains(
+ release_targets)
prepend_columns = ["Target"] + ["mbed OS %s" % x for x in RELEASE_VERSIONS]
# All tests status table print
columns = prepend_columns + unique_supported_toolchains
- pt = PrettyTable(columns)
+ table_printer = PrettyTable(columns)
# Align table
for col in columns:
- pt.align[col] = "c"
- pt.align["Target"] = "l"
+ table_printer.align[col] = "c"
+ table_printer.align["Target"] = "l"
perm_counter = 0
target_counter = 0
@@ -884,9 +1114,10 @@
text = "-"
row.append(text)
- pt.add_row(row)
+ table_printer.add_row(row)
- result = pt.get_html_string() if verbose_html else pt.get_string()
+ result = table_printer.get_html_string() if verbose_html \
+ else table_printer.get_string()
result += "\n"
result += "Supported targets: %d\n"% (target_counter)
if target_counter == 1:
@@ -895,57 +1126,87 @@
def get_target_supported_toolchains(target):
- """ Returns target supported toolchains list """
- return TARGET_MAP[target].supported_toolchains if target in TARGET_MAP else None
+ """ Returns target supported toolchains list
+
+ Positional arguments:
+ target - the target to get the supported toolchains of
+ """
+ return TARGET_MAP[target].supported_toolchains if target in TARGET_MAP \
+ else None
-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):
+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):
+ """Perform static analysis on a target and toolchain combination
+
+ Positional arguments:
+ target - the target to fake the build for
+ toolchain_name - pretend you would compile with this toolchain
+ cppcheck_cmd - the command used to do static analysis
+ cppcheck_msg_format - the format of the check messages
+
+ Keyword arguments:
+ options - things like debug-symbols, or small-build, etc.
+ verbose - more printing!
+ clean - start from a clean slate
+ macros - extra macros to compile with
+ notify - the notification event handling function
+ jobs - number of commands to run at once
+ extra_verbose - even moar printing
+ """
# Toolchain
- toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options, macros=macros, notify=notify, extra_verbose=extra_verbose)
+ toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options,
+ macros=macros, notify=notify,
+ extra_verbose=extra_verbose)
toolchain.VERBOSE = verbose
toolchain.jobs = jobs
toolchain.build_all = clean
# Source and Build Paths
- BUILD_TARGET = join(MBED_LIBRARIES, "TARGET_" + target.name)
- BUILD_TOOLCHAIN = join(BUILD_TARGET, "TOOLCHAIN_" + toolchain.name)
- mkdir(BUILD_TOOLCHAIN)
+ build_target = join(MBED_LIBRARIES, "TARGET_" + target.name)
+ build_toolchain = join(build_target, "TOOLCHAIN_" + toolchain.name)
+ mkdir(build_toolchain)
- TMP_PATH = join(MBED_LIBRARIES, '.temp', toolchain.obj_path)
- mkdir(TMP_PATH)
+ tmp_path = join(MBED_LIBRARIES, '.temp', toolchain.obj_path)
+ mkdir(tmp_path)
# CMSIS
- toolchain.info("Static analysis for %s (%s, %s)" % ('CMSIS', target.name, toolchain_name))
+ toolchain.info("Static analysis for %s (%s, %s)" %
+ ('CMSIS', target.name, toolchain_name))
cmsis_src = join(MBED_TARGETS_PATH, "cmsis")
resources = toolchain.scan_resources(cmsis_src)
# Copy files before analysis
- toolchain.copy_files(resources.headers, BUILD_TARGET)
- toolchain.copy_files(resources.linker_script, BUILD_TOOLCHAIN)
+ toolchain.copy_files(resources.headers, build_target)
+ toolchain.copy_files(resources.linker_script, build_toolchain)
- # Gather include paths, c, cpp sources and macros to transfer to cppcheck command line
+ # Gather include paths, c, cpp sources and macros to transfer to cppcheck
+ # command line
includes = ["-I%s"% i for i in resources.inc_dirs]
- includes.append("-I%s"% str(BUILD_TARGET))
+ includes.append("-I%s"% str(build_target))
c_sources = " ".join(resources.c_sources)
cpp_sources = " ".join(resources.cpp_sources)
macros = ["-D%s"% s for s in toolchain.get_symbols() + toolchain.macros]
- includes = map(str.strip, includes)
- macros = map(str.strip, macros)
+ includes = [inc.strip() for inc in includes]
+ macros = [mac.strip() for mac in macros]
- check_cmd = CPPCHECK_CMD
- check_cmd += CPPCHECK_MSG_FORMAT
+ check_cmd = cppcheck_cmd
+ check_cmd += cppcheck_msg_format
check_cmd += includes
check_cmd += macros
- # We need to pass some params via file to avoid "command line too long in some OSs"
+ # We need to pass some params via file to avoid "command line too long in
+ # some OSs"
tmp_file = tempfile.NamedTemporaryFile(delete=False)
tmp_file.writelines(line + '\n' for line in c_sources.split())
tmp_file.writelines(line + '\n' for line in cpp_sources.split())
tmp_file.close()
check_cmd += ["--file-list=%s"% tmp_file.name]
- _stdout, _stderr, _rc = run_cmd(check_cmd)
+ _stdout, _stderr, _ = run_cmd(check_cmd)
if verbose:
print _stdout
print _stderr
@@ -953,50 +1214,58 @@
# =========================================================================
# MBED
- toolchain.info("Static analysis for %s (%s, %s)" % ('MBED', target.name, toolchain_name))
+ toolchain.info("Static analysis for %s (%s, %s)" %
+ ('MBED', target.name, toolchain_name))
# Common Headers
- toolchain.copy_files(toolchain.scan_resources(MBED_API).headers, MBED_LIBRARIES)
- toolchain.copy_files(toolchain.scan_resources(MBED_HAL).headers, MBED_LIBRARIES)
+ toolchain.copy_files(toolchain.scan_resources(MBED_API).headers,
+ MBED_LIBRARIES)
+ toolchain.copy_files(toolchain.scan_resources(MBED_HAL).headers,
+ MBED_LIBRARIES)
# Target specific sources
- HAL_SRC = join(MBED_TARGETS_PATH, "hal")
- hal_implementation = toolchain.scan_resources(HAL_SRC)
+ hal_src = join(MBED_TARGETS_PATH, "hal")
+ hal_implementation = toolchain.scan_resources(hal_src)
# Copy files before analysis
- toolchain.copy_files(hal_implementation.headers + hal_implementation.hex_files, BUILD_TARGET, resources=hal_implementation)
- incdirs = toolchain.scan_resources(BUILD_TARGET)
+ toolchain.copy_files(hal_implementation.headers +
+ hal_implementation.hex_files, build_target,
+ resources=hal_implementation)
+ incdirs = toolchain.scan_resources(build_target)
target_includes = ["-I%s" % i for i in incdirs.inc_dirs]
- target_includes.append("-I%s"% str(BUILD_TARGET))
- target_includes.append("-I%s"% str(HAL_SRC))
+ target_includes.append("-I%s"% str(build_target))
+ target_includes.append("-I%s"% str(hal_src))
target_c_sources = " ".join(incdirs.c_sources)
target_cpp_sources = " ".join(incdirs.cpp_sources)
- target_macros = ["-D%s"% s for s in toolchain.get_symbols() + toolchain.macros]
+ target_macros = ["-D%s"% s for s in
+ toolchain.get_symbols() + toolchain.macros]
# Common Sources
mbed_resources = toolchain.scan_resources(MBED_COMMON)
- # Gather include paths, c, cpp sources and macros to transfer to cppcheck command line
+ # Gather include paths, c, cpp sources and macros to transfer to cppcheck
+ # command line
mbed_includes = ["-I%s" % i for i in mbed_resources.inc_dirs]
- mbed_includes.append("-I%s"% str(BUILD_TARGET))
+ mbed_includes.append("-I%s"% str(build_target))
mbed_includes.append("-I%s"% str(MBED_COMMON))
mbed_includes.append("-I%s"% str(MBED_API))
mbed_includes.append("-I%s"% str(MBED_HAL))
mbed_c_sources = " ".join(mbed_resources.c_sources)
mbed_cpp_sources = " ".join(mbed_resources.cpp_sources)
- target_includes = map(str.strip, target_includes)
- mbed_includes = map(str.strip, mbed_includes)
- target_macros = map(str.strip, target_macros)
+ target_includes = [inc.strip() for inc in target_includes]
+ mbed_includes = [inc.strip() for inc in mbed_includes]
+ target_macros = [mac.strip() for mac in target_macros]
- check_cmd = CPPCHECK_CMD
- check_cmd += CPPCHECK_MSG_FORMAT
+ check_cmd = cppcheck_cmd
+ check_cmd += cppcheck_msg_format
check_cmd += target_includes
check_cmd += mbed_includes
check_cmd += target_macros
- # We need to pass some parames via file to avoid "command line too long in some OSs"
+ # We need to pass some parames via file to avoid "command line too long in
+ # some OSs"
tmp_file = tempfile.NamedTemporaryFile(delete=False)
tmp_file.writelines(line + '\n' for line in target_c_sources.split())
tmp_file.writelines(line + '\n' for line in target_cpp_sources.split())
@@ -1005,42 +1274,77 @@
tmp_file.close()
check_cmd += ["--file-list=%s"% tmp_file.name]
- _stdout, _stderr, _rc = run_cmd_ext(check_cmd)
+ _stdout, _stderr, _ = run_cmd_ext(check_cmd)
if verbose:
print _stdout
print _stderr
-def static_analysis_scan_lib(lib_id, target, toolchain, cppcheck_cmd, cppcheck_msg_format,
- options=None, verbose=False, clean=False, macros=None, notify=None, jobs=1, extra_verbose=False):
+def static_analysis_scan_lib(lib_id, target, toolchain, cppcheck_cmd,
+ cppcheck_msg_format, options=None, verbose=False,
+ clean=False, macros=None, notify=None, jobs=1,
+ extra_verbose=False):
+ """Perform static analysis on a library as if it were to be compiled for a
+ particular target and toolchain combination
+ """
lib = Library(lib_id)
if lib.is_supported(target, toolchain):
- static_analysis_scan_library(lib.source_dir, lib.build_dir, target, toolchain, cppcheck_cmd, cppcheck_msg_format,
- lib.dependencies, options,
- verbose=verbose, clean=clean, macros=macros, notify=notify, jobs=jobs, extra_verbose=extra_verbose)
+ static_analysis_scan_library(
+ lib.source_dir, lib.build_dir, target, toolchain, cppcheck_cmd,
+ cppcheck_msg_format, lib.dependencies, options, verbose=verbose,
+ clean=clean, macros=macros, notify=notify, jobs=jobs,
+ extra_verbose=extra_verbose)
else:
- print 'Library "%s" is not yet supported on target %s with toolchain %s'% (lib_id, target.name, toolchain)
+ print('Library "%s" is not yet supported on target %s with toolchain %s'
+ % (lib_id, target.name, toolchain))
-def static_analysis_scan_library(src_paths, build_path, target, toolchain_name, cppcheck_cmd, cppcheck_msg_format,
- dependencies_paths=None, options=None, name=None, clean=False,
- notify=None, verbose=False, macros=None, jobs=1, extra_verbose=False):
- """ Function scans library (or just some set of sources/headers) for staticly detectable defects """
+def static_analysis_scan_library(src_paths, build_path, target, toolchain_name,
+ cppcheck_cmd, cppcheck_msg_format,
+ dependencies_paths=None, options=None,
+ name=None, clean=False, notify=None,
+ verbose=False, macros=None, jobs=1,
+ extra_verbose=False):
+ """ Function scans library for statically detectable defects
+
+ Positional arguments:
+ src_paths - the list of library paths to scan
+ build_path - the location directory of result files
+ target - the target to fake the build for
+ toolchain_name - pretend you would compile with this toolchain
+ cppcheck_cmd - the command used to do static analysis
+ cppcheck_msg_format - the format of the check messages
+
+ Keyword arguments:
+ dependencies_paths - the paths to sources that this library depends on
+ options - things like debug-symbols, or small-build, etc.
+ name - the name of this library
+ clean - start from a clean slate
+ notify - the notification event handling function
+ verbose - more printing!
+ macros - extra macros to compile with
+ jobs - number of commands to run at once
+ extra_verbose - even moar printing
+ """
if type(src_paths) != ListType:
src_paths = [src_paths]
for src_path in src_paths:
if not exists(src_path):
- raise Exception("The library source folder does not exist: %s", src_path)
+ raise Exception("The library source folder does not exist: %s",
+ src_path)
# Toolchain instance
- toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options, macros=macros, notify=notify, extra_verbose=extra_verbose)
+ toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options,
+ macros=macros, notify=notify,
+ extra_verbose=extra_verbose)
toolchain.VERBOSE = verbose
toolchain.jobs = jobs
# The first path will give the name to the library
name = basename(src_paths[0])
- toolchain.info("Static analysis for library %s (%s, %s)" % (name.upper(), target.name, toolchain_name))
+ toolchain.info("Static analysis for library %s (%s, %s)" %
+ (name.upper(), target.name, toolchain_name))
# Scan Resources
resources = []
@@ -1060,7 +1364,8 @@
tmp_path = join(build_path, '.temp', toolchain.obj_path)
mkdir(tmp_path)
- # Gather include paths, c, cpp sources and macros to transfer to cppcheck command line
+ # Gather include paths, c, cpp sources and macros to transfer to cppcheck
+ # command line
includes = ["-I%s" % i for i in dependencies_include_dir + src_paths]
c_sources = " "
cpp_sources = " "
@@ -1073,34 +1378,42 @@
c_sources += " ".join(resource.c_sources) + " "
cpp_sources += " ".join(resource.cpp_sources) + " "
- dependencies_include_dir.extend(toolchain.scan_resources(build_path).inc_dirs)
+ dependencies_include_dir.extend(
+ toolchain.scan_resources(build_path).inc_dirs)
- includes = map(str.strip, includes)
- macros = map(str.strip, macros)
+ includes = [inc.strip() for inc in includes]
+ macros = [mac.strip() for mac in macros]
check_cmd = cppcheck_cmd
check_cmd += cppcheck_msg_format
check_cmd += includes
check_cmd += macros
- # We need to pass some parameters via file to avoid "command line too long in some OSs"
- # Temporary file is created to store e.g. cppcheck list of files for command line
+ # We need to pass some parameters via file to avoid "command line too long
+ # in some OSs". A temporary file is created to store e.g. cppcheck list of
+ # files for command line
tmp_file = tempfile.NamedTemporaryFile(delete=False)
tmp_file.writelines(line + '\n' for line in c_sources.split())
tmp_file.writelines(line + '\n' for line in cpp_sources.split())
tmp_file.close()
check_cmd += ["--file-list=%s"% tmp_file.name]
- # This will allow us to grab result from both stdio and stderr outputs (so we can show them)
- # We assume static code analysis tool is outputting defects on STDERR
- _stdout, _stderr, _rc = run_cmd_ext(check_cmd)
+ # This will allow us to grab result from both stdio and stderr outputs (so
+ # we can show them) We assume static code analysis tool is outputting
+ # defects on STDERR
+ _stdout, _stderr, _ = run_cmd_ext(check_cmd)
if verbose:
print _stdout
print _stderr
def print_build_results(result_list, build_name):
- """ Generate result string for build results """
+ """ Generate result string for build results
+
+ Positional arguments:
+ result_list - the list of results to print
+ build_name - the name of the build we are printing result for
+ """
result = ""
if len(result_list) > 0:
result += build_name + "\n"
@@ -1108,10 +1421,12 @@
result += "\n"
return result
-def print_build_memory_usage_results(report):
+def print_build_memory_usage(report):
""" Generate result table with memory usage values for build results
- Agregates (puts together) reports obtained from self.get_memory_summary()
- @param report Report generated during build procedure. See
+ Aggregates (puts together) reports obtained from self.get_memory_summary()
+
+ Positional arguments:
+ report - Report generated during build procedure.
"""
from prettytable import PrettyTable
columns_text = ['name', 'target', 'toolchain']
@@ -1129,21 +1444,25 @@
for name in report[target][toolchain]:
for dlist in report[target][toolchain][name]:
for dlistelem in dlist:
- # Get 'memory_usage' record and build table with statistics
+ # Get 'memory_usage' record and build table with
+ # statistics
record = dlist[dlistelem]
if 'memory_usage' in record and record['memory_usage']:
# Note that summary should be in the last record of
- # 'memory_usage' section. This is why we are grabbing
- # last "[-1]" record.
+ # 'memory_usage' section. This is why we are
+ # grabbing last "[-1]" record.
row = [
record['description'],
record['target_name'],
record['toolchain_name'],
- record['memory_usage'][-1]['summary']['static_ram'],
+ record['memory_usage'][-1]['summary'][
+ 'static_ram'],
record['memory_usage'][-1]['summary']['stack'],
record['memory_usage'][-1]['summary']['heap'],
- record['memory_usage'][-1]['summary']['total_ram'],
- record['memory_usage'][-1]['summary']['total_flash'],
+ record['memory_usage'][-1]['summary'][
+ 'total_ram'],
+ record['memory_usage'][-1]['summary'][
+ 'total_flash'],
]
table.add_row(row)
@@ -1152,6 +1471,14 @@
return result
def write_build_report(build_report, template_filename, filename):
+ """Write a build report to disk using a template file
+
+ Positional arguments:
+ build_report - a report generated by the build system
+ template_filename - a file that contains the template for the style of build
+ report
+ filename - the location on disk to write the file to
+ """
build_report_failing = []
build_report_passing = []
@@ -1165,5 +1492,7 @@
env.loader = FileSystemLoader('ci_templates')
template = env.get_template(template_filename)
- with open(filename, 'w+') as f:
- f.write(template.render(failing_builds=build_report_failing, passing_builds=build_report_passing))
+ with open(filename, 'w+') as placeholder:
+ placeholder.write(template.render(
+ failing_builds=build_report_failing,
+ passing_builds=build_report_passing))
