Skip to content

Commit b820ec8

Browse files
author
Cruz Monrreal
authored
Merge pull request #9561 from theotherjimmy/test-resources
Tools changes for bare metal
2 parents a477354 + f331d9e commit b820ec8

File tree

77 files changed

+543
-10
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+543
-10
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"name": "greentea-client"
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"name": "mbed-client-cli"
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"name": "mbed-client-randlib"
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"name": "mbed-coap"
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"name": "nanostack-libservice"
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"name": "unity"
3+
}

features/mbedtls/mbed_lib.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"name": "mbedtls"
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"name": "coap-service"
3+
}

features/nanostack/mbed-mesh-api/mbed_lib.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"name": "mbed-mesh-api",
3+
"requires": ["nanostack"],
34
"config": {
45
"heap-size": {
56
"help": "Nanostack's heap size [bytes: 0-65534]",
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"name": "nanostack-interface",
3+
"requires": ["nanostack"]
4+
}

features/nanostack/sal-stack-nanostack-eventloop/mbed_lib.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"name": "nanostack-eventloop",
3+
"requires": ["nanostack-hal"],
34
"config": {
45
"use_platform_tick_timer": {
56
"help": "Use platform provided low resolution tick timer for eventloop",

features/nanostack/sal-stack-nanostack/mbed_lib.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"name": "nanostack",
3+
"requires": ["nanostack-eventloop", "coap-service"],
34
"config": {
45
"configuration": {
56
"help": "Build time configuration. Refer to Handbook for valid values. Default: full stack",

features/nfc/mbed_lib.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"name": "nfc"
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"name": "system-storage"
3+
}

tools/build_api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ def get_config(src_paths, target, toolchain_name=None, app_config=None):
156156

157157
cfg, macros = config.get_config_data()
158158
features = config.get_features()
159-
return cfg, macros, features
159+
return cfg, macros, features, res
160160

161161
def is_official_target(target_name, version):
162162
""" Returns True, None if a target is part of the official release for the

tools/config/__init__.py

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,6 @@ def add_config_files(self, flist):
545545
# Check that we didn't already process this file
546546
if full_path in self.processed_configs:
547547
continue
548-
self.processed_configs[full_path] = True
549548
# Read the library configuration and add a "__full_config_path"
550549
# attribute to it
551550
try:
@@ -570,6 +569,12 @@ def add_config_files(self, flist):
570569
raise ConfigException("; ".join(
571570
self.format_validation_error(x, config_file)
572571
for x in errors))
572+
if "requires" in self.app_config_data:
573+
if cfg["name"] not in self.app_config_data["requires"]:
574+
continue
575+
self.app_config_data["requires"].extend(cfg.get("requires", []))
576+
577+
self.processed_configs[full_path] = True
573578

574579
cfg["__config_path"] = full_path
575580

@@ -1279,6 +1284,7 @@ def load_resources(self, resources):
12791284
"""
12801285
# Update configuration files until added features creates no changes
12811286
prev_features = set()
1287+
prev_requires = set()
12821288
while True:
12831289
# Add/update the configuration with any .json files found while
12841290
# scanning
@@ -1288,14 +1294,37 @@ def load_resources(self, resources):
12881294

12891295
# Add features while we find new ones
12901296
features = set(self.get_features())
1291-
if features == prev_features:
1297+
requires = set(self.app_config_data.get("requires", []))
1298+
if features == prev_features and requires == prev_requires:
12921299
break
12931300

12941301
resources.add_features(features)
12951302

12961303
prev_features = features
1304+
prev_requires = requires
12971305
self.validate_config()
1298-
1306+
missing_requirements = {}
1307+
for name, lib in self.lib_config_data.items():
1308+
for req in lib.get("requires", []):
1309+
if req not in self.lib_config_data:
1310+
missing_requirements.setdefault(name, [])
1311+
missing_requirements[name].append(req)
1312+
if missing_requirements:
1313+
message = "; ".join(
1314+
"library '{}' requires {} which is not present".format(
1315+
name, ", ".join("'{}'".format(i) for i in missing)
1316+
)
1317+
for name, missing in missing_requirements.items()
1318+
)
1319+
raise ConfigException(message)
1320+
all_json_paths = [
1321+
cfg["__config_path"] for cfg in self.lib_config_data.values()
1322+
]
1323+
included_json_files = [
1324+
ref for ref in resources.get_file_refs(FileType.JSON)
1325+
if abspath(ref.path) in all_json_paths
1326+
]
1327+
resources.filter_by_libraries(included_json_files)
12991328
if (hasattr(self.target, "release_versions") and
13001329
"5" not in self.target.release_versions and
13011330
"rtos" in self.lib_config_data):

tools/config/definitions.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66
"type": "string"
77
}
88
},
9+
"requires_definition": {
10+
"description": "Required libraries",
11+
"type": "array",
12+
"items": {
13+
"$ref": "#/name_definition"
14+
}
15+
},
916
"macro_definition": {
1017
"description": "A list of extra macros that will be defined when compiling a project that includes this library.",
1118
"type": "array",

tools/config/schema_app.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
"macros": {
1717
"$ref": "definitions.json#/macro_definition"
1818
},
19+
"requires": {
20+
"$ref": "definitions.json#/requires_definition"
21+
},
1922
"artifact_name": {
2023
"type": "string"
2124
}

tools/config/schema_lib.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
"target_overrides": {
1414
"$ref": "definitions.json#/target_overrides_definition"
1515
},
16+
"requires": {
17+
"$ref": "definitions.json#/requires_definition"
18+
},
1619
"macros": {
1720
"$ref": "definitions.json#/macro_definition"
1821
}

tools/get_config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
options.prefix = options.prefix or [""]
5757

5858
try:
59-
params, macros, features = get_config(
59+
params, macros, features, _ = get_config(
6060
options.source_dir,
6161
target,
6262
options.tool[0] if options.tool else None,

tools/resources/__init__.py

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,17 @@
8080
'ARMC6': 'ARMC6',
8181
}
8282

83+
MBED_LIB_FILENAME = 'mbed_lib.json'
84+
MBED_APP_FILENAME = 'mbed_app.json'
85+
CONFIG_FILES = set([
86+
MBED_LIB_FILENAME,
87+
MBED_APP_FILENAME
88+
])
89+
8390

8491
FileRef = namedtuple("FileRef", "name path")
8592

93+
8694
class FileType(object):
8795
C_SRC = "c"
8896
CPP_SRC = "c++"
@@ -126,6 +134,9 @@ def __init__(self, notify, collect_ignores=False):
126134
# publicly accessible things
127135
self.ignored_dirs = []
128136

137+
# library requirements
138+
self._libs_filtered = None
139+
129140
# Pre-mbed 2.0 ignore dirs
130141
self._legacy_ignore_dirs = (LEGACY_IGNORE_DIRS)
131142

@@ -260,9 +271,47 @@ def add_file_ref(self, file_type, file_name, file_path):
260271
file_name = file_name.replace(sep, self._sep)
261272
self._file_refs[file_type].add(FileRef(file_name, file_path))
262273

274+
def _include_file(self, ref):
275+
"""Determine if a given file ref should be included in the build
276+
277+
Files may be part of a library if a parent directory contains an
278+
mbed_lib.json. If a file is part of a library, include or exclude
279+
it based on the library it's part of.
280+
If a file is not part of a library, it's included.
281+
"""
282+
_, path = ref
283+
cur_dir = dirname(path)
284+
included_lib_paths = [dirname(e.path) for e in self._libs_filtered]
285+
excluded_lib_paths = [dirname(e.path) for e in self._excluded_libs]
286+
while dirname(cur_dir) != cur_dir:
287+
if cur_dir in included_lib_paths:
288+
return True
289+
elif cur_dir in excluded_lib_paths:
290+
return False
291+
cur_dir = dirname(cur_dir)
292+
return True
293+
263294
def get_file_refs(self, file_type):
264295
"""Return a list of FileRef for every file of the given type"""
265-
return list(self._file_refs[file_type])
296+
if self._libs_filtered is None:
297+
return list(self._file_refs[file_type])
298+
else:
299+
return [
300+
ref for ref in self._file_refs[file_type]
301+
if self._include_file(ref)
302+
]
303+
304+
def filter_by_libraries(self, libraries_included):
305+
"""
306+
Call after completely done scanning to filter resources based on
307+
libraries
308+
"""
309+
self._libs_filtered = set(libraries_included)
310+
all_library_refs = set(
311+
ref for ref in self._file_refs[FileType.JSON]
312+
if ref.name.endswith(MBED_LIB_FILENAME)
313+
)
314+
self._excluded_libs = all_library_refs - self._libs_filtered
266315

267316
def _get_from_refs(self, file_type, key):
268317
return sorted([key(f) for f in self.get_file_refs(file_type)])

tools/test/config/config_test.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@
2626
from tools.build_api import get_config
2727
from tools.targets import set_targets_json_location, Target, TARGET_NAMES
2828
from tools.config import ConfigException, Config, ConfigParameter, ConfigMacro
29+
from tools.resources import Resources
30+
31+
NOT_CONFIG = [
32+
"expected_macros",
33+
"expected_features",
34+
"included_source",
35+
"excluded_source",
36+
]
2937

3038
def compare_config(cfg, expected):
3139
"""Compare the output of config against a dictionary of known good results
@@ -40,7 +48,7 @@ def compare_config(cfg, expected):
4048
except KeyError:
4149
return "Unexpected key '%s' in configuration data" % k
4250
for k in expected:
43-
if k not in ["expected_macros", "expected_features"] + list(cfg.keys()):
51+
if k not in NOT_CONFIG + list(cfg.keys()):
4452
return "Expected key '%s' was not found in configuration data" % k
4553
return ""
4654

@@ -73,7 +81,7 @@ def test_config(name):
7381
set_targets_json_location(targets_json if isfile(targets_json) else None)
7482
for target, expected in test_data.items():
7583
try:
76-
cfg, macros, features = get_config(test_dir, target, "GCC_ARM")
84+
cfg, macros, features, resources = get_config(test_dir, target, "GCC_ARM")
7785
res = compare_config(cfg, expected)
7886
assert not(res), res
7987
expected_macros = expected.get("expected_macros", None)
@@ -84,6 +92,24 @@ def test_config(name):
8492
assert sorted(expected_macros) == sorted(macros)
8593
if expected_features is not None:
8694
assert sorted(expected_features) == sorted(features)
95+
96+
included_source = [
97+
join(test_dir, src) for src in
98+
expected.get("included_source", [])
99+
]
100+
excluded_source = [
101+
join(test_dir, src) for src in
102+
expected.get("excluded_source", [])
103+
]
104+
for typ in Resources.ALL_FILE_TYPES:
105+
for _, path in resources.get_file_refs(typ):
106+
if included_source and path in included_source:
107+
included_source.remove(path)
108+
if excluded_source:
109+
assert(path not in excluded_source)
110+
assert(not included_source)
111+
if included_source:
112+
assert(False)
87113
except ConfigException as e:
88114
err_msg = str(e)
89115
if "exception_msg" not in expected:

tools/test/config/feature_recursive_add/FEATURE_BOOTLOADER/lib1/lib1.c

Whitespace-only changes.

tools/test/config/feature_recursive_add/FEATURE_STORAGE/lib2/lib2.c

Whitespace-only changes.
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"test_target": {
3-
"expected_features": ["BOOTLOADER", "STORAGE"]
3+
"expected_features": ["BOOTLOADER", "STORAGE"],
4+
"included_source": ["FEATURE_BOOTLOADER/lib1/lib1.c", "FEATURE_STORAGE/lib2/lib2.c"]
45
}
56
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "lib1",
3+
"requires": ["lib2"],
4+
"config": {
5+
"test": "BAD"
6+
}
7+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"name": "lib2",
3+
"requires": ["lib3"],
4+
"config": {
5+
"test": {
6+
"value": "BAD"
7+
}
8+
}
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"requires" : ["lib1"],
3+
"target_overrides": {
4+
"test_target": {
5+
"lib2.test": "GOOD",
6+
"lib1.test": "GOOD"
7+
}
8+
}
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"test_target": {
3+
"supported_toolchains": ["GCC_ARM"],
4+
"core": "Cortex-M0",
5+
"extra_labels": [],
6+
"features": [],
7+
"default_lib": "std"
8+
}
9+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"test_target": {
3+
"exception_msg": "'lib2' requires 'lib3' which is not present"
4+
}
5+
}

tools/test/config/requires_exclude_in_include/lib1/lib1.cpp

Whitespace-only changes.

tools/test/config/requires_exclude_in_include/lib1/lib2/lib2.c

Whitespace-only changes.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"name": "lib2",
3+
"config": {
4+
"test": {
5+
"value": "BAD"
6+
}
7+
}
8+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "lib1",
3+
"config": {
4+
"test": "BAD"
5+
}
6+
}

0 commit comments

Comments
 (0)