Skip to content

Fix targets py #2148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 12, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 34 additions & 34 deletions tools/targets.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,27 +48,31 @@ class HookError(Exception):
caches = {}
def cached(func):
def wrapper(*args, **kwargs):
if not caches.has_key(func):
caches[func] = func(*args, **kwargs)
return caches[func]
if not caches.has_key((func.__name__, args)):
caches[(func.__name__, args)] = func(*args, **kwargs)
return caches[(func.__name__, args)]
return wrapper

class Target:
# Cumulative attributes can have values appended to them, so they
# need to be computed differently than regular attributes
__cumulative_attributes = ['extra_labels', 'macros', 'device_has', 'features']

# {target_name: target_instance} map for all the targets in the system
__target_map = {}

# List of targets that were added dynamically using "add_py_targets" (see below)
__py_targets = set()
# Location of the 'targets.json' file
__targets_json_location = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'hal', 'targets.json')

# Load the description of JSON target data
@staticmethod
@cached
def get_json_target_data():
return json_file_to_dict(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'hal', 'targets.json'))
return json_file_to_dict(Target.__targets_json_location)

# Set the location of the targets.json file
@staticmethod
def set_targets_json_location(location):
Target.__targets_json_location = location
# Invalidate caches, since the location of the JSON file changed
caches.clear()

# Get the members of this module using Python's "inspect" module
@staticmethod
Expand Down Expand Up @@ -168,42 +172,26 @@ def __getattr__(self, attrname):
return v

# Add one or more new target(s) represented as a Python dictionary in 'new_targets'
# It it an error to add a target with a name that exists in "targets.json"
# However, it is OK to add a target that was previously added via "add_py_targets"
# (this makes testing easier without changing the regular semantics)
# It is an error to add a target with a name that already exists.
@staticmethod
def add_py_targets(new_targets):
crt_data = Target.get_json_target_data()
# First add all elemnts to the internal dictionary
for tk, tv in new_targets.items():
if crt_data.has_key(tk) and (not tk in Target.__py_targets):
if crt_data.has_key(tk):
raise Exception("Attempt to add target '%s' that already exists" % tk)
# Add target data to the internal target dictionary
crt_data[tk] = tv
Target.__py_targets.add(tk)
# Then create the new instances and update global variables if needed
for tk, tv in new_targets.items():
# Is the target already created?
old_target = Target.__target_map.get(tk, None)
# Instantiate this target. If it is public, update the data in
# in TARGETS, TARGET_MAP, TARGET_NAMES
# Create the new target and add it to the relevant data structures
new_target = Target(tk)
if tv.get("public", True):
if old_target: # remove the old target from TARGETS and TARGET_NAMES
TARGETS.remove(old_target)
TARGET_NAMES.remove(tk)
# Add the new target
TARGETS.append(new_target)
TARGET_MAP[tk] = new_target
TARGET_NAMES.append(tk)
# Update the target cache
Target.__target_map[tk] = new_target
TARGETS.append(new_target)
TARGET_MAP[tk] = new_target
TARGET_NAMES.append(tk)

# Return the target instance starting from the target name
@staticmethod
@cached
def get_target(name):
if not Target.__target_map.has_key(name):
Target.__target_map[name] = Target(name)
return Target.__target_map[name]
return Target(name)

def __init__(self, name):
self.name = name
Expand Down Expand Up @@ -414,3 +402,15 @@ def get_target_detect_codes():
for detect_code in target.detect_code:
result[detect_code] = target.name
return result

# Sets the location of the JSON file that contains the targets
def set_targets_json_location(location):
# First instruct Target about the new location
Target.set_targets_json_location(location)
# Then re-initialize TARGETS, TARGET_MAP and TARGET_NAMES
# The re-initialization does not create new variables, it keeps the old ones instead
# This ensures compatibility with code that does "from tools.targets import TARGET_NAMES"
TARGETS[:] = [Target.get_target(name) for name, value in Target.get_json_target_data().items() if value.get("public", True)]
TARGET_MAP.clear()
TARGET_MAP.update(dict([(t.name, t) for t in TARGETS]))
TARGET_NAMES[:] = TARGET_MAP.keys()
3 changes: 3 additions & 0 deletions tools/test/config_test/config_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"""

from tools.build_api import get_config
from tools.targets import set_targets_json_location, Target
from tools.config import ConfigException, Config
import os, sys

Expand Down Expand Up @@ -43,6 +44,8 @@ def test_tree(full_name, name):
sys.stdout.flush()
err_msg = None
try:
# Use 'set_targets_json_location' to remove the previous custom targets from the target list
set_targets_json_location(Target._Target__targets_json_location)
cfg, macros, features = get_config(full_name, target, "GCC_ARM")
macros = Config.config_macros_to_macros(macros)
except ConfigException as e:
Expand Down