## @file # Global variables for GenFds # # Copyright (c) 2007 - 2012, 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 # http://opensource.org/licenses/bsd-license.php # # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. # ## # Import Modules # import os import sys import subprocess import struct import array from Common.BuildToolError import * from Common import EdkLogger from Common.Misc import SaveFileOnChange from Common.TargetTxtClassObject import TargetTxtClassObject from Common.ToolDefClassObject import ToolDefClassObject from AutoGen.BuildEngine import BuildRule import Common.DataType as DataType from Common.Misc import PathClass ## Global variables # # class GenFdsGlobalVariable: FvDir = '' OutputDirDict = {} BinDir = '' # will be FvDir + os.sep + 'Ffs' FfsDir = '' FdfParser = None LibDir = '' WorkSpace = None WorkSpaceDir = '' EdkSourceDir = '' OutputDirFromDscDict = {} TargetName = '' ToolChainTag = '' RuleDict = {} ArchList = None VtfDict = {} ActivePlatform = None FvAddressFileName = '' VerboseMode = False DebugLevel = -1 SharpCounter = 0 SharpNumberPerLine = 40 FdfFile = '' FdfFileTimeStamp = 0 FixedLoadAddress = False PlatformName = '' BuildRuleFamily = "MSFT" ToolChainFamily = "MSFT" __BuildRuleDatabase = None SectionHeader = struct.Struct("3B 1B") ## LoadBuildRule # @staticmethod def __LoadBuildRule(): if GenFdsGlobalVariable.__BuildRuleDatabase: return GenFdsGlobalVariable.__BuildRuleDatabase BuildConfigurationFile = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, "Conf/target.txt")) TargetTxt = TargetTxtClassObject() if os.path.isfile(BuildConfigurationFile) == True: TargetTxt.LoadTargetTxtFile(BuildConfigurationFile) if DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF in TargetTxt.TargetTxtDictionary: BuildRuleFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF] if BuildRuleFile in [None, '']: BuildRuleFile = 'Conf/build_rule.txt' GenFdsGlobalVariable.__BuildRuleDatabase = BuildRule(BuildRuleFile) ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF] if ToolDefinitionFile == '': ToolDefinitionFile = "Conf/tools_def.txt" if os.path.isfile(ToolDefinitionFile): ToolDef = ToolDefClassObject() ToolDef.LoadToolDefFile(ToolDefinitionFile) ToolDefinition = ToolDef.ToolsDefTxtDatabase if DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDefinition \ and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY] \ and ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]: GenFdsGlobalVariable.BuildRuleFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag] if DataType.TAB_TOD_DEFINES_FAMILY in ToolDefinition \ and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY] \ and ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]: GenFdsGlobalVariable.ToolChainFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag] return GenFdsGlobalVariable.__BuildRuleDatabase ## GetBuildRules # @param Inf: object of InfBuildData # @param Arch: current arch # @staticmethod def GetBuildRules(Inf, Arch): if not Arch: Arch = 'COMMON' if not Arch in GenFdsGlobalVariable.OutputDirDict: return {} BuildRuleDatabase = GenFdsGlobalVariable.__LoadBuildRule() if not BuildRuleDatabase: return {} PathClassObj = PathClass(Inf.MetaFile.File, GenFdsGlobalVariable.WorkSpaceDir) Macro = {} Macro["WORKSPACE" ] = GenFdsGlobalVariable.WorkSpaceDir Macro["MODULE_NAME" ] = Inf.BaseName Macro["MODULE_GUID" ] = Inf.Guid Macro["MODULE_VERSION" ] = Inf.Version Macro["MODULE_TYPE" ] = Inf.ModuleType Macro["MODULE_FILE" ] = str(PathClassObj) Macro["MODULE_FILE_BASE_NAME" ] = PathClassObj.BaseName Macro["MODULE_RELATIVE_DIR" ] = PathClassObj.SubDir Macro["MODULE_DIR" ] = PathClassObj.SubDir Macro["BASE_NAME" ] = Inf.BaseName Macro["ARCH" ] = Arch Macro["TOOLCHAIN" ] = GenFdsGlobalVariable.ToolChainTag Macro["TOOLCHAIN_TAG" ] = GenFdsGlobalVariable.ToolChainTag Macro["TOOL_CHAIN_TAG" ] = GenFdsGlobalVariable.ToolChainTag Macro["TARGET" ] = GenFdsGlobalVariable.TargetName Macro["BUILD_DIR" ] = GenFdsGlobalVariable.OutputDirDict[Arch] Macro["BIN_DIR" ] = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch) Macro["LIB_DIR" ] = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch) BuildDir = os.path.join( GenFdsGlobalVariable.OutputDirDict[Arch], Arch, PathClassObj.SubDir, PathClassObj.BaseName ) Macro["MODULE_BUILD_DIR" ] = BuildDir Macro["OUTPUT_DIR" ] = os.path.join(BuildDir, "OUTPUT") Macro["DEBUG_DIR" ] = os.path.join(BuildDir, "DEBUG") BuildRules = {} for Type in BuildRuleDatabase.FileTypeList: #first try getting build rule by BuildRuleFamily RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.BuildRuleFamily] if not RuleObject: # build type is always module type, but ... if Inf.ModuleType != Inf.BuildType: RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.BuildRuleFamily] #second try getting build rule by ToolChainFamily if not RuleObject: RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.ToolChainFamily] if not RuleObject: # build type is always module type, but ... if Inf.ModuleType != Inf.BuildType: RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.ToolChainFamily] if not RuleObject: continue RuleObject = RuleObject.Instantiate(Macro) BuildRules[Type] = RuleObject for Ext in RuleObject.SourceFileExtList: BuildRules[Ext] = RuleObject return BuildRules ## GetModuleCodaTargetList # # @param Inf: object of InfBuildData # @param Arch: current arch # @staticmethod def GetModuleCodaTargetList(Inf, Arch): BuildRules = GenFdsGlobalVariable.GetBuildRules(Inf, Arch) if not BuildRules: return [] TargetList = set() FileList = [] for File in Inf.Sources: if File.TagName in ("", "*", GenFdsGlobalVariable.ToolChainTag) and \ File.ToolChainFamily in ("", "*", GenFdsGlobalVariable.ToolChainFamily): FileList.append((File, DataType.TAB_UNKNOWN_FILE)) for File in Inf.Binaries: if File.Target in ['COMMON', '*', GenFdsGlobalVariable.TargetName]: FileList.append((File, File.Type)) for File, FileType in FileList: LastTarget = None RuleChain = [] SourceList = [File] Index = 0 while Index < len(SourceList): Source = SourceList[Index] Index = Index + 1 if File.IsBinary and File == Source and Inf.Binaries != None and File in Inf.Binaries: # Skip all files that are not binary libraries if not Inf.LibraryClass: continue RuleObject = BuildRules[DataType.TAB_DEFAULT_BINARY_FILE] elif FileType in BuildRules: RuleObject = BuildRules[FileType] elif Source.Ext in BuildRules: RuleObject = BuildRules[Source.Ext] else: # stop at no more rules if LastTarget: TargetList.add(str(LastTarget)) break FileType = RuleObject.SourceFileType # stop at STATIC_LIBRARY for library if Inf.LibraryClass and FileType == DataType.TAB_STATIC_LIBRARY: if LastTarget: TargetList.add(str(LastTarget)) break Target = RuleObject.Apply(Source) if not Target: if LastTarget: TargetList.add(str(LastTarget)) break elif not Target.Outputs: # Only do build for target with outputs TargetList.add(str(Target)) # to avoid cyclic rule if FileType in RuleChain: break RuleChain.append(FileType) SourceList.extend(Target.Outputs) LastTarget = Target FileType = DataType.TAB_UNKNOWN_FILE return list(TargetList) ## SetDir() # # @param OutputDir Output directory # @param FdfParser FDF contents parser # @param Workspace The directory of workspace # @param ArchList The Arch list of platform # def SetDir (OutputDir, FdfParser, WorkSpace, ArchList): GenFdsGlobalVariable.VerboseLogger( "GenFdsGlobalVariable.OutputDir :%s" %OutputDir) # GenFdsGlobalVariable.OutputDirDict = OutputDir GenFdsGlobalVariable.FdfParser = FdfParser GenFdsGlobalVariable.WorkSpace = WorkSpace GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], 'FV') if not os.path.exists(GenFdsGlobalVariable.FvDir) : os.makedirs(GenFdsGlobalVariable.FvDir) GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs') if not os.path.exists(GenFdsGlobalVariable.FfsDir) : os.makedirs(GenFdsGlobalVariable.FfsDir) if ArchList != None: GenFdsGlobalVariable.ArchList = ArchList T_CHAR_LF = '\n' # # Create FV Address inf file # GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf') FvAddressFile = open (GenFdsGlobalVariable.FvAddressFileName, 'w') # # Add [Options] # FvAddressFile.writelines("[options]" + T_CHAR_LF) BsAddress = '0' for Arch in ArchList: if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress: BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress break FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \ BsAddress + \ T_CHAR_LF) RtAddress = '0' for Arch in ArchList: if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress: RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \ RtAddress + \ T_CHAR_LF) FvAddressFile.close() ## ReplaceWorkspaceMacro() # # @param String String that may contain macro # def ReplaceWorkspaceMacro(String): Str = String.replace('$(WORKSPACE)', GenFdsGlobalVariable.WorkSpaceDir) if os.path.exists(Str): if not os.path.isabs(Str): Str = os.path.abspath(Str) else: Str = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, String) return os.path.normpath(Str) ## Check if the input files are newer than output files # # @param Output Path of output file # @param Input Path list of input files # # @retval True if Output doesn't exist, or any Input is newer # @retval False if all Input is older than Output # @staticmethod def NeedsUpdate(Output, Input): if not os.path.exists(Output): return True # always update "Output" if no "Input" given if Input == None or len(Input) == 0: return True # if fdf file is changed after the 'Output" is generated, update the 'Output' OutputTime = os.path.getmtime(Output) if GenFdsGlobalVariable.FdfFileTimeStamp > OutputTime: return True for F in Input: # always update "Output" if any "Input" doesn't exist if not os.path.exists(F): return True # always update "Output" if any "Input" is newer than "Output" if os.path.getmtime(F) > OutputTime: return True return False @staticmethod def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None, GuidHdrLen=None, GuidAttr=[], Ui=None, Ver=None, InputAlign=None, BuildNumber=None): Cmd = ["GenSec"] if Type not in [None, '']: Cmd += ["-s", Type] if CompressionType not in [None, '']: Cmd += ["-c", CompressionType] if Guid != None: Cmd += ["-g", Guid] if GuidHdrLen not in [None, '']: Cmd += ["-l", GuidHdrLen] if len(GuidAttr) != 0: #Add each guided attribute for Attr in GuidAttr: Cmd += ["-r", Attr] if InputAlign != None: #Section Align is only for dummy section without section type for SecAlign in InputAlign: Cmd += ["--sectionalign", SecAlign] CommandFile = Output + '.txt' if Ui not in [None, '']: #Cmd += ["-n", '"' + Ui + '"'] SectionData = array.array('B', [0,0,0,0]) SectionData.fromstring(Ui.encode("utf_16_le")) SectionData.append(0) SectionData.append(0) Len = len(SectionData) GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x15) SaveFileOnChange(Output, SectionData.tostring()) elif Ver not in [None, '']: Cmd += ["-n", Ver] if BuildNumber: Cmd += ["-j", BuildNumber] Cmd += ["-o", Output] SaveFileOnChange(CommandFile, ' '.join(Cmd), False) if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]): return GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section") else: Cmd += ["-o", Output] Cmd += Input SaveFileOnChange(CommandFile, ' '.join(Cmd), False) if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]): return GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section") @staticmethod def GetAlignment (AlignString): if AlignString == None: return 0 if AlignString in ("1K", "2K", "4K", "8K", "16K", "32K", "64K"): return int (AlignString.rstrip('K')) * 1024 else: return int (AlignString) @staticmethod def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None, SectionAlign=None): Cmd = ["GenFfs", "-t", Type, "-g", Guid] if Fixed == True: Cmd += ["-x"] if CheckSum: Cmd += ["-s"] if Align not in [None, '']: Cmd += ["-a", Align] Cmd += ["-o", Output] for I in range(0, len(Input)): Cmd += ("-i", Input[I]) if SectionAlign not in [None, '', []] and SectionAlign[I] not in [None, '']: Cmd += ("-n", SectionAlign[I]) CommandFile = Output + '.txt' SaveFileOnChange(CommandFile, ' '.join(Cmd), False) if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]): return GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS") @staticmethod def GenerateFirmwareVolume(Output, Input, BaseAddress=None, ForceRebase=None, Capsule=False, Dump=False, AddressFile=None, MapFile=None, FfsList=[]): if not GenFdsGlobalVariable.NeedsUpdate(Output, Input+FfsList): return GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) Cmd = ["GenFv"] if BaseAddress not in [None, '']: Cmd += ["-r", BaseAddress] if ForceRebase == False: Cmd +=["-F", "FALSE"] elif ForceRebase == True: Cmd +=["-F", "TRUE"] if Capsule: Cmd += ["-c"] if Dump: Cmd += ["-p"] if AddressFile not in [None, '']: Cmd += ["-a", AddressFile] if MapFile not in [None, '']: Cmd += ["-m", MapFile] Cmd += ["-o", Output] for I in Input: Cmd += ["-i", I] GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FV") @staticmethod def GenerateVtf(Output, Input, BaseAddress=None, FvSize=None): if not GenFdsGlobalVariable.NeedsUpdate(Output, Input): return GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) Cmd = ["GenVtf"] if BaseAddress not in [None, ''] and FvSize not in [None, ''] \ and len(BaseAddress) == len(FvSize): for I in range(0, len(BaseAddress)): Cmd += ["-r", BaseAddress[I], "-s", FvSize[I]] Cmd += ["-o", Output] for F in Input: Cmd += ["-f", F] GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate VTF") @staticmethod def GenerateFirmwareImage(Output, Input, Type="efi", SubType=None, Zero=False, Strip=False, Replace=False, TimeStamp=None, Join=False, Align=None, Padding=None, Convert=False): if not GenFdsGlobalVariable.NeedsUpdate(Output, Input): return GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) Cmd = ["GenFw"] if Type.lower() == "te": Cmd += ["-t"] if SubType not in [None, '']: Cmd += ["-e", SubType] if TimeStamp not in [None, '']: Cmd += ["-s", TimeStamp] if Align not in [None, '']: Cmd += ["-a", Align] if Padding not in [None, '']: Cmd += ["-p", Padding] if Zero: Cmd += ["-z"] if Strip: Cmd += ["-l"] if Replace: Cmd += ["-r"] if Join: Cmd += ["-j"] if Convert: Cmd += ["-m"] Cmd += ["-o", Output] Cmd += Input GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image") @staticmethod def GenerateOptionRom(Output, EfiInput, BinaryInput, Compress=False, ClassCode=None, Revision=None, DeviceId=None, VendorId=None): InputList = [] Cmd = ["EfiRom"] if len(EfiInput) > 0: if Compress: Cmd += ["-ec"] else: Cmd += ["-e"] for EfiFile in EfiInput: Cmd += [EfiFile] InputList.append (EfiFile) if len(BinaryInput) > 0: Cmd += ["-b"] for BinFile in BinaryInput: Cmd += [BinFile] InputList.append (BinFile) # Check List if not GenFdsGlobalVariable.NeedsUpdate(Output, InputList): return GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, InputList)) if ClassCode != None: Cmd += ["-l", ClassCode] if Revision != None: Cmd += ["-r", Revision] if DeviceId != None: Cmd += ["-i", DeviceId] if VendorId != None: Cmd += ["-f", VendorId] Cmd += ["-o", Output] GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate option rom") @staticmethod def GuidTool(Output, Input, ToolPath, Options='', returnValue=[]): if not GenFdsGlobalVariable.NeedsUpdate(Output, Input): return GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) Cmd = [ToolPath, ] Cmd += Options.split(' ') Cmd += ["-o", Output] Cmd += Input GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath, returnValue) def CallExternalTool (cmd, errorMess, returnValue=[]): if type(cmd) not in (tuple, list): GenFdsGlobalVariable.ErrorLogger("ToolError! Invalid parameter type in call to CallExternalTool") if GenFdsGlobalVariable.DebugLevel != -1: cmd += ('--debug', str(GenFdsGlobalVariable.DebugLevel)) GenFdsGlobalVariable.InfLogger (cmd) if GenFdsGlobalVariable.VerboseMode: cmd += ('-v',) GenFdsGlobalVariable.InfLogger (cmd) else: sys.stdout.write ('#') sys.stdout.flush() GenFdsGlobalVariable.SharpCounter = GenFdsGlobalVariable.SharpCounter + 1 if GenFdsGlobalVariable.SharpCounter % GenFdsGlobalVariable.SharpNumberPerLine == 0: sys.stdout.write('\n') try: PopenObject = subprocess.Popen(' '.join(cmd), stdout=subprocess.PIPE, stderr= subprocess.PIPE, shell=True) except Exception, X: EdkLogger.error("GenFds", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0])) (out, error) = PopenObject.communicate() while PopenObject.returncode == None : PopenObject.wait() if returnValue != [] and returnValue[0] != 0: #get command return value returnValue[0] = PopenObject.returncode return if PopenObject.returncode != 0 or GenFdsGlobalVariable.VerboseMode or GenFdsGlobalVariable.DebugLevel != -1: GenFdsGlobalVariable.InfLogger ("Return Value = %d" %PopenObject.returncode) GenFdsGlobalVariable.InfLogger (out) GenFdsGlobalVariable.InfLogger (error) if PopenObject.returncode != 0: print "###", cmd EdkLogger.error("GenFds", COMMAND_FAILURE, errorMess) def VerboseLogger (msg): EdkLogger.verbose(msg) def InfLogger (msg): EdkLogger.info(msg) def ErrorLogger (msg, File = None, Line = None, ExtraData = None): EdkLogger.error('GenFds', GENFDS_ERROR, msg, File, Line, ExtraData) def DebugLogger (Level, msg): EdkLogger.debug(Level, msg) ## ReplaceWorkspaceMacro() # # @param Str String that may contain macro # @param MacroDict Dictionary that contains macro value pair # def MacroExtend (Str, MacroDict = {}, Arch = 'COMMON'): if Str == None : return None Dict = {'$(WORKSPACE)' : GenFdsGlobalVariable.WorkSpaceDir, '$(EDK_SOURCE)' : GenFdsGlobalVariable.EdkSourceDir, # '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc, '$(TARGET)' : GenFdsGlobalVariable.TargetName, '$(TOOL_CHAIN_TAG)' : GenFdsGlobalVariable.ToolChainTag } OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[GenFdsGlobalVariable.ArchList[0]] if Arch != 'COMMON' and Arch in GenFdsGlobalVariable.ArchList: OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[Arch] Dict['$(OUTPUT_DIRECTORY)'] = OutputDir if MacroDict != None and len (MacroDict) != 0: Dict.update(MacroDict) for key in Dict.keys(): if Str.find(key) >= 0 : Str = Str.replace (key, Dict[key]) if Str.find('$(ARCH)') >= 0: if len(GenFdsGlobalVariable.ArchList) == 1: Str = Str.replace('$(ARCH)', GenFdsGlobalVariable.ArchList[0]) else: EdkLogger.error("GenFds", GENFDS_ERROR, "No way to determine $(ARCH) for %s" % Str) return Str ## GetPcdValue() # # @param PcdPattern pattern that labels a PCD. # def GetPcdValue (PcdPattern): if PcdPattern == None : return None PcdPair = PcdPattern.lstrip('PCD(').rstrip(')').strip().split('.') TokenSpace = PcdPair[0] TokenCName = PcdPair[1] PcdValue = '' for Arch in GenFdsGlobalVariable.ArchList: Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] PcdDict = Platform.Pcds for Key in PcdDict: PcdObj = PcdDict[Key] if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace): if PcdObj.Type != 'FixedAtBuild': EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern) if PcdObj.DatumType != 'VOID*': EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern) PcdValue = PcdObj.DefaultValue return PcdValue for Package in GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag): PcdDict = Package.Pcds for Key in PcdDict: PcdObj = PcdDict[Key] if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace): if PcdObj.Type != 'FixedAtBuild': EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern) if PcdObj.DatumType != 'VOID*': EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern) PcdValue = PcdObj.DefaultValue return PcdValue return PcdValue SetDir = staticmethod(SetDir) ReplaceWorkspaceMacro = staticmethod(ReplaceWorkspaceMacro) CallExternalTool = staticmethod(CallExternalTool) VerboseLogger = staticmethod(VerboseLogger) InfLogger = staticmethod(InfLogger) ErrorLogger = staticmethod(ErrorLogger) DebugLogger = staticmethod(DebugLogger) MacroExtend = staticmethod (MacroExtend) GetPcdValue = staticmethod(GetPcdValue)