Merge pull request #750 from PrzemekWirkus/travis-linking

Tools: Travis - Simple mbed SDK test linking against popular libraries
pull/759/head
Martin Kojtal 2014-12-03 14:34:36 +00:00
commit a6279aa351
8 changed files with 139 additions and 58 deletions

View File

@ -122,6 +122,12 @@ if __name__ == '__main__':
default=False, default=False,
help="Verbose diagnostic output") help="Verbose diagnostic output")
parser.add_option("--silent",
action="store_true",
dest="silent",
default=False,
help="Silent diagnostic output (no copy, compile notification)")
parser.add_option("-x", "--extra-verbose-notifications", parser.add_option("-x", "--extra-verbose-notifications",
action="store_true", action="store_true",
dest="extra_verbose_notify", dest="extra_verbose_notify",
@ -213,14 +219,24 @@ if __name__ == '__main__':
tt_id = "%s::%s" % (toolchain, target) tt_id = "%s::%s" % (toolchain, target)
try: try:
mcu = TARGET_MAP[target] mcu = TARGET_MAP[target]
lib_build_res = build_mbed_libs(mcu, toolchain, options=options.options, lib_build_res = build_mbed_libs(mcu, toolchain,
notify=notify, verbose=options.verbose, jobs=options.jobs, clean=options.clean, options=options.options,
notify=notify,
verbose=options.verbose,
silent=options.silent,
jobs=options.jobs,
clean=options.clean,
macros=options.macros) macros=options.macros)
for lib_id in libraries: for lib_id in libraries:
notify = print_notify_verbose if options.extra_verbose_notify else None # Special notify for CI (more verbose) notify = print_notify_verbose if options.extra_verbose_notify else None # Special notify for CI (more verbose)
build_lib(lib_id, mcu, toolchain, options=options.options, build_lib(lib_id, mcu, toolchain,
notify=notify, verbose=options.verbose, clean=options.clean, options=options.options,
macros=options.macros, jobs=options.jobs) notify=notify,
verbose=options.verbose,
silent=options.silent,
clean=options.clean,
macros=options.macros,
jobs=options.jobs)
if lib_build_res: if lib_build_res:
successes.append(tt_id) successes.append(tt_id)
else: else:
@ -234,6 +250,7 @@ if __name__ == '__main__':
print e print e
# Write summary of the builds # Write summary of the builds
print
print "Completed in: (%.2f)s" % (time() - start) print "Completed in: (%.2f)s" % (time() - start)
print print

View File

@ -31,11 +31,11 @@ from workspace_tools.toolchains import TOOLCHAIN_CLASSES
def build_project(src_path, build_path, target, toolchain_name, def build_project(src_path, build_path, target, toolchain_name,
libraries_paths=None, options=None, linker_script=None, libraries_paths=None, options=None, linker_script=None,
clean=False, notify=None, verbose=False, name=None, macros=None, inc_dirs=None, jobs=1): clean=False, notify=None, verbose=False, name=None, macros=None, inc_dirs=None, jobs=1, silent=False):
""" This function builds project. Project can be for example one test / UT """ This function builds project. Project can be for example one test / UT
""" """
# Toolchain instance # Toolchain instance
toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options, notify, macros) toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options, notify, macros, silent)
toolchain.VERBOSE = verbose toolchain.VERBOSE = verbose
toolchain.jobs = jobs toolchain.jobs = jobs
toolchain.build_all = clean toolchain.build_all = clean
@ -92,7 +92,7 @@ def build_project(src_path, build_path, target, toolchain_name,
def build_library(src_paths, build_path, target, toolchain_name, def build_library(src_paths, build_path, target, toolchain_name,
dependencies_paths=None, options=None, name=None, clean=False, dependencies_paths=None, options=None, name=None, clean=False,
notify=None, verbose=False, macros=None, inc_dirs=None, inc_dirs_ext=None, jobs=1): notify=None, verbose=False, macros=None, inc_dirs=None, inc_dirs_ext=None, jobs=1, silent=False):
""" src_path: the path of the source directory """ src_path: the path of the source directory
build_path: the path of the build directory build_path: the path of the build directory
target: ['LPC1768', 'LPC11U24', 'LPC2368'] target: ['LPC1768', 'LPC11U24', 'LPC2368']
@ -112,7 +112,7 @@ def build_library(src_paths, build_path, target, toolchain_name,
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 instance
toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options, macros=macros, notify=notify) toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options, macros=macros, notify=notify, silent=silent)
toolchain.VERBOSE = verbose toolchain.VERBOSE = verbose
toolchain.jobs = jobs toolchain.jobs = jobs
toolchain.build_all = clean toolchain.build_all = clean
@ -162,7 +162,7 @@ def build_library(src_paths, build_path, target, toolchain_name,
toolchain.build_library(objects, bin_path, name) toolchain.build_library(objects, bin_path, name)
def build_lib(lib_id, target, toolchain, options=None, verbose=False, clean=False, macros=None, notify=None, jobs=1): def build_lib(lib_id, target, toolchain, options=None, verbose=False, clean=False, macros=None, notify=None, jobs=1, silent=False):
""" Wrapper for build_library function. """ Wrapper for build_library function.
Function builds library in proper directory using all dependencies and macros defined by user. Function builds library in proper directory using all dependencies and macros defined by user.
""" """
@ -175,6 +175,7 @@ def build_lib(lib_id, target, toolchain, options=None, verbose=False, clean=Fals
build_library(lib.source_dir, lib.build_dir, target, toolchain, lib.dependencies, options, build_library(lib.source_dir, lib.build_dir, target, toolchain, lib.dependencies, options,
verbose=verbose, verbose=verbose,
silent=silent,
clean=clean, clean=clean,
macros=MACROS, macros=MACROS,
notify=notify, notify=notify,
@ -186,7 +187,7 @@ def build_lib(lib_id, target, toolchain, options=None, verbose=False, clean=Fals
# We do have unique legacy conventions about how we build and package the mbed library # 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): def build_mbed_libs(target, toolchain_name, options=None, verbose=False, clean=False, macros=None, notify=None, jobs=1, silent=False):
""" Function returns True is library was built and false if building was skipped """ """ Function returns True is library was built and false if building was skipped """
# Check toolchain support # Check toolchain support
if toolchain_name not in target.supported_toolchains: if toolchain_name not in target.supported_toolchains:
@ -196,7 +197,7 @@ def build_mbed_libs(target, toolchain_name, options=None, verbose=False, clean=F
return False return False
# Toolchain # Toolchain
toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options, macros=macros, notify=notify) toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options, macros=macros, notify=notify, silent=silent)
toolchain.VERBOSE = verbose toolchain.VERBOSE = verbose
toolchain.jobs = jobs toolchain.jobs = jobs
toolchain.build_all = clean toolchain.build_all = clean

View File

@ -64,6 +64,22 @@ build_list = (
) )
################################################################################ ################################################################################
# Configure example test building (linking against external mbed SDK libraries liek fat or rtos)
linking_list = [
{"target": "LPC1768",
"toolchains": "GCC_ARM",
"tests": {"" : ["MBED_2", "MBED_10", "MBED_11", "MBED_15", "MBED_16", "MBED_17"],
"eth" : ["NET_1", "NET_2", "NET_3", "NET_4"],
"fat" : ["MBED_A12", "MBED_19", "PERF_1", "PERF_2", "PERF_3"],
"rtos" : ["RTOS_1", "RTOS_2", "RTOS_3"],
"usb" : ["USB_1", "USB_2" ,"USB_3"],
}
}
]
################################################################################
# Driver # Driver
def run_builds(dry_run): def run_builds(dry_run):
@ -71,7 +87,7 @@ def run_builds(dry_run):
toolchain_list = build["toolchains"] toolchain_list = build["toolchains"]
if type(toolchain_list) != type([]): toolchain_list = [toolchain_list] if type(toolchain_list) != type([]): toolchain_list = [toolchain_list]
for toolchain in toolchain_list: for toolchain in toolchain_list:
cmdline = "python workspace_tools/build.py -m %s -t %s -j 4 -c " % (build["target"], toolchain) cmdline = "python workspace_tools/build.py -m %s -t %s -j 4 -c --silent "% (build["target"], toolchain)
libs = build.get("libs", []) libs = build.get("libs", [])
if libs: if libs:
cmdline = cmdline + " ".join(["--" + l for l in libs]) cmdline = cmdline + " ".join(["--" + l for l in libs])
@ -80,5 +96,28 @@ def run_builds(dry_run):
if os.system(cmdline) != 0: if os.system(cmdline) != 0:
sys.exit(1) sys.exit(1)
def run_test_linking(dry_run):
""" Function run make.py commands to build and link simple mbed SDK
tests against few libraries to make sure there are no simple linking errors.
"""
for link in linking_list:
toolchain_list = link["toolchains"]
if type(toolchain_list) != type([]):
toolchain_list = [toolchain_list]
for toolchain in toolchain_list:
tests = link["tests"]
# Call make.py for each test group for particular library
for test_lib in tests:
test_names = tests[test_lib]
test_lib_switch = "--" + test_lib if test_lib else ""
cmdline = "python workspace_tools/make.py -m %s -t %s -c --silent %s -n %s " % (link["target"], toolchain, test_lib_switch, ",".join(test_names))
print "Executing: " + cmdline
if not dry_run:
if os.system(cmdline) != 0:
sys.exit(1)
if __name__ == "__main__": if __name__ == "__main__":
run_builds("-s" in sys.argv) run_builds("-s" in sys.argv)
run_test_linking("-s" in sys.argv)

View File

@ -49,15 +49,36 @@ except:
if __name__ == '__main__': if __name__ == '__main__':
# Parse Options # Parse Options
parser = get_default_options_parser() parser = get_default_options_parser()
parser.add_option("-p", type="int", dest="program", parser.add_option("-p",
type="int",
dest="program",
help="The index of the desired test program: [0-%d]" % (len(TESTS)-1)) help="The index of the desired test program: [0-%d]" % (len(TESTS)-1))
parser.add_option("-n", dest="program_name",
parser.add_option("-n",
dest="program_name",
help="The name of the desired test program") help="The name of the desired test program")
parser.add_option("-j", "--jobs", type="int", dest="jobs",
default=1, help="Number of concurrent jobs (default 1). Use 0 for auto based on host machine's number of CPUs") parser.add_option("-j", "--jobs",
parser.add_option("-v", "--verbose", action="store_true", dest="verbose", type="int",
default=False, help="Verbose diagnostic output") dest="jobs",
parser.add_option("-D", "", action="append", dest="macros", default=1,
help="Number of concurrent jobs (default 1). Use 0 for auto based on host machine's number of CPUs")
parser.add_option("-v", "--verbose",
action="store_true",
dest="verbose",
default=False,
help="Verbose diagnostic output")
parser.add_option("--silent",
action="store_true",
dest="silent",
default=False,
help="Silent diagnostic output (no copy, compile notification)")
parser.add_option("-D", "",
action="append",
dest="macros",
help="Add a macro definition") help="Add a macro definition")
# Local run # Local run
@ -219,6 +240,7 @@ if __name__ == '__main__':
linker_script=options.linker_script, linker_script=options.linker_script,
clean=options.clean, clean=options.clean,
verbose=options.verbose, verbose=options.verbose,
silent=options.silent,
macros=options.macros, macros=options.macros,
jobs=options.jobs) jobs=options.jobs)
print 'Image: %s'% bin_file print 'Image: %s'% bin_file

View File

@ -16,6 +16,7 @@ limitations under the License.
""" """
import re import re
import sys
from os import stat, walk from os import stat, walk
from copy import copy from copy import copy
from time import time, sleep from time import time, sleep
@ -33,8 +34,9 @@ import workspace_tools.hooks as hooks
#Disables multiprocessing if set to higher number than the host machine CPUs #Disables multiprocessing if set to higher number than the host machine CPUs
CPU_COUNT_MIN = 1 CPU_COUNT_MIN = 1
def print_notify(event): def print_notify(event, silent=False):
# Default command line notification """ Default command line notification
"""
if event['type'] in ['info', 'debug']: if event['type'] in ['info', 'debug']:
print event['message'] print event['message']
@ -44,11 +46,12 @@ def print_notify(event):
print '[%(severity)s] %(file)s@%(line)s: %(message)s' % event print '[%(severity)s] %(file)s@%(line)s: %(message)s' % event
elif event['type'] == 'progress': elif event['type'] == 'progress':
print '%s: %s' % (event['action'].title(), basename(event['file'])) if not silent:
print '%s: %s' % (event['action'].title(), basename(event['file']))
def print_notify_verbose(event, silent=False):
def print_notify_verbose(event): """ Default command line notification with more verbose mode
""" Default command line notification with more verbose mode """ """
if event['type'] in ['info', 'debug']: if event['type'] in ['info', 'debug']:
print_notify(event) # standard handle print_notify(event) # standard handle
@ -204,22 +207,16 @@ class mbedToolchain:
GOANNA_FORMAT = "[Goanna] warning [%FILENAME%:%LINENO%] - [%CHECKNAME%(%SEVERITY%)] %MESSAGE%" GOANNA_FORMAT = "[Goanna] warning [%FILENAME%:%LINENO%] - [%CHECKNAME%(%SEVERITY%)] %MESSAGE%"
GOANNA_DIAGNOSTIC_PATTERN = re.compile(r'"\[Goanna\] (?P<severity>warning) \[(?P<file>[^:]+):(?P<line>\d+)\] \- (?P<message>.*)"') GOANNA_DIAGNOSTIC_PATTERN = re.compile(r'"\[Goanna\] (?P<severity>warning) \[(?P<file>[^:]+):(?P<line>\d+)\] \- (?P<message>.*)"')
def __init__(self, target, options=None, notify=None, macros=None): def __init__(self, target, options=None, notify=None, macros=None, silent=False):
self.target = target self.target = target
self.name = self.__class__.__name__ self.name = self.__class__.__name__
self.hook = hooks.Hook(target, self) self.hook = hooks.Hook(target, self)
self.silent = silent
self.legacy_ignore_dirs = LEGACY_IGNORE_DIRS - set([target.name, LEGACY_TOOLCHAIN_NAMES[self.name]]) self.legacy_ignore_dirs = LEGACY_IGNORE_DIRS - set([target.name, LEGACY_TOOLCHAIN_NAMES[self.name]])
if notify is not None: self.notify_fun = notify if notify is not None else print_notify
self.notify = notify self.options = options if options is not None else []
else:
self.notify = print_notify
if options is None:
self.options = []
else:
self.options = options
self.macros = macros or [] self.macros = macros or []
self.options.extend(BUILD_OPTIONS) self.options.extend(BUILD_OPTIONS)
@ -240,6 +237,11 @@ class mbedToolchain:
self.mp_pool = None self.mp_pool = None
def notify(self, event):
""" Little closure for notify functions
"""
return self.notify_fun(event, self.silent)
def __exit__(self): def __exit__(self):
if self.mp_pool is not None: if self.mp_pool is not None:
self.mp_pool.terminate() self.mp_pool.terminate()

View File

@ -30,8 +30,8 @@ class ARM(mbedToolchain):
DIAGNOSTIC_PATTERN = re.compile('"(?P<file>[^"]+)", line (?P<line>\d+): (?P<severity>Warning|Error): (?P<message>.+)') DIAGNOSTIC_PATTERN = re.compile('"(?P<file>[^"]+)", line (?P<line>\d+): (?P<severity>Warning|Error): (?P<message>.+)')
DEP_PATTERN = re.compile('\S+:\s(?P<file>.+)\n') DEP_PATTERN = re.compile('\S+:\s(?P<file>.+)\n')
def __init__(self, target, options=None, notify=None, macros=None): def __init__(self, target, options=None, notify=None, macros=None, silent=False):
mbedToolchain.__init__(self, target, options, notify, macros) mbedToolchain.__init__(self, target, options, notify, macros, silent)
if target.core == "Cortex-M0+": if target.core == "Cortex-M0+":
cpu = "Cortex-M0" cpu = "Cortex-M0"
@ -147,8 +147,8 @@ class ARM(mbedToolchain):
self.default_cmd(args) self.default_cmd(args)
class ARM_STD(ARM): class ARM_STD(ARM):
def __init__(self, target, options=None, notify=None, macros=None): def __init__(self, target, options=None, notify=None, macros=None, silent=False):
ARM.__init__(self, target, options, notify, macros) ARM.__init__(self, target, options, notify, macros, silent)
self.cc += ["-D__ASSERT_MSG"] self.cc += ["-D__ASSERT_MSG"]
self.cppc += ["-D__ASSERT_MSG"] self.cppc += ["-D__ASSERT_MSG"]
self.ld.append("--libpath=%s" % ARM_LIB) self.ld.append("--libpath=%s" % ARM_LIB)
@ -157,8 +157,8 @@ class ARM_STD(ARM):
class ARM_MICRO(ARM): class ARM_MICRO(ARM):
PATCHED_LIBRARY = False PATCHED_LIBRARY = False
def __init__(self, target, options=None, notify=None, macros=None): def __init__(self, target, options=None, notify=None, macros=None, silent=False):
ARM.__init__(self, target, options, notify, macros) ARM.__init__(self, target, options, notify, macros, silent)
# Compiler # Compiler
self.asm += ["-D__MICROLIB"] self.asm += ["-D__MICROLIB"]

View File

@ -30,8 +30,8 @@ class GCC(mbedToolchain):
CIRCULAR_DEPENDENCIES = True CIRCULAR_DEPENDENCIES = True
DIAGNOSTIC_PATTERN = re.compile('((?P<line>\d+):)(\d+:)? (?P<severity>warning|error): (?P<message>.+)') DIAGNOSTIC_PATTERN = re.compile('((?P<line>\d+):)(\d+:)? (?P<severity>warning|error): (?P<message>.+)')
def __init__(self, target, options=None, notify=None, macros=None, tool_path=""): def __init__(self, target, options=None, notify=None, macros=None, silent=False, tool_path=""):
mbedToolchain.__init__(self, target, options, notify, macros) mbedToolchain.__init__(self, target, options, notify, macros, silent)
if target.core == "Cortex-M0+": if target.core == "Cortex-M0+":
cpu = "cortex-m0" cpu = "cortex-m0"
@ -170,8 +170,8 @@ class GCC(mbedToolchain):
class GCC_ARM(GCC): class GCC_ARM(GCC):
def __init__(self, target, options=None, notify=None, macros=None): def __init__(self, target, options=None, notify=None, macros=None, silent=False):
GCC.__init__(self, target, options, notify, macros, GCC_ARM_PATH) GCC.__init__(self, target, options, notify, macros, silent, GCC_ARM_PATH)
# Use latest gcc nanolib # Use latest gcc nanolib
self.ld.append("--specs=nano.specs") self.ld.append("--specs=nano.specs")
@ -182,8 +182,8 @@ class GCC_ARM(GCC):
class GCC_CR(GCC): class GCC_CR(GCC):
def __init__(self, target, options=None, notify=None, macros=None): def __init__(self, target, options=None, notify=None, macros=None, silent=False):
GCC.__init__(self, target, options, notify, macros, GCC_CR_PATH) GCC.__init__(self, target, options, notify, macros, silent, GCC_CR_PATH)
additional_compiler_flags = [ additional_compiler_flags = [
"-D__NEWLIB__", "-D__CODE_RED", "-D__USE_CMSIS", "-DCPP_USE_HEAP", "-D__NEWLIB__", "-D__CODE_RED", "-D__USE_CMSIS", "-DCPP_USE_HEAP",
@ -199,8 +199,8 @@ class GCC_CR(GCC):
class GCC_CS(GCC): class GCC_CS(GCC):
def __init__(self, target, options=None, notify=None, macros=None): def __init__(self, target, options=None, notify=None, macros=None, silent=False):
GCC.__init__(self, target, options, notify, macros, GCC_CS_PATH) GCC.__init__(self, target, options, notify, macros, silent, GCC_CS_PATH)
class GCC_CW(GCC): class GCC_CW(GCC):
@ -208,13 +208,13 @@ class GCC_CW(GCC):
"Cortex-M0+": "armv6-m", "Cortex-M0+": "armv6-m",
} }
def __init__(self, target, options=None, notify=None, macros=None): def __init__(self, target, options=None, notify=None, macros=None, silent=False):
GCC.__init__(self, target, options, notify, macros, CW_GCC_PATH) GCC.__init__(self, target, options, notify, macros, silent, CW_GCC_PATH)
class GCC_CW_EWL(GCC_CW): class GCC_CW_EWL(GCC_CW):
def __init__(self, target, options=None, notify=None, macros=None): def __init__(self, target, options=None, notify=None, macros=None, silent=False):
GCC_CW.__init__(self, target, options, notify, macros) GCC_CW.__init__(self, target, options, notify, macros, silent)
# Compiler # Compiler
common = [ common = [
@ -242,5 +242,5 @@ class GCC_CW_EWL(GCC_CW):
class GCC_CW_NEWLIB(GCC_CW): class GCC_CW_NEWLIB(GCC_CW):
def __init__(self, target, options=None, notify=None, macros=None): def __init__(self, target, options=None, notify=None, macros=None, silent=False):
GCC_CW.__init__(self, target, options, notify, macros) GCC_CW.__init__(self, target, options, notify, macros, silent)

View File

@ -30,8 +30,8 @@ class IAR(mbedToolchain):
DIAGNOSTIC_PATTERN = re.compile('"(?P<file>[^"]+)",(?P<line>[\d]+)\s+(?P<severity>Warning|Error)(?P<message>.+)') DIAGNOSTIC_PATTERN = re.compile('"(?P<file>[^"]+)",(?P<line>[\d]+)\s+(?P<severity>Warning|Error)(?P<message>.+)')
def __init__(self, target, options=None, notify=None, macros=None): def __init__(self, target, options=None, notify=None, macros=None, silent=False):
mbedToolchain.__init__(self, target, options, notify, macros) mbedToolchain.__init__(self, target, options, notify, macros, silent)
c_flags = [ c_flags = [
"--cpu=%s" % target.core, "--thumb", "--cpu=%s" % target.core, "--thumb",