| ## @file |
| # Global variables for GenFds |
| # |
| # Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR> |
| # |
| # 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): |
| 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] |
| |
| 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 += ["-j", Ver] |
| SectionData = array.array('B', [0,0,0,0]) |
| SectionData.fromstring(Ver.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, 0x14) |
| SaveFileOnChange(Output, SectionData.tostring()) |
| else: |
| Cmd += ["-o", Output] |
| Cmd += Input |
| |
| 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 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(cmd, stdout=subprocess.PIPE, stderr= subprocess.PIPE) |
| 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) |