BaseTools: Refactor PlatformAutoGen

use decorators for property and automatic caching
remove circular dependency between some APIs

Cc: Liming Gao <liming.gao@intel.com>
Cc: Yonghong Zhu <yonghong.zhu@intel.com>
Cc: Bob Feng <Bob.c.Feng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jaben Carsey <jaben.carsey@intel.com>
Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
This commit is contained in:
Carsey, Jaben
2018-09-11 06:18:01 +08:00
committed by Yonghong Zhu
parent f199664ce7
commit e6eae3b4c7

View File

@ -1046,41 +1046,13 @@ class PlatformAutoGen(AutoGen):
# get the original module/package/platform objects # get the original module/package/platform objects
self.BuildDatabase = Workspace.BuildDatabase self.BuildDatabase = Workspace.BuildDatabase
self.DscBuildDataObj = Workspace.Platform self.DscBuildDataObj = Workspace.Platform
self._GuidDict = Workspace._GuidDict
# flag indicating if the makefile/C-code file has been created or not # flag indicating if the makefile/C-code file has been created or not
self.IsMakeFileCreated = False self.IsMakeFileCreated = False
self.IsCodeFileCreated = False
self._Platform = None
self._Name = None
self._Guid = None
self._Version = None
self._BuildRule = None
self._SourceDir = None
self._BuildDir = None
self._OutputDir = None
self._FvDir = None
self._MakeFileDir = None
self._FdfFile = None
self._PcdTokenNumber = None # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber
self._DynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...] self._DynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
self._NonDynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...] self._NonDynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
self._NonDynamicPcdDict = {}
self._ToolDefinitions = None
self._ToolDefFile = None # toolcode : tool path
self._ToolChainFamily = None
self._BuildRuleFamily = None
self._BuildOption = None # toolcode : option
self._EdkBuildOption = None # edktoolcode : option
self._EdkIIBuildOption = None # edkiitoolcode : option
self._PackageList = None
self._ModuleAutoGenList = None
self._LibraryAutoGenList = None
self._BuildCommand = None
self._AsBuildInfList = [] self._AsBuildInfList = []
self._AsBuildModuleList = [] self._AsBuildModuleList = []
@ -1100,6 +1072,7 @@ class PlatformAutoGen(AutoGen):
return True return True
@cached_class_function
def __repr__(self): def __repr__(self):
return "%s [%s]" % (self.MetaFile, self.Arch) return "%s [%s]" % (self.MetaFile, self.Arch)
@ -1111,19 +1084,18 @@ class PlatformAutoGen(AutoGen):
# @param CreateModuleCodeFile Flag indicating if creating module's # @param CreateModuleCodeFile Flag indicating if creating module's
# autogen code file or not # autogen code file or not
# #
@cached_class_function
def CreateCodeFile(self, CreateModuleCodeFile=False): def CreateCodeFile(self, CreateModuleCodeFile=False):
# only module has code to be greated, so do nothing if CreateModuleCodeFile is False # only module has code to be greated, so do nothing if CreateModuleCodeFile is False
if self.IsCodeFileCreated or not CreateModuleCodeFile: if not CreateModuleCodeFile:
return return
for Ma in self.ModuleAutoGenList: for Ma in self.ModuleAutoGenList:
Ma.CreateCodeFile(True) Ma.CreateCodeFile(True)
# don't do this twice
self.IsCodeFileCreated = True
## Generate Fds Command ## Generate Fds Command
def _GenFdsCommand(self): @cached_property
def GenFdsCommand(self):
return self.Workspace.GenFdsCommand return self.Workspace.GenFdsCommand
## Create makefile for the platform and mdoules in it ## Create makefile for the platform and mdoules in it
@ -1185,7 +1157,6 @@ class PlatformAutoGen(AutoGen):
LibAuto.ConstPcd[key] = FixedAtBuildPcds[key] LibAuto.ConstPcd[key] = FixedAtBuildPcds[key]
def CollectVariables(self, DynamicPcdSet): def CollectVariables(self, DynamicPcdSet):
VpdRegionSize = 0 VpdRegionSize = 0
VpdRegionBase = 0 VpdRegionBase = 0
if self.Workspace.FdfFile: if self.Workspace.FdfFile:
@ -1197,7 +1168,6 @@ class PlatformAutoGen(AutoGen):
VpdRegionBase = FdRegion.Offset VpdRegionBase = FdRegion.Offset
break break
VariableInfo = VariableMgr(self.DscBuildDataObj._GetDefaultStores(), self.DscBuildDataObj._GetSkuIds()) VariableInfo = VariableMgr(self.DscBuildDataObj._GetDefaultStores(), self.DscBuildDataObj._GetSkuIds())
VariableInfo.SetVpdRegionMaxSize(VpdRegionSize) VariableInfo.SetVpdRegionMaxSize(VpdRegionSize)
VariableInfo.SetVpdRegionOffset(VpdRegionBase) VariableInfo.SetVpdRegionOffset(VpdRegionBase)
@ -1250,7 +1220,6 @@ class PlatformAutoGen(AutoGen):
# This interface should be invoked explicitly when platform action is created. # This interface should be invoked explicitly when platform action is created.
# #
def CollectPlatformDynamicPcds(self): def CollectPlatformDynamicPcds(self):
for key in self.Platform.Pcds: for key in self.Platform.Pcds:
for SinglePcd in GlobalData.MixedPcd: for SinglePcd in GlobalData.MixedPcd:
if (self.Platform.Pcds[key].TokenCName, self.Platform.Pcds[key].TokenSpaceGuidCName) == SinglePcd: if (self.Platform.Pcds[key].TokenCName, self.Platform.Pcds[key].TokenSpaceGuidCName) == SinglePcd:
@ -1687,308 +1656,301 @@ class PlatformAutoGen(AutoGen):
EdkLogger.error("Build", FILE_NOT_FOUND, "Fail to find third-party BPDG tool to process VPD PCDs. BPDG Guid tool need to be defined in tools_def.txt and VPD_TOOL_GUID need to be provided in DSC file.") EdkLogger.error("Build", FILE_NOT_FOUND, "Fail to find third-party BPDG tool to process VPD PCDs. BPDG Guid tool need to be defined in tools_def.txt and VPD_TOOL_GUID need to be provided in DSC file.")
## Return the platform build data object ## Return the platform build data object
def _GetPlatform(self): @cached_property
if self._Platform is None: def Platform(self):
self._Platform = self.BuildDatabase[self.MetaFile, self.Arch, self.BuildTarget, self.ToolChain] return self.BuildDatabase[self.MetaFile, self.Arch, self.BuildTarget, self.ToolChain]
return self._Platform
## Return platform name ## Return platform name
def _GetName(self): @cached_property
def Name(self):
return self.Platform.PlatformName return self.Platform.PlatformName
## Return the meta file GUID ## Return the meta file GUID
def _GetGuid(self): @cached_property
def Guid(self):
return self.Platform.Guid return self.Platform.Guid
## Return the platform version ## Return the platform version
def _GetVersion(self): @cached_property
def Version(self):
return self.Platform.Version return self.Platform.Version
## Return the FDF file name ## Return the FDF file name
def _GetFdfFile(self): @cached_property
if self._FdfFile is None: def FdfFile(self):
if self.Workspace.FdfFile != "": if self.Workspace.FdfFile:
self._FdfFile= mws.join(self.WorkspaceDir, self.Workspace.FdfFile) RetVal= mws.join(self.WorkspaceDir, self.Workspace.FdfFile)
else: else:
self._FdfFile = '' RetVal = ''
return self._FdfFile return RetVal
## Return the build output directory platform specifies ## Return the build output directory platform specifies
def _GetOutputDir(self): @cached_property
def OutputDir(self):
return self.Platform.OutputDirectory return self.Platform.OutputDirectory
## Return the directory to store all intermediate and final files built ## Return the directory to store all intermediate and final files built
def _GetBuildDir(self): @cached_property
if self._BuildDir is None: def BuildDir(self):
if os.path.isabs(self.OutputDir): if os.path.isabs(self.OutputDir):
self._BuildDir = path.join( GlobalData.gBuildDirectory = RetVal = path.join(
path.abspath(self.OutputDir), path.abspath(self.OutputDir),
self.BuildTarget + "_" + self.ToolChain, self.BuildTarget + "_" + self.ToolChain,
) )
else: else:
self._BuildDir = path.join( GlobalData.gBuildDirectory = RetVal = path.join(
self.WorkspaceDir, self.WorkspaceDir,
self.OutputDir, self.OutputDir,
self.BuildTarget + "_" + self.ToolChain, self.BuildTarget + "_" + self.ToolChain,
) )
GlobalData.gBuildDirectory = self._BuildDir return RetVal
return self._BuildDir
## Return directory of platform makefile ## Return directory of platform makefile
# #
# @retval string Makefile directory # @retval string Makefile directory
# #
def _GetMakeFileDir(self): @cached_property
if self._MakeFileDir is None: def MakeFileDir(self):
self._MakeFileDir = path.join(self.BuildDir, self.Arch) return path.join(self.BuildDir, self.Arch)
return self._MakeFileDir
## Return build command string ## Return build command string
# #
# @retval string Build command string # @retval string Build command string
# #
def _GetBuildCommand(self): @cached_property
if self._BuildCommand is None: def BuildCommand(self):
self._BuildCommand = [] RetVal = []
if "MAKE" in self.ToolDefinition and "PATH" in self.ToolDefinition["MAKE"]: if "MAKE" in self.ToolDefinition and "PATH" in self.ToolDefinition["MAKE"]:
self._BuildCommand += SplitOption(self.ToolDefinition["MAKE"]["PATH"]) RetVal += SplitOption(self.ToolDefinition["MAKE"]["PATH"])
if "FLAGS" in self.ToolDefinition["MAKE"]: if "FLAGS" in self.ToolDefinition["MAKE"]:
NewOption = self.ToolDefinition["MAKE"]["FLAGS"].strip() NewOption = self.ToolDefinition["MAKE"]["FLAGS"].strip()
if NewOption != '': if NewOption != '':
self._BuildCommand += SplitOption(NewOption) RetVal += SplitOption(NewOption)
if "MAKE" in self.EdkIIBuildOption: if "MAKE" in self.EdkIIBuildOption:
if "FLAGS" in self.EdkIIBuildOption["MAKE"]: if "FLAGS" in self.EdkIIBuildOption["MAKE"]:
Flags = self.EdkIIBuildOption["MAKE"]["FLAGS"] Flags = self.EdkIIBuildOption["MAKE"]["FLAGS"]
if Flags.startswith('='): if Flags.startswith('='):
self._BuildCommand = [self._BuildCommand[0]] + [Flags[1:]] RetVal = [RetVal[0]] + [Flags[1:]]
else: else:
self._BuildCommand.append(Flags) RetVal.append(Flags)
return self._BuildCommand return RetVal
## Get tool chain definition ## Get tool chain definition
# #
# Get each tool defition for given tool chain from tools_def.txt and platform # Get each tool defition for given tool chain from tools_def.txt and platform
# #
def _GetToolDefinition(self): @cached_property
if self._ToolDefinitions is None: def ToolDefinition(self):
ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDictionary ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDictionary
if TAB_TOD_DEFINES_COMMAND_TYPE not in self.Workspace.ToolDef.ToolsDefTxtDatabase: if TAB_TOD_DEFINES_COMMAND_TYPE not in self.Workspace.ToolDef.ToolsDefTxtDatabase:
EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No tools found in configuration", EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No tools found in configuration",
ExtraData="[%s]" % self.MetaFile) ExtraData="[%s]" % self.MetaFile)
self._ToolDefinitions = {} RetVal = {}
DllPathList = set() DllPathList = set()
for Def in ToolDefinition: for Def in ToolDefinition:
Target, Tag, Arch, Tool, Attr = Def.split("_") Target, Tag, Arch, Tool, Attr = Def.split("_")
if Target != self.BuildTarget or Tag != self.ToolChain or Arch != self.Arch: if Target != self.BuildTarget or Tag != self.ToolChain or Arch != self.Arch:
continue continue
Value = ToolDefinition[Def] Value = ToolDefinition[Def]
# don't record the DLL # don't record the DLL
if Attr == "DLL": if Attr == "DLL":
DllPathList.add(Value) DllPathList.add(Value)
continue continue
if Tool not in self._ToolDefinitions: if Tool not in RetVal:
self._ToolDefinitions[Tool] = {} RetVal[Tool] = {}
self._ToolDefinitions[Tool][Attr] = Value RetVal[Tool][Attr] = Value
ToolsDef = '' ToolsDef = ''
if GlobalData.gOptions.SilentMode and "MAKE" in self._ToolDefinitions: if GlobalData.gOptions.SilentMode and "MAKE" in RetVal:
if "FLAGS" not in self._ToolDefinitions["MAKE"]: if "FLAGS" not in RetVal["MAKE"]:
self._ToolDefinitions["MAKE"]["FLAGS"] = "" RetVal["MAKE"]["FLAGS"] = ""
self._ToolDefinitions["MAKE"]["FLAGS"] += " -s" RetVal["MAKE"]["FLAGS"] += " -s"
MakeFlags = '' MakeFlags = ''
for Tool in self._ToolDefinitions: for Tool in RetVal:
for Attr in self._ToolDefinitions[Tool]: for Attr in RetVal[Tool]:
Value = self._ToolDefinitions[Tool][Attr] Value = RetVal[Tool][Attr]
if Tool in self.BuildOption and Attr in self.BuildOption[Tool]: if Tool in self._BuildOptionWithToolDef(RetVal) and Attr in self._BuildOptionWithToolDef(RetVal)[Tool]:
# check if override is indicated # check if override is indicated
if self.BuildOption[Tool][Attr].startswith('='): if self._BuildOptionWithToolDef(RetVal)[Tool][Attr].startswith('='):
Value = self.BuildOption[Tool][Attr][1:] Value = self._BuildOptionWithToolDef(RetVal)[Tool][Attr][1:]
else:
if Attr != 'PATH':
Value += " " + self._BuildOptionWithToolDef(RetVal)[Tool][Attr]
else: else:
if Attr != 'PATH': Value = self._BuildOptionWithToolDef(RetVal)[Tool][Attr]
Value += " " + self.BuildOption[Tool][Attr]
else:
Value = self.BuildOption[Tool][Attr]
if Attr == "PATH": if Attr == "PATH":
# Don't put MAKE definition in the file # Don't put MAKE definition in the file
if Tool != "MAKE": if Tool != "MAKE":
ToolsDef += "%s = %s\n" % (Tool, Value) ToolsDef += "%s = %s\n" % (Tool, Value)
elif Attr != "DLL": elif Attr != "DLL":
# Don't put MAKE definition in the file # Don't put MAKE definition in the file
if Tool == "MAKE": if Tool == "MAKE":
if Attr == "FLAGS": if Attr == "FLAGS":
MakeFlags = Value MakeFlags = Value
else: else:
ToolsDef += "%s_%s = %s\n" % (Tool, Attr, Value) ToolsDef += "%s_%s = %s\n" % (Tool, Attr, Value)
ToolsDef += "\n" ToolsDef += "\n"
SaveFileOnChange(self.ToolDefinitionFile, ToolsDef) SaveFileOnChange(self.ToolDefinitionFile, ToolsDef)
for DllPath in DllPathList: for DllPath in DllPathList:
os.environ["PATH"] = DllPath + os.pathsep + os.environ["PATH"] os.environ["PATH"] = DllPath + os.pathsep + os.environ["PATH"]
os.environ["MAKE_FLAGS"] = MakeFlags os.environ["MAKE_FLAGS"] = MakeFlags
return self._ToolDefinitions return RetVal
## Return the paths of tools ## Return the paths of tools
def _GetToolDefFile(self): @cached_property
if self._ToolDefFile is None: def ToolDefinitionFile(self):
self._ToolDefFile = os.path.join(self.MakeFileDir, "TOOLS_DEF." + self.Arch) return os.path.join(self.MakeFileDir, "TOOLS_DEF." + self.Arch)
return self._ToolDefFile
## Retrieve the toolchain family of given toolchain tag. Default to 'MSFT'. ## Retrieve the toolchain family of given toolchain tag. Default to 'MSFT'.
def _GetToolChainFamily(self): @cached_property
if self._ToolChainFamily is None: def ToolChainFamily(self):
ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase
if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \ if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \
or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \ or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \
or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain]: or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain]:
EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \ EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
% self.ToolChain) % self.ToolChain)
self._ToolChainFamily = TAB_COMPILER_MSFT RetVal = TAB_COMPILER_MSFT
else: else:
self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain] RetVal = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain]
return self._ToolChainFamily return RetVal
def _GetBuildRuleFamily(self): @cached_property
if self._BuildRuleFamily is None: def BuildRuleFamily(self):
ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase
if TAB_TOD_DEFINES_BUILDRULEFAMILY not in ToolDefinition \ if TAB_TOD_DEFINES_BUILDRULEFAMILY not in ToolDefinition \
or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY] \ or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY] \
or not ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain]: or not ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain]:
EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \ EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
% self.ToolChain) % self.ToolChain)
self._BuildRuleFamily = TAB_COMPILER_MSFT return TAB_COMPILER_MSFT
else:
self._BuildRuleFamily = ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain] return ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain]
return self._BuildRuleFamily
## Return the build options specific for all modules in this platform ## Return the build options specific for all modules in this platform
def _GetBuildOptions(self): @cached_property
if self._BuildOption is None: def BuildOption(self):
self._BuildOption = self._ExpandBuildOption(self.Platform.BuildOptions) return self._ExpandBuildOption(self.Platform.BuildOptions)
return self._BuildOption
def _BuildOptionWithToolDef(self, ToolDef):
return self._ExpandBuildOption(self.Platform.BuildOptions, ToolDef=ToolDef)
## Return the build options specific for EDK modules in this platform ## Return the build options specific for EDK modules in this platform
def _GetEdkBuildOptions(self): @cached_property
if self._EdkBuildOption is None: def EdkBuildOption(self):
self._EdkBuildOption = self._ExpandBuildOption(self.Platform.BuildOptions, EDK_NAME) return self._ExpandBuildOption(self.Platform.BuildOptions, EDK_NAME)
return self._EdkBuildOption
## Return the build options specific for EDKII modules in this platform ## Return the build options specific for EDKII modules in this platform
def _GetEdkIIBuildOptions(self): @cached_property
if self._EdkIIBuildOption is None: def EdkIIBuildOption(self):
self._EdkIIBuildOption = self._ExpandBuildOption(self.Platform.BuildOptions, EDKII_NAME) return self._ExpandBuildOption(self.Platform.BuildOptions, EDKII_NAME)
return self._EdkIIBuildOption
## Parse build_rule.txt in Conf Directory. ## Parse build_rule.txt in Conf Directory.
# #
# @retval BuildRule object # @retval BuildRule object
# #
def _GetBuildRule(self): @cached_property
if self._BuildRule is None: def BuildRule(self):
BuildRuleFile = None BuildRuleFile = None
if TAB_TAT_DEFINES_BUILD_RULE_CONF in self.Workspace.TargetTxt.TargetTxtDictionary: if TAB_TAT_DEFINES_BUILD_RULE_CONF in self.Workspace.TargetTxt.TargetTxtDictionary:
BuildRuleFile = self.Workspace.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_BUILD_RULE_CONF] BuildRuleFile = self.Workspace.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_BUILD_RULE_CONF]
if not BuildRuleFile: if not BuildRuleFile:
BuildRuleFile = gDefaultBuildRuleFile BuildRuleFile = gDefaultBuildRuleFile
self._BuildRule = BuildRule(BuildRuleFile) RetVal = BuildRule(BuildRuleFile)
if self._BuildRule._FileVersion == "": if RetVal._FileVersion == "":
self._BuildRule._FileVersion = AutoGenReqBuildRuleVerNum RetVal._FileVersion = AutoGenReqBuildRuleVerNum
else: else:
if self._BuildRule._FileVersion < AutoGenReqBuildRuleVerNum : if RetVal._FileVersion < AutoGenReqBuildRuleVerNum :
# If Build Rule's version is less than the version number required by the tools, halting the build. # If Build Rule's version is less than the version number required by the tools, halting the build.
EdkLogger.error("build", AUTOGEN_ERROR, EdkLogger.error("build", AUTOGEN_ERROR,
ExtraData="The version number [%s] of build_rule.txt is less than the version number required by the AutoGen.(the minimum required version number is [%s])"\ ExtraData="The version number [%s] of build_rule.txt is less than the version number required by the AutoGen.(the minimum required version number is [%s])"\
% (self._BuildRule._FileVersion, AutoGenReqBuildRuleVerNum)) % (RetVal._FileVersion, AutoGenReqBuildRuleVerNum))
return RetVal
return self._BuildRule
## Summarize the packages used by modules in this platform ## Summarize the packages used by modules in this platform
def _GetPackageList(self): @cached_property
if self._PackageList is None: def PackageList(self):
self._PackageList = set() RetVal = set()
for La in self.LibraryAutoGenList: for La in self.LibraryAutoGenList:
self._PackageList.update(La.DependentPackageList) RetVal.update(La.DependentPackageList)
for Ma in self.ModuleAutoGenList: for Ma in self.ModuleAutoGenList:
self._PackageList.update(Ma.DependentPackageList) RetVal.update(Ma.DependentPackageList)
#Collect package set information from INF of FDF #Collect package set information from INF of FDF
PkgSet = set() for ModuleFile in self._AsBuildModuleList:
for ModuleFile in self._AsBuildModuleList: if ModuleFile in self.Platform.Modules:
if ModuleFile in self.Platform.Modules: continue
continue ModuleData = self.BuildDatabase[ModuleFile, self.Arch, self.BuildTarget, self.ToolChain]
ModuleData = self.BuildDatabase[ModuleFile, self.Arch, self.BuildTarget, self.ToolChain] RetVal.update(ModuleData.Packages)
PkgSet.update(ModuleData.Packages) return list(RetVal)
self._PackageList = list(self._PackageList) + list (PkgSet)
return self._PackageList
def _GetNonDynamicPcdDict(self): @cached_property
if self._NonDynamicPcdDict: def NonDynamicPcdDict(self):
return self._NonDynamicPcdDict return {(Pcd.TokenCName, Pcd.TokenSpaceGuidCName):Pcd for Pcd in self.NonDynamicPcdList}
for Pcd in self.NonDynamicPcdList:
self._NonDynamicPcdDict[(Pcd.TokenCName, Pcd.TokenSpaceGuidCName)] = Pcd
return self._NonDynamicPcdDict
## Get list of non-dynamic PCDs ## Get list of non-dynamic PCDs
def _GetNonDynamicPcdList(self): @cached_property
if self._NonDynamicPcdList is None: def NonDynamicPcdList(self):
self.CollectPlatformDynamicPcds() self.CollectPlatformDynamicPcds()
return self._NonDynamicPcdList return self._NonDynamicPcdList
## Get list of dynamic PCDs ## Get list of dynamic PCDs
def _GetDynamicPcdList(self): @cached_property
if self._DynamicPcdList is None: def DynamicPcdList(self):
self.CollectPlatformDynamicPcds() self.CollectPlatformDynamicPcds()
return self._DynamicPcdList return self._DynamicPcdList
## Generate Token Number for all PCD ## Generate Token Number for all PCD
def _GetPcdTokenNumbers(self): @cached_property
if self._PcdTokenNumber is None: def PcdTokenNumber(self):
self._PcdTokenNumber = OrderedDict() RetVal = OrderedDict()
TokenNumber = 1 TokenNumber = 1
# #
# Make the Dynamic and DynamicEx PCD use within different TokenNumber area. # Make the Dynamic and DynamicEx PCD use within different TokenNumber area.
# Such as: # Such as:
# #
# Dynamic PCD: # Dynamic PCD:
# TokenNumber 0 ~ 10 # TokenNumber 0 ~ 10
# DynamicEx PCD: # DynamicEx PCD:
# TokeNumber 11 ~ 20 # TokeNumber 11 ~ 20
# #
for Pcd in self.DynamicPcdList: for Pcd in self.DynamicPcdList:
if Pcd.Phase == "PEI" and Pcd.Type in PCD_DYNAMIC_TYPE_SET: if Pcd.Phase == "PEI" and Pcd.Type in PCD_DYNAMIC_TYPE_SET:
EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber)) EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber RetVal[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
TokenNumber += 1
for Pcd in self.DynamicPcdList:
if Pcd.Phase == "PEI" and Pcd.Type in PCD_DYNAMIC_EX_TYPE_SET:
EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
TokenNumber += 1
for Pcd in self.DynamicPcdList:
if Pcd.Phase == "DXE" and Pcd.Type in PCD_DYNAMIC_TYPE_SET:
EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
TokenNumber += 1
for Pcd in self.DynamicPcdList:
if Pcd.Phase == "DXE" and Pcd.Type in PCD_DYNAMIC_EX_TYPE_SET:
EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
TokenNumber += 1
for Pcd in self.NonDynamicPcdList:
self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
TokenNumber += 1 TokenNumber += 1
return self._PcdTokenNumber
## Summarize ModuleAutoGen objects of all modules/libraries to be built for this platform for Pcd in self.DynamicPcdList:
def _GetAutoGenObjectList(self): if Pcd.Phase == "PEI" and Pcd.Type in PCD_DYNAMIC_EX_TYPE_SET:
self._ModuleAutoGenList = [] EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
self._LibraryAutoGenList = [] RetVal[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
TokenNumber += 1
for Pcd in self.DynamicPcdList:
if Pcd.Phase == "DXE" and Pcd.Type in PCD_DYNAMIC_TYPE_SET:
EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
RetVal[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
TokenNumber += 1
for Pcd in self.DynamicPcdList:
if Pcd.Phase == "DXE" and Pcd.Type in PCD_DYNAMIC_EX_TYPE_SET:
EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
RetVal[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
TokenNumber += 1
for Pcd in self.NonDynamicPcdList:
RetVal[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
TokenNumber += 1
return RetVal
## Summarize ModuleAutoGen objects of all modules to be built for this platform
@cached_property
def ModuleAutoGenList(self):
RetVal = []
for ModuleFile in self.Platform.Modules: for ModuleFile in self.Platform.Modules:
Ma = ModuleAutoGen( Ma = ModuleAutoGen(
self.Workspace, self.Workspace,
@ -1998,25 +1960,29 @@ class PlatformAutoGen(AutoGen):
self.Arch, self.Arch,
self.MetaFile self.MetaFile
) )
if Ma not in self._ModuleAutoGenList: if Ma not in RetVal:
self._ModuleAutoGenList.append(Ma) RetVal.append(Ma)
for La in Ma.LibraryAutoGenList: return RetVal
if La not in self._LibraryAutoGenList:
self._LibraryAutoGenList.append(La)
if Ma not in La.ReferenceModules:
La.ReferenceModules.append(Ma)
## Summarize ModuleAutoGen objects of all modules to be built for this platform
def _GetModuleAutoGenList(self):
if self._ModuleAutoGenList is None:
self._GetAutoGenObjectList()
return self._ModuleAutoGenList
## Summarize ModuleAutoGen objects of all libraries to be built for this platform ## Summarize ModuleAutoGen objects of all libraries to be built for this platform
def _GetLibraryAutoGenList(self): @cached_property
if self._LibraryAutoGenList is None: def LibraryAutoGenList(self):
self._GetAutoGenObjectList() RetVal = []
return self._LibraryAutoGenList for ModuleFile in self.Platform.Modules:
Ma = ModuleAutoGen(
self.Workspace,
ModuleFile,
self.BuildTarget,
self.ToolChain,
self.Arch,
self.MetaFile
)
for La in Ma.LibraryAutoGenList:
if La not in RetVal:
RetVal.append(La)
if Ma not in La.ReferenceModules:
La.ReferenceModules.append(Ma)
return RetVal
## Test if a module is supported by the platform ## Test if a module is supported by the platform
# #
@ -2099,7 +2065,7 @@ class PlatformAutoGen(AutoGen):
# Add Flexible PCD format parse # Add Flexible PCD format parse
if ToPcd.DefaultValue: if ToPcd.DefaultValue:
try: try:
ToPcd.DefaultValue = ValueExpressionEx(ToPcd.DefaultValue, ToPcd.DatumType, self._GuidDict)(True) ToPcd.DefaultValue = ValueExpressionEx(ToPcd.DefaultValue, ToPcd.DatumType, self.Workspace._GuidDict)(True)
except BadExpression as Value: except BadExpression as Value:
EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %(ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName, ToPcd.DefaultValue, Value), EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %(ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName, ToPcd.DefaultValue, Value),
File=self.MetaFile) File=self.MetaFile)
@ -2265,10 +2231,16 @@ class PlatformAutoGen(AutoGen):
## Expand * in build option key ## Expand * in build option key
# #
# @param Options Options to be expanded # @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 # @retval options Options expanded
# #
def _ExpandBuildOption(self, Options, ModuleStyle=None): def _ExpandBuildOption(self, Options, ModuleStyle=None, ToolDef=None):
if not ToolDef:
ToolDef = self.ToolDefinition
BuildOptions = {} BuildOptions = {}
FamilyMatch = False FamilyMatch = False
FamilyIsNull = True FamilyIsNull = True
@ -2332,12 +2304,12 @@ class PlatformAutoGen(AutoGen):
Family = Key[0] Family = Key[0]
Target, Tag, Arch, Tool, Attr = Key[1].split("_") Target, Tag, Arch, Tool, Attr = Key[1].split("_")
# if tool chain family doesn't match, skip it # if tool chain family doesn't match, skip it
if Tool in self.ToolDefinition and Family != "": if Tool in ToolDef and Family != "":
FamilyIsNull = False FamilyIsNull = False
if self.ToolDefinition[Tool].get(TAB_TOD_DEFINES_BUILDRULEFAMILY, "") != "": if ToolDef[Tool].get(TAB_TOD_DEFINES_BUILDRULEFAMILY, "") != "":
if Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]: if Family != ToolDef[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
continue continue
elif Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_FAMILY]: elif Family != ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
continue continue
FamilyMatch = True FamilyMatch = True
# expand any wildcard # expand any wildcard
@ -2369,10 +2341,10 @@ class PlatformAutoGen(AutoGen):
Family = Key[0] Family = Key[0]
Target, Tag, Arch, Tool, Attr = Key[1].split("_") Target, Tag, Arch, Tool, Attr = Key[1].split("_")
# if tool chain family doesn't match, skip it # if tool chain family doesn't match, skip it
if Tool not in self.ToolDefinition or Family == "": if Tool not in ToolDef or Family == "":
continue continue
# option has been added before # option has been added before
if Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_FAMILY]: if Family != ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
continue continue
# expand any wildcard # expand any wildcard
@ -2451,36 +2423,6 @@ class PlatformAutoGen(AutoGen):
BuildOptions['BUILD']['FLAGS'] = self.Workspace.UniFlag BuildOptions['BUILD']['FLAGS'] = self.Workspace.UniFlag
return BuildOptions, BuildRuleOrder return BuildOptions, BuildRuleOrder
Platform = property(_GetPlatform)
Name = property(_GetName)
Guid = property(_GetGuid)
Version = property(_GetVersion)
OutputDir = property(_GetOutputDir)
BuildDir = property(_GetBuildDir)
MakeFileDir = property(_GetMakeFileDir)
FdfFile = property(_GetFdfFile)
PcdTokenNumber = property(_GetPcdTokenNumbers) # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber
DynamicPcdList = property(_GetDynamicPcdList) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
NonDynamicPcdList = property(_GetNonDynamicPcdList) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
NonDynamicPcdDict = property(_GetNonDynamicPcdDict)
PackageList = property(_GetPackageList)
ToolDefinition = property(_GetToolDefinition) # toolcode : tool path
ToolDefinitionFile = property(_GetToolDefFile) # toolcode : lib path
ToolChainFamily = property(_GetToolChainFamily)
BuildRuleFamily = property(_GetBuildRuleFamily)
BuildOption = property(_GetBuildOptions) # toolcode : option
EdkBuildOption = property(_GetEdkBuildOptions) # edktoolcode : option
EdkIIBuildOption = property(_GetEdkIIBuildOptions) # edkiitoolcode : option
BuildCommand = property(_GetBuildCommand)
BuildRule = property(_GetBuildRule)
ModuleAutoGenList = property(_GetModuleAutoGenList)
LibraryAutoGenList = property(_GetLibraryAutoGenList)
GenFdsCommand = property(_GenFdsCommand)
# #
# extend lists contained in a dictionary with lists stored in another dictionary # extend lists contained in a dictionary with lists stored in another dictionary
# if CopyToDict is not derived from DefaultDict(list) then this may raise exception # if CopyToDict is not derived from DefaultDict(list) then this may raise exception
@ -2536,7 +2478,6 @@ class ModuleAutoGen(AutoGen):
self.Workspace = Workspace self.Workspace = Workspace
self.WorkspaceDir = Workspace.WorkspaceDir self.WorkspaceDir = Workspace.WorkspaceDir
self._GuidDict = Workspace._GuidDict
self.MetaFile = ModuleFile self.MetaFile = ModuleFile
self.PlatformInfo = PlatformAutoGen(Workspace, PlatformFile, Target, Toolchain, Arch) self.PlatformInfo = PlatformAutoGen(Workspace, PlatformFile, Target, Toolchain, Arch)