Gabe Black has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/44388 )
Change subject: scons: Move loose tag_implies to env.TagImplies.
......................................................................
scons: Move loose tag_implies to env.TagImplies.
Also plumb through an environment to resolve tags against when applying
filters to source lists.
Change-Id: I93010d208272fcfa5f1a13219d58f237f82e3ed9
---
M src/SConscript
1 file changed, 60 insertions(+), 69 deletions(-)
diff --git a/src/SConscript b/src/SConscript
index 6206e1a..e5536dd 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -71,7 +71,7 @@
# When specifying a source file of some type, a set of tags can be
# specified for that file.
-class TagImplies(object):
+def tag_implies(env, tag, tag_list):
'''
Associates a tag X to a list of tags which are implied by X.
@@ -98,73 +98,64 @@
after being resolved.
'''
- # The dictionary of tag dependencies, which is populated with every
- # instance of this class
- _dependencies = {}
+ env.SetDefault(_tag_implies={})
+ implications = env['_tag_implies']
+ if tag in implications:
+ raise AttributeError("Dependency list of tag {} has already " \
+ "been specified".format(tag))
- def __init__(self, tag, tag_list):
- if tag in TagImplies._dependencies:
- raise AttributeError("Dependency list of tag {} has already " \
- "been specified".format(tag))
+ if isinstance(tag_list, str):
+ tag_list = frozenset([tag_list])
+ if not isinstance(tag_list, frozenset):
+ tag_list = frozenset(tag_list)
+ implications[tag] = tag_list
- if isinstance(tag_list, str):
- tag_list = frozenset([tag_list])
- if not isinstance(tag_list, frozenset):
- tag_list = frozenset(tag_list)
- TagImplies._dependencies[tag] = tag_list
+ # Check if any of the tags on which the new tag depends on already
+ # has a list of dependencies. If so, add the list to the new tag's
+ # dependencies
+ for t in tag_list:
+ if t in implications:
+ implications[tag] |= implications[t]
- # Check if any of the tags on which the new tag depends on already
- # has a list of dependencies. If so, add the list to the new tag's
- # dependencies
- for t in tag_list:
- if t in TagImplies._dependencies:
- TagImplies._dependencies[tag] |= \
- TagImplies._dependencies[t]
+ # Check if another tag depends on this tag. If so, add this tag's
+ # dependencies to that tag.
+ for t,dep in implications.items():
+ if tag in dep:
+ implications[t] |= implications[tag]
- # Check if another tag depends on this tag. If so, add this tag's
- # dependencies to that tag.
- for t,dep in TagImplies._dependencies.items():
- if tag in dep:
- TagImplies._dependencies[t] |= \
- TagImplies._dependencies[tag]
+env.AddMethod(tag_implies, 'TagImplies')
- def resolve(tags):
- '''
- Returns the complete set of tags implied (dependencies) by the
- supplied tags.
- '''
- if isinstance(tags, str):
- tags = frozenset([tags])
- if not isinstance(tags, frozenset):
- tags = frozenset(tags)
-
- dependencies = set()
- dependencies |= tags
- for tag in tags:
- if tag in TagImplies._dependencies:
- dependencies |= TagImplies._dependencies[tag]
- return dependencies
-
-# External API
-def tag_implies(tag, implied_tags):
+def resolve_tags(env, tags):
'''
- Associates a tag X to a list of tags which are implied by X.
- @see TagImplies
+ Returns the complete set of tags implied (dependencies) by the
+ supplied tags.
'''
- TagImplies(tag, implied_tags)
-Export('tag_implies')
+
+ implications = env.SetDefault(_tag_implies={})
+ implications = env['_tag_implies']
+
+ if isinstance(tags, str):
+ tags = frozenset([tags])
+ if not isinstance(tags, frozenset):
+ tags = frozenset(tags)
+
+ tags = tags.copy()
+ for tag in tags:
+ if tag in implications:
+ tags |= implications[tag]
+ return tags
class SourceFilter(object):
def __init__(self, predicate):
self.predicate = predicate
def __or__(self, other):
- return SourceFilter(lambda tags: self.predicate(tags) or
- other.predicate(tags))
+ return SourceFilter(lambda env, tags: self.predicate(env, tags) or
+ other.predicate(env, tags))
def __and__(self, other):
- return SourceFilter(lambda tags: self.predicate(tags) and
- other.predicate(tags))
+ return SourceFilter(lambda env, tags: self.predicate(env, tags) and
+ other.predicate(env, tags))
def with_tags_that(predicate):
'''Return a list of sources with tags that satisfy a predicate.'''
@@ -172,13 +163,12 @@
def with_any_tags(*tags):
'''Return a list of sources with any of the supplied tags.'''
- return SourceFilter(lambda stags: \
- len(TagImplies.resolve(tags) & stags) > 0)
+ return SourceFilter(lambda env, stags: \
+ len(resolve_tags(env, tags) & stags) > 0)
def with_all_tags(*tags):
'''Return a list of sources with all of the supplied tags.'''
- return SourceFilter(lambda stags: \
- TagImplies.resolve(tags) <= stags)
+ return SourceFilter(lambda env, stags: resolve_tags(env, tags) <=
stags)
def with_tag(tag):
'''Return a list of sources with the supplied tag.'''
@@ -186,8 +176,8 @@
def without_tags(*tags):
'''Return a list of sources without any of the supplied tags.'''
- return SourceFilter(lambda stags: \
- len(TagImplies.resolve(tags) & stags) == 0)
+ return SourceFilter(lambda env, stags: \
+ len(resolve_tags(env, tags) & stags) == 0)
def without_tag(tag):
'''Return a list of sources without the supplied tag.'''
@@ -205,9 +195,9 @@
Export(source_filter_factories)
class SourceList(list):
- def apply_filter(self, f):
+ def apply_filter(self, env, f):
def match(source):
- return f.predicate(source.tags)
+ return f.predicate(env, source.tags)
return SourceList(filter(match, self))
def __getattr__(self, name):
@@ -216,8 +206,8 @@
raise AttributeError
@functools.wraps(func)
- def wrapper(*args, **kwargs):
- return self.apply_filter(func(*args, **kwargs))
+ def wrapper(env, *args, **kwargs):
+ return self.apply_filter(env, func(*args, **kwargs))
return wrapper
class SourceMeta(type):
@@ -609,7 +599,7 @@
def declare(self, env):
sources = list(self.sources)
for f in self.filters:
- sources += Source.all.apply_filter(f)
+ sources += Source.all.apply_filter(env, f)
objs = self.srcs_to_objs(env, sources) + env['STATIC_OBJS']
if self.main:
objs += env['MAIN_OBJS']
@@ -628,7 +618,7 @@
env = env.Clone()
env.Append(LIBS=env['GTEST_LIBS'])
env.Append(CPPFLAGS=env['GTEST_CPPFLAGS'])
- env['GTEST_LIB_SOURCES'] = Source.all.with_tag('gtest lib')
+ env['GTEST_LIB_SOURCES'] = Source.all.with_tag(env, 'gtest lib')
env['GTEST_OUT_DIR'] = \
Dir(env['BUILDDIR']).Dir('unittests.' + env['EXE_SUFFIX'])
return super(GTest, cls).declare_all(env)
@@ -638,7 +628,7 @@
if not self.skip_lib:
sources += env['GTEST_LIB_SOURCES']
for f in self.filters:
- sources += Source.all.apply_filter(f)
+ sources += Source.all.apply_filter(env, f)
objs = self.srcs_to_objs(env, sources)
binary = super(GTest, self).declare(env, objs)
@@ -1372,12 +1362,12 @@
new_env.Label = label
new_env.Append(**kwargs)
- lib_sources = Source.all.with_tag('gem5 lib')
+ lib_sources = Source.all.with_tag(new_env, 'gem5 lib')
# Without Python, leave out all Python content from the library
# builds. The option doesn't affect gem5 built as a program
if GetOption('without_python'):
- lib_sources = lib_sources.without_tag('python')
+ lib_sources = lib_sources.without_tag(new_env, 'python')
static_objs = list([ s.static(new_env) for s in lib_sources ])
shared_objs = list([ s.shared(new_env) for s in lib_sources ])
@@ -1390,7 +1380,8 @@
new_env.Depends(shared_date, shared_objs)
shared_objs.extend(shared_date)
- main_objs = [ s.static(new_env) for s in Source.all.with_tag('main') ]
+ main_objs = [ s.static(new_env) for s in
+ Source.all.with_tag(new_env, 'main') ]
# First make a library of everything but main() so other programs can
# link against m5.
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/44388
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I93010d208272fcfa5f1a13219d58f237f82e3ed9
Gerrit-Change-Number: 44388
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s