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: config.py
- Revision:
- 31:8ea194f6145b
- Parent:
- 30:f12ce67666d0
- Child:
- 35:da9c89f8be7d
diff -r f12ce67666d0 -r 8ea194f6145b config.py
--- a/config.py Mon Aug 29 11:56:59 2016 +0100
+++ b/config.py Wed Jan 04 11:58:24 2017 -0600
@@ -15,10 +15,13 @@
limitations under the License.
"""
+from copy import deepcopy
+import os
+import sys
# Implementation of mbed configuration mechanism
from tools.utils import json_file_to_dict
-from tools.targets import Target
-import os
+from tools.targets import CUMULATIVE_ATTRIBUTES, TARGET_MAP, \
+ generate_py_target, get_resolution_order
# Base class for all configuration exceptions
class ConfigException(Exception):
@@ -339,16 +342,18 @@
__allowed_keys = {
"library": set(["name", "config", "target_overrides", "macros",
"__config_path"]),
- "application": set(["config", "custom_targets", "target_overrides",
+ "application": set(["config", "target_overrides",
"macros", "__config_path"])
}
# Allowed features in configurations
__allowed_features = [
- "UVISOR", "BLE", "CLIENT", "IPV4", "IPV6", "COMMON_PAL", "STORAGE"
- ]
+ "UVISOR", "BLE", "CLIENT", "IPV4", "LWIP", "COMMON_PAL", "STORAGE", "NANOSTACK",
+ # Nanostack configurations
+ "LOWPAN_BORDER_ROUTER", "LOWPAN_HOST", "LOWPAN_ROUTER", "NANOSTACK_FULL", "THREAD_BORDER_ROUTER", "THREAD_END_DEVICE", "THREAD_ROUTER"
+ ]
- def __init__(self, target, top_level_dirs=None):
+ def __init__(self, tgt, top_level_dirs=None, app_config=None):
"""Construct a mbed configuration
Positional arguments:
@@ -357,27 +362,32 @@
Keyword argumets:
top_level_dirs - a list of top level source directories (where
- mbed_abb_config.json could be found)
+ mbed_app_config.json could be found)
+ app_config - location of a chosen mbed_app.json file
NOTE: Construction of a Config object will look for the application
- configuration file in top_level_dirs. If found once, it'll parse it and
- check if it has a custom_targets function. If it does, it'll update the
- list of targets as needed. If more than one config file is found, an
- exception is raised. top_level_dirs may be None (in this case,
- the constructor will not search for a configuration file)
+ configuration file in top_level_dirs. If found once, it'll parse it.
+ top_level_dirs may be None (in this case, the constructor will not
+ search for a configuration file).
"""
- app_config_location = None
- for directory in top_level_dirs or []:
- full_path = os.path.join(directory, self.__mbed_app_config_name)
- if os.path.isfile(full_path):
- if app_config_location is not None:
- raise ConfigException("Duplicate '%s' file in '%s' and '%s'"
- % (self.__mbed_app_config_name,
- app_config_location, full_path))
- else:
- app_config_location = full_path
- self.app_config_data = json_file_to_dict(app_config_location) \
- if app_config_location else {}
+ app_config_location = app_config
+ if app_config_location is None:
+ for directory in top_level_dirs or []:
+ full_path = os.path.join(directory, self.__mbed_app_config_name)
+ if os.path.isfile(full_path):
+ if app_config_location is not None:
+ raise ConfigException("Duplicate '%s' file in '%s' and '%s'"
+ % (self.__mbed_app_config_name,
+ app_config_location, full_path))
+ else:
+ app_config_location = full_path
+ try:
+ self.app_config_data = json_file_to_dict(app_config_location) \
+ if app_config_location else {}
+ except ValueError as exc:
+ sys.stderr.write(str(exc) + "\n")
+ self.app_config_data = {}
+
# Check the keys in the application configuration data
unknown_keys = set(self.app_config_data.keys()) - \
self.__allowed_keys["application"]
@@ -387,20 +397,26 @@
self.__mbed_app_config_name))
# Update the list of targets with the ones defined in the application
# config, if applicable
- Target.add_py_targets(self.app_config_data.get("custom_targets", {}))
self.lib_config_data = {}
# Make sure that each config is processed only once
self.processed_configs = {}
- self.target = target if isinstance(target, basestring) else target.name
- self.target_labels = Target.get_target(self.target).get_labels()
+ if isinstance(tgt, basestring):
+ if tgt in TARGET_MAP:
+ self.target = TARGET_MAP[tgt]
+ else:
+ self.target = generate_py_target(
+ self.app_config_data.get("custom_targets", {}), tgt)
+
+ else:
+ self.target = tgt
+ self.target = deepcopy(self.target)
+ self.target_labels = self.target.labels
self.cumulative_overrides = {key: ConfigCumulativeOverride(key)
- for key in
- Target.cumulative_attributes}
+ for key in CUMULATIVE_ATTRIBUTES}
self._process_config_and_overrides(self.app_config_data, {}, "app",
"application")
- self.target_labels = Target.get_target(self.target).get_labels()
self.config_errors = None
def add_config_files(self, flist):
@@ -419,7 +435,12 @@
self.processed_configs[full_path] = True
# Read the library configuration and add a "__full_config_path"
# attribute to it
- cfg = json_file_to_dict(config_file)
+ try:
+ cfg = json_file_to_dict(config_file)
+ except ValueError as exc:
+ sys.stderr.write(str(exc) + "\n")
+ continue
+
cfg["__config_path"] = full_path
if "name" not in cfg:
@@ -498,7 +519,7 @@
label)))))
for cumulatives in self.cumulative_overrides.itervalues():
- cumulatives.update_target(Target.get_target(self.target))
+ cumulatives.update_target(self.target)
return params
@@ -517,10 +538,10 @@
Arguments: None
"""
- params, json_data = {}, Target.get_json_target_data()
+ params, json_data = {}, self.target.json_data
resolution_order = [e[0] for e
in sorted(
- Target.get_target(self.target).resolution_order,
+ self.target.resolution_order,
key=lambda e: e[1], reverse=True)]
for tname in resolution_order:
# Read the target data directly from its description
@@ -536,9 +557,11 @@
# in the target inheritance tree, raise an error We need to use
# 'defined_by[7:]' to remove the "target:" prefix from
# defined_by
+ rel_names = [tgt for tgt, _ in
+ get_resolution_order(self.target.json_data, tname,
+ [])]
if (full_name not in params) or \
- (params[full_name].defined_by[7:] not in
- Target.get_target(tname).resolution_order_names):
+ (params[full_name].defined_by[7:] not in rel_names):
raise ConfigException(
"Attempt to override undefined parameter '%s' in '%s'"
% (name,
@@ -669,15 +692,9 @@
params, _ = self.get_config_data()
self._check_required_parameters(params)
self.cumulative_overrides['features']\
- .update_target(Target.get_target(self.target))
- features = Target.get_target(self.target).features
+ .update_target(self.target)
- for feature in features:
- if feature not in self.__allowed_features:
- raise ConfigException(
- "Feature '%s' is not a supported features" % feature)
-
- return features
+ return self.target.features
def validate_config(self):
""" Validate configuration settings. This either returns True or
@@ -774,14 +791,15 @@
if macro.macro_value:
header_data += ("#define {0:<{1}} {2!s:<{3}}" +
" // defined by {4}\n")\
- .format(m.macro_name, max_macro_name_len, m.macro_value,
- max_macro_val_len, m.defined_by)
+ .format(macro.macro_name, max_macro_name_len,
+ macro.macro_value, max_macro_val_len,
+ macro.defined_by)
else:
header_data += ("#define {0:<{1}}" +
" // defined by {2}\n")\
- .format(m.macro_name,
+ .format(macro.macro_name,
max_macro_name_len + max_macro_val_len + 1,
- m.defined_by)
+ macro.defined_by)
header_data += "\n#endif\n"
# If fname is given, write "header_data" to it
if fname:
