From af1a266670d040d2f4083ff309d732d648afba2a Mon Sep 17 00:00:00 2001 From: Angelos Mouzakitis Date: Tue, 10 Oct 2023 14:33:42 +0000 Subject: Add submodule dependency files Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec --- .../Source/Python/AutoGen/ModuleAutoGenHelper.py | 648 +++++++++++++++++++++ 1 file changed, 648 insertions(+) create mode 100644 roms/edk2/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py (limited to 'roms/edk2/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py') diff --git a/roms/edk2/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py b/roms/edk2/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py new file mode 100644 index 000000000..9dd93b9be --- /dev/null +++ b/roms/edk2/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py @@ -0,0 +1,648 @@ +## @file +# Create makefile for MS nmake and GNU make +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# 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): + if not hasattr(self, "_Init"): + self.do_init(Workspace, MetaFile, Target, ToolChain, Arch) + self._Init = True + def do_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 + self.AutoGenObjectList = [] + @property + def BuildDir(self): + return self.AutoGenObjectList[0].BuildDir + + @property + def Name(self): + return self.AutoGenObjectList[0].Platform.PlatformName + + @property + def FlashDefinition(self): + return self.AutoGenObjectList[0].Platform.FlashDefinition + @property + def GenFdsCommandDict(self): + FdsCommandDict = self.AutoGenObjectList[0].DataPipe.Get("FdsCommandDict") + if FdsCommandDict: + return FdsCommandDict + return {} + + @cached_property + def FvDir(self): + return os.path.join(self.BuildDir, TAB_FV_DIRECTORY) + +class PlatformInfo(AutoGenInfo): + def __init__(self, Workspace, MetaFile, Target, ToolChain, Arch,DataPipe): + if not hasattr(self, "_Init"): + self.do_init(Workspace, MetaFile, Target, ToolChain, Arch,DataPipe) + self._Init = True + def do_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 -- cgit 1.2.3-korg