public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Jaben Carsey <jaben.carsey@intel.com>
To: edk2-devel@lists.01.org
Cc: Liming Gao <liming.gao@intel.com>, Yonghong Zhu <yonghong.zhu@intel.com>
Subject: [PATCH v1 1/2] BaseTools: refactor to remove functions
Date: Thu, 17 May 2018 17:06:51 -0700	[thread overview]
Message-ID: <fccbcbbb2f9f65e3a93c74c28c01c293c67fa5d5.1526601941.git.jaben.carsey@intel.com> (raw)
In-Reply-To: <cover.1526601941.git.jaben.carsey@intel.com>
In-Reply-To: <cover.1526601941.git.jaben.carsey@intel.com>

refactoring almost identical functions to delete and use the other.

Cc: Liming Gao <liming.gao@intel.com>
Cc: Yonghong Zhu <yonghong.zhu@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jaben Carsey <jaben.carsey@intel.com>
---
 BaseTools/Source/Python/AutoGen/AutoGen.py           | 165 ++------------------
 BaseTools/Source/Python/Workspace/WorkspaceCommon.py |  52 ++++--
 2 files changed, 45 insertions(+), 172 deletions(-)

diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py b/BaseTools/Source/Python/AutoGen/AutoGen.py
index 1e6511cdb5d2..d1801bff9c83 100644
--- a/BaseTools/Source/Python/AutoGen/AutoGen.py
+++ b/BaseTools/Source/Python/AutoGen/AutoGen.py
@@ -42,6 +42,7 @@ from GenPatchPcdTable.GenPatchPcdTable import parsePcdInfoFromMapFile
 import Common.VpdInfoFile as VpdInfoFile
 from GenPcdDb import CreatePcdDatabaseCode
 from Workspace.MetaFileCommentParser import UsageList
+from Workspace.WorkspaceCommon import GetModuleLibInstances
 from Common.MultipleWorkspace import MultipleWorkspace as mws
 import InfSectionParser
 import datetime
@@ -2156,162 +2157,14 @@ class PlatformAutoGen(AutoGen):
         if str(Module) not in self.Platform.Modules:
             return []
 
-        ModuleType = Module.ModuleType
-
-        # for overridding library instances with module specific setting
-        PlatformModule = self.Platform.Modules[str(Module)]
-
-        # add forced library instances (specified under LibraryClasses sections)
-        #
-        # If a module has a MODULE_TYPE of USER_DEFINED,
-        # do not link in NULL library class instances from the global [LibraryClasses.*] sections.
-        #
-        if Module.ModuleType != SUP_MODULE_USER_DEFINED:
-            for LibraryClass in self.Platform.LibraryClasses.GetKeys():
-                if LibraryClass.startswith("NULL") and self.Platform.LibraryClasses[LibraryClass, Module.ModuleType]:
-                    Module.LibraryClasses[LibraryClass] = self.Platform.LibraryClasses[LibraryClass, Module.ModuleType]
-
-        # add forced library instances (specified in module overrides)
-        for LibraryClass in PlatformModule.LibraryClasses:
-            if LibraryClass.startswith("NULL"):
-                Module.LibraryClasses[LibraryClass] = PlatformModule.LibraryClasses[LibraryClass]
-
-        # EdkII module
-        LibraryConsumerList = [Module]
-        Constructor         = []
-        ConsumedByList      = OrderedDict()
-        LibraryInstance     = OrderedDict()
-
-        EdkLogger.verbose("")
-        EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))
-        while len(LibraryConsumerList) > 0:
-            M = LibraryConsumerList.pop()
-            for LibraryClassName in M.LibraryClasses:
-                if LibraryClassName not in LibraryInstance:
-                    # override library instance for this module
-                    if LibraryClassName in PlatformModule.LibraryClasses:
-                        LibraryPath = PlatformModule.LibraryClasses[LibraryClassName]
-                    else:
-                        LibraryPath = self.Platform.LibraryClasses[LibraryClassName, ModuleType]
-                    if LibraryPath is None or LibraryPath == "":
-                        LibraryPath = M.LibraryClasses[LibraryClassName]
-                        if LibraryPath is None or LibraryPath == "":
-                            EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,
-                                            "Instance of library class [%s] is not found" % LibraryClassName,
-                                            File=self.MetaFile,
-                                            ExtraData="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M), self.Arch, str(Module)))
-
-                    LibraryModule = self.BuildDatabase[LibraryPath, self.Arch, self.BuildTarget, self.ToolChain]
-                    # for those forced library instance (NULL library), add a fake library class
-                    if LibraryClassName.startswith("NULL"):
-                        LibraryModule.LibraryClass.append(LibraryClassObject(LibraryClassName, [ModuleType]))
-                    elif LibraryModule.LibraryClass is None \
-                         or len(LibraryModule.LibraryClass) == 0 \
-                         or (ModuleType != SUP_MODULE_USER_DEFINED
-                             and ModuleType not in LibraryModule.LibraryClass[0].SupModList):
-                        # only USER_DEFINED can link against any library instance despite of its SupModList
-                        EdkLogger.error("build", OPTION_MISSING,
-                                        "Module type [%s] is not supported by library instance [%s]" \
-                                        % (ModuleType, LibraryPath), File=self.MetaFile,
-                                        ExtraData="consumed by [%s]" % str(Module))
-
-                    LibraryInstance[LibraryClassName] = LibraryModule
-                    LibraryConsumerList.append(LibraryModule)
-                    EdkLogger.verbose("\t" + str(LibraryClassName) + " : " + str(LibraryModule))
-                else:
-                    LibraryModule = LibraryInstance[LibraryClassName]
-
-                if LibraryModule is None:
-                    continue
-
-                if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor:
-                    Constructor.append(LibraryModule)
-
-                if LibraryModule not in ConsumedByList:
-                    ConsumedByList[LibraryModule] = []
-                # don't add current module itself to consumer list
-                if M != Module:
-                    if M in ConsumedByList[LibraryModule]:
-                        continue
-                    ConsumedByList[LibraryModule].append(M)
-        #
-        # Initialize the sorted output list to the empty set
-        #
-        SortedLibraryList = []
-        #
-        # Q <- Set of all nodes with no incoming edges
-        #
-        LibraryList = [] #LibraryInstance.values()
-        Q = []
-        for LibraryClassName in LibraryInstance:
-            M = LibraryInstance[LibraryClassName]
-            LibraryList.append(M)
-            if ConsumedByList[M] == []:
-                Q.append(M)
-
-        #
-        # start the  DAG algorithm
-        #
-        while True:
-            EdgeRemoved = True
-            while Q == [] and EdgeRemoved:
-                EdgeRemoved = False
-                # for each node Item with a Constructor
-                for Item in LibraryList:
-                    if Item not in Constructor:
-                        continue
-                    # for each Node without a constructor with an edge e from Item to Node
-                    for Node in ConsumedByList[Item]:
-                        if Node in Constructor:
-                            continue
-                        # remove edge e from the graph if Node has no constructor
-                        ConsumedByList[Item].remove(Node)
-                        EdgeRemoved = True
-                        if ConsumedByList[Item] == []:
-                            # insert Item into Q
-                            Q.insert(0, Item)
-                            break
-                    if Q != []:
-                        break
-            # DAG is done if there's no more incoming edge for all nodes
-            if Q == []:
-                break
-
-            # remove node from Q
-            Node = Q.pop()
-            # output Node
-            SortedLibraryList.append(Node)
-
-            # for each node Item with an edge e from Node to Item do
-            for Item in LibraryList:
-                if Node not in ConsumedByList[Item]:
-                    continue
-                # remove edge e from the graph
-                ConsumedByList[Item].remove(Node)
-
-                if ConsumedByList[Item] != []:
-                    continue
-                # insert Item into Q, if Item has no other incoming edges
-                Q.insert(0, Item)
-
-        #
-        # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle
-        #
-        for Item in LibraryList:
-            if ConsumedByList[Item] != [] and Item in Constructor and len(Constructor) > 1:
-                ErrorMessage = "\tconsumed by " + "\n\tconsumed by ".join(str(L) for L in ConsumedByList[Item])
-                EdkLogger.error("build", BUILD_ERROR, 'Library [%s] with constructors has a cycle' % str(Item),
-                                ExtraData=ErrorMessage, File=self.MetaFile)
-            if Item not in SortedLibraryList:
-                SortedLibraryList.append(Item)
-
-        #
-        # Build the list of constructor and destructir names
-        # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order
-        #
-        SortedLibraryList.reverse()
-        return SortedLibraryList
-
+        return GetModuleLibInstances(Module,
+                                     self.Platform,
+                                     self.BuildDatabase,
+                                     self.Arch,
+                                     self.BuildTarget,
+                                     self.ToolChain,
+                                     self.MetaFile,
+                                     EdkLogger)
 
     ## Override PCD setting (type, value, ...)
     #
diff --git a/BaseTools/Source/Python/Workspace/WorkspaceCommon.py b/BaseTools/Source/Python/Workspace/WorkspaceCommon.py
index 573100081815..a28fbdf03021 100644
--- a/BaseTools/Source/Python/Workspace/WorkspaceCommon.py
+++ b/BaseTools/Source/Python/Workspace/WorkspaceCommon.py
@@ -83,16 +83,13 @@ def GetDeclaredPcd(Platform, BuildDatabase, Arch, Target, Toolchain,additionalPk
 #
 def GetLiabraryInstances(Module, Platform, BuildDatabase, Arch, Target, Toolchain):
     if Module.AutoGenVersion >= 0x00010005:
-        return _GetModuleLibraryInstances(Module, Platform, BuildDatabase, Arch, Target, Toolchain)
+        return GetModuleLibInstances(Module, Platform, BuildDatabase, Arch, Target, Toolchain)
     else:
         return _ResolveLibraryReference(Module, Platform)
 
-def _GetModuleLibraryInstances(Module, Platform, BuildDatabase, Arch, Target, Toolchain):
+def GetModuleLibInstances(Module, Platform, BuildDatabase, Arch, Target, Toolchain, FileName = '', EdkLogger = None):
     ModuleType = Module.ModuleType
 
-    # for overriding library instances with module specific setting
-    PlatformModule = Platform.Modules[str(Module)]
-
     # add forced library instances (specified under LibraryClasses sections)
     #
     # If a module has a MODULE_TYPE of USER_DEFINED,
@@ -104,9 +101,9 @@ def _GetModuleLibraryInstances(Module, Platform, BuildDatabase, Arch, Target, To
                 Module.LibraryClasses[LibraryClass] = Platform.LibraryClasses[LibraryClass, Module.ModuleType]
 
     # add forced library instances (specified in module overrides)
-    for LibraryClass in PlatformModule.LibraryClasses:
+    for LibraryClass in Platform.Modules[str(Module)].LibraryClasses:
         if LibraryClass.startswith("NULL"):
-            Module.LibraryClasses[LibraryClass] = PlatformModule.LibraryClasses[LibraryClass]
+            Module.LibraryClasses[LibraryClass] = Platform.Modules[str(Module)].LibraryClasses[LibraryClass]
 
     # EdkII module
     LibraryConsumerList = [Module]
@@ -114,19 +111,29 @@ def _GetModuleLibraryInstances(Module, Platform, BuildDatabase, Arch, Target, To
     ConsumedByList = OrderedListDict()
     LibraryInstance = OrderedDict()
 
+    if FileName:
+        EdkLogger.verbose("")
+        EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), Arch))
+
     while len(LibraryConsumerList) > 0:
         M = LibraryConsumerList.pop()
         for LibraryClassName in M.LibraryClasses:
             if LibraryClassName not in LibraryInstance:
                 # override library instance for this module
-                if LibraryClassName in PlatformModule.LibraryClasses:
-                    LibraryPath = PlatformModule.LibraryClasses[LibraryClassName]
+                if LibraryClassName in Platform.Modules[str(Module)].LibraryClasses:
+                    LibraryPath = Platform.Modules[str(Module)].LibraryClasses[LibraryClassName]
                 else:
                     LibraryPath = Platform.LibraryClasses[LibraryClassName, ModuleType]
                 if LibraryPath is None or LibraryPath == "":
                     LibraryPath = M.LibraryClasses[LibraryClassName]
                     if LibraryPath is None or LibraryPath == "":
-                        return []
+                        if FileName:
+                            EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,
+                                            "Instance of library class [%s] is not found" % LibraryClassName,
+                                            File=FileName,
+                                            ExtraData="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M), Arch, str(Module)))
+                        else:
+                            return []
 
                 LibraryModule = BuildDatabase[LibraryPath, Arch, Target, Toolchain]
                 # for those forced library instance (NULL library), add a fake library class
@@ -137,10 +144,18 @@ def _GetModuleLibraryInstances(Module, Platform, BuildDatabase, Arch, Target, To
                      or (ModuleType != SUP_MODULE_USER_DEFINED
                          and ModuleType not in LibraryModule.LibraryClass[0].SupModList):
                     # only USER_DEFINED can link against any library instance despite of its SupModList
-                    return []
+                    if FileName:
+                        EdkLogger.error("build", OPTION_MISSING,
+                                        "Module type [%s] is not supported by library instance [%s]" \
+                                        % (ModuleType, LibraryPath), File=FileName,
+                                        ExtraData="consumed by [%s]" % str(Module))
+                    else:
+                        return []
 
                 LibraryInstance[LibraryClassName] = LibraryModule
                 LibraryConsumerList.append(LibraryModule)
+                if FileName:
+                    EdkLogger.verbose("\t" + str(LibraryClassName) + " : " + str(LibraryModule))
             else:
                 LibraryModule = LibraryInstance[LibraryClassName]
 
@@ -167,7 +182,7 @@ def _GetModuleLibraryInstances(Module, Platform, BuildDatabase, Arch, Target, To
     for LibraryClassName in LibraryInstance:
         M = LibraryInstance[LibraryClassName]
         LibraryList.append(M)
-        if len(ConsumedByList[M]) == 0:
+        if not ConsumedByList[M]:
             Q.append(M)
 
     #
@@ -188,7 +203,7 @@ def _GetModuleLibraryInstances(Module, Platform, BuildDatabase, Arch, Target, To
                     # remove edge e from the graph if Node has no constructor
                     ConsumedByList[Item].remove(Node)
                     EdgeRemoved = True
-                    if len(ConsumedByList[Item]) == 0:
+                    if not ConsumedByList[Item]:
                         # insert Item into Q
                         Q.insert(0, Item)
                         break
@@ -210,7 +225,7 @@ def _GetModuleLibraryInstances(Module, Platform, BuildDatabase, Arch, Target, To
             # remove edge e from the graph
             ConsumedByList[Item].remove(Node)
 
-            if len(ConsumedByList[Item]) != 0:
+            if ConsumedByList[Item]:
                 continue
             # insert Item into Q, if Item has no other incoming edges
             Q.insert(0, Item)
@@ -219,8 +234,13 @@ def _GetModuleLibraryInstances(Module, Platform, BuildDatabase, Arch, Target, To
     # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle
     #
     for Item in LibraryList:
-        if len(ConsumedByList[Item]) != 0 and Item in Constructor and len(Constructor) > 1:
-            return []
+        if ConsumedByList[Item] and Item in Constructor and len(Constructor) > 1:
+            if FileName:
+                ErrorMessage = "\tconsumed by " + "\n\tconsumed by ".join(str(L) for L in ConsumedByList[Item])
+                EdkLogger.error("build", BUILD_ERROR, 'Library [%s] with constructors has a cycle' % str(Item),
+                                ExtraData=ErrorMessage, File=FileName)
+            else:
+                return []
         if Item not in SortedLibraryList:
             SortedLibraryList.append(Item)
 
-- 
2.16.2.windows.1



  reply	other threads:[~2018-05-18  0:06 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-18  0:06 [PATCH v1 0/2] BaseTools: cleanup for speed Jaben Carsey
2018-05-18  0:06 ` Jaben Carsey [this message]
2018-05-18  0:06 ` [PATCH v1 2/2] BaseTools: Cleanup unneeded code Jaben Carsey
2018-06-12  6:43 ` [PATCH v1 0/2] BaseTools: cleanup for speed Zhu, Yonghong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=fccbcbbb2f9f65e3a93c74c28c01c293c67fa5d5.1526601941.git.jaben.carsey@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox