-## @file
-# Global variables for GenFds
-#
-# Copyright (c) 2007 - 2012, 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"):\r
+## @file\r
+# Global variables for GenFds\r
+#\r
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+#\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+\r
+##\r
+# Import Modules\r
+#\r
+import Common.LongFilePathOs as os\r
+import sys\r
+import subprocess\r
+import struct\r
+import array\r
+\r
+from Common.BuildToolError import *\r
+from Common import EdkLogger\r
+from Common.Misc import SaveFileOnChange\r
+\r
+from Common.TargetTxtClassObject import TargetTxtClassObject\r
+from Common.ToolDefClassObject import ToolDefClassObject\r
+from AutoGen.BuildEngine import BuildRule\r
+import Common.DataType as DataType\r
+from Common.Misc import PathClass\r
+from Common.LongFilePathSupport import OpenLongFilePath as open\r
+from Common.MultipleWorkspace import MultipleWorkspace as mws\r
+\r
+## Global variables\r
+#\r
+#\r
+class GenFdsGlobalVariable:\r
+ FvDir = ''\r
+ OutputDirDict = {}\r
+ BinDir = ''\r
+ # will be FvDir + os.sep + 'Ffs'\r
+ FfsDir = ''\r
+ FdfParser = None\r
+ LibDir = ''\r
+ WorkSpace = None\r
+ WorkSpaceDir = ''\r
+ ConfDir = ''\r
+ EdkSourceDir = ''\r
+ OutputDirFromDscDict = {}\r
+ TargetName = ''\r
+ ToolChainTag = ''\r
+ RuleDict = {}\r
+ ArchList = None\r
+ VtfDict = {}\r
+ ActivePlatform = None\r
+ FvAddressFileName = ''\r
+ VerboseMode = False\r
+ DebugLevel = -1\r
+ SharpCounter = 0\r
+ SharpNumberPerLine = 40\r
+ FdfFile = ''\r
+ FdfFileTimeStamp = 0\r
+ FixedLoadAddress = False\r
+ PlatformName = ''\r
+ \r
+ BuildRuleFamily = "MSFT"\r
+ ToolChainFamily = "MSFT"\r
+ __BuildRuleDatabase = None\r
+ GuidToolDefinition = {}\r
+ FfsCmdDict = {}\r
+ SecCmdList = []\r
+ CopyList = []\r
+ ModuleFile = ''\r
+ EnableGenfdsMultiThread = False\r
+ \r
+ #\r
+ # The list whose element are flags to indicate if large FFS or SECTION files exist in FV.\r
+ # At the beginning of each generation of FV, false flag is appended to the list,\r
+ # after the call to GenerateSection returns, check the size of the output file,\r
+ # if it is greater than 0xFFFFFF, the tail flag in list is set to true,\r
+ # and EFI_FIRMWARE_FILE_SYSTEM3_GUID is passed to C GenFv.\r
+ # At the end of generation of FV, pop the flag.\r
+ # List is used as a stack to handle nested FV generation.\r
+ #\r
+ LargeFileInFvFlags = []\r
+ EFI_FIRMWARE_FILE_SYSTEM3_GUID = '5473C07A-3DCB-4dca-BD6F-1E9689E7349A'\r
+ LARGE_FILE_SIZE = 0x1000000\r
+\r
+ SectionHeader = struct.Struct("3B 1B")\r
+ \r
+ ## LoadBuildRule\r
+ #\r
+ @staticmethod\r
+ def __LoadBuildRule():\r
+ if GenFdsGlobalVariable.__BuildRuleDatabase:\r
+ return GenFdsGlobalVariable.__BuildRuleDatabase\r
+ BuildConfigurationFile = os.path.normpath(os.path.join(GenFdsGlobalVariable.ConfDir, "target.txt"))\r
+ TargetTxt = TargetTxtClassObject()\r
+ if os.path.isfile(BuildConfigurationFile) == True:\r
+ TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)\r
+ if DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF in TargetTxt.TargetTxtDictionary:\r
+ BuildRuleFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF]\r
+ if BuildRuleFile in [None, '']:\r
+ BuildRuleFile = 'Conf/build_rule.txt'\r
+ GenFdsGlobalVariable.__BuildRuleDatabase = BuildRule(BuildRuleFile)\r
+ ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]\r
+ if ToolDefinitionFile == '':\r
+ ToolDefinitionFile = "Conf/tools_def.txt"\r
+ if os.path.isfile(ToolDefinitionFile):\r
+ ToolDef = ToolDefClassObject()\r
+ ToolDef.LoadToolDefFile(ToolDefinitionFile)\r
+ ToolDefinition = ToolDef.ToolsDefTxtDatabase\r
+ if DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDefinition \\r
+ and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY] \\r
+ and ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]:\r
+ GenFdsGlobalVariable.BuildRuleFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]\r
+ \r
+ if DataType.TAB_TOD_DEFINES_FAMILY in ToolDefinition \\r
+ and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY] \\r
+ and ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]:\r
+ GenFdsGlobalVariable.ToolChainFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]\r
+ return GenFdsGlobalVariable.__BuildRuleDatabase\r
+\r
+ ## GetBuildRules\r
+ # @param Inf: object of InfBuildData\r
+ # @param Arch: current arch\r
+ #\r
+ @staticmethod\r
+ def GetBuildRules(Inf, Arch):\r
+ if not Arch:\r
+ Arch = DataType.TAB_COMMON\r
+\r
+ if not Arch in GenFdsGlobalVariable.OutputDirDict:\r
+ return {}\r
+\r
+ BuildRuleDatabase = GenFdsGlobalVariable.__LoadBuildRule()\r
+ if not BuildRuleDatabase:\r
+ return {}\r
+\r
+ PathClassObj = PathClass(Inf.MetaFile.File,\r
+ GenFdsGlobalVariable.WorkSpaceDir)\r
+ Macro = {}\r
+ Macro["WORKSPACE" ] = GenFdsGlobalVariable.WorkSpaceDir\r
+ Macro["MODULE_NAME" ] = Inf.BaseName\r
+ Macro["MODULE_GUID" ] = Inf.Guid\r
+ Macro["MODULE_VERSION" ] = Inf.Version\r
+ Macro["MODULE_TYPE" ] = Inf.ModuleType\r
+ Macro["MODULE_FILE" ] = str(PathClassObj)\r
+ Macro["MODULE_FILE_BASE_NAME" ] = PathClassObj.BaseName\r
+ Macro["MODULE_RELATIVE_DIR" ] = PathClassObj.SubDir\r
+ Macro["MODULE_DIR" ] = PathClassObj.SubDir\r
+\r
+ Macro["BASE_NAME" ] = Inf.BaseName\r
+\r
+ Macro["ARCH" ] = Arch\r
+ Macro["TOOLCHAIN" ] = GenFdsGlobalVariable.ToolChainTag\r
+ Macro["TOOLCHAIN_TAG" ] = GenFdsGlobalVariable.ToolChainTag\r
+ Macro["TOOL_CHAIN_TAG" ] = GenFdsGlobalVariable.ToolChainTag\r
+ Macro["TARGET" ] = GenFdsGlobalVariable.TargetName\r
+\r
+ Macro["BUILD_DIR" ] = GenFdsGlobalVariable.OutputDirDict[Arch]\r
+ Macro["BIN_DIR" ] = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch)\r
+ Macro["LIB_DIR" ] = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch)\r
+ BuildDir = os.path.join(\r
+ GenFdsGlobalVariable.OutputDirDict[Arch],\r
+ Arch,\r
+ PathClassObj.SubDir,\r
+ PathClassObj.BaseName\r
+ )\r
+ Macro["MODULE_BUILD_DIR" ] = BuildDir\r
+ Macro["OUTPUT_DIR" ] = os.path.join(BuildDir, "OUTPUT")\r
+ Macro["DEBUG_DIR" ] = os.path.join(BuildDir, "DEBUG")\r
+\r
+ BuildRules = {}\r
+ for Type in BuildRuleDatabase.FileTypeList:\r
+ #first try getting build rule by BuildRuleFamily\r
+ RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.BuildRuleFamily]\r
+ if not RuleObject:\r
+ # build type is always module type, but ...\r
+ if Inf.ModuleType != Inf.BuildType:\r
+ RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.BuildRuleFamily]\r
+ #second try getting build rule by ToolChainFamily\r
+ if not RuleObject:\r
+ RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.ToolChainFamily]\r
+ if not RuleObject:\r
+ # build type is always module type, but ...\r
+ if Inf.ModuleType != Inf.BuildType:\r
+ RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.ToolChainFamily]\r
+ if not RuleObject:\r
+ continue\r
+ RuleObject = RuleObject.Instantiate(Macro)\r
+ BuildRules[Type] = RuleObject\r
+ for Ext in RuleObject.SourceFileExtList:\r
+ BuildRules[Ext] = RuleObject\r
+ return BuildRules\r
+\r
+ ## GetModuleCodaTargetList\r
+ #\r
+ # @param Inf: object of InfBuildData\r
+ # @param Arch: current arch\r
+ #\r
+ @staticmethod\r
+ def GetModuleCodaTargetList(Inf, Arch):\r
+ BuildRules = GenFdsGlobalVariable.GetBuildRules(Inf, Arch)\r
+ if not BuildRules:\r
+ return []\r
+\r
+ TargetList = set()\r
+ FileList = []\r
+\r
+ if not Inf.IsBinaryModule:\r
+ for File in Inf.Sources:\r
+ if File.TagName in ("", "*", GenFdsGlobalVariable.ToolChainTag) and \\r
+ File.ToolChainFamily in ("", "*", GenFdsGlobalVariable.ToolChainFamily):\r
+ FileList.append((File, DataType.TAB_UNKNOWN_FILE))\r
+\r
+ for File in Inf.Binaries:\r
+ if File.Target in [DataType.TAB_COMMON, '*', GenFdsGlobalVariable.TargetName]:\r
+ FileList.append((File, File.Type))\r
+\r
+ for File, FileType in FileList:\r
+ LastTarget = None\r
+ RuleChain = []\r
+ SourceList = [File]\r
+ Index = 0\r
+ while Index < len(SourceList):\r
+ Source = SourceList[Index]\r
+ Index = Index + 1\r
+ \r
+ if File.IsBinary and File == Source and Inf.Binaries is not None and File in Inf.Binaries:\r
+ # Skip all files that are not binary libraries\r
+ if not Inf.LibraryClass:\r
+ continue \r
+ RuleObject = BuildRules[DataType.TAB_DEFAULT_BINARY_FILE]\r
+ elif FileType in BuildRules:\r
+ RuleObject = BuildRules[FileType]\r
+ elif Source.Ext in BuildRules:\r
+ RuleObject = BuildRules[Source.Ext]\r
+ else:\r
+ # stop at no more rules\r
+ if LastTarget:\r
+ TargetList.add(str(LastTarget))\r
+ break\r
+ \r
+ FileType = RuleObject.SourceFileType\r
+ \r
+ # stop at STATIC_LIBRARY for library\r
+ if Inf.LibraryClass and FileType == DataType.TAB_STATIC_LIBRARY:\r
+ if LastTarget:\r
+ TargetList.add(str(LastTarget))\r
+ break\r
+ \r
+ Target = RuleObject.Apply(Source)\r
+ if not Target:\r
+ if LastTarget:\r
+ TargetList.add(str(LastTarget))\r
+ break\r
+ elif not Target.Outputs:\r
+ # Only do build for target with outputs\r
+ TargetList.add(str(Target))\r
+ \r
+ # to avoid cyclic rule\r
+ if FileType in RuleChain:\r
+ break\r
+ \r
+ RuleChain.append(FileType)\r
+ SourceList.extend(Target.Outputs)\r
+ LastTarget = Target\r
+ FileType = DataType.TAB_UNKNOWN_FILE\r
+ for Cmd in Target.Commands:\r
+ if "$(CP)" == Cmd.split()[0]:\r
+ CpTarget = Cmd.split()[2]\r
+ TargetList.add(CpTarget)\r
+\r
+ return list(TargetList)\r
+\r
+ ## SetDir()\r
+ #\r
+ # @param OutputDir Output directory\r
+ # @param FdfParser FDF contents parser\r
+ # @param Workspace The directory of workspace\r
+ # @param ArchList The Arch list of platform\r
+ #\r
+ def SetDir (OutputDir, FdfParser, WorkSpace, ArchList):\r
+ GenFdsGlobalVariable.VerboseLogger("GenFdsGlobalVariable.OutputDir :%s" % OutputDir)\r
+# GenFdsGlobalVariable.OutputDirDict = OutputDir\r
+ GenFdsGlobalVariable.FdfParser = FdfParser\r
+ GenFdsGlobalVariable.WorkSpace = WorkSpace\r
+ GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], 'FV')\r
+ if not os.path.exists(GenFdsGlobalVariable.FvDir) :\r
+ os.makedirs(GenFdsGlobalVariable.FvDir)\r
+ GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')\r
+ if not os.path.exists(GenFdsGlobalVariable.FfsDir) :\r
+ os.makedirs(GenFdsGlobalVariable.FfsDir)\r
+\r
+ T_CHAR_LF = '\n'\r
+ #\r
+ # Create FV Address inf file\r
+ #\r
+ GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf')\r
+ FvAddressFile = open(GenFdsGlobalVariable.FvAddressFileName, 'w')\r
+ #\r
+ # Add [Options]\r
+ #\r
+ FvAddressFile.writelines("[options]" + T_CHAR_LF)\r
+ BsAddress = '0'\r
+ for Arch in ArchList:\r
+ if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress:\r
+ BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress\r
+ break\r
+\r
+ FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \\r
+ BsAddress + \\r
+ T_CHAR_LF)\r
+\r
+ RtAddress = '0'\r
+ for Arch in ArchList:\r
+ if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress:\r
+ RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress\r
+\r
+ FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \\r
+ RtAddress + \\r
+ T_CHAR_LF)\r
+\r
+ FvAddressFile.close()\r
+\r
+ def SetEnv(FdfParser, WorkSpace, ArchList, GlobalData):\r
+ GenFdsGlobalVariable.ModuleFile = WorkSpace.ModuleFile\r
+ GenFdsGlobalVariable.FdfParser = FdfParser\r
+ GenFdsGlobalVariable.WorkSpace = WorkSpace.Db\r
+ GenFdsGlobalVariable.ArchList = ArchList\r
+ GenFdsGlobalVariable.ToolChainTag = GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]\r
+ GenFdsGlobalVariable.TargetName = GlobalData.gGlobalDefines["TARGET"]\r
+ GenFdsGlobalVariable.ActivePlatform = GlobalData.gActivePlatform\r
+ GenFdsGlobalVariable.EdkSourceDir = GlobalData.gGlobalDefines["EDK_SOURCE"]\r
+ GenFdsGlobalVariable.ConfDir = GlobalData.gConfDirectory\r
+ GenFdsGlobalVariable.EnableGenfdsMultiThread = GlobalData.gEnableGenfdsMultiThread\r
+ for Arch in ArchList:\r
+ GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.normpath(\r
+ os.path.join(GlobalData.gWorkspace,\r
+ WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,GlobalData.gGlobalDefines['TARGET'],\r
+ GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory,\r
+ GlobalData.gGlobalDefines['TARGET'] +'_' + GlobalData.gGlobalDefines['TOOLCHAIN']))\r
+ GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = os.path.normpath(\r
+ WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,\r
+ GlobalData.gGlobalDefines['TARGET'], GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory)\r
+ GenFdsGlobalVariable.PlatformName = WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,\r
+ GlobalData.gGlobalDefines['TARGET'],\r
+ GlobalData.gGlobalDefines['TOOLCHAIN']].PlatformName\r
+ GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], 'FV')\r
+ if not os.path.exists(GenFdsGlobalVariable.FvDir):\r
+ os.makedirs(GenFdsGlobalVariable.FvDir)\r
+ GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')\r
+ if not os.path.exists(GenFdsGlobalVariable.FfsDir):\r
+ os.makedirs(GenFdsGlobalVariable.FfsDir)\r
+\r
+ T_CHAR_LF = '\n'\r
+ #\r
+ # Create FV Address inf file\r
+ #\r
+ GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf')\r
+ FvAddressFile = open(GenFdsGlobalVariable.FvAddressFileName, 'w')\r
+ #\r
+ # Add [Options]\r
+ #\r
+ FvAddressFile.writelines("[options]" + T_CHAR_LF)\r
+ BsAddress = '0'\r
+ for Arch in ArchList:\r
+ BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,\r
+ GlobalData.gGlobalDefines['TARGET'],\r
+ GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].BsBaseAddress\r
+ if BsAddress:\r
+ break\r
+\r
+ FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \\r
+ BsAddress + \\r
+ T_CHAR_LF)\r
+\r
+ RtAddress = '0'\r
+ for Arch in ArchList:\r
+ if GenFdsGlobalVariable.WorkSpace.BuildObject[\r
+ GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'],\r
+ GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].RtBaseAddress:\r
+ RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[\r
+ GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'],\r
+ GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].RtBaseAddress\r
+\r
+ FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \\r
+ RtAddress + \\r
+ T_CHAR_LF)\r
+\r
+ FvAddressFile.close()\r
+\r
+ ## ReplaceWorkspaceMacro()\r
+ #\r
+ # @param String String that may contain macro\r
+ #\r
+ def ReplaceWorkspaceMacro(String):\r
+ String = mws.handleWsMacro(String)\r
+ Str = String.replace('$(WORKSPACE)', GenFdsGlobalVariable.WorkSpaceDir)\r
+ if os.path.exists(Str):\r
+ if not os.path.isabs(Str):\r
+ Str = os.path.abspath(Str)\r
+ else:\r
+ Str = mws.join(GenFdsGlobalVariable.WorkSpaceDir, String)\r
+ return os.path.normpath(Str)\r
+\r
+ ## Check if the input files are newer than output files\r
+ #\r
+ # @param Output Path of output file\r
+ # @param Input Path list of input files\r
+ #\r
+ # @retval True if Output doesn't exist, or any Input is newer\r
+ # @retval False if all Input is older than Output\r
+ #\r
+ @staticmethod\r
+ def NeedsUpdate(Output, Input):\r
+ if not os.path.exists(Output):\r
+ return True\r
+ # always update "Output" if no "Input" given\r
+ if Input is None or len(Input) == 0:\r
+ return True\r
+\r
+ # if fdf file is changed after the 'Output" is generated, update the 'Output'\r
+ OutputTime = os.path.getmtime(Output)\r
+ if GenFdsGlobalVariable.FdfFileTimeStamp > OutputTime:\r
+ return True\r
+\r
+ for F in Input:\r
+ # always update "Output" if any "Input" doesn't exist\r
+ if not os.path.exists(F):\r
+ return True\r
+ # always update "Output" if any "Input" is newer than "Output"\r
+ if os.path.getmtime(F) > OutputTime:\r
+ return True\r
+ return False\r
+\r
+ @staticmethod\r
+ def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None,\r
+ GuidHdrLen=None, GuidAttr=[], Ui=None, Ver=None, InputAlign=None, BuildNumber=None, DummyFile=None, IsMakefile=False):\r
+ Cmd = ["GenSec"]\r
+ if Type not in [None, '']:\r
+ Cmd += ["-s", Type]\r
+ if CompressionType not in [None, '']:\r
+ Cmd += ["-c", CompressionType]\r
+ if Guid is not None:\r
+ Cmd += ["-g", Guid]\r
+ if DummyFile is not None:\r
+ Cmd += ["--dummy", DummyFile]\r
+ if GuidHdrLen not in [None, '']:\r
+ Cmd += ["-l", GuidHdrLen]\r
+ if len(GuidAttr) != 0:\r
+ #Add each guided attribute\r
+ for Attr in GuidAttr:\r
+ Cmd += ["-r", Attr]\r
+ if InputAlign is not None:\r
+ #Section Align is only for dummy section without section type\r
+ for SecAlign in InputAlign:\r
+ Cmd += ["--sectionalign", SecAlign]\r
+\r
+ CommandFile = Output + '.txt'\r
+ if Ui not in [None, '']:\r
+ #Cmd += ["-n", '"' + Ui + '"']\r
+ if IsMakefile:\r
+ if Ui == "$(MODULE_NAME)":\r
+ Cmd += ['-n', Ui]\r
+ else:\r
+ Cmd += ["-n", '"' + Ui + '"']\r
+ Cmd += ["-o", Output]\r
+ if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r
+ GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())\r
+ else:\r
+ SectionData = array.array('B', [0, 0, 0, 0])\r
+ SectionData.fromstring(Ui.encode("utf_16_le"))\r
+ SectionData.append(0)\r
+ SectionData.append(0)\r
+ Len = len(SectionData)\r
+ GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x15)\r
+ SaveFileOnChange(Output, SectionData.tostring())\r
+\r
+ elif Ver not in [None, '']:\r
+ Cmd += ["-n", Ver]\r
+ if BuildNumber:\r
+ Cmd += ["-j", BuildNumber]\r
+ Cmd += ["-o", Output]\r
+\r
+ SaveFileOnChange(CommandFile, ' '.join(Cmd), False)\r
+ if IsMakefile:\r
+ if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r
+ GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())\r
+ else:\r
+ if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):\r
+ return\r
+ GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")\r
+ else:\r
+ Cmd += ["-o", Output]\r
+ Cmd += Input\r
+\r
+ SaveFileOnChange(CommandFile, ' '.join(Cmd), False)\r
+ if IsMakefile:\r
+ if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r
+ GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())\r
+ elif GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):\r
+ GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r
+ GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")\r
+ if (os.path.getsize(Output) >= GenFdsGlobalVariable.LARGE_FILE_SIZE and\r
+ GenFdsGlobalVariable.LargeFileInFvFlags):\r
+ GenFdsGlobalVariable.LargeFileInFvFlags[-1] = True\r
+\r
+ @staticmethod\r
+ def GetAlignment (AlignString):\r
+ if AlignString is None:\r
+ return 0\r
+ if AlignString in ("1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K"):\r