- ModuleType = Module.ModuleType\r
-\r
- # for overridding library instances with module specific setting\r
- PlatformModule = self.Platform.Modules[str(Module)]\r
-\r
- # add forced library instances (specified under LibraryClasses sections)\r
- #\r
- # If a module has a MODULE_TYPE of USER_DEFINED,\r
- # do not link in NULL library class instances from the global [LibraryClasses.*] sections.\r
- #\r
- if Module.ModuleType != SUP_MODULE_USER_DEFINED:\r
- for LibraryClass in self.Platform.LibraryClasses.GetKeys():\r
- if LibraryClass.startswith("NULL") and self.Platform.LibraryClasses[LibraryClass, Module.ModuleType]:\r
- Module.LibraryClasses[LibraryClass] = self.Platform.LibraryClasses[LibraryClass, Module.ModuleType]\r
-\r
- # add forced library instances (specified in module overrides)\r
- for LibraryClass in PlatformModule.LibraryClasses:\r
- if LibraryClass.startswith("NULL"):\r
- Module.LibraryClasses[LibraryClass] = PlatformModule.LibraryClasses[LibraryClass]\r
-\r
- # EdkII module\r
- LibraryConsumerList = [Module]\r
- Constructor = []\r
- ConsumedByList = sdict()\r
- LibraryInstance = sdict()\r
-\r
- EdkLogger.verbose("")\r
- EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))\r
- while len(LibraryConsumerList) > 0:\r
- M = LibraryConsumerList.pop()\r
- for LibraryClassName in M.LibraryClasses:\r
- if LibraryClassName not in LibraryInstance:\r
- # override library instance for this module\r
- if LibraryClassName in PlatformModule.LibraryClasses:\r
- LibraryPath = PlatformModule.LibraryClasses[LibraryClassName]\r
- else:\r
- LibraryPath = self.Platform.LibraryClasses[LibraryClassName, ModuleType]\r
- if LibraryPath == None or LibraryPath == "":\r
- LibraryPath = M.LibraryClasses[LibraryClassName]\r
- if LibraryPath == None or LibraryPath == "":\r
- EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,\r
- "Instance of library class [%s] is not found" % LibraryClassName,\r
- File=self.MetaFile,\r
- ExtraData="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M), self.Arch, str(Module)))\r
-\r
- LibraryModule = self.BuildDatabase[LibraryPath, self.Arch, self.BuildTarget, self.ToolChain]\r
- # for those forced library instance (NULL library), add a fake library class\r
- if LibraryClassName.startswith("NULL"):\r
- LibraryModule.LibraryClass.append(LibraryClassObject(LibraryClassName, [ModuleType]))\r
- elif LibraryModule.LibraryClass == None \\r
- or len(LibraryModule.LibraryClass) == 0 \\r
- or (ModuleType != 'USER_DEFINED'\r
- and ModuleType not in LibraryModule.LibraryClass[0].SupModList):\r
- # only USER_DEFINED can link against any library instance despite of its SupModList\r
- EdkLogger.error("build", OPTION_MISSING,\r
- "Module type [%s] is not supported by library instance [%s]" \\r
- % (ModuleType, LibraryPath), File=self.MetaFile,\r
- ExtraData="consumed by [%s]" % str(Module))\r
-\r
- LibraryInstance[LibraryClassName] = LibraryModule\r
- LibraryConsumerList.append(LibraryModule)\r
- EdkLogger.verbose("\t" + str(LibraryClassName) + " : " + str(LibraryModule))\r
- else:\r
- LibraryModule = LibraryInstance[LibraryClassName]\r
-\r
- if LibraryModule == None:\r
- continue\r
-\r
- if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor:\r
- Constructor.append(LibraryModule)\r
-\r
- if LibraryModule not in ConsumedByList:\r
- ConsumedByList[LibraryModule] = []\r
- # don't add current module itself to consumer list\r
- if M != Module:\r
- if M in ConsumedByList[LibraryModule]:\r
- continue\r
- ConsumedByList[LibraryModule].append(M)\r
- #\r
- # Initialize the sorted output list to the empty set\r
- #\r
- SortedLibraryList = []\r
- #\r
- # Q <- Set of all nodes with no incoming edges\r
- #\r
- LibraryList = [] #LibraryInstance.values()\r
- Q = []\r
- for LibraryClassName in LibraryInstance:\r
- M = LibraryInstance[LibraryClassName]\r
- LibraryList.append(M)\r
- if ConsumedByList[M] == []:\r
- Q.append(M)\r
-\r
- #\r
- # start the DAG algorithm\r
- #\r
- while True:\r
- EdgeRemoved = True\r
- while Q == [] and EdgeRemoved:\r
- EdgeRemoved = False\r
- # for each node Item with a Constructor\r
- for Item in LibraryList:\r
- if Item not in Constructor:\r
- continue\r
- # for each Node without a constructor with an edge e from Item to Node\r
- for Node in ConsumedByList[Item]:\r
- if Node in Constructor:\r
- continue\r
- # remove edge e from the graph if Node has no constructor\r
- ConsumedByList[Item].remove(Node)\r
- EdgeRemoved = True\r
- if ConsumedByList[Item] == []:\r
- # insert Item into Q\r
- Q.insert(0, Item)\r
- break\r
- if Q != []:\r
- break\r
- # DAG is done if there's no more incoming edge for all nodes\r
- if Q == []:\r
- break\r
-\r
- # remove node from Q\r
- Node = Q.pop()\r
- # output Node\r
- SortedLibraryList.append(Node)\r
-\r
- # for each node Item with an edge e from Node to Item do\r
- for Item in LibraryList:\r
- if Node not in ConsumedByList[Item]:\r
- continue\r
- # remove edge e from the graph\r
- ConsumedByList[Item].remove(Node)\r
-\r
- if ConsumedByList[Item] != []:\r
- continue\r
- # insert Item into Q, if Item has no other incoming edges\r
- Q.insert(0, Item)\r
-\r
- #\r
- # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle\r
- #\r
- for Item in LibraryList:\r
- if ConsumedByList[Item] != [] and Item in Constructor and len(Constructor) > 1:\r
- ErrorMessage = "\tconsumed by " + "\n\tconsumed by ".join([str(L) for L in ConsumedByList[Item]])\r
- EdkLogger.error("build", BUILD_ERROR, 'Library [%s] with constructors has a cycle' % str(Item),\r
- ExtraData=ErrorMessage, File=self.MetaFile)\r
- if Item not in SortedLibraryList:\r
- SortedLibraryList.append(Item)\r
-\r
- #\r
- # Build the list of constructor and destructir names\r
- # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order\r
- #\r
- SortedLibraryList.reverse()\r
- return SortedLibraryList\r
-\r