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: