aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Trofimov <sergei.trofimov@arm.com>2018-03-01 16:42:53 +0000
committerMarc Bonnici <marc.bonnici@arm.com>2018-03-08 11:18:12 +0000
commit10f79c37c288f1692de94f3d544a987b37a93b0d (patch)
tree1b0015dcc7d659480a492dbb011a961d480b18a1
parent9303c70727975676f3e0ee136915fda600c80b80 (diff)
fw/target/descriptor: add usability functions
- Add SimpleTargetDescriptor that simply returns a global list of target descriptions. - Add create_target_description function to populate that list with a description crated from the specified components. - Add add_description_for_target helper function to create a description for the specified target class, and specified components. For components that are not explicitly specified, attempt to guess sensible defaults based on the target class' bases.
-rw-r--r--wa/framework/target/descriptor.py83
1 files changed, 82 insertions, 1 deletions
diff --git a/wa/framework/target/descriptor.py b/wa/framework/target/descriptor.py
index d05bd8b3..d0c96ae4 100644
--- a/wa/framework/target/descriptor.py
+++ b/wa/framework/target/descriptor.py
@@ -1,3 +1,4 @@
+import inspect
from collections import OrderedDict
from copy import copy
@@ -12,7 +13,7 @@ from wa.framework.configuration.core import get_config_point_map
from wa.framework.exception import PluginLoaderError
from wa.framework.plugin import Plugin, Parameter
from wa.framework.target.assistant import LinuxAssistant, AndroidAssistant, ChromeOsAssistant
-from wa.utils.types import list_of_strings, list_of_ints, regex
+from wa.utils.types import list_of_strings, list_of_ints, regex, identifier, caseless_string
from wa.utils.misc import isiterable
@@ -488,3 +489,83 @@ class DefaultTargetDescriptor(TargetDescriptor):
raise ValueError('Unexpected default "{}"'.format(name))
param_map[name].default = value
return cls, param_map.values()
+
+
+
+_adhoc_target_descriptions = []
+
+
+def create_target_description(name, *args, **kwargs):
+ name = identifier(name)
+ for td in _adhoc_target_descriptions:
+ if caseless_string(name) == td.name:
+ msg = 'Target with name "{}" already exists (from source: {})'
+ raise ValueError(msg.format(name, td.source))
+
+ stack = inspect.stack()
+ # inspect.stack() returns a list of call frame records for the current thread
+ # in reverse call order. So the first entry is for the current frame and next one
+ # for the immediate caller. Each entry is a tuple in the format
+ # (frame_object, module_path, line_no, function_name, source_lines, source_lines_index)
+ #
+ # Here we assign the path of the calling module as the "source" for this description.
+ # because this might be invoked via the add_scription_for_target wrapper, we need to
+ # check for that, and make sure that we get the info for *its* caller in that case.
+ if stack[1][3] == 'add_description_for_target':
+ source = stack[2][1]
+ else:
+ source = stack[1][1]
+
+ _adhoc_target_descriptions.append(TargetDescription(name, source, *args, **kwargs))
+
+
+def _get_target_defaults(target):
+ specificity = 0
+ res = ('linux', TARGETS['linux']) # fallback to a generic linux target
+ for name, ttup in TARGETS.iteritems():
+ if issubclass(target, ttup[0][0]):
+ new_spec = len(inspect.getmro(ttup[0][0]))
+ if new_spec > specificity:
+ res = (name, ttup)
+ specificity = new_spec
+ return res
+
+
+def add_description_for_target(target, description=None, **kwargs):
+ (base_name, ((base_target, base_conn), base_params, base_defaults)) = _get_target_defaults(target)
+
+ if 'target_params' not in kwargs:
+ kwargs['target_params'] = base_params
+
+ if 'platform' not in kwargs:
+ kwargs['platform'] = Platform
+ if 'platform_params' not in kwargs:
+ for (plat, conn), params, _ in PLATFORMS.itervalues():
+ if plat == kwargs['platform']:
+ kwargs['platform_params'] = params
+ if conn is not None and kwargs['conn'] is None:
+ kwargs['conn'] = conn
+ break
+
+ if 'conn' not in kwargs:
+ kwargs['conn'] = base_conn
+ if 'conn_params' not in kwargs:
+ kwargs['conn_params'] = CONNECTION_PARAMS.get(kwargs['conn'])
+
+ if 'assistant' not in kwargs:
+ kwargs['assistant'] = ASSISTANTS.get(base_name)
+
+ create_target_description(target.name, target=target, description=description, **kwargs)
+
+
+class SimpleTargetDescriptor(TargetDescriptor):
+
+ name = 'adhoc_targets'
+
+ description="""
+ Returns target descriptions added with ``create_target_description``.
+
+ """
+
+ def get_descriptions(self):
+ return _adhoc_target_descriptions