summaryrefslogtreecommitdiffstats
path: root/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
diff options
context:
space:
mode:
authorFeng, Bob C <bob.c.feng@intel.com>2019-07-22 11:09:22 +0800
committerFeng, Bob C <bob.c.feng@intel.com>2019-08-09 23:15:52 +0800
commite8449e1d8e3b40186eb16ff25242397cffb00a63 (patch)
tree91e6fd4742f6cc2b351be2f5bfe02ab1a4ea1b38 /BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
parent197ca7febf8668be505ff904f75b97f9e465df82 (diff)
downloadedk2-e8449e1d8e3b40186eb16ff25242397cffb00a63.tar.gz
edk2-e8449e1d8e3b40186eb16ff25242397cffb00a63.tar.bz2
edk2-e8449e1d8e3b40186eb16ff25242397cffb00a63.zip
BaseTools: Decouple AutoGen Objects
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=1875 1. Separate the AutoGen.py into 3 small py files. One is for AutoGen base class, one is for WorkspaceAutoGen class and PlatformAutoGen class, and the one for ModuleAutoGen class. 2. Create a new class DataPipe to store the Platform scope settings. Create a new class PlatformInfo to provide the same interface as PlatformAutoGen. PlatformInfo class is initialized by DataPipe instance. Create a new class WorkspaceInfo to provide the same interface as WorkspaceAutoGen. WorkspaceInfo class is initialized by DataPipe instance. 3. Change ModuleAutoGen to depends on DataPipe, PlatformInfo and WorkspaceInfo. Remove the dependency of ModuleAutoGen to PlatformAutoGen. Cc: Liming Gao <liming.gao@intel.com> Cc: Steven Shi <steven.shi@intel.com> Signed-off-by: Bob Feng <bob.c.feng@intel.com> Acked-by: Laszlo Ersek <lersek@redhat.com> Tested-by: Laszlo Ersek <lersek@redhat.com> Acked-by: Liming Gao <liming.gao@intel.com>
Diffstat (limited to 'BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py')
-rw-r--r--BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py619
1 files changed, 619 insertions, 0 deletions
diff --git a/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py b/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
new file mode 100644
index 0000000000..c7591253de
--- /dev/null
+++ b/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
@@ -0,0 +1,619 @@
+## @file
+# Create makefile for MS nmake and GNU make
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+from __future__ import absolute_import
+from Workspace.WorkspaceDatabase import WorkspaceDatabase,BuildDB
+from Common.caching import cached_property
+from AutoGen.BuildEngine import BuildRule,AutoGenReqBuildRuleVerNum
+from AutoGen.AutoGen import CalculatePriorityValue
+from Common.Misc import CheckPcdDatum,GuidValue
+from Common.Expression import ValueExpressionEx
+from Common.DataType import *
+from CommonDataClass.Exceptions import *
+from CommonDataClass.CommonClass import SkuInfoClass
+import Common.EdkLogger as EdkLogger
+from Common.BuildToolError import OPTION_CONFLICT,FORMAT_INVALID,RESOURCE_NOT_AVAILABLE
+from Common.MultipleWorkspace import MultipleWorkspace as mws
+from collections import defaultdict
+from Common.Misc import PathClass
+import os
+
+
+#
+# The priority list while override build option
+#
+PrioList = {"0x11111" : 16, # TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE (Highest)
+ "0x01111" : 15, # ******_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE
+ "0x10111" : 14, # TARGET_*********_ARCH_COMMANDTYPE_ATTRIBUTE
+ "0x00111" : 13, # ******_*********_ARCH_COMMANDTYPE_ATTRIBUTE
+ "0x11011" : 12, # TARGET_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE
+ "0x01011" : 11, # ******_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE
+ "0x10011" : 10, # TARGET_*********_****_COMMANDTYPE_ATTRIBUTE
+ "0x00011" : 9, # ******_*********_****_COMMANDTYPE_ATTRIBUTE
+ "0x11101" : 8, # TARGET_TOOLCHAIN_ARCH_***********_ATTRIBUTE
+ "0x01101" : 7, # ******_TOOLCHAIN_ARCH_***********_ATTRIBUTE
+ "0x10101" : 6, # TARGET_*********_ARCH_***********_ATTRIBUTE
+ "0x00101" : 5, # ******_*********_ARCH_***********_ATTRIBUTE
+ "0x11001" : 4, # TARGET_TOOLCHAIN_****_***********_ATTRIBUTE
+ "0x01001" : 3, # ******_TOOLCHAIN_****_***********_ATTRIBUTE
+ "0x10001" : 2, # TARGET_*********_****_***********_ATTRIBUTE
+ "0x00001" : 1} # ******_*********_****_***********_ATTRIBUTE (Lowest)
+## Base class for AutoGen
+#
+# This class just implements the cache mechanism of AutoGen objects.
+#
+class AutoGenInfo(object):
+ # database to maintain the objects in each child class
+ __ObjectCache = {} # (BuildTarget, ToolChain, ARCH, platform file): AutoGen object
+
+ ## Factory method
+ #
+ # @param Class class object of real AutoGen class
+ # (WorkspaceAutoGen, ModuleAutoGen or PlatformAutoGen)
+ # @param Workspace Workspace directory or WorkspaceAutoGen object
+ # @param MetaFile The path of meta file
+ # @param Target Build target
+ # @param Toolchain Tool chain name
+ # @param Arch Target arch
+ # @param *args The specific class related parameters
+ # @param **kwargs The specific class related dict parameters
+ #
+ @classmethod
+ def GetCache(cls):
+ return cls.__ObjectCache
+ def __new__(cls, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):
+ # check if the object has been created
+ Key = (Target, Toolchain, Arch, MetaFile)
+ if Key in cls.__ObjectCache:
+ # if it exists, just return it directly
+ return cls.__ObjectCache[Key]
+ # it didnt exist. create it, cache it, then return it
+ RetVal = cls.__ObjectCache[Key] = super(AutoGenInfo, cls).__new__(cls)
+ return RetVal
+
+
+ ## hash() operator
+ #
+ # The file path of platform file will be used to represent hash value of this object
+ #
+ # @retval int Hash value of the file path of platform file
+ #
+ def __hash__(self):
+ return hash(self.MetaFile)
+
+ ## str() operator
+ #
+ # The file path of platform file will be used to represent this object
+ #
+ # @retval string String of platform file path
+ #
+ def __str__(self):
+ return str(self.MetaFile)
+
+ ## "==" operator
+ def __eq__(self, Other):
+ return Other and self.MetaFile == Other
+
+ ## Expand * in build option key
+ #
+ # @param Options Options to be expanded
+ # @param ToolDef Use specified ToolDef instead of full version.
+ # This is needed during initialization to prevent
+ # infinite recursion betweeh BuildOptions,
+ # ToolDefinition, and this function.
+ #
+ # @retval options Options expanded
+ #
+ def _ExpandBuildOption(self, Options, ModuleStyle=None, ToolDef=None):
+ if not ToolDef:
+ ToolDef = self.ToolDefinition
+ BuildOptions = {}
+ FamilyMatch = False
+ FamilyIsNull = True
+
+ OverrideList = {}
+ #
+ # Construct a list contain the build options which need override.
+ #
+ for Key in Options:
+ #
+ # Key[0] -- tool family
+ # Key[1] -- TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE
+ #
+ if (Key[0] == self.BuildRuleFamily and
+ (ModuleStyle is None or len(Key) < 3 or (len(Key) > 2 and Key[2] == ModuleStyle))):
+ Target, ToolChain, Arch, CommandType, Attr = Key[1].split('_')
+ if (Target == self.BuildTarget or Target == TAB_STAR) and\
+ (ToolChain == self.ToolChain or ToolChain == TAB_STAR) and\
+ (Arch == self.Arch or Arch == TAB_STAR) and\
+ Options[Key].startswith("="):
+
+ if OverrideList.get(Key[1]) is not None:
+ OverrideList.pop(Key[1])
+ OverrideList[Key[1]] = Options[Key]
+
+ #
+ # Use the highest priority value.
+ #
+ if (len(OverrideList) >= 2):
+ KeyList = list(OverrideList.keys())
+ for Index in range(len(KeyList)):
+ NowKey = KeyList[Index]
+ Target1, ToolChain1, Arch1, CommandType1, Attr1 = NowKey.split("_")
+ for Index1 in range(len(KeyList) - Index - 1):
+ NextKey = KeyList[Index1 + Index + 1]
+ #
+ # Compare two Key, if one is included by another, choose the higher priority one
+ #
+ Target2, ToolChain2, Arch2, CommandType2, Attr2 = NextKey.split("_")
+ if (Target1 == Target2 or Target1 == TAB_STAR or Target2 == TAB_STAR) and\
+ (ToolChain1 == ToolChain2 or ToolChain1 == TAB_STAR or ToolChain2 == TAB_STAR) and\
+ (Arch1 == Arch2 or Arch1 == TAB_STAR or Arch2 == TAB_STAR) and\
+ (CommandType1 == CommandType2 or CommandType1 == TAB_STAR or CommandType2 == TAB_STAR) and\
+ (Attr1 == Attr2 or Attr1 == TAB_STAR or Attr2 == TAB_STAR):
+
+ if CalculatePriorityValue(NowKey) > CalculatePriorityValue(NextKey):
+ if Options.get((self.BuildRuleFamily, NextKey)) is not None:
+ Options.pop((self.BuildRuleFamily, NextKey))
+ else:
+ if Options.get((self.BuildRuleFamily, NowKey)) is not None:
+ Options.pop((self.BuildRuleFamily, NowKey))
+
+ for Key in Options:
+ if ModuleStyle is not None and len (Key) > 2:
+ # Check Module style is EDK or EDKII.
+ # Only append build option for the matched style module.
+ if ModuleStyle == EDK_NAME and Key[2] != EDK_NAME:
+ continue
+ elif ModuleStyle == EDKII_NAME and Key[2] != EDKII_NAME:
+ continue
+ Family = Key[0]
+ Target, Tag, Arch, Tool, Attr = Key[1].split("_")
+ # if tool chain family doesn't match, skip it
+ if Tool in ToolDef and Family != "":
+ FamilyIsNull = False
+ if ToolDef[Tool].get(TAB_TOD_DEFINES_BUILDRULEFAMILY, "") != "":
+ if Family != ToolDef[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
+ continue
+ elif Family != ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
+ continue
+ FamilyMatch = True
+ # expand any wildcard
+ if Target == TAB_STAR or Target == self.BuildTarget:
+ if Tag == TAB_STAR or Tag == self.ToolChain:
+ if Arch == TAB_STAR or Arch == self.Arch:
+ if Tool not in BuildOptions:
+ BuildOptions[Tool] = {}
+ if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or Options[Key].startswith('='):
+ BuildOptions[Tool][Attr] = Options[Key]
+ else:
+ # append options for the same tool except PATH
+ if Attr != 'PATH':
+ BuildOptions[Tool][Attr] += " " + Options[Key]
+ else:
+ BuildOptions[Tool][Attr] = Options[Key]
+ # Build Option Family has been checked, which need't to be checked again for family.
+ if FamilyMatch or FamilyIsNull:
+ return BuildOptions
+
+ for Key in Options:
+ if ModuleStyle is not None and len (Key) > 2:
+ # Check Module style is EDK or EDKII.
+ # Only append build option for the matched style module.
+ if ModuleStyle == EDK_NAME and Key[2] != EDK_NAME:
+ continue
+ elif ModuleStyle == EDKII_NAME and Key[2] != EDKII_NAME:
+ continue
+ Family = Key[0]
+ Target, Tag, Arch, Tool, Attr = Key[1].split("_")
+ # if tool chain family doesn't match, skip it
+ if Tool not in ToolDef or Family == "":
+ continue
+ # option has been added before
+ if Family != ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
+ continue
+
+ # expand any wildcard
+ if Target == TAB_STAR or Target == self.BuildTarget:
+ if Tag == TAB_STAR or Tag == self.ToolChain:
+ if Arch == TAB_STAR or Arch == self.Arch:
+ if Tool not in BuildOptions:
+ BuildOptions[Tool] = {}
+ if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or Options[Key].startswith('='):
+ BuildOptions[Tool][Attr] = Options[Key]
+ else:
+ # append options for the same tool except PATH
+ if Attr != 'PATH':
+ BuildOptions[Tool][Attr] += " " + Options[Key]
+ else:
+ BuildOptions[Tool][Attr] = Options[Key]
+ return BuildOptions
+#
+#This class is the pruned WorkSpaceAutoGen for ModuleAutoGen in multiple thread
+#
+class WorkSpaceInfo(AutoGenInfo):
+ def __init__(self,Workspace, MetaFile, Target, ToolChain, Arch):
+ self._SrcTimeStamp = 0
+ self.Db = BuildDB
+ self.BuildDatabase = self.Db.BuildObject
+ self.Target = Target
+ self.ToolChain = ToolChain
+ self.WorkspaceDir = Workspace
+ self.ActivePlatform = MetaFile
+ self.ArchList = Arch
+
+
+class PlatformInfo(AutoGenInfo):
+ def __init__(self, Workspace, MetaFile, Target, ToolChain, Arch,DataPipe):
+ self.Wa = Workspace
+ self.WorkspaceDir = self.Wa.WorkspaceDir
+ self.MetaFile = MetaFile
+ self.Arch = Arch
+ self.Target = Target
+ self.BuildTarget = Target
+ self.ToolChain = ToolChain
+ self.Platform = self.Wa.BuildDatabase[self.MetaFile, self.Arch, self.Target, self.ToolChain]
+
+ self.SourceDir = MetaFile.SubDir
+ self.DataPipe = DataPipe
+ @cached_property
+ def _AsBuildModuleList(self):
+ retVal = self.DataPipe.Get("AsBuildModuleList")
+ if retVal is None:
+ retVal = {}
+ return retVal
+
+ ## Test if a module is supported by the platform
+ #
+ # An error will be raised directly if the module or its arch is not supported
+ # by the platform or current configuration
+ #
+ def ValidModule(self, Module):
+ return Module in self.Platform.Modules or Module in self.Platform.LibraryInstances \
+ or Module in self._AsBuildModuleList
+
+ @cached_property
+ def ToolChainFamily(self):
+ retVal = self.DataPipe.Get("ToolChainFamily")
+ if retVal is None:
+ retVal = {}
+ return retVal
+
+ @cached_property
+ def BuildRuleFamily(self):
+ retVal = self.DataPipe.Get("BuildRuleFamily")
+ if retVal is None:
+ retVal = {}
+ return retVal
+
+ @cached_property
+ def _MbList(self):
+ return [self.Wa.BuildDatabase[m, self.Arch, self.BuildTarget, self.ToolChain] for m in self.Platform.Modules]
+
+ @cached_property
+ def PackageList(self):
+ RetVal = set()
+ for dec_file,Arch in self.DataPipe.Get("PackageList"):
+ RetVal.add(self.Wa.BuildDatabase[dec_file,Arch,self.BuildTarget, self.ToolChain])
+ return list(RetVal)
+
+ ## Return the directory to store all intermediate and final files built
+ @cached_property
+ def BuildDir(self):
+ if os.path.isabs(self.OutputDir):
+ RetVal = os.path.join(
+ os.path.abspath(self.OutputDir),
+ self.Target + "_" + self.ToolChain,
+ )
+ else:
+ RetVal = os.path.join(
+ self.WorkspaceDir,
+ self.OutputDir,
+ self.Target + "_" + self.ToolChain,
+ )
+ return RetVal
+
+ ## Return the build output directory platform specifies
+ @cached_property
+ def OutputDir(self):
+ return self.Platform.OutputDirectory
+
+ ## Return platform name
+ @cached_property
+ def Name(self):
+ return self.Platform.PlatformName
+
+ ## Return meta-file GUID
+ @cached_property
+ def Guid(self):
+ return self.Platform.Guid
+
+ ## Return platform version
+ @cached_property
+ def Version(self):
+ return self.Platform.Version
+
+ ## Return paths of tools
+ @cached_property
+ def ToolDefinition(self):
+ retVal = self.DataPipe.Get("TOOLDEF")
+ if retVal is None:
+ retVal = {}
+ return retVal
+
+ ## Return build command string
+ #
+ # @retval string Build command string
+ #
+ @cached_property
+ def BuildCommand(self):
+ retVal = self.DataPipe.Get("BuildCommand")
+ if retVal is None:
+ retVal = []
+ return retVal
+
+ @cached_property
+ def PcdTokenNumber(self):
+ retVal = self.DataPipe.Get("PCD_TNUM")
+ if retVal is None:
+ retVal = {}
+ return retVal
+
+ ## Override PCD setting (type, value, ...)
+ #
+ # @param ToPcd The PCD to be overridden
+ # @param FromPcd The PCD overriding from
+ #
+ def _OverridePcd(self, ToPcd, FromPcd, Module="", Msg="", Library=""):
+ #
+ # in case there's PCDs coming from FDF file, which have no type given.
+ # at this point, ToPcd.Type has the type found from dependent
+ # package
+ #
+ TokenCName = ToPcd.TokenCName
+ for PcdItem in self.MixedPcd:
+ if (ToPcd.TokenCName, ToPcd.TokenSpaceGuidCName) in self.MixedPcd[PcdItem]:
+ TokenCName = PcdItem[0]
+ break
+ if FromPcd is not None:
+ if ToPcd.Pending and FromPcd.Type:
+ ToPcd.Type = FromPcd.Type
+ elif ToPcd.Type and FromPcd.Type\
+ and ToPcd.Type != FromPcd.Type and ToPcd.Type in FromPcd.Type:
+ if ToPcd.Type.strip() == TAB_PCDS_DYNAMIC_EX:
+ ToPcd.Type = FromPcd.Type
+ elif ToPcd.Type and FromPcd.Type \
+ and ToPcd.Type != FromPcd.Type:
+ if Library:
+ Module = str(Module) + " 's library file (" + str(Library) + ")"
+ EdkLogger.error("build", OPTION_CONFLICT, "Mismatched PCD type",
+ ExtraData="%s.%s is used as [%s] in module %s, but as [%s] in %s."\
+ % (ToPcd.TokenSpaceGuidCName, TokenCName,
+ ToPcd.Type, Module, FromPcd.Type, Msg),
+ File=self.MetaFile)
+
+ if FromPcd.MaxDatumSize:
+ ToPcd.MaxDatumSize = FromPcd.MaxDatumSize
+ ToPcd.MaxSizeUserSet = FromPcd.MaxDatumSize
+ if FromPcd.DefaultValue:
+ ToPcd.DefaultValue = FromPcd.DefaultValue
+ if FromPcd.TokenValue:
+ ToPcd.TokenValue = FromPcd.TokenValue
+ if FromPcd.DatumType:
+ ToPcd.DatumType = FromPcd.DatumType
+ if FromPcd.SkuInfoList:
+ ToPcd.SkuInfoList = FromPcd.SkuInfoList
+ if FromPcd.UserDefinedDefaultStoresFlag:
+ ToPcd.UserDefinedDefaultStoresFlag = FromPcd.UserDefinedDefaultStoresFlag
+ # Add Flexible PCD format parse
+ if ToPcd.DefaultValue:
+ try:
+ ToPcd.DefaultValue = ValueExpressionEx(ToPcd.DefaultValue, ToPcd.DatumType, self._GuidDict)(True)
+ except BadExpression as Value:
+ EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %(ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName, ToPcd.DefaultValue, Value),
+ File=self.MetaFile)
+
+ # check the validation of datum
+ IsValid, Cause = CheckPcdDatum(ToPcd.DatumType, ToPcd.DefaultValue)
+ if not IsValid:
+ EdkLogger.error('build', FORMAT_INVALID, Cause, File=self.MetaFile,
+ ExtraData="%s.%s" % (ToPcd.TokenSpaceGuidCName, TokenCName))
+ ToPcd.validateranges = FromPcd.validateranges
+ ToPcd.validlists = FromPcd.validlists
+ ToPcd.expressions = FromPcd.expressions
+ ToPcd.CustomAttribute = FromPcd.CustomAttribute
+
+ if FromPcd is not None and ToPcd.DatumType == TAB_VOID and not ToPcd.MaxDatumSize:
+ EdkLogger.debug(EdkLogger.DEBUG_9, "No MaxDatumSize specified for PCD %s.%s" \
+ % (ToPcd.TokenSpaceGuidCName, TokenCName))
+ Value = ToPcd.DefaultValue
+ if not Value:
+ ToPcd.MaxDatumSize = '1'
+ elif Value[0] == 'L':
+ ToPcd.MaxDatumSize = str((len(Value) - 2) * 2)
+ elif Value[0] == '{':
+ ToPcd.MaxDatumSize = str(len(Value.split(',')))
+ else:
+ ToPcd.MaxDatumSize = str(len(Value) - 1)
+
+ # apply default SKU for dynamic PCDS if specified one is not available
+ if (ToPcd.Type in PCD_DYNAMIC_TYPE_SET or ToPcd.Type in PCD_DYNAMIC_EX_TYPE_SET) \
+ and not ToPcd.SkuInfoList:
+ if self.Platform.SkuName in self.Platform.SkuIds:
+ SkuName = self.Platform.SkuName
+ else:
+ SkuName = TAB_DEFAULT
+ ToPcd.SkuInfoList = {
+ SkuName : SkuInfoClass(SkuName, self.Platform.SkuIds[SkuName][0], '', '', '', '', '', ToPcd.DefaultValue)
+ }
+
+ def ApplyPcdSetting(self, Module, Pcds, Library=""):
+ # for each PCD in module
+ for Name, Guid in Pcds:
+ PcdInModule = Pcds[Name, Guid]
+ # find out the PCD setting in platform
+ if (Name, Guid) in self.Pcds:
+ PcdInPlatform = self.Pcds[Name, Guid]
+ else:
+ PcdInPlatform = None
+ # then override the settings if any
+ self._OverridePcd(PcdInModule, PcdInPlatform, Module, Msg="DSC PCD sections", Library=Library)
+ # resolve the VariableGuid value
+ for SkuId in PcdInModule.SkuInfoList:
+ Sku = PcdInModule.SkuInfoList[SkuId]
+ if Sku.VariableGuid == '': continue
+ Sku.VariableGuidValue = GuidValue(Sku.VariableGuid, self.PackageList, self.MetaFile.Path)
+ if Sku.VariableGuidValue is None:
+ PackageList = "\n\t".join(str(P) for P in self.PackageList)
+ EdkLogger.error(
+ 'build',
+ RESOURCE_NOT_AVAILABLE,
+ "Value of GUID [%s] is not found in" % Sku.VariableGuid,
+ ExtraData=PackageList + "\n\t(used with %s.%s from module %s)" \
+ % (Guid, Name, str(Module)),
+ File=self.MetaFile
+ )
+
+ # override PCD settings with module specific setting
+ if Module in self.Platform.Modules:
+ PlatformModule = self.Platform.Modules[str(Module)]
+ for Key in PlatformModule.Pcds:
+ if self.BuildOptionPcd:
+ for pcd in self.BuildOptionPcd:
+ (TokenSpaceGuidCName, TokenCName, FieldName, pcdvalue, _) = pcd
+ if (TokenCName, TokenSpaceGuidCName) == Key and FieldName =="":
+ PlatformModule.Pcds[Key].DefaultValue = pcdvalue
+ PlatformModule.Pcds[Key].PcdValueFromComm = pcdvalue
+ break
+ Flag = False
+ if Key in Pcds:
+ ToPcd = Pcds[Key]
+ Flag = True
+ elif Key in self.MixedPcd:
+ for PcdItem in self.MixedPcd[Key]:
+ if PcdItem in Pcds:
+ ToPcd = Pcds[PcdItem]
+ Flag = True
+ break
+ if Flag:
+ self._OverridePcd(ToPcd, PlatformModule.Pcds[Key], Module, Msg="DSC Components Module scoped PCD section", Library=Library)
+ # use PCD value to calculate the MaxDatumSize when it is not specified
+ for Name, Guid in Pcds:
+ Pcd = Pcds[Name, Guid]
+ if Pcd.DatumType == TAB_VOID and not Pcd.MaxDatumSize:
+ Pcd.MaxSizeUserSet = None
+ Value = Pcd.DefaultValue
+ if not Value:
+ Pcd.MaxDatumSize = '1'
+ elif Value[0] == 'L':
+ Pcd.MaxDatumSize = str((len(Value) - 2) * 2)
+ elif Value[0] == '{':
+ Pcd.MaxDatumSize = str(len(Value.split(',')))
+ else:
+ Pcd.MaxDatumSize = str(len(Value) - 1)
+ return list(Pcds.values())
+
+ @cached_property
+ def Pcds(self):
+ PlatformPcdData = self.DataPipe.Get("PLA_PCD")
+# for pcd in PlatformPcdData:
+# for skuid in pcd.SkuInfoList:
+# pcd.SkuInfoList[skuid] = self.CreateSkuInfoFromDict(pcd.SkuInfoList[skuid])
+ return {(pcddata.TokenCName,pcddata.TokenSpaceGuidCName):pcddata for pcddata in PlatformPcdData}
+
+ def CreateSkuInfoFromDict(self,SkuInfoDict):
+ return SkuInfoClass(
+ SkuInfoDict.get("SkuIdName"),
+ SkuInfoDict.get("SkuId"),
+ SkuInfoDict.get("VariableName"),
+ SkuInfoDict.get("VariableGuid"),
+ SkuInfoDict.get("VariableOffset"),
+ SkuInfoDict.get("HiiDefaultValue"),
+ SkuInfoDict.get("VpdOffset"),
+ SkuInfoDict.get("DefaultValue"),
+ SkuInfoDict.get("VariableGuidValue"),
+ SkuInfoDict.get("VariableAttribute",""),
+ SkuInfoDict.get("DefaultStore",None)
+ )
+ @cached_property
+ def MixedPcd(self):
+ return self.DataPipe.Get("MixedPcd")
+ @cached_property
+ def _GuidDict(self):
+ RetVal = self.DataPipe.Get("GuidDict")
+ if RetVal is None:
+ RetVal = {}
+ return RetVal
+ @cached_property
+ def BuildOptionPcd(self):
+ return self.DataPipe.Get("BuildOptPcd")
+ def ApplyBuildOption(self,module):
+ PlatformOptions = self.DataPipe.Get("PLA_BO")
+ ModuleBuildOptions = self.DataPipe.Get("MOL_BO")
+ ModuleOptionFromDsc = ModuleBuildOptions.get((module.MetaFile.File,module.MetaFile.Root))
+ if ModuleOptionFromDsc:
+ ModuleTypeOptions, PlatformModuleOptions = ModuleOptionFromDsc["ModuleTypeOptions"],ModuleOptionFromDsc["PlatformModuleOptions"]
+ else:
+ ModuleTypeOptions, PlatformModuleOptions = {}, {}
+ ToolDefinition = self.DataPipe.Get("TOOLDEF")
+ ModuleOptions = self._ExpandBuildOption(module.BuildOptions)
+ BuildRuleOrder = None
+ for Options in [ToolDefinition, ModuleOptions, PlatformOptions, ModuleTypeOptions, PlatformModuleOptions]:
+ for Tool in Options:
+ for Attr in Options[Tool]:
+ if Attr == TAB_TOD_DEFINES_BUILDRULEORDER:
+ BuildRuleOrder = Options[Tool][Attr]
+
+ AllTools = set(list(ModuleOptions.keys()) + list(PlatformOptions.keys()) +
+ list(PlatformModuleOptions.keys()) + list(ModuleTypeOptions.keys()) +
+ list(ToolDefinition.keys()))
+ BuildOptions = defaultdict(lambda: defaultdict(str))
+ for Tool in AllTools:
+ for Options in [ToolDefinition, ModuleOptions, PlatformOptions, ModuleTypeOptions, PlatformModuleOptions]:
+ if Tool not in Options:
+ continue
+ for Attr in Options[Tool]:
+ #
+ # Do not generate it in Makefile
+ #
+ if Attr == TAB_TOD_DEFINES_BUILDRULEORDER:
+ continue
+ Value = Options[Tool][Attr]
+ # check if override is indicated
+ if Value.startswith('='):
+ BuildOptions[Tool][Attr] = mws.handleWsMacro(Value[1:])
+ else:
+ if Attr != 'PATH':
+ BuildOptions[Tool][Attr] += " " + mws.handleWsMacro(Value)
+ else:
+ BuildOptions[Tool][Attr] = mws.handleWsMacro(Value)
+
+ return BuildOptions, BuildRuleOrder
+
+ def ApplyLibraryInstance(self,module):
+ alldeps = self.DataPipe.Get("DEPS")
+ if alldeps is None:
+ alldeps = {}
+ mod_libs = alldeps.get((module.MetaFile.File,module.MetaFile.Root,module.Arch,module.MetaFile.Path),[])
+ retVal = []
+ for (file_path,root,arch,abs_path) in mod_libs:
+ libMetaFile = PathClass(file_path,root)
+ libMetaFile.OriginalPath = PathClass(file_path,root)
+ libMetaFile.Path = abs_path
+ retVal.append(self.Wa.BuildDatabase[libMetaFile, arch, self.Target,self.ToolChain])
+ return retVal
+
+ ## Parse build_rule.txt in Conf Directory.
+ #
+ # @retval BuildRule object
+ #
+ @cached_property
+ def BuildRule(self):
+ WInfo = self.DataPipe.Get("P_Info")
+ RetVal = WInfo.get("BuildRuleFile")
+ if RetVal._FileVersion == "":
+ RetVal._FileVersion = AutoGenReqBuildRuleVerNum
+ return RetVal