X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2FWorkspace%2FWorkspaceCommon.py;h=d987bbf441eab71c149a88b5d7f4658c7d8cc52a;hp=60acc914e9d262f6ab15c960ed854ed3a9272f6c;hb=1100bc5aa05097306cdecc4d0118cc312da79d45;hpb=4afd3d042215afe68d00b9ab8c32f063a3a1c03f diff --git a/BaseTools/Source/Python/Workspace/WorkspaceCommon.py b/BaseTools/Source/Python/Workspace/WorkspaceCommon.py index 60acc914e9..d987bbf441 100644 --- a/BaseTools/Source/Python/Workspace/WorkspaceCommon.py +++ b/BaseTools/Source/Python/Workspace/WorkspaceCommon.py @@ -1,7 +1,7 @@ ## @file # Common routines used by workspace # -# Copyright (c) 2012, Intel Corporation. All rights reserved.
+# Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.
# This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License # which accompanies this distribution. The full text of the license may be found at @@ -11,9 +11,20 @@ # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. # -from Common.Misc import sdict +from __future__ import absolute_import +from collections import OrderedDict, defaultdict from Common.DataType import SUP_MODULE_USER_DEFINED -from BuildClassObject import LibraryClassObject +from .BuildClassObject import LibraryClassObject +import Common.GlobalData as GlobalData +from Workspace.BuildClassObject import StructurePcd +from Common.BuildToolError import RESOURCE_NOT_AVAILABLE +from Common.BuildToolError import OPTION_MISSING +from Common.BuildToolError import BUILD_ERROR + +class OrderedListDict(OrderedDict, defaultdict): + def __init__(self, *args, **kwargs): + super(OrderedListDict, self).__init__(*args, **kwargs) + self.default_factory = list ## Get all packages from platform for specified arch, target and toolchain # @@ -41,14 +52,28 @@ def GetPackageList(Platform, BuildDatabase, Arch, Target, Toolchain): # @param Target: Current target # @param Toolchain: Current toolchain # @retval: A dictionary contains instances of PcdClassObject with key (PcdCName, TokenSpaceGuid) +# @retval: A dictionary contains real GUIDs of TokenSpaceGuid # -def GetDeclaredPcd(Platform, BuildDatabase, Arch, Target, Toolchain): +def GetDeclaredPcd(Platform, BuildDatabase, Arch, Target, Toolchain, additionalPkgs): PkgList = GetPackageList(Platform, BuildDatabase, Arch, Target, Toolchain) + PkgList = set(PkgList) + PkgList |= additionalPkgs DecPcds = {} + GuidDict = {} for Pkg in PkgList: + Guids = Pkg.Guids + GuidDict.update(Guids) for Pcd in Pkg.Pcds: - DecPcds[Pcd[0], Pcd[1]] = Pkg.Pcds[Pcd] - return DecPcds + PcdCName = Pcd[0] + PcdTokenName = Pcd[1] + if GlobalData.MixedPcd: + for PcdItem in GlobalData.MixedPcd: + if (PcdCName, PcdTokenName) in GlobalData.MixedPcd[PcdItem]: + PcdCName = PcdItem[0] + break + if (PcdCName, PcdTokenName) not in DecPcds: + DecPcds[PcdCName, PcdTokenName] = Pkg.Pcds[Pcd] + return DecPcds, GuidDict ## Get all dependent libraries for a module # @@ -62,16 +87,13 @@ def GetDeclaredPcd(Platform, BuildDatabase, Arch, Target, Toolchain): # 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, @@ -83,54 +105,70 @@ 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] Constructor = [] - ConsumedByList = sdict() - LibraryInstance = sdict() + 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 == None or LibraryPath == "": + if LibraryPath is None or LibraryPath == "": LibraryPath = M.LibraryClasses[LibraryClassName] - if LibraryPath == None or LibraryPath == "": - return [] + if LibraryPath is None or LibraryPath == "": + 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 if LibraryClassName.startswith("NULL"): LibraryModule.LibraryClass.append(LibraryClassObject(LibraryClassName, [ModuleType])) - elif LibraryModule.LibraryClass == None \ + elif LibraryModule.LibraryClass is None \ or len(LibraryModule.LibraryClass) == 0 \ - or (ModuleType != 'USER_DEFINED' + 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] - if LibraryModule == None: + 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]: @@ -148,7 +186,7 @@ def _GetModuleLibraryInstances(Module, Platform, BuildDatabase, Arch, Target, To for LibraryClassName in LibraryInstance: M = LibraryInstance[LibraryClassName] LibraryList.append(M) - if ConsumedByList[M] == []: + if not ConsumedByList[M]: Q.append(M) # @@ -169,7 +207,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 ConsumedByList[Item] == []: + if not ConsumedByList[Item]: # insert Item into Q Q.insert(0, Item) break @@ -191,7 +229,7 @@ def _GetModuleLibraryInstances(Module, Platform, BuildDatabase, Arch, Target, To # remove edge e from the graph ConsumedByList[Item].remove(Node) - if ConsumedByList[Item] != []: + if ConsumedByList[Item]: continue # insert Item into Q, if Item has no other incoming edges Q.insert(0, Item) @@ -200,8 +238,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 ConsumedByList[Item] != [] 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) @@ -223,12 +266,12 @@ def _ResolveLibraryReference(Module, Platform): M = LibraryConsumerList.pop() for LibraryName in M.Libraries: Library = Platform.LibraryClasses[LibraryName, ':dummy:'] - if Library == None: - for Key in Platform.LibraryClasses.data.keys(): + if Library is None: + for Key in Platform.LibraryClasses.data: if LibraryName.upper() == Key.upper(): Library = Platform.LibraryClasses[Key, ':dummy:'] break - if Library == None: + if Library is None: continue if Library not in LibraryList: