Add tests to the config system. Add GCC flags to support uVisor

pull/1911/head
Mihail Stoyanov 2016-06-12 19:04:41 +01:00
parent 95c83935ac
commit 0034ffb716
64 changed files with 1507 additions and 5 deletions

239
tools/build_everything.py Normal file
View File

@ -0,0 +1,239 @@
#! /usr/bin/env python
"""
mbed SDK
Copyright (c) 2011-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import sys
from time import time
from os.path import join, abspath, dirname, normpath
from optparse import OptionParser
import json
# Be sure that the tools directory is in the search path
ROOT = abspath(join(dirname(__file__), ".."))
sys.path.insert(0, ROOT)
from tools.build_api import build_library
from tools.build_api import write_build_report
from tools.targets import TARGET_MAP, TARGET_NAMES
from tools.toolchains import TOOLCHAINS
from tools.test_exporters import ReportExporter, ResultExporterType
from tools.test_api import find_tests, build_tests, test_spec_from_test_builds
from tools.build_release import OFFICIAL_MBED_LIBRARY_BUILD
if __name__ == '__main__':
try:
parser = OptionParser()
parser.add_option("--source", dest="source_dir",
default=None, help="The source (input) directory (for sources other than tests). Defaults to current directory.", action="append")
parser.add_option("--build", dest="build_dir",
default=None, help="The build (output) directory")
parser.add_option('-c', '--clean',
dest='clean',
metavar=False,
action="store_true",
help='Clean the build directory')
parser.add_option('-a', '--all', dest="all", default=False, action="store_true",
help="Build every target (including unofficial targets) and with each of the supported toolchains")
parser.add_option('-o', '--official', dest="official_only", default=False, action="store_true",
help="Build using only the official toolchain for each target")
parser.add_option("-D", "",
action="append",
dest="macros",
help="Add a macro definition")
parser.add_option("-j", "--jobs", type="int", dest="jobs",
default=0, help="Number of concurrent jobs. Default: 0/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("-t", "--toolchains", dest="toolchains", help="Use toolchains names separated by comma")
parser.add_option("-p", "--platforms", dest="platforms", default="", help="Build only for the platform namesseparated by comma")
parser.add_option("", "--config", action="store_true", dest="list_config",
default=False, help="List the platforms and toolchains in the release in JSON")
parser.add_option("", "--test-spec", dest="test_spec",
default=None, help="Destination path for a test spec file that can be used by the Greentea automated test tool")
parser.add_option("", "--build-report-junit", dest="build_report_junit", help="Output the build results to an junit xml file")
parser.add_option("--continue-on-build-fail", action="store_true", dest="continue_on_build_fail",
default=False, help="Continue trying to build all tests if a build failure occurs")
options, args = parser.parse_args()
# Get set of valid targets
all_platforms = set(TARGET_NAMES)
bad_platforms = set()
platforms = set()
if options.platforms != "":
platforms = set(options.platforms.split(","))
bad_platforms = platforms.difference(all_platforms)
platforms = platforms.intersection(all_platforms)
elif options.all:
platforms = all_platforms
else:
platforms = set(x[0] for x in OFFICIAL_MBED_LIBRARY_BUILD)
bad_platforms = platforms.difference(all_platforms)
platforms = platforms.intersection(all_platforms)
for bad_platform in bad_platforms:
print "Platform '%s' is not a valid platform. Skipping." % bad_platform
if options.platforms:
print "Limiting build to the following platforms: %s" % ",".join(platforms)
# Get set of valid toolchains
all_toolchains = set(TOOLCHAINS)
bad_toolchains = set()
toolchains = set()
if options.toolchains:
toolchains = set(options.toolchains.split(","))
bad_toolchains = toolchains.difference(all_toolchains)
toolchains = toolchains.intersection(all_toolchains)
else:
toolchains = all_toolchains
for bad_toolchain in bad_toolchains:
print "Toolchain '%s' is not a valid toolchain. Skipping." % bad_toolchain
if options.toolchains:
print "Limiting build to the following toolchains: %s" % ",".join(toolchains)
build_config = {}
for platform in platforms:
target = TARGET_MAP[platform]
if options.official_only:
default_toolchain = getattr(target, 'default_toolchain', 'ARM')
build_config[platform] = list(toolchains.intersection(set([default_toolchain])))
else:
build_config[platform] = list(toolchains.intersection(set(target.supported_toolchains)))
if options.list_config:
print json.dumps(build_config, indent=4)
sys.exit(0)
# Ensure build directory is set
if not options.build_dir:
print "[ERROR] You must specify a build path"
sys.exit(1)
# Default base source path is the current directory
base_source_paths = options.source_dir
if not base_source_paths:
base_source_paths = ['.']
all_tests = find_tests(base_source_paths[0])
start = time()
build_report = {}
build_properties = {}
test_builds = {}
total_build_success = True
for target_name, target_toolchains in build_config.iteritems():
target = TARGET_MAP[target_name]
for target_toolchain in target_toolchains:
library_build_success = True
try:
build_directory = join(options.build_dir, target_name, target_toolchain)
# Build sources
build_library(base_source_paths, build_directory, target, target_toolchain,
jobs=options.jobs,
clean=options.clean,
report=build_report,
properties=build_properties,
name="mbed-os",
macros=options.macros,
verbose=options.verbose,
archive=False)
except Exception, e:
library_build_success = False
print "Failed to build library"
print e
if options.continue_on_build_fail or library_build_success:
# Build all the tests
test_build_success, test_build = build_tests(all_tests, [build_directory], build_directory, target, target_toolchain,
clean=options.clean,
report=build_report,
properties=build_properties,
macros=options.macros,
verbose=options.verbose,
jobs=options.jobs,
continue_on_build_fail=options.continue_on_build_fail)
if not test_build_success:
total_build_success = False
print "Failed to build some tests, check build log for details"
test_builds.update(test_build)
else:
total_build_success = False
break
# If a path to a test spec is provided, write it to a file
if options.test_spec:
test_spec_data = test_spec_from_test_builds(test_builds)
# Create the target dir for the test spec if necessary
# mkdir will not create the dir if it already exists
test_spec_dir = dirname(options.test_spec)
if test_spec_dir:
mkdir(test_spec_dir)
try:
with open(options.test_spec, 'w') as f:
f.write(json.dumps(test_spec_data, indent=2))
except IOError, e:
print "[ERROR] Error writing test spec to file"
print e
# If a path to a JUnit build report spec is provided, write it to a file
if options.build_report_junit:
report_exporter = ReportExporter(ResultExporterType.JUNIT)
report_exporter.report_to_file(build_report, options.build_report_junit, test_suite_properties=build_properties)
print "\n\nCompleted in: (%.2f)s" % (time() - start)
print_report_exporter = ReportExporter(ResultExporterType.PRINT, package="build")
status = print_report_exporter.report(build_report)
if status:
sys.exit(0)
else:
sys.exit(1)
except KeyboardInterrupt, e:
print "\n[CTRL+c] exit"
except Exception,e:
import traceback
traceback.print_exc(file=sys.stdout)
print "[ERROR] %s" % str(e)
sys.exit(1)

View File

@ -37,12 +37,11 @@ CPU = {% block cpu %}{% for cf in cpu_flags %}{{cf|replace("-mfloat-abi=softfp",
CC_FLAGS = {% block cc_flags %}$(CPU) -c -g -fno-common -fmessage-length=0 -Wall -Wextra -fno-exceptions -ffunction-sections -fdata-sections -fomit-frame-pointer -MMD -MP{% endblock %}
CC_SYMBOLS = {% block cc_symbols %}{% for s in symbols %}-D{{s}} {% endfor %}{% endblock %}
LD_FLAGS = {%- block ld_flags -%}
LD_FLAGS = {%- block ld_flags -%} $(CPU) -Wl,--gc-sections --specs=nano.specs -Wl,--wrap,main -Wl,-Map=$(PROJECT).map,--cref -Wl,--wrap,_malloc_r -Wl,--wrap,_free_r -Wl,--wrap,_realloc_r
{%- if "-mcpu=cortex-m0" in cpu_flags or "-mcpu=cortex-m0plus" in cpu_flags -%}
{{ ' ' }}$(CPU) -Wl,--gc-sections --specs=nano.specs -Wl,--wrap,main -Wl,-Map=$(PROJECT).map,--cref
#LD_FLAGS += -u _printf_float -u _scanf_float
{%- else -%}
{{ ' ' }}$(CPU) -Wl,--gc-sections --specs=nano.specs -u _printf_float -u _scanf_float -Wl,--wrap,main -Wl,-Map=$(PROJECT).map,--cref
{{ ' ' }}-u _printf_float -u _scanf_float
{%- endif -%}
{% endblock %}
LD_SYS_LIBS = {% block ld_sys_libs %}-lstdc++ -lsupc++ -lm -lc -lgcc -lnosys{% endblock %}

View File

@ -0,0 +1,94 @@
"""
mbed SDK
Copyright (c) 2011-2016 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from tools.build_api import get_config
from tools.config import ConfigException
import os, sys
# Compare the output of config against a dictionary of known good results
def compare_config(cfg, expected):
try:
for k in cfg:
if cfg[k].value != expected[k]:
return "'%s': expected '%s', got '%s'" % (k, expected[k], cfg[k].value)
except KeyError:
return "Unexpected key '%s' in configuration data" % k
for k in expected:
if k != "desc" and k != "expected_macros" and not k in cfg:
return "Expected key '%s' was not found in configuration data" % k
return ""
def test_tree(full_name, name):
failed = 0
sys.path.append(full_name)
if "test_data" in sys.modules:
del sys.modules["test_data"]
import test_data
for target, expected in test_data.expected_results.items():
sys.stdout.write("%s:'%s'(%s) " % (name, expected["desc"], target))
sys.stdout.flush()
err_msg = None
try:
cfg, macros = get_config(full_name, target, "GCC_ARM")
except ConfigException as e:
err_msg = e.message
if err_msg:
if expected.has_key("exception_msg"):
if err_msg.find(expected["exception_msg"]) == -1:
print "FAILED!"
sys.stderr.write(" Unexpected error message!\n")
sys.stderr.write(" Expected: '%s'\n" % expected["exception_msg"])
sys.stderr.write(" Got: '%s'\n" % err_msg)
failed += 1
else:
print "OK"
else:
print "FAILED!"
sys.stderr.write(" Error while getting configuration!\n")
sys.stderr.write(" " + err_msg + "\n")
failed += 1
else:
res = compare_config(cfg, expected)
if res:
print "FAILED!"
sys.stdout.write(" " + res + "\n")
failed += 1
else:
expected_macros = expected.get("expected_macros", None)
if expected_macros is not None:
if sorted(expected_macros) != sorted(macros):
print "FAILED!"
sys.stderr.write(" List of macros doesn't match\n")
sys.stderr.write(" Expected: '%s'\n" % ",".join(sorted(expected_macros)))
sys.stderr.write(" Got: '%s'\n" % ",".join(sorted(expected_macros)))
failed += 1
else:
print "OK"
else:
print "OK"
sys.path.remove(full_name)
return failed
failed = 0
root_dir = os.path.abspath(os.path.dirname(__file__))
tlist = sorted(os.listdir(root_dir), key = lambda e: int(e[4:]) if e.startswith('test') else -1)
for test_name in tlist:
full_name = os.path.join(root_dir, test_name)
if os.path.isdir(full_name) and test_name.startswith('test'):
failed += test_tree(full_name, test_name)
sys.exit(failed)

View File

@ -0,0 +1,43 @@
{
"custom_targets": {
"b1": {
"inherits": ["Target"],
"core": "Cortex-M0",
"config": {
"base1_1": "v_base1_1_b1",
"base1_2": "v_base1_2_b1",
"base1_3": "v_base1_3_b1"
}
},
"d1": {
"inherits": ["b1"],
"config": {
"derived1": "v_derived1_d1",
"derived2": "v_derived2_d1"
},
"overrides": {
"base1_1": "v_base1_1_d1",
"base1_2": "v_base1_2_d1"
}
},
"b2": {
"config": {
"base2_1": "v_base2_1_b2",
"base2_2": "v_base2_2_b2"
}
},
"f": {
"inherits": ["b2", "d1"],
"config": {
"f1_1": "v_f1_1_f",
"f1_2": "v_f1_2_f"
},
"overrides": {
"base2_1": "v_base2_1_f",
"base1_1": "v_base1_1_f",
"derived2": "v_derived2_f",
"f1_1": "v_f1_1_f_override"
}
}
}
}

View File

@ -0,0 +1,46 @@
# Test for configuration data defined in targets
# A base target (B1) defines 3 configuration parameters (base1_1, base1_2 and base1_3)
# A derived target (D1) inherits drom B1 and defines one configuration parameters (derived1 and derived2) and overrides base1_1 and base1_2
# Another base target (B2) defines its own configuration parameters (base2_1 and base2_2)
# The final target F derives from B2 and D1, defines two configuration paramaters (f1_1 and f1_2)
# and overrides base2_1, base1_1, derived2 and its own configuration parameter f1_1 (which is legal)
# Final result:
# base1_1 must have the value defined in F
# base1_2 must have the value defined in D1
# base1_3 must have the value defined in B1
# derived1 must have the value defined in D1
# derived2 must have the value defined in F
# base2_1 must have the value defined in F
# base2_2 must have the value defined in B2
# f1_1 must have the value defined and then overriden in F
# f1_2 must have the value defined in F
expected_results = {
"f": {
"desc": "test multiple target inheritance",
"target.base1_1": "v_base1_1_f",
"target.base1_2": "v_base1_2_d1",
"target.base1_3": "v_base1_3_b1",
"target.derived1": "v_derived1_d1",
"target.derived2": "v_derived2_f",
"target.base2_1": "v_base2_1_f",
"target.base2_2": "v_base2_2_b2",
"target.f1_1": "v_f1_1_f_override",
"target.f1_2": "v_f1_2_f"
},
"b1": {
"desc": "test with a single base target, no inheritance",
"target.base1_1": "v_base1_1_b1",
"target.base1_2": "v_base1_2_b1",
"target.base1_3": "v_base1_3_b1"
},
"d1": {
"desc": "test single target inheritance",
"target.base1_1": "v_base1_1_d1",
"target.base1_2": "v_base1_2_d1",
"target.base1_3": "v_base1_3_b1",
"target.derived1": "v_derived1_d1",
"target.derived2": "v_derived2_d1"
}
}

View File

@ -0,0 +1,47 @@
{
"custom_targets": {
"b1": {
"inherits": ["Target"],
"core": "Cortex-M0",
"config": {
"base1_1": "v_base1_1_b1",
"base1_2": "v_base1_2_b1",
"base1_3": "v_base1_3_b1"
}
},
"d1": {
"inherits": ["b1"],
"config": {
"derived1": "v_derived1_d1",
"derived2": "v_derived2_d1"
},
"overrides": {
"base1_1": "v_base1_1_d1",
"base1_2": "v_base1_2_d1"
}
},
"b2": {
"inherits": ["b1"],
"config": {
"base2_1": "v_base2_1_b2",
"base2_2": "v_base2_2_b2"
},
"overrides": {
"base1_2": "v_base1_2_b2"
}
},
"f": {
"inherits": ["d1", "b2"],
"config": {
"f1_1": "v_f1_1_f",
"f1_2": "v_f1_2_f"
},
"overrides": {
"base2_1": "v_base2_1_f",
"base1_1": "v_base1_1_f",
"derived2": "v_derived2_f",
"f1_1": "v_f1_1_f_override"
}
}
}
}

View File

@ -0,0 +1,30 @@
# This is similar to test1, but this time B2 also inherits from B1, which allows it to override its config data.
# B2 also overrides base1_2, like D1.
# The order of inheritace in F is also reversed ([D1, B2] instead of [B2, D1])
# Since the last override of base1_2 in inheritance order is in B2, base1_2 must now
# have the value that was overriden in B2, not in D1.
# This test also shows that multiple inheritance works for a simple diamond shaped inheritance pattern
expected_results = {
"f": {
"desc": "test multiple target inheritance (diamond shape)",
"target.base1_1": "v_base1_1_f",
"target.base1_2": "v_base1_2_b2",
"target.base1_3": "v_base1_3_b1",
"target.derived1": "v_derived1_d1",
"target.derived2": "v_derived2_f",
"target.base2_1": "v_base2_1_f",
"target.base2_2": "v_base2_2_b2",
"target.f1_1": "v_f1_1_f_override",
"target.f1_2": "v_f1_2_f"
},
"b2": {
"desc": "another single inheritance test",
"target.base1_1": "v_base1_1_b1",
"target.base1_2": "v_base1_2_b2",
"target.base1_3": "v_base1_3_b1",
"target.base2_1": "v_base2_1_b2",
"target.base2_2": "v_base2_2_b2"
}
}

View File

@ -0,0 +1,46 @@
{
"custom_targets": {
"b1": {
"inherits": ["Target"],
"core": "Cortex-M0",
"config": {
"base1_1": "v_base1_1_b1",
"base1_2": "v_base1_2_b1",
"base1_3": "v_base1_3_b1"
}
},
"d1": {
"inherits": ["b1"],
"config": {
"derived1": "v_derived1_d1",
"derived2": "v_derived2_d1"
},
"overrides": {
"base1_1": "v_base1_1_d1",
"base1_2": "v_base1_2_d1"
}
},
"b2": {
"config": {
"base2_1": "v_base2_1_b2",
"base2_2": "v_base2_2_b2"
},
"overrides": {
"base1_1": "v_base1_1_b2"
}
},
"f": {
"inherits": ["b2", "d1"],
"config": {
"f1_1": "v_f1_1_f",
"f1_2": "v_f1_2_f"
},
"overrides": {
"base2_1": "v_base2_1_f",
"base1_1": "v_base1_1_f",
"derived2": "v_derived2_f",
"f1_1": "v_f1_1_f_override"
}
}
}
}

View File

@ -0,0 +1,18 @@
# Similar to test1, but this time B2 attempt to override base1_1. Since B2 doesn't directly inherit
# from B1, this must raise an error
expected_results = {
"f": {
"desc": "attempt to override undefined parameter in inherited target",
"exception_msg": "Attempt to override undefined parameter 'base1_1' in 'target:b2'"
},
"d1": {
"desc": "single target inheritance again",
"target.base1_1": "v_base1_1_d1",
"target.base1_2": "v_base1_2_d1",
"target.base1_3": "v_base1_3_b1",
"target.derived1": "v_derived1_d1",
"target.derived2": "v_derived2_d1"
}
}

View File

@ -0,0 +1,46 @@
{
"custom_targets": {
"b1": {
"inherits": ["Target"],
"core": "Cortex-M0",
"config": {
"base1_1": "v_base1_1_b1",
"base1_2": "v_base1_2_b1",
"base1_3": "v_base1_3_b1"
}
},
"d1": {
"inherits": ["b1"],
"config": {
"derived1": "v_derived1_d1",
"derived2": "v_derived2_d1"
},
"overrides": {
"base1_1": "v_base1_1_d1",
"base1_2": "v_base1_2_d1"
}
},
"b2": {
"inherits": ["Target"],
"core": "Cortex-M0",
"config": {
"base2_1": "v_base2_1_b2",
"base2_2": "v_base2_2_b2",
"base1_1": "v_base1_1_b2"
}
},
"f": {
"inherits": ["b2", "d1"],
"config": {
"f1_1": "v_f1_1_f",
"f1_2": "v_f1_2_f"
},
"overrides": {
"base2_1": "v_base2_1_f",
"base1_1": "v_base1_1_f",
"derived2": "v_derived2_f",
"f1_1": "v_f1_1_f_override"
}
}
}
}

View File

@ -0,0 +1,18 @@
# Similar to test1, but this time B2 attempt to define base1_1. Since base1_1
# is already defined in B1 and F derives from both B1 and B2, this results
# in an error. However, when building for B2 instead of F, defining base1_1
# should be OK.
expected_results = {
"f": {
"desc": "attempt to redefine parameter in target inheritance tree",
"exception_msg": "Parameter name 'base1_1' defined in both 'target:b2' and 'target:b1'"
},
"b2": {
"desc": "it should be OK to define parameters with the same name in non-related targets",
"target.base2_1": "v_base2_1_b2",
"target.base2_2": "v_base2_2_b2",
"target.base1_1": "v_base1_1_b2"
}
}

View File

@ -0,0 +1,35 @@
{
"custom_targets": {
"base": {
"inherits": ["Target"],
"core": "Cortex-M0"
},
"b1": {
"inherits": ["base"],
"extra_labels_add": ["b1_label"]
},
"b2": {
"inherits": ["base"],
"extra_labels_add": ["b2_label"]
},
"both": {
"inherits": ["b1", "b2"]
}
},
"config": {
"app1": "v_app1",
"app2": "v_app2"
},
"target_overrides": {
"b1_label": {
"app1": "v_app1[b1_label]"
},
"b2_label": {
"app2": "v_app2[b2_label]"
},
"dummy_label": {
"app1": "dummy.app1",
"app2": "dummy.app2"
}
}
}

View File

@ -0,0 +1,29 @@
# This tests overriding configuration values based on target labels.
# Four targets are defined:
# - "base" is the base target, it doesn't define any extra labels
# - "b1" inherits from "base" and adds the "b1_label" label
# - "b2" inherits from "base" and adds the "b2_label" label
# - "both" inherits from both "b1" and "b2", so it inherits both labels
expected_results = {
"b1": {
"desc": "override values based on labels (first label)",
"app.app1": "v_app1[b1_label]",
"app.app2": "v_app2"
},
"b2": {
"desc": "override values based on labels (second label)",
"app.app1": "v_app1",
"app.app2": "v_app2[b2_label]"
},
"both": {
"desc": "override values based on labels (both labels)",
"app.app1": "v_app1[b1_label]",
"app.app2": "v_app2[b2_label]"
},
"base": {
"desc": "override values based on labels (no labels)",
"app.app1": "v_app1",
"app.app2": "v_app2"
}
}

View File

@ -0,0 +1,17 @@
{
"name": "lib2",
"config": {
"p1": "v_p1_lib2",
"p2": "v_p2_lib2"
},
"target_overrides": {
"b1_label": {
"p1": "v_p1_lib2[b1_label]",
"p2": "v_p2_lib2[b1_label]"
},
"b2_label": {
"p1": "v_p1_lib2[b2_label]",
"p2": "v_p2_lib2[b2_label]"
}
}
}

View File

@ -0,0 +1,16 @@
{
"name": "lib1",
"config": {
"p1": "v_p1_lib1",
"p2": "v_p2_lib1",
"p3": "v_p3_lib1"
},
"target_overrides": {
"b1_label": {
"p1": "v_p1_lib1[b1_label]"
},
"b2_label": {
"p2": "v_p2_lib1[b2_label]"
}
}
}

View File

@ -0,0 +1,31 @@
{
"custom_targets": {
"base": {
"inherits": ["Target"],
"core": "Cortex-M0"
},
"b1": {
"inherits": ["base"],
"extra_labels_add": ["b1_label"]
},
"b2": {
"inherits": ["base"],
"extra_labels_add": ["b2_label"]
},
"both": {
"inherits": ["b1", "b2"]
}
},
"config": {
"app1": "v_app1",
"app2": "v_app2"
},
"target_overrides": {
"b1_label": {
"app1": "v_app1[b1_label]"
},
"b2_label": {
"app2": "v_app2[b2_label]"
}
}
}

View File

@ -0,0 +1,49 @@
# This build on top of test5 by adding a few libraries with their own configurations
# and overrides. The same targets are used for building and testing (base, b1, b2, both)
expected_results = {
"base": {
"desc": "override values based on labels with libs (no labels)",
"app.app1": "v_app1",
"app.app2": "v_app2",
"lib1.p1": "v_p1_lib1",
"lib1.p2": "v_p2_lib1",
"lib1.p3": "v_p3_lib1",
"lib2.p1": "v_p1_lib2",
"lib2.p2": "v_p2_lib2"
},
"b1": {
"desc": "override values based on labels with libs (first label)",
"app.app1": "v_app1[b1_label]",
"app.app2": "v_app2",
"lib1.p1": "v_p1_lib1[b1_label]",
"lib1.p2": "v_p2_lib1",
"lib1.p3": "v_p3_lib1",
"lib2.p1": "v_p1_lib2[b1_label]",
"lib2.p2": "v_p2_lib2[b1_label]"
},
"b2": {
"desc": "override values based on labels with libs (second label)",
"app.app1": "v_app1",
"app.app2": "v_app2[b2_label]",
"lib1.p1": "v_p1_lib1",
"lib1.p2": "v_p2_lib1[b2_label]",
"lib1.p3": "v_p3_lib1",
"lib2.p1": "v_p1_lib2[b2_label]",
"lib2.p2": "v_p2_lib2[b2_label]"
},
# The values for lib2.p1 and lib2.p2 illustrate how overriding on multiple
# labels work. In lib2, both lib2.p1 and lib2.p2 are overriden for both
# labels (b1_label and b2_label). However, since "b2_label" is specified
# after "b1_label", it sets the final values of the overrides.
"both": {
"desc": "override values based on labels with libs (both labels)",
"app.app1": "v_app1[b1_label]",
"app.app2": "v_app2[b2_label]",
"lib1.p1": "v_p1_lib1[b1_label]",
"lib1.p2": "v_p2_lib1[b2_label]",
"lib1.p3": "v_p3_lib1",
"lib2.p1": "v_p1_lib2[b2_label]",
"lib2.p2": "v_p2_lib2[b2_label]"
},
}

View File

@ -0,0 +1,17 @@
{
"name": "lib2",
"config": {
"p1": "v_p1_lib2",
"p2": "v_p2_lib2"
},
"target_overrides": {
"b1_label": {
"p1": "v_p1_lib2[b1_label]",
"p2": "v_p2_lib2[b1_label]"
},
"b2_label": {
"p1": "v_p1_lib2[b2_label]",
"p2": "v_p2_lib2[b2_label]"
}
}
}

View File

@ -0,0 +1,16 @@
{
"name": "lib1",
"config": {
"p1": "v_p1_lib1",
"p2": "v_p2_lib1",
"p3": "v_p3_lib1"
},
"target_overrides": {
"b1_label": {
"p1": "v_p1_lib1[b1_label]"
},
"b2_label": {
"p2": "v_p2_lib1[b2_label]"
}
}
}

View File

@ -0,0 +1,36 @@
{
"custom_targets": {
"base": {
"inherits": ["Target"],
"core": "Cortex-M0"
},
"b1": {
"inherits": ["base"],
"extra_labels_add": ["b1_label"]
},
"b2": {
"inherits": ["base"],
"extra_labels_add": ["b2_label"]
},
"both": {
"inherits": ["b1", "b2"]
}
},
"config": {
"app1": "v_app1",
"app2": "v_app2"
},
"target_overrides": {
"*": {
"lib1.p3": "v_p3_lib1_app",
"lib1.p1": "v_p1_lib1_app",
"lib2.p1": "v_p1_lib2_app"
},
"b1_label": {
"app1": "v_app1[b1_label]"
},
"b2_label": {
"app2": "v_app2[b2_label]"
}
}
}

View File

@ -0,0 +1,48 @@
# This build on top of test6 by adding overrides for libs in the application
expected_results = {
"base": {
"desc": "override values based on labels with libs (no labels)",
"app.app1": "v_app1",
"app.app2": "v_app2",
"lib1.p1": "v_p1_lib1_app",
"lib1.p2": "v_p2_lib1",
"lib1.p3": "v_p3_lib1_app",
"lib2.p1": "v_p1_lib2_app",
"lib2.p2": "v_p2_lib2"
},
"b1": {
"desc": "override values based on labels with libs (first label)",
"app.app1": "v_app1[b1_label]",
"app.app2": "v_app2",
"lib1.p1": "v_p1_lib1_app",
"lib1.p2": "v_p2_lib1",
"lib1.p3": "v_p3_lib1_app",
"lib2.p1": "v_p1_lib2_app",
"lib2.p2": "v_p2_lib2[b1_label]"
},
"b2": {
"desc": "override values based on labels with libs (second label)",
"app.app1": "v_app1",
"app.app2": "v_app2[b2_label]",
"lib1.p1": "v_p1_lib1_app",
"lib1.p2": "v_p2_lib1[b2_label]",
"lib1.p3": "v_p3_lib1_app",
"lib2.p1": "v_p1_lib2_app",
"lib2.p2": "v_p2_lib2[b2_label]"
},
# The values for lib2.p1 and lib2.p2 illustrate how overriding on multiple
# labels work. In lib2, both lib2.p1 and lib2.p2 are overriden for both
# labels (b1_label and b2_label). However, since "b2_label" is specified
# after "b1_label", it sets the final values of the overrides.
"both": {
"desc": "override values based on labels with libs (both labels)",
"app.app1": "v_app1[b1_label]",
"app.app2": "v_app2[b2_label]",
"lib1.p1": "v_p1_lib1_app",
"lib1.p2": "v_p2_lib1[b2_label]",
"lib1.p3": "v_p3_lib1_app",
"lib2.p1": "v_p1_lib2_app",
"lib2.p2": "v_p2_lib2[b2_label]"
}
}

View File

@ -0,0 +1,17 @@
{
"name": "lib2",
"config": {
"p1": "v_p1_lib2",
"p2": "v_p2_lib2"
},
"target_overrides": {
"b1_label": {
"p1": "v_p1_lib2[b1_label]",
"p2": "v_p2_lib2[b1_label]"
},
"b2_label": {
"p1": "v_p1_lib2[b2_label]",
"p2": "v_p2_lib2[b2_label]"
}
}
}

View File

@ -0,0 +1,16 @@
{
"name": "lib1",
"config": {
"p1": "v_p1_lib1",
"p2": "v_p2_lib1",
"p3": "v_p3_lib1"
},
"target_overrides": {
"b1_label": {
"p1": "v_p1_lib1[b1_label]"
},
"b2_label": {
"p2": "v_p2_lib1[b2_label]"
}
}
}

View File

@ -0,0 +1,54 @@
{
"custom_targets": {
"base": {
"inherits": ["Target"],
"core": "Cortex-M0",
"config": {
"par1": "v_par1_base",
"par2": "v_par2_base",
"par3": "v_par3_base"
}
},
"b1": {
"inherits": ["base"],
"extra_labels_add": ["b1_label"],
"overrides": {
"par1": "v_par1_b1"
}
},
"b2": {
"inherits": ["base"],
"extra_labels_add": ["b2_label"],
"overrides": {
"par2": "v_par2_b2"
}
},
"both": {
"inherits": ["b1", "b2"],
"config": {
"par4": "v_par4_both"
},
"overrides": {
"par3": "v_par3_both"
}
}
},
"config": {
"app1": "v_app1",
"app2": "v_app2"
},
"target_overrides": {
"*": {
"lib1.p3": "v_p3_lib1_app",
"lib1.p1": "v_p1_lib1_app",
"lib2.p1": "v_p1_lib2_app",
"target.par1": "v_par1_target_app"
},
"b1_label": {
"app1": "v_app1[b1_label]"
},
"b2_label": {
"app2": "v_app2[b2_label]"
}
}
}

View File

@ -0,0 +1,58 @@
# This build on top of test7 by adding some configuration values in targets
# and overriding them in the application
expected_results = {
"base": {
"desc": "override values based on labels with libs and target params (no labels)",
"app.app1": "v_app1",
"app.app2": "v_app2",
"lib1.p1": "v_p1_lib1_app",
"lib1.p2": "v_p2_lib1",
"lib1.p3": "v_p3_lib1_app",
"lib2.p1": "v_p1_lib2_app",
"lib2.p2": "v_p2_lib2",
"target.par1": "v_par1_target_app",
"target.par2": "v_par2_base",
"target.par3": "v_par3_base"
},
"b1": {
"desc": "override values based on labels with libs and target params (first label)",
"app.app1": "v_app1[b1_label]",
"app.app2": "v_app2",
"lib1.p1": "v_p1_lib1_app",
"lib1.p2": "v_p2_lib1",
"lib1.p3": "v_p3_lib1_app",
"lib2.p1": "v_p1_lib2_app",
"lib2.p2": "v_p2_lib2[b1_label]",
"target.par1": "v_par1_target_app",
"target.par2": "v_par2_base",
"target.par3": "v_par3_base"
},
"b2": {
"desc": "override values based on labels with libs and target params (second label)",
"app.app1": "v_app1",
"app.app2": "v_app2[b2_label]",
"lib1.p1": "v_p1_lib1_app",
"lib1.p2": "v_p2_lib1[b2_label]",
"lib1.p3": "v_p3_lib1_app",
"lib2.p1": "v_p1_lib2_app",
"lib2.p2": "v_p2_lib2[b2_label]",
"target.par1": "v_par1_target_app",
"target.par2": "v_par2_b2",
"target.par3": "v_par3_base"
},
"both": {
"desc": "override values based on labels with libs and target params (both labels)",
"app.app1": "v_app1[b1_label]",
"app.app2": "v_app2[b2_label]",
"lib1.p1": "v_p1_lib1_app",
"lib1.p2": "v_p2_lib1[b2_label]",
"lib1.p3": "v_p3_lib1_app",
"lib2.p1": "v_p1_lib2_app",
"lib2.p2": "v_p2_lib2[b2_label]",
"target.par1": "v_par1_target_app",
"target.par2": "v_par2_b2",
"target.par3": "v_par3_both",
"target.par4": "v_par4_both"
}
}

View File

@ -0,0 +1,17 @@
{
"name": "lib2",
"config": {
"p1": "v_p1_lib2",
"p2": "v_p2_lib2"
},
"target_overrides": {
"b1_label": {
"p1": "v_p1_lib2[b1_label]",
"p2": "v_p2_lib2[b1_label]"
},
"b2_label": {
"p1": "v_p1_lib2[b2_label]",
"p2": "v_p2_lib2[b2_label]"
}
}
}

View File

@ -0,0 +1,16 @@
{
"name": "lib1",
"config": {
"p1": "v_p1_lib1",
"p2": "v_p2_lib1",
"p3": "v_p3_lib1"
},
"target_overrides": {
"b1_label": {
"p1": "v_p1_lib1[b1_label]"
},
"b2_label": {
"p2": "v_p2_lib1[b2_label]"
}
}
}

View File

@ -0,0 +1,32 @@
{
"custom_targets": {
"base": {
"inherits": ["Target"],
"core": "Cortex-M0"
},
"b1": {
"inherits": ["base"],
"extra_labels_add": ["b1_label"]
},
"b2": {
"inherits": ["base"],
"extra_labels_add": ["b2_label"]
},
"both": {
"inherits": ["b1", "b2"]
}
},
"config": {
"app1": "v_app1",
"app2": "v_app2"
},
"target_overrides": {
"b1_label": {
"app1": "v_app1[b1_label]",
"app_wrong": "v_dummy"
},
"b2_label": {
"app2": "v_app2[b2_label]"
}
}
}

View File

@ -0,0 +1,34 @@
# This build on top of test6 by adding an invalid override in mbed_app_override.json for b1_label.
# This will prevent the configuration for working for b1 and both, but it should still
# work for base and b2.
expected_results = {
"base": {
"desc": "override values based on labels with libs (no labels)",
"app.app1": "v_app1",
"app.app2": "v_app2",
"lib1.p1": "v_p1_lib1",
"lib1.p2": "v_p2_lib1",
"lib1.p3": "v_p3_lib1",
"lib2.p1": "v_p1_lib2",
"lib2.p2": "v_p2_lib2"
},
"b1": {
"desc": "override values based on labels with libs - invalid override (first label)",
"exception_msg": "Attempt to override undefined parameter 'app.app_wrong' in 'application[b1_label]"
},
"b2": {
"desc": "override values based on labels with libs (second label)",
"app.app1": "v_app1",
"app.app2": "v_app2[b2_label]",
"lib1.p1": "v_p1_lib1",
"lib1.p2": "v_p2_lib1[b2_label]",
"lib1.p3": "v_p3_lib1",
"lib2.p1": "v_p1_lib2[b2_label]",
"lib2.p2": "v_p2_lib2[b2_label]"
},
"both": {
"desc": "override values based on labels with libs - invalid override (both labels)",
"exception_msg": "Attempt to override undefined parameter 'app.app_wrong' in 'application[b1_label]"
},
}

View File

@ -0,0 +1,17 @@
{
"name": "lib2",
"config": {
"p1": "v_p1_lib2",
"p2": "v_p2_lib2"
},
"target_overrides": {
"b1_label": {
"p1": "v_p1_lib2[b1_label]",
"p2": "v_p2_lib2[b1_label]"
},
"b2_label": {
"p1": "v_p1_lib2[b2_label]",
"p2": "v_p2_lib2[b2_label]"
}
}
}

View File

@ -0,0 +1,16 @@
{
"name": "lib1",
"config": {
"p1": "v_p1_lib1",
"p2": "v_p2_lib1",
"p3": "v_p3_lib1"
},
"target_overrides": {
"b1_label": {
"p1": "v_p1_lib1[b1_label]"
},
"b2_label": {
"p2": "v_p2_lib1[b2_label]"
}
}
}

View File

@ -0,0 +1,58 @@
{
"custom_targets": {
"base": {
"inherits": ["Target"],
"core": "Cortex-M0",
"config": {
"par1": "v_par1_base",
"par2": "v_par2_base",
"par3": "v_par3_base"
}
},
"b1": {
"inherits": ["base"],
"extra_labels_add": ["b1_label"],
"overrides": {
"par1": "v_par1_b1"
}
},
"b2": {
"inherits": ["base"],
"extra_labels_add": ["b2_label"],
"overrides": {
"par2": "v_par2_b2"
}
},
"both": {
"inherits": ["b1", "b2"],
"config": {
"par4": "v_par4_both"
},
"overrides": {
"par3": "v_par3_both"
}
}
},
"config": {
"app1": "v_app1",
"app2": "v_app2"
},
"target_overrides": {
"*": {
"lib1.p3": "v_p3_lib1_app",
"lib1.p1": "v_p1_lib1_app",
"lib2.p1": "v_p1_lib2_app",
"target.par1": "v_par1_target_app"
},
"b1_label": {
"app.app1": "v_app1[b1_label_label]"
},
"b2_label": {
"app2": "v_app2[b2_label]"
},
"both": {
"target.par4": "v_par4_app[both_label]",
"lib2.p1": "v_p1_lib2_app[both_label]"
}
}
}

View File

@ -0,0 +1,57 @@
# This builds on top of test8 by adding target-conditional overrides in mbed_app_config.json.
expected_results = {
"base": {
"desc": "override values based on labels with libs, target params and target overrides (no labels)",
"app.app1": "v_app1",
"app.app2": "v_app2",
"lib1.p1": "v_p1_lib1_app",
"lib1.p2": "v_p2_lib1",
"lib1.p3": "v_p3_lib1_app",
"lib2.p1": "v_p1_lib2_app",
"lib2.p2": "v_p2_lib2",
"target.par1": "v_par1_target_app",
"target.par2": "v_par2_base",
"target.par3": "v_par3_base"
},
"b1": {
"desc": "override values based on labels with libs, target params and target overrides (first label)",
"app.app1": "v_app1[b1_label_label]",
"app.app2": "v_app2",
"lib1.p1": "v_p1_lib1_app",
"lib1.p2": "v_p2_lib1",
"lib1.p3": "v_p3_lib1_app",
"lib2.p1": "v_p1_lib2_app",
"lib2.p2": "v_p2_lib2[b1_label]",
"target.par1": "v_par1_target_app",
"target.par2": "v_par2_base",
"target.par3": "v_par3_base"
},
"b2": {
"desc": "override values based on labels with libs, target params and target overrides (second label)",
"app.app1": "v_app1",
"app.app2": "v_app2[b2_label]",
"lib1.p1": "v_p1_lib1_app",
"lib1.p2": "v_p2_lib1[b2_label]",
"lib1.p3": "v_p3_lib1_app",
"lib2.p1": "v_p1_lib2_app",
"lib2.p2": "v_p2_lib2[b2_label]",
"target.par1": "v_par1_target_app",
"target.par2": "v_par2_b2",
"target.par3": "v_par3_base"
},
"both": {
"desc": "override values based on labels with libs, target params and target overrides (both labels)",
"app.app1": "v_app1[b1_label_label]",
"app.app2": "v_app2[b2_label]",
"lib1.p1": "v_p1_lib1_app",
"lib1.p2": "v_p2_lib1[b2_label]",
"lib1.p3": "v_p3_lib1_app",
"lib2.p1": "v_p1_lib2_app[both_label]",
"lib2.p2": "v_p2_lib2[b2_label]",
"target.par1": "v_par1_target_app",
"target.par2": "v_par2_b2",
"target.par3": "v_par3_both",
"target.par4": "v_par4_app[both_label]"
}
}

View File

@ -0,0 +1,7 @@
{
"name": "lib2",
"config": {
"p1": "v_p1_lib2",
"p2": "v_p2_lib2"
}
}

View File

@ -0,0 +1,14 @@
{
"name": "lib1",
"config": {
"p1": "v_p1_lib1",
"p2": "v_p2_lib1",
"p3": "v_p3_lib1"
},
"target_overrides": {
"K64F": {
"p1": "v_p1_lib1[b1_label]",
"lib2.p1": "dummy"
}
}
}

View File

@ -0,0 +1,9 @@
# Two libraries (lib1 and lib2) define their own configuration parameters
# lib1 tries to override a configuration parameter in lib2, which raises an error
expected_results = {
"K64F": {
"desc": "lib1 trying to override a config parameter in lib2",
"exception_msg": "Invalid prefix 'lib2' for parameter name 'lib2.p1' in 'library:lib1[K64F]'"
}
}

View File

@ -0,0 +1,7 @@
{
"name": "lib2",
"config": {
"p1": "v_p1_lib2",
"p2": "v_p2_lib2"
}
}

View File

@ -0,0 +1,8 @@
{
"name": "lib1",
"config": {
"p1": "v_p1_lib1",
"p2": "v_p2_lib1",
"p3": "v_p3_lib1"
}
}

View File

@ -0,0 +1,8 @@
{
"target_overrides": {
"K64F": {
"lib1.p1": "v_p1_lib1_app",
"lib2.p1": "v_p1_lib2_app"
}
}
}

View File

@ -0,0 +1,14 @@
# Two libraries (lib1 and lib2) define their own configuration parameters
# The application config doesn't have any parameters itself, it just overrides the parameter
# named p1 from both lib1 and lib2.
expected_results = {
"K64F": {
"desc": "app without its own parameters overrides parameters in other libs",
"lib1.p1": "v_p1_lib1_app",
"lib1.p2": "v_p2_lib1",
"lib1.p3": "v_p3_lib1",
"lib2.p1": "v_p1_lib2_app",
"lib2.p2": "v_p2_lib2"
}
}

View File

@ -0,0 +1,3 @@
{
"name": "lib1"
}

View File

@ -0,0 +1,3 @@
{
"name": "lib1"
}

View File

@ -0,0 +1,8 @@
# Create two libraries named "lib1", which must raise an error
expected_results = {
"K64F": {
"desc": "attempt to configure two libraries named 'lib1'",
"exception_msg": "Library name 'lib1' is not unique"
}
}

View File

@ -0,0 +1,3 @@
{
"unknown_key": "dummy_value"
}

View File

@ -0,0 +1,8 @@
# Put an invalid key in the application configuration
expected_results = {
"K64F": {
"desc": "invalid key in mbed_app_config.json",
"exception_msg": "Unknown key(s)"
}
}

View File

@ -0,0 +1,4 @@
{
"name": "lib1",
"unknown_key": "dummy_value"
}

View File

@ -0,0 +1,8 @@
# Put an invalid key in the library configuration
expected_results = {
"K64F": {
"desc": "invalid key in mbed_lib_config.json",
"exception_msg": "Unknown key(s)"
}
}

View File

@ -0,0 +1,4 @@
{
"name": "lib1",
"macros": ["LIB1_1=1", "LIB1_2"]
}

View File

@ -0,0 +1,4 @@
{
"name": "lib2",
"macros": ["LIB2_1=5", "LIB1_2"]
}

View File

@ -0,0 +1,3 @@
{
"macros": ["APP1=10", "APP2", "LIB2_1=5"]
}

View File

@ -0,0 +1,12 @@
# Macro test: defined macros in the top level app and 2 libs, check if they
# are reported properly.
# The app defines one macro with value the same as lib2, while lib2 defined
# the same macro without value as lib1. Since the definitions are comptabile,
# no error should be raised
expected_results = {
"K64F": {
"desc": "test macro definitions",
"expected_macros": ["APP1=10", "APP2", "LIB1_1=1","LIB1_2", "LIB2_1=5"]
}
}

View File

@ -0,0 +1,4 @@
{
"name": "lib1",
"macros": ["LIB1_1=1", "LIB1_2"]
}

View File

@ -0,0 +1,4 @@
{
"name": "lib2",
"macros": ["LIB2_1=5", "LIB1_2"]
}

View File

@ -0,0 +1,3 @@
{
"macros": ["APP1=10", "APP2", "LIB2_1=10"]
}

View File

@ -0,0 +1,9 @@
# Build on top of test16
# Adds an invalid macro redefinition in the app
expected_results = {
"K64F": {
"desc": "test invalid macro re-definition in the app",
"exception_msg": "Macro 'LIB2_1' defined in both 'library:lib2' and 'application' with incompatible values"
}
}

View File

@ -0,0 +1,4 @@
{
"name": "lib1",
"macros": ["LIB1_1=1", "LIB1_2"]
}

View File

@ -0,0 +1,4 @@
{
"name": "lib2",
"macros": ["LIB2_1=5", "LIB1_2=3"]
}

View File

@ -0,0 +1,3 @@
{
"macros": ["APP1=10", "APP2", "LIB2_1=5"]
}

View File

@ -0,0 +1,8 @@
# Like test17, but this time the invalid re-definition is in lib2, not in the app
expected_results = {
"K64F": {
"desc": "test invalid macro re-definition in a library",
"exception_msg": "defined in both"
}
}

View File

@ -0,0 +1,4 @@
{
"macros": [],
"invalid_key": "invalid_value"
}

View File

@ -0,0 +1,8 @@
# Test that invalid keys in application configuration are not allowed
expected_results = {
"K64F": {
"desc": "test invalid key in application config",
"exception_msg": "Unknown key(s) 'invalid_key'"
}
}

View File

@ -0,0 +1,5 @@
{
"name": "lib1",
"macros": [],
"invalid_key": "invalid_value"
}

View File

@ -0,0 +1,8 @@
# Like test19, but this time check invalid key in a library configuration
expected_results = {
"K64F": {
"desc": "test invalid key in lib config",
"exception_msg": "Unknown key(s) 'invalid_key'"
}
}

View File

@ -89,7 +89,7 @@ class GCC(mbedToolchain):
self.cc = [join(GOANNA_PATH, "goannacc"), "--with-cc=" + main_cc.replace('\\', '/'), "-std=gnu99", "--dialect=gnu", '--output-format="%s"' % self.GOANNA_FORMAT] + common_flags
self.cppc= [join(GOANNA_PATH, "goannac++"), "--with-cxx=" + main_cppc.replace('\\', '/'), "-std=gnu++98", "-fno-rtti", "--dialect=gnu", '--output-format="%s"' % self.GOANNA_FORMAT] + common_flags
self.ld = [join(tool_path, "arm-none-eabi-gcc"), "-Wl,--gc-sections", "-Wl,--wrap,main"] + self.cpu
self.ld = [join(tool_path, "arm-none-eabi-gcc"), "-Wl,--gc-sections", "-Wl,--wrap,main", "-Wl,--wrap,_malloc_r", "-Wl,--wrap,_free_r", "-Wl,--wrap,_realloc_r"] + self.cpu
self.sys_libs = ["stdc++", "supc++", "m", "c", "gcc"]
self.ar = join(tool_path, "arm-none-eabi-ar")
@ -277,4 +277,3 @@ class GCC_CR(GCC):
if target.name in ["LPC1768", "LPC4088", "LPC4088_DM", "LPC4330", "UBLOX_C027", "LPC2368"]:
self.ld.extend(["-u _printf_float", "-u _scanf_float"])
self.ld += ["-nostdlib"]