Daniel Carvalho has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/43587 )

Change subject: scons: Allow declaring dependencies of tags
......................................................................

scons: Allow declaring dependencies of tags

It was quite incovenient to declare tags. tags either
had to be added to the Source declaration of included
files, or using (with_tag()) would need to be added
with all the indirect sub-tags. For example,

Assume:
- B.hh includes A.hh
- C.hh includes B.hh (i.e., it needs A transitively)
- D.hh includes A.hh and C.hh (i.e., it needs B trans.)

So either their SConscript would be:
  Source('A.cc', add_tags=['B', 'D'])
  Source('B.cc', add_tags='B')
  Source('C.cc', add_tags='C')
  Source('D.cc', add_tags='D')

  GTest('A.test', 'A.test.cc', 'a.cc')
  GTest('B.test', 'B.test.cc', with_tag('B'))
  GTest('C.test', 'C.test.cc', with_any_tags('B', 'C'))
  GTest('D.test', 'D.test.cc', with_any_tags('B', 'C', 'D'))

or:
  Source('A.cc', add_tags=['B', 'C', 'D'])
  Source('B.cc', add_tags=['B', 'C', 'D'])
  Source('C.cc', add_tags=['C', 'D'])
  Source('D.cc', add_tags='D')

  GTest('A.test', 'A.test.cc', 'a.cc')
  GTest('B.test', 'B.test.cc', with_tag('B'))
  GTest('C.test', 'C.test.cc', with_tag('C'))
  GTest('D.test', 'D.test.cc', with_tag('D'))

This change makes it simpler. The tag should be added
only to the files directly included by the functionality
being tagged. Using the same example:

  Source('A.cc', add_tags=['B', 'D'])
  Source('B.cc', add_tags='B')
  Source('C.cc', add_tags='C')
  Source('D.cc', add_tags='D')

  DeclareTagDependencies('B', 'A')
  DeclareTagDependencies('C', 'B')
  DeclareTagDependencies('D', ['A', 'C'])

  GTest('A.test', 'A.test.cc', 'a.cc')
  GTest('B.test', 'B.test.cc', with_tag('B'))
  GTest('C.test', 'C.test.cc', with_tag('C'))
  GTest('D.test', 'D.test.cc', with_tag('D'))

This also means that when changing the includes one
only needs to change the declared tag dependencies,
not the transitive tag dependencies.

Change-Id: I5be07b01864f8d5df83f59002dfd2f01c73d5e09
Signed-off-by: Daniel R. Carvalho <oda...@yahoo.com.br>
---
M src/SConscript
1 file changed, 38 insertions(+), 4 deletions(-)



diff --git a/src/SConscript b/src/SConscript
index 31fce0c..c3a1db3 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -71,6 +71,35 @@
 # When specifying a source file of some type, a set of tags can be
 # specified for that file.

+tag_dependencies = {}
+class DeclareTagDependencies(object):
+    '''Associates a tag A to a list of tags on which A depends.'''
+    def __init__(self, tag, tag_list):
+        if tag in tag_dependencies.keys():
+            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)
+        tag_dependencies[tag] = tag_list
+
+    def get_all_dependencies(tags):
+        if isinstance(tags, str):
+            tags = frozenset([tags])
+        if not isinstance(tags, frozenset):
+            tags = frozenset(tags)
+
+        dependencies = set()
+        for tag in tags:
+            if tag_dependencies.get(tag) is not None:
+                dependencies |= tag_dependencies.get(tag)
+                for dependency in tag_dependencies.get(tag):
+                    dependencies |= DeclareTagDependencies.\
+                        get_all_dependencies(tag_dependencies[tag])
+        return dependencies
+
 class SourceFilter(object):
     def __init__(self, predicate):
         self.predicate = predicate
@@ -89,22 +118,26 @@

 def with_any_tags(*tags):
     '''Return a list of sources with any of the supplied tags.'''
-    return SourceFilter(lambda stags: len(set(tags) & stags) > 0)
+    return SourceFilter((lambda stags: len(set(tags) & stags) > 0) or \
+ (len(set(DeclareTagDependencies.get_all_dependencies(tags)) & stags) \
+            > 0))

 def with_all_tags(*tags):
     '''Return a list of sources with all of the supplied tags.'''
-    return SourceFilter(lambda stags: set(tags) <= stags)
+    return SourceFilter(lambda stags: (set(tags) <= stags) and \
+        (set(DeclareTagDependencies.get_all_dependencies(tags)) <= stags))

 def with_tag(tag):
     '''Return a list of sources with the supplied tag.'''
-    return SourceFilter(lambda stags: tag in stags)
+    return SourceFilter(lambda stags: (tag in stags) or \
+ (len(DeclareTagDependencies.get_all_dependencies(tag) & stags) > 0))

 def without_tags(*tags):
     '''Return a list of sources without any of the supplied tags.'''
     return SourceFilter(lambda stags: len(set(tags) & stags) == 0)

 def without_tag(tag):
-    '''Return a list of sources with the supplied tag.'''
+    '''Return a list of sources without the supplied tag.'''
     return SourceFilter(lambda stags: tag not in stags)

 source_filter_factories = {
@@ -576,6 +609,7 @@


 # Children should have access
+Export('DeclareTagDependencies')
 Export('Blob')
 Export('GdbXml')
 Export('Source')

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/43587
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: I5be07b01864f8d5df83f59002dfd2f01c73d5e09
Gerrit-Change-Number: 43587
Gerrit-PatchSet: 1
Gerrit-Owner: Daniel Carvalho <oda...@yahoo.com.br>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to