Skip to content

Commit 99dbc8b

Browse files
authored
Merge pull request #2148 from mbedmicro/fix_targets_py
Fix targets py
2 parents 6f86064 + 9704edf commit 99dbc8b

File tree

2 files changed

+37
-34
lines changed

2 files changed

+37
-34
lines changed

tools/targets.py

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -48,27 +48,31 @@ class HookError(Exception):
4848
caches = {}
4949
def cached(func):
5050
def wrapper(*args, **kwargs):
51-
if not caches.has_key(func):
52-
caches[func] = func(*args, **kwargs)
53-
return caches[func]
51+
if not caches.has_key((func.__name__, args)):
52+
caches[(func.__name__, args)] = func(*args, **kwargs)
53+
return caches[(func.__name__, args)]
5454
return wrapper
5555

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

61-
# {target_name: target_instance} map for all the targets in the system
62-
__target_map = {}
63-
64-
# List of targets that were added dynamically using "add_py_targets" (see below)
65-
__py_targets = set()
61+
# Location of the 'targets.json' file
62+
__targets_json_location = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'hal', 'targets.json')
6663

6764
# Load the description of JSON target data
6865
@staticmethod
6966
@cached
7067
def get_json_target_data():
71-
return json_file_to_dict(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'hal', 'targets.json'))
68+
return json_file_to_dict(Target.__targets_json_location)
69+
70+
# Set the location of the targets.json file
71+
@staticmethod
72+
def set_targets_json_location(location):
73+
Target.__targets_json_location = location
74+
# Invalidate caches, since the location of the JSON file changed
75+
caches.clear()
7276

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

170174
# Add one or more new target(s) represented as a Python dictionary in 'new_targets'
171-
# It it an error to add a target with a name that exists in "targets.json"
172-
# However, it is OK to add a target that was previously added via "add_py_targets"
173-
# (this makes testing easier without changing the regular semantics)
175+
# It is an error to add a target with a name that already exists.
174176
@staticmethod
175177
def add_py_targets(new_targets):
176178
crt_data = Target.get_json_target_data()
177-
# First add all elemnts to the internal dictionary
178179
for tk, tv in new_targets.items():
179-
if crt_data.has_key(tk) and (not tk in Target.__py_targets):
180+
if crt_data.has_key(tk):
180181
raise Exception("Attempt to add target '%s' that already exists" % tk)
182+
# Add target data to the internal target dictionary
181183
crt_data[tk] = tv
182-
Target.__py_targets.add(tk)
183-
# Then create the new instances and update global variables if needed
184-
for tk, tv in new_targets.items():
185-
# Is the target already created?
186-
old_target = Target.__target_map.get(tk, None)
187-
# Instantiate this target. If it is public, update the data in
188-
# in TARGETS, TARGET_MAP, TARGET_NAMES
184+
# Create the new target and add it to the relevant data structures
189185
new_target = Target(tk)
190-
if tv.get("public", True):
191-
if old_target: # remove the old target from TARGETS and TARGET_NAMES
192-
TARGETS.remove(old_target)
193-
TARGET_NAMES.remove(tk)
194-
# Add the new target
195-
TARGETS.append(new_target)
196-
TARGET_MAP[tk] = new_target
197-
TARGET_NAMES.append(tk)
198-
# Update the target cache
199-
Target.__target_map[tk] = new_target
186+
TARGETS.append(new_target)
187+
TARGET_MAP[tk] = new_target
188+
TARGET_NAMES.append(tk)
200189

201190
# Return the target instance starting from the target name
202191
@staticmethod
192+
@cached
203193
def get_target(name):
204-
if not Target.__target_map.has_key(name):
205-
Target.__target_map[name] = Target(name)
206-
return Target.__target_map[name]
194+
return Target(name)
207195

208196
def __init__(self, name):
209197
self.name = name
@@ -414,3 +402,15 @@ def get_target_detect_codes():
414402
for detect_code in target.detect_code:
415403
result[detect_code] = target.name
416404
return result
405+
406+
# Sets the location of the JSON file that contains the targets
407+
def set_targets_json_location(location):
408+
# First instruct Target about the new location
409+
Target.set_targets_json_location(location)
410+
# Then re-initialize TARGETS, TARGET_MAP and TARGET_NAMES
411+
# The re-initialization does not create new variables, it keeps the old ones instead
412+
# This ensures compatibility with code that does "from tools.targets import TARGET_NAMES"
413+
TARGETS[:] = [Target.get_target(name) for name, value in Target.get_json_target_data().items() if value.get("public", True)]
414+
TARGET_MAP.clear()
415+
TARGET_MAP.update(dict([(t.name, t) for t in TARGETS]))
416+
TARGET_NAMES[:] = TARGET_MAP.keys()

tools/test/config_test/config_test.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"""
1717

1818
from tools.build_api import get_config
19+
from tools.targets import set_targets_json_location, Target
1920
from tools.config import ConfigException, Config
2021
import os, sys
2122

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

0 commit comments

Comments
 (0)