summaryrefslogtreecommitdiff
path: root/BaseTools/Source/Python/AutoGen
diff options
context:
space:
mode:
authorGao, Liming <liming.gao@intel.com>2014-01-27 05:23:15 +0000
committerlgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>2014-01-27 05:23:15 +0000
commitf51461c829c124288a930829a78e2a5a799f4039 (patch)
tree1072993516da9d887f0e0fd876c9ac5630c19ae2 /BaseTools/Source/Python/AutoGen
parent7771be9fd0b9b3c7f5c0659c416535171de31191 (diff)
downloadedk2-platforms-f51461c829c124288a930829a78e2a5a799f4039.tar.xz
Sync BaseTool trunk (version r2649) into EDKII BaseTools.
Signed-off-by: Gao, Liming <liming.gao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15188 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'BaseTools/Source/Python/AutoGen')
-rw-r--r--BaseTools/Source/Python/AutoGen/BuildEngine.py1254
-rw-r--r--BaseTools/Source/Python/AutoGen/GenC.py3146
-rw-r--r--BaseTools/Source/Python/AutoGen/GenMake.py2822
3 files changed, 3611 insertions, 3611 deletions
diff --git a/BaseTools/Source/Python/AutoGen/BuildEngine.py b/BaseTools/Source/Python/AutoGen/BuildEngine.py
index 5a7527ef4b..b3083d0395 100644
--- a/BaseTools/Source/Python/AutoGen/BuildEngine.py
+++ b/BaseTools/Source/Python/AutoGen/BuildEngine.py
@@ -1,627 +1,627 @@
-## @file
-# The engine for building files
-#
-# Copyright (c) 2007, 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 re
-import copy
-import string
-
-from Common.GlobalData import *
-from Common.BuildToolError import *
-from Common.Misc import tdict, PathClass
-from Common.String import NormPath
-from Common.DataType import *
-
-import Common.EdkLogger as EdkLogger
-
-## Convert file type to file list macro name
-#
-# @param FileType The name of file type
-#
-# @retval string The name of macro
-#
-def FileListMacro(FileType):
- return "%sS" % FileType.replace("-", "_").upper()
-
-## Convert file type to list file macro name
-#
-# @param FileType The name of file type
-#
-# @retval string The name of macro
-#
-def ListFileMacro(FileType):
- return "%s_LIST" % FileListMacro(FileType)
-
-class TargetDescBlock(object):
- _Cache_ = {} # {TargetFile : TargetDescBlock object}
-
- # Factory method
- def __new__(Class, Inputs, Outputs, Commands, Dependencies):
- if Outputs[0] in Class._Cache_:
- Tdb = Class._Cache_[Outputs[0]]
- for File in Inputs:
- Tdb.AddInput(File)
- else:
- Tdb = super(TargetDescBlock, Class).__new__(Class)
- Tdb._Init(Inputs, Outputs, Commands, Dependencies)
- #Class._Cache_[Outputs[0]] = Tdb
- return Tdb
-
- def _Init(self, Inputs, Outputs, Commands, Dependencies):
- self.Inputs = Inputs
- self.Outputs = Outputs
- self.Commands = Commands
- self.Dependencies = Dependencies
- if self.Outputs:
- self.Target = self.Outputs[0]
- else:
- self.Target = None
-
- def __str__(self):
- return self.Target.Path
-
- def __hash__(self):
- return hash(self.Target.Path)
-
- def __eq__(self, Other):
- if type(Other) == type(self):
- return Other.Target.Path == self.Target.Path
- else:
- return str(Other) == self.Target.Path
-
- def AddInput(self, Input):
- if Input not in self.Inputs:
- self.Inputs.append(Input)
-
- def IsMultipleInput(self):
- return len(self.Inputs) > 1
-
- @staticmethod
- def Renew():
- TargetDescBlock._Cache_ = {}
-
-## Class for one build rule
-#
-# This represents a build rule which can give out corresponding command list for
-# building the given source file(s). The result can be used for generating the
-# target for makefile.
-#
-class FileBuildRule:
- INC_LIST_MACRO = "INC_LIST"
- INC_MACRO = "INC"
-
- ## constructor
- #
- # @param Input The dictionary represeting input file(s) for a rule
- # @param Output The list represeting output file(s) for a rule
- # @param Command The list containing commands to generate the output from input
- #
- def __init__(self, Type, Input, Output, Command, ExtraDependency=None):
- # The Input should not be empty
- if not Input:
- Input = []
- if not Output:
- Output = []
- if not Command:
- Command = []
-
- self.FileListMacro = FileListMacro(Type)
- self.ListFileMacro = ListFileMacro(Type)
- self.IncListFileMacro = self.INC_LIST_MACRO
-
- self.SourceFileType = Type
- # source files listed not in "*" or "?" pattern format
- if not ExtraDependency:
- self.ExtraSourceFileList = []
- else:
- self.ExtraSourceFileList = ExtraDependency
-
- #
- # Search macros used in command lines for <FILE_TYPE>_LIST and INC_LIST.
- # If found, generate a file to keep the input files used to get over the
- # limitation of command line length
- #
- self.MacroList = []
- self.CommandList = []
- for CmdLine in Command:
- self.MacroList.extend(gMacroRefPattern.findall(CmdLine))
- # replace path separator with native one
- self.CommandList.append(CmdLine)
-
- # Indicate what should be generated
- if self.FileListMacro in self.MacroList:
- self.GenFileListMacro = True
- else:
- self.GenFileListMacro = False
-
- if self.ListFileMacro in self.MacroList:
- self.GenListFile = True
- self.GenFileListMacro = True
- else:
- self.GenListFile = False
-
- if self.INC_LIST_MACRO in self.MacroList:
- self.GenIncListFile = True
- else:
- self.GenIncListFile = False
-
- # Check input files
- self.IsMultipleInput = False
- self.SourceFileExtList = []
- for File in Input:
- Base, Ext = os.path.splitext(File)
- if Base.find("*") >= 0:
- # There's "*" in the file name
- self.IsMultipleInput = True
- self.GenFileListMacro = True
- elif Base.find("?") < 0:
- # There's no "*" and "?" in file name
- self.ExtraSourceFileList.append(File)
- continue
- if Ext not in self.SourceFileExtList:
- self.SourceFileExtList.append(Ext)
-
- # Check output files
- self.DestFileList = []
- for File in Output:
- self.DestFileList.append(File)
-
- # All build targets generated by this rule for a module
- self.BuildTargets = {}
-
- ## str() function support
- #
- # @retval string
- #
- def __str__(self):
- SourceString = ""
- SourceString += " %s %s %s" % (self.SourceFileType, " ".join(self.SourceFileExtList), self.ExtraSourceFileList)
- DestString = ", ".join(self.DestFileList)
- CommandString = "\n\t".join(self.CommandList)
- return "%s : %s\n\t%s" % (DestString, SourceString, CommandString)
-
- ## Check if given file extension is supported by this rule
- #
- # @param FileExt The extension of a file
- #
- # @retval True If the extension is supported
- # @retval False If the extension is not supported
- #
- def IsSupported(self, FileExt):
- return FileExt in self.SourceFileExtList
-
- def Instantiate(self, Macros={}):
- NewRuleObject = copy.copy(self)
- NewRuleObject.BuildTargets = {}
- NewRuleObject.DestFileList = []
- for File in self.DestFileList:
- NewRuleObject.DestFileList.append(PathClass(NormPath(File, Macros)))
- return NewRuleObject
-
- ## Apply the rule to given source file(s)
- #
- # @param SourceFile One file or a list of files to be built
- # @param RelativeToDir The relative path of the source file
- # @param PathSeparator Path separator
- #
- # @retval tuple (Source file in full path, List of individual sourcefiles, Destionation file, List of build commands)
- #
- def Apply(self, SourceFile):
- if not self.CommandList or not self.DestFileList:
- return None
-
- # source file
- if self.IsMultipleInput:
- SrcFileName = ""
- SrcFileBase = ""
- SrcFileExt = ""
- SrcFileDir = ""
- SrcPath = ""
- # SourceFile must be a list
- SrcFile = "$(%s)" % self.FileListMacro
- else:
- SrcFileName, SrcFileBase, SrcFileExt = SourceFile.Name, SourceFile.BaseName, SourceFile.Ext
- if SourceFile.Root:
- SrcFileDir = SourceFile.SubDir
- if SrcFileDir == "":
- SrcFileDir = "."
- else:
- SrcFileDir = "."
- SrcFile = SourceFile.Path
- SrcPath = SourceFile.Dir
-
- # destination file (the first one)
- if self.DestFileList:
- DestFile = self.DestFileList[0].Path
- DestPath = self.DestFileList[0].Dir
- DestFileName = self.DestFileList[0].Name
- DestFileBase, DestFileExt = self.DestFileList[0].BaseName, self.DestFileList[0].Ext
- else:
- DestFile = ""
- DestPath = ""
- DestFileName = ""
- DestFileBase = ""
- DestFileExt = ""
-
- BuildRulePlaceholderDict = {
- # source file
- "src" : SrcFile,
- "s_path" : SrcPath,
- "s_dir" : SrcFileDir,
- "s_name" : SrcFileName,
- "s_base" : SrcFileBase,
- "s_ext" : SrcFileExt,
- # destination file
- "dst" : DestFile,
- "d_path" : DestPath,
- "d_name" : DestFileName,
- "d_base" : DestFileBase,
- "d_ext" : DestFileExt,
- }
-
- DstFile = []
- for File in self.DestFileList:
- File = string.Template(str(File)).safe_substitute(BuildRulePlaceholderDict)
- File = string.Template(str(File)).safe_substitute(BuildRulePlaceholderDict)
- DstFile.append(PathClass(File, IsBinary=True))
-
- if DstFile[0] in self.BuildTargets:
- TargetDesc = self.BuildTargets[DstFile[0]]
- TargetDesc.AddInput(SourceFile)
- else:
- CommandList = []
- for CommandString in self.CommandList:
- CommandString = string.Template(CommandString).safe_substitute(BuildRulePlaceholderDict)
- CommandString = string.Template(CommandString).safe_substitute(BuildRulePlaceholderDict)
- CommandList.append(CommandString)
- TargetDesc = TargetDescBlock([SourceFile], DstFile, CommandList, self.ExtraSourceFileList)
- TargetDesc.ListFileMacro = self.ListFileMacro
- TargetDesc.FileListMacro = self.FileListMacro
- TargetDesc.IncListFileMacro = self.IncListFileMacro
- TargetDesc.GenFileListMacro = self.GenFileListMacro
- TargetDesc.GenListFile = self.GenListFile
- TargetDesc.GenIncListFile = self.GenIncListFile
- self.BuildTargets[DstFile[0]] = TargetDesc
- return TargetDesc
-
-## Class for build rules
-#
-# BuildRule class parses rules defined in a file or passed by caller, and converts
-# the rule into FileBuildRule object.
-#
-class BuildRule:
- _SectionHeader = "SECTIONHEADER"
- _Section = "SECTION"
- _SubSectionHeader = "SUBSECTIONHEADER"
- _SubSection = "SUBSECTION"
- _InputFile = "INPUTFILE"
- _OutputFile = "OUTPUTFILE"
- _ExtraDependency = "EXTRADEPENDENCY"
- _Command = "COMMAND"
- _UnknownSection = "UNKNOWNSECTION"
-
- _SubSectionList = [_InputFile, _OutputFile, _Command]
-
- _PATH_SEP = "(+)"
- _FileTypePattern = re.compile("^[_a-zA-Z][_\-0-9a-zA-Z]*$")
- _BinaryFileRule = FileBuildRule(TAB_DEFAULT_BINARY_FILE, [], [os.path.join("$(OUTPUT_DIR)", "${s_name}")],
- ["$(CP) ${src} ${dst}"], [])
-
- ## Constructor
- #
- # @param File The file containing build rules in a well defined format
- # @param Content The string list of build rules in a well defined format
- # @param LineIndex The line number from which the parsing will begin
- # @param SupportedFamily The list of supported tool chain families
- #
- def __init__(self, File=None, Content=None, LineIndex=0, SupportedFamily=["MSFT", "INTEL", "GCC", "RVCT"]):
- self.RuleFile = File
- # Read build rules from file if it's not none
- if File != None:
- try:
- self.RuleContent = open(File, 'r').readlines()
- except:
- EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=File)
- elif Content != None:
- self.RuleContent = Content
- else:
- EdkLogger.error("build", PARAMETER_MISSING, ExtraData="No rule file or string given")
-
- self.SupportedToolChainFamilyList = SupportedFamily
- self.RuleDatabase = tdict(True, 4) # {FileExt, ModuleType, Arch, Family : FileBuildRule object}
- self.Ext2FileType = {} # {ext : file-type}
- self.FileTypeList = set()
-
- self._LineIndex = LineIndex
- self._State = ""
- self._RuleInfo = tdict(True, 2) # {toolchain family : {"InputFile": {}, "OutputFile" : [], "Command" : []}}
- self._FileType = ''
- self._BuildTypeList = []
- self._ArchList = []
- self._FamilyList = []
- self._TotalToolChainFamilySet = set()
- self._RuleObjectList = [] # FileBuildRule object list
- self._FileVersion = ""
-
- self.Parse()
-
- # some intrinsic rules
- self.RuleDatabase[TAB_DEFAULT_BINARY_FILE, "COMMON", "COMMON", "COMMON"] = self._BinaryFileRule
- self.FileTypeList.add(TAB_DEFAULT_BINARY_FILE)
-
- ## Parse the build rule strings
- def Parse(self):
- self._State = self._Section
- for Index in range(self._LineIndex, len(self.RuleContent)):
- # Clean up the line and replace path separator with native one
- Line = self.RuleContent[Index].strip().replace(self._PATH_SEP, os.path.sep)
- self.RuleContent[Index] = Line
-
- # find the build_rule_version
- if Line and Line[0] == "#" and Line.find(TAB_BUILD_RULE_VERSION) <> -1:
- if Line.find("=") <> -1 and Line.find("=") < (len(Line)-1) and (Line[(Line.find("=") + 1):]).split():
- self._FileVersion = (Line[(Line.find("=") + 1):]).split()[0]
- # skip empty or comment line
- if Line == "" or Line[0] == "#":
- continue
-
- # find out section header, enclosed by []
- if Line[0] == '[' and Line[-1] == ']':
- # merge last section information into rule database
- self.EndOfSection()
- self._State = self._SectionHeader
- # find out sub-section header, enclosed by <>
- elif Line[0] == '<' and Line[-1] == '>':
- if self._State != self._UnknownSection:
- self._State = self._SubSectionHeader
-
- # call section handler to parse each (sub)section
- self._StateHandler[self._State](self, Index)
- # merge last section information into rule database
- self.EndOfSection()
-
- ## Parse definitions under a section
- #
- # @param LineIndex The line index of build rule text
- #
- def ParseSection(self, LineIndex):
- pass
-
- ## Parse definitions under a subsection
- #
- # @param LineIndex The line index of build rule text
- #
- def ParseSubSection(self, LineIndex):
- # currenly nothing here
- pass
-
- ## Placeholder for not supported sections
- #
- # @param LineIndex The line index of build rule text
- #
- def SkipSection(self, LineIndex):
- pass
-
- ## Merge section information just got into rule database
- def EndOfSection(self):
- Database = self.RuleDatabase
- # if there's specific toochain family, 'COMMON' doesn't make sense any more
- if len(self._TotalToolChainFamilySet) > 1 and 'COMMON' in self._TotalToolChainFamilySet:
- self._TotalToolChainFamilySet.remove('COMMON')
- for Family in self._TotalToolChainFamilySet:
- Input = self._RuleInfo[Family, self._InputFile]
- Output = self._RuleInfo[Family, self._OutputFile]
- Command = self._RuleInfo[Family, self._Command]
- ExtraDependency = self._RuleInfo[Family, self._ExtraDependency]
-
- BuildRule = FileBuildRule(self._FileType, Input, Output, Command, ExtraDependency)
- for BuildType in self._BuildTypeList:
- for Arch in self._ArchList:
- Database[self._FileType, BuildType, Arch, Family] = BuildRule
- for FileExt in BuildRule.SourceFileExtList:
- self.Ext2FileType[FileExt] = self._FileType
-
- ## Parse section header
- #
- # @param LineIndex The line index of build rule text
- #
- def ParseSectionHeader(self, LineIndex):
- self._RuleInfo = tdict(True, 2)
- self._BuildTypeList = []
- self._ArchList = []
- self._FamilyList = []
- self._TotalToolChainFamilySet = set()
- FileType = ''
- RuleNameList = self.RuleContent[LineIndex][1:-1].split(',')
- for RuleName in RuleNameList:
- Arch = 'COMMON'
- BuildType = 'COMMON'
- TokenList = [Token.strip().upper() for Token in RuleName.split('.')]
- # old format: Build.File-Type
- if TokenList[0] == "BUILD":
- if len(TokenList) == 1:
- EdkLogger.error("build", FORMAT_INVALID, "Invalid rule section",
- File=self.RuleFile, Line=LineIndex+1,
- ExtraData=self.RuleContent[LineIndex])
-
- FileType = TokenList[1]
- if FileType == '':
- EdkLogger.error("build", FORMAT_INVALID, "No file type given",
- File=self.RuleFile, Line=LineIndex+1,
- ExtraData=self.RuleContent[LineIndex])
- if self._FileTypePattern.match(FileType) == None:
- EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex+1,
- ExtraData="Only character, number (non-first character), '_' and '-' are allowed in file type")
- # new format: File-Type.Build-Type.Arch
- else:
- if FileType == '':
- FileType = TokenList[0]
- elif FileType != TokenList[0]:
- EdkLogger.error("build", FORMAT_INVALID,
- "Different file types are not allowed in the same rule section",
- File=self.RuleFile, Line=LineIndex+1,
- ExtraData=self.RuleContent[LineIndex])
- if len(TokenList) > 1:
- BuildType = TokenList[1]
- if len(TokenList) > 2:
- Arch = TokenList[2]
- if BuildType not in self._BuildTypeList:
- self._BuildTypeList.append(BuildType)
- if Arch not in self._ArchList:
- self._ArchList.append(Arch)
-
- if 'COMMON' in self._BuildTypeList and len(self._BuildTypeList) > 1:
- EdkLogger.error("build", FORMAT_INVALID,
- "Specific build types must not be mixed with common one",
- File=self.RuleFile, Line=LineIndex+1,
- ExtraData=self.RuleContent[LineIndex])
- if 'COMMON' in self._ArchList and len(self._ArchList) > 1:
- EdkLogger.error("build", FORMAT_INVALID,
- "Specific ARCH must not be mixed with common one",
- File=self.RuleFile, Line=LineIndex+1,
- ExtraData=self.RuleContent[LineIndex])
-
- self._FileType = FileType
- self._State = self._Section
- self.FileTypeList.add(FileType)
-
- ## Parse sub-section header
- #
- # @param LineIndex The line index of build rule text
- #
- def ParseSubSectionHeader(self, LineIndex):
- SectionType = ""
- List = self.RuleContent[LineIndex][1:-1].split(',')
- FamilyList = []
- for Section in List:
- TokenList = Section.split('.')
- Type = TokenList[0].strip().upper()
-
- if SectionType == "":
- SectionType = Type
- elif SectionType != Type:
- EdkLogger.error("build", FORMAT_INVALID,
- "Two different section types are not allowed in the same sub-section",
- File=self.RuleFile, Line=LineIndex+1,
- ExtraData=self.RuleContent[LineIndex])
-
- if len(TokenList) > 1:
- Family = TokenList[1].strip().upper()
- else:
- Family = "COMMON"
-
- if Family not in FamilyList:
- FamilyList.append(Family)
-
- self._FamilyList = FamilyList
- self._TotalToolChainFamilySet.update(FamilyList)
- self._State = SectionType.upper()
- if 'COMMON' in FamilyList and len(FamilyList) > 1:
- EdkLogger.error("build", FORMAT_INVALID,
- "Specific tool chain family should not be mixed with general one",
- File=self.RuleFile, Line=LineIndex+1,
- ExtraData=self.RuleContent[LineIndex])
- if self._State not in self._StateHandler:
- EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex+1,
- ExtraData="Unknown subsection: %s" % self.RuleContent[LineIndex])
- ## Parse <InputFile> sub-section
- #
- # @param LineIndex The line index of build rule text
- #
- def ParseInputFile(self, LineIndex):
- FileList = [File.strip() for File in self.RuleContent[LineIndex].split(",")]
- for ToolChainFamily in self._FamilyList:
- InputFiles = self._RuleInfo[ToolChainFamily, self._State]
- if InputFiles == None:
- InputFiles = []
- self._RuleInfo[ToolChainFamily, self._State] = InputFiles
- InputFiles.extend(FileList)
-
- ## Parse <ExtraDependency> sub-section
- #
- # @param LineIndex The line index of build rule text
- #
- def ParseCommon(self, LineIndex):
- for ToolChainFamily in self._FamilyList:
- Items = self._RuleInfo[ToolChainFamily, self._State]
- if Items == None:
- Items = []
- self._RuleInfo[ToolChainFamily, self._State] = Items
- Items.append(self.RuleContent[LineIndex])
-
- ## Get a build rule via [] operator
- #
- # @param FileExt The extension of a file
- # @param ToolChainFamily The tool chain family name
- # @param BuildVersion The build version number. "*" means any rule
- # is applicalbe.
- #
- # @retval FileType The file type string
- # @retval FileBuildRule The object of FileBuildRule
- #
- # Key = (FileExt, ModuleType, Arch, ToolChainFamily)
- def __getitem__(self, Key):
- if not Key:
- return None
-
- if Key[0] in self.Ext2FileType:
- Type = self.Ext2FileType[Key[0]]
- elif Key[0].upper() in self.FileTypeList:
- Type = Key[0].upper()
- else:
- return None
-
- if len(Key) > 1:
- Key = (Type,) + Key[1:]
- else:
- Key = (Type,)
- return self.RuleDatabase[Key]
-
- _StateHandler = {
- _SectionHeader : ParseSectionHeader,
- _Section : ParseSection,
- _SubSectionHeader : ParseSubSectionHeader,
- _SubSection : ParseSubSection,
- _InputFile : ParseInputFile,
- _OutputFile : ParseCommon,
- _ExtraDependency : ParseCommon,
- _Command : ParseCommon,
- _UnknownSection : SkipSection,
- }
-
-# This acts like the main() function for the script, unless it is 'import'ed into another
-# script.
-if __name__ == '__main__':
- import sys
- EdkLogger.Initialize()
- if len(sys.argv) > 1:
- Br = BuildRule(sys.argv[1])
- print str(Br[".c", "DXE_DRIVER", "IA32", "MSFT"][1])
- print
- print str(Br[".c", "DXE_DRIVER", "IA32", "INTEL"][1])
- print
- print str(Br[".c", "DXE_DRIVER", "IA32", "GCC"][1])
- print
- print str(Br[".ac", "ACPI_TABLE", "IA32", "MSFT"][1])
- print
- print str(Br[".h", "ACPI_TABLE", "IA32", "INTEL"][1])
- print
- print str(Br[".ac", "ACPI_TABLE", "IA32", "MSFT"][1])
- print
- print str(Br[".s", "SEC", "IPF", "COMMON"][1])
- print
- print str(Br[".s", "SEC"][1])
-
+## @file
+# The engine for building files
+#
+# Copyright (c) 2007, 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 re
+import copy
+import string
+
+from Common.GlobalData import *
+from Common.BuildToolError import *
+from Common.Misc import tdict, PathClass
+from Common.String import NormPath
+from Common.DataType import *
+
+import Common.EdkLogger as EdkLogger
+
+## Convert file type to file list macro name
+#
+# @param FileType The name of file type
+#
+# @retval string The name of macro
+#
+def FileListMacro(FileType):
+ return "%sS" % FileType.replace("-", "_").upper()
+
+## Convert file type to list file macro name
+#
+# @param FileType The name of file type
+#
+# @retval string The name of macro
+#
+def ListFileMacro(FileType):
+ return "%s_LIST" % FileListMacro(FileType)
+
+class TargetDescBlock(object):
+ _Cache_ = {} # {TargetFile : TargetDescBlock object}
+
+ # Factory method
+ def __new__(Class, Inputs, Outputs, Commands, Dependencies):
+ if Outputs[0] in Class._Cache_:
+ Tdb = Class._Cache_[Outputs[0]]
+ for File in Inputs:
+ Tdb.AddInput(File)
+ else:
+ Tdb = super(TargetDescBlock, Class).__new__(Class)
+ Tdb._Init(Inputs, Outputs, Commands, Dependencies)
+ #Class._Cache_[Outputs[0]] = Tdb
+ return Tdb
+
+ def _Init(self, Inputs, Outputs, Commands, Dependencies):
+ self.Inputs = Inputs
+ self.Outputs = Outputs
+ self.Commands = Commands
+ self.Dependencies = Dependencies
+ if self.Outputs:
+ self.Target = self.Outputs[0]
+ else:
+ self.Target = None
+
+ def __str__(self):
+ return self.Target.Path
+
+ def __hash__(self):
+ return hash(self.Target.Path)
+
+ def __eq__(self, Other):
+ if type(Other) == type(self):
+ return Other.Target.Path == self.Target.Path
+ else:
+ return str(Other) == self.Target.Path
+
+ def AddInput(self, Input):
+ if Input not in self.Inputs:
+ self.Inputs.append(Input)
+
+ def IsMultipleInput(self):
+ return len(self.Inputs) > 1
+
+ @staticmethod
+ def Renew():
+ TargetDescBlock._Cache_ = {}
+
+## Class for one build rule
+#
+# This represents a build rule which can give out corresponding command list for
+# building the given source file(s). The result can be used for generating the
+# target for makefile.
+#
+class FileBuildRule:
+ INC_LIST_MACRO = "INC_LIST"
+ INC_MACRO = "INC"
+
+ ## constructor
+ #
+ # @param Input The dictionary represeting input file(s) for a rule
+ # @param Output The list represeting output file(s) for a rule
+ # @param Command The list containing commands to generate the output from input
+ #
+ def __init__(self, Type, Input, Output, Command, ExtraDependency=None):
+ # The Input should not be empty
+ if not Input:
+ Input = []
+ if not Output:
+ Output = []
+ if not Command:
+ Command = []
+
+ self.FileListMacro = FileListMacro(Type)
+ self.ListFileMacro = ListFileMacro(Type)
+ self.IncListFileMacro = self.INC_LIST_MACRO
+
+ self.SourceFileType = Type
+ # source files listed not in "*" or "?" pattern format
+ if not ExtraDependency:
+ self.ExtraSourceFileList = []
+ else:
+ self.ExtraSourceFileList = ExtraDependency
+
+ #
+ # Search macros used in command lines for <FILE_TYPE>_LIST and INC_LIST.
+ # If found, generate a file to keep the input files used to get over the
+ # limitation of command line length
+ #
+ self.MacroList = []
+ self.CommandList = []
+ for CmdLine in Command:
+ self.MacroList.extend(gMacroRefPattern.findall(CmdLine))
+ # replace path separator with native one
+ self.CommandList.append(CmdLine)
+
+ # Indicate what should be generated
+ if self.FileListMacro in self.MacroList:
+ self.GenFileListMacro = True
+ else:
+ self.GenFileListMacro = False
+
+ if self.ListFileMacro in self.MacroList:
+ self.GenListFile = True
+ self.GenFileListMacro = True
+ else:
+ self.GenListFile = False
+
+ if self.INC_LIST_MACRO in self.MacroList:
+ self.GenIncListFile = True
+ else:
+ self.GenIncListFile = False
+
+ # Check input files
+ self.IsMultipleInput = False
+ self.SourceFileExtList = []
+ for File in Input:
+ Base, Ext = os.path.splitext(File)
+ if Base.find("*") >= 0:
+ # There's "*" in the file name
+ self.IsMultipleInput = True
+ self.GenFileListMacro = True
+ elif Base.find("?") < 0:
+ # There's no "*" and "?" in file name
+ self.ExtraSourceFileList.append(File)
+ continue
+ if Ext not in self.SourceFileExtList:
+ self.SourceFileExtList.append(Ext)
+
+ # Check output files
+ self.DestFileList = []
+ for File in Output:
+ self.DestFileList.append(File)
+
+ # All build targets generated by this rule for a module
+ self.BuildTargets = {}
+
+ ## str() function support
+ #
+ # @retval string
+ #
+ def __str__(self):
+ SourceString = ""
+ SourceString += " %s %s %s" % (self.SourceFileType, " ".join(self.SourceFileExtList), self.ExtraSourceFileList)
+ DestString = ", ".join(self.DestFileList)
+ CommandString = "\n\t".join(self.CommandList)
+ return "%s : %s\n\t%s" % (DestString, SourceString, CommandString)
+
+ ## Check if given file extension is supported by this rule
+ #
+ # @param FileExt The extension of a file
+ #
+ # @retval True If the extension is supported
+ # @retval False If the extension is not supported
+ #
+ def IsSupported(self, FileExt):
+ return FileExt in self.SourceFileExtList
+
+ def Instantiate(self, Macros={}):
+ NewRuleObject = copy.copy(self)
+ NewRuleObject.BuildTargets = {}
+ NewRuleObject.DestFileList = []
+ for File in self.DestFileList:
+ NewRuleObject.DestFileList.append(PathClass(NormPath(File, Macros)))
+ return NewRuleObject
+
+ ## Apply the rule to given source file(s)
+ #
+ # @param SourceFile One file or a list of files to be built
+ # @param RelativeToDir The relative path of the source file
+ # @param PathSeparator Path separator
+ #
+ # @retval tuple (Source file in full path, List of individual sourcefiles, Destionation file, List of build commands)
+ #
+ def Apply(self, SourceFile):
+ if not self.CommandList or not self.DestFileList:
+ return None
+
+ # source file
+ if self.IsMultipleInput:
+ SrcFileName = ""
+ SrcFileBase = ""
+ SrcFileExt = ""
+ SrcFileDir = ""
+ SrcPath = ""
+ # SourceFile must be a list
+ SrcFile = "$(%s)" % self.FileListMacro
+ else:
+ SrcFileName, SrcFileBase, SrcFileExt = SourceFile.Name, SourceFile.BaseName, SourceFile.Ext
+ if SourceFile.Root:
+ SrcFileDir = SourceFile.SubDir
+ if SrcFileDir == "":
+ SrcFileDir = "."
+ else:
+ SrcFileDir = "."
+ SrcFile = SourceFile.Path
+ SrcPath = SourceFile.Dir
+
+ # destination file (the first one)
+ if self.DestFileList:
+ DestFile = self.DestFileList[0].Path
+ DestPath = self.DestFileList[0].Dir
+ DestFileName = self.DestFileList[0].Name
+ DestFileBase, DestFileExt = self.DestFileList[0].BaseName, self.DestFileList[0].Ext
+ else:
+ DestFile = ""
+ DestPath = ""
+ DestFileName = ""
+ DestFileBase = ""
+ DestFileExt = ""
+
+ BuildRulePlaceholderDict = {
+ # source file
+ "src" : SrcFile,
+ "s_path" : SrcPath,
+ "s_dir" : SrcFileDir,
+ "s_name" : SrcFileName,
+ "s_base" : SrcFileBase,
+ "s_ext" : SrcFileExt,
+ # destination file
+ "dst" : DestFile,
+ "d_path" : DestPath,
+ "d_name" : DestFileName,
+ "d_base" : DestFileBase,
+ "d_ext" : DestFileExt,
+ }
+
+ DstFile = []
+ for File in self.DestFileList:
+ File = string.Template(str(File)).safe_substitute(BuildRulePlaceholderDict)
+ File = string.Template(str(File)).safe_substitute(BuildRulePlaceholderDict)
+ DstFile.append(PathClass(File, IsBinary=True))
+
+ if DstFile[0] in self.BuildTargets:
+ TargetDesc = self.BuildTargets[DstFile[0]]
+ TargetDesc.AddInput(SourceFile)
+ else:
+ CommandList = []
+ for CommandString in self.CommandList:
+ CommandString = string.Template(CommandString).safe_substitute(BuildRulePlaceholderDict)
+ CommandString = string.Template(CommandString).safe_substitute(BuildRulePlaceholderDict)
+ CommandList.append(CommandString)
+ TargetDesc = TargetDescBlock([SourceFile], DstFile, CommandList, self.ExtraSourceFileList)
+ TargetDesc.ListFileMacro = self.ListFileMacro
+ TargetDesc.FileListMacro = self.FileListMacro
+ TargetDesc.IncListFileMacro = self.IncListFileMacro
+ TargetDesc.GenFileListMacro = self.GenFileListMacro
+ TargetDesc.GenListFile = self.GenListFile
+ TargetDesc.GenIncListFile = self.GenIncListFile
+ self.BuildTargets[DstFile[0]] = TargetDesc
+ return TargetDesc
+
+## Class for build rules
+#
+# BuildRule class parses rules defined in a file or passed by caller, and converts
+# the rule into FileBuildRule object.
+#
+class BuildRule:
+ _SectionHeader = "SECTIONHEADER"
+ _Section = "SECTION"
+ _SubSectionHeader = "SUBSECTIONHEADER"
+ _SubSection = "SUBSECTION"
+ _InputFile = "INPUTFILE"
+ _OutputFile = "OUTPUTFILE"
+ _ExtraDependency = "EXTRADEPENDENCY"
+ _Command = "COMMAND"
+ _UnknownSection = "UNKNOWNSECTION"
+
+ _SubSectionList = [_InputFile, _OutputFile, _Command]
+
+ _PATH_SEP = "(+)"
+ _FileTypePattern = re.compile("^[_a-zA-Z][_\-0-9a-zA-Z]*$")
+ _BinaryFileRule = FileBuildRule(TAB_DEFAULT_BINARY_FILE, [], [os.path.join("$(OUTPUT_DIR)", "${s_name}")],
+ ["$(CP) ${src} ${dst}"], [])
+
+ ## Constructor
+ #
+ # @param File The file containing build rules in a well defined format
+ # @param Content The string list of build rules in a well defined format
+ # @param LineIndex The line number from which the parsing will begin
+ # @param SupportedFamily The list of supported tool chain families
+ #
+ def __init__(self, File=None, Content=None, LineIndex=0, SupportedFamily=["MSFT", "INTEL", "GCC", "RVCT"]):
+ self.RuleFile = File
+ # Read build rules from file if it's not none
+ if File != None:
+ try:
+ self.RuleContent = open(File, 'r').readlines()
+ except:
+ EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=File)
+ elif Content != None:
+ self.RuleContent = Content
+ else:
+ EdkLogger.error("build", PARAMETER_MISSING, ExtraData="No rule file or string given")
+
+ self.SupportedToolChainFamilyList = SupportedFamily
+ self.RuleDatabase = tdict(True, 4) # {FileExt, ModuleType, Arch, Family : FileBuildRule object}
+ self.Ext2FileType = {} # {ext : file-type}
+ self.FileTypeList = set()
+
+ self._LineIndex = LineIndex
+ self._State = ""
+ self._RuleInfo = tdict(True, 2) # {toolchain family : {"InputFile": {}, "OutputFile" : [], "Command" : []}}
+ self._FileType = ''
+ self._BuildTypeList = []
+ self._ArchList = []
+ self._FamilyList = []
+ self._TotalToolChainFamilySet = set()
+ self._RuleObjectList = [] # FileBuildRule object list
+ self._FileVersion = ""
+
+ self.Parse()
+
+ # some intrinsic rules
+ self.RuleDatabase[TAB_DEFAULT_BINARY_FILE, "COMMON", "COMMON", "COMMON"] = self._BinaryFileRule
+ self.FileTypeList.add(TAB_DEFAULT_BINARY_FILE)
+
+ ## Parse the build rule strings
+ def Parse(self):
+ self._State = self._Section
+ for Index in range(self._LineIndex, len(self.RuleContent)):
+ # Clean up the line and replace path separator with native one
+ Line = self.RuleContent[Index].strip().replace(self._PATH_SEP, os.path.sep)
+ self.RuleContent[Index] = Line
+
+ # find the build_rule_version
+ if Line and Line[0] == "#" and Line.find(TAB_BUILD_RULE_VERSION) <> -1:
+ if Line.find("=") <> -1 and Line.find("=") < (len(Line)-1) and (Line[(Line.find("=") + 1):]).split():
+ self._FileVersion = (Line[(Line.find("=") + 1):]).split()[0]
+ # skip empty or comment line
+ if Line == "" or Line[0] == "#":
+ continue
+
+ # find out section header, enclosed by []
+ if Line[0] == '[' and Line[-1] == ']':
+ # merge last section information into rule database
+ self.EndOfSection()
+ self._State = self._SectionHeader
+ # find out sub-section header, enclosed by <>
+ elif Line[0] == '<' and Line[-1] == '>':
+ if self._State != self._UnknownSection:
+ self._State = self._SubSectionHeader
+
+ # call section handler to parse each (sub)section
+ self._StateHandler[self._State](self, Index)
+ # merge last section information into rule database
+ self.EndOfSection()
+
+ ## Parse definitions under a section
+ #
+ # @param LineIndex The line index of build rule text
+ #
+ def ParseSection(self, LineIndex):
+ pass
+
+ ## Parse definitions under a subsection
+ #
+ # @param LineIndex The line index of build rule text
+ #
+ def ParseSubSection(self, LineIndex):
+ # currenly nothing here
+ pass
+
+ ## Placeholder for not supported sections
+ #
+ # @param LineIndex The line index of build rule text
+ #
+ def SkipSection(self, LineIndex):
+ pass
+
+ ## Merge section information just got into rule database
+ def EndOfSection(self):
+ Database = self.RuleDatabase
+ # if there's specific toochain family, 'COMMON' doesn't make sense any more
+ if len(self._TotalToolChainFamilySet) > 1 and 'COMMON' in self._TotalToolChainFamilySet:
+ self._TotalToolChainFamilySet.remove('COMMON')
+ for Family in self._TotalToolChainFamilySet:
+ Input = self._RuleInfo[Family, self._InputFile]
+ Output = self._RuleInfo[Family, self._OutputFile]
+ Command = self._RuleInfo[Family, self._Command]
+ ExtraDependency = self._RuleInfo[Family, self._ExtraDependency]
+
+ BuildRule = FileBuildRule(self._FileType, Input, Output, Command, ExtraDependency)
+ for BuildType in self._BuildTypeList:
+ for Arch in self._ArchList:
+ Database[self._FileType, BuildType, Arch, Family] = BuildRule
+ for FileExt in BuildRule.SourceFileExtList:
+ self.Ext2FileType[FileExt] = self._FileType
+
+ ## Parse section header
+ #
+ # @param LineIndex The line index of build rule text
+ #
+ def ParseSectionHeader(self, LineIndex):
+ self._RuleInfo = tdict(True, 2)
+ self._BuildTypeList = []
+ self._ArchList = []
+ self._FamilyList = []
+ self._TotalToolChainFamilySet = set()
+ FileType = ''
+ RuleNameList = self.RuleContent[LineIndex][1:-1].split(',')
+ for RuleName in RuleNameList:
+ Arch = 'COMMON'
+ BuildType = 'COMMON'
+ TokenList = [Token.strip().upper() for Token in RuleName.split('.')]
+ # old format: Build.File-Type
+ if TokenList[0] == "BUILD":
+ if len(TokenList) == 1:
+ EdkLogger.error("build", FORMAT_INVALID, "Invalid rule section",
+ File=self.RuleFile, Line=LineIndex+1,
+ ExtraData=self.RuleContent[LineIndex])
+
+ FileType = TokenList[1]
+ if FileType == '':
+ EdkLogger.error("build", FORMAT_INVALID, "No file type given",
+ File=self.RuleFile, Line=LineIndex+1,
+ ExtraData=self.RuleContent[LineIndex])
+ if self._FileTypePattern.match(FileType) == None:
+ EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex+1,
+ ExtraData="Only character, number (non-first character), '_' and '-' are allowed in file type")
+ # new format: File-Type.Build-Type.Arch
+ else:
+ if FileType == '':
+ FileType = TokenList[0]
+ elif FileType != TokenList[0]:
+ EdkLogger.error("build", FORMAT_INVALID,
+ "Different file types are not allowed in the same rule section",
+ File=self.RuleFile, Line=LineIndex+1,
+ ExtraData=self.RuleContent[LineIndex])
+ if len(TokenList) > 1:
+ BuildType = TokenList[1]
+ if len(TokenList) > 2:
+ Arch = TokenList[2]
+ if BuildType not in self._BuildTypeList:
+ self._BuildTypeList.append(BuildType)
+ if Arch not in self._ArchList:
+ self._ArchList.append(Arch)
+
+ if 'COMMON' in self._BuildTypeList and len(self._BuildTypeList) > 1:
+ EdkLogger.error("build", FORMAT_INVALID,
+ "Specific build types must not be mixed with common one",
+ File=self.RuleFile, Line=LineIndex+1,
+ ExtraData=self.RuleContent[LineIndex])
+ if 'COMMON' in self._ArchList and len(self._ArchList) > 1:
+ EdkLogger.error("build", FORMAT_INVALID,
+ "Specific ARCH must not be mixed with common one",
+ File=self.RuleFile, Line=LineIndex+1,
+ ExtraData=self.RuleContent[LineIndex])
+
+ self._FileType = FileType
+ self._State = self._Section
+ self.FileTypeList.add(FileType)
+
+ ## Parse sub-section header
+ #
+ # @param LineIndex The line index of build rule text
+ #
+ def ParseSubSectionHeader(self, LineIndex):
+ SectionType = ""
+ List = self.RuleContent[LineIndex][1:-1].split(',')
+ FamilyList = []
+ for Section in List:
+ TokenList = Section.split('.')
+ Type = TokenList[0].strip().upper()
+
+ if SectionType == "":
+ SectionType = Type
+ elif SectionType != Type:
+ EdkLogger.error("build", FORMAT_INVALID,
+ "Two different section types are not allowed in the same sub-section",
+ File=self.RuleFile, Line=LineIndex+1,
+ ExtraData=self.RuleContent[LineIndex])
+
+ if len(TokenList) > 1:
+ Family = TokenList[1].strip().upper()
+ else:
+ Family = "COMMON"
+
+ if Family not in FamilyList:
+ FamilyList.append(Family)
+
+ self._FamilyList = FamilyList
+ self._TotalToolChainFamilySet.update(FamilyList)
+ self._State = SectionType.upper()
+ if 'COMMON' in FamilyList and len(FamilyList) > 1:
+ EdkLogger.error("build", FORMAT_INVALID,
+ "Specific tool chain family should not be mixed with general one",
+ File=self.RuleFile, Line=LineIndex+1,
+ ExtraData=self.RuleContent[LineIndex])
+ if self._State not in self._StateHandler:
+ EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex+1,
+ ExtraData="Unknown subsection: %s" % self.RuleContent[LineIndex])
+ ## Parse <InputFile> sub-section
+ #
+ # @param LineIndex The line index of build rule text
+ #
+ def ParseInputFile(self, LineIndex):
+ FileList = [File.strip() for File in self.RuleContent[LineIndex].split(",")]
+ for ToolChainFamily in self._FamilyList:
+ InputFiles = self._RuleInfo[ToolChainFamily, self._State]
+ if InputFiles == None:
+ InputFiles = []
+ self._RuleInfo[ToolChainFamily, self._State] = InputFiles
+ InputFiles.extend(FileList)
+
+ ## Parse <ExtraDependency> sub-section
+ #
+ # @param LineIndex The line index of build rule text
+ #
+ def ParseCommon(self, LineIndex):
+ for ToolChainFamily in self._FamilyList:
+ Items = self._RuleInfo[ToolChainFamily, self._State]
+ if Items == None:
+ Items = []
+ self._RuleInfo[ToolChainFamily, self._State] = Items
+ Items.append(self.RuleContent[LineIndex])
+
+ ## Get a build rule via [] operator
+ #
+ # @param FileExt The extension of a file
+ # @param ToolChainFamily The tool chain family name
+ # @param BuildVersion The build version number. "*" means any rule
+ # is applicalbe.
+ #
+ # @retval FileType The file type string
+ # @retval FileBuildRule The object of FileBuildRule
+ #
+ # Key = (FileExt, ModuleType, Arch, ToolChainFamily)
+ def __getitem__(self, Key):
+ if not Key:
+ return None
+
+ if Key[0] in self.Ext2FileType:
+ Type = self.Ext2FileType[Key[0]]
+ elif Key[0].upper() in self.FileTypeList:
+ Type = Key[0].upper()
+ else:
+ return None
+
+ if len(Key) > 1:
+ Key = (Type,) + Key[1:]
+ else:
+ Key = (Type,)
+ return self.RuleDatabase[Key]
+
+ _StateHandler = {
+ _SectionHeader : ParseSectionHeader,
+ _Section : ParseSection,
+ _SubSectionHeader : ParseSubSectionHeader,
+ _SubSection : ParseSubSection,
+ _InputFile : ParseInputFile,
+ _OutputFile : ParseCommon,
+ _ExtraDependency : ParseCommon,
+ _Command : ParseCommon,
+ _UnknownSection : SkipSection,
+ }
+
+# This acts like the main() function for the script, unless it is 'import'ed into another
+# script.
+if __name__ == '__main__':
+ import sys
+ EdkLogger.Initialize()
+ if len(sys.argv) > 1:
+ Br = BuildRule(sys.argv[1])
+ print str(Br[".c", "DXE_DRIVER", "IA32", "MSFT"][1])
+ print
+ print str(Br[".c", "DXE_DRIVER", "IA32", "INTEL"][1])
+ print
+ print str(Br[".c", "DXE_DRIVER", "IA32", "GCC"][1])
+ print
+ print str(Br[".ac", "ACPI_TABLE", "IA32", "MSFT"][1])
+ print
+ print str(Br[".h", "ACPI_TABLE", "IA32", "INTEL"][1])
+ print
+ print str(Br[".ac", "ACPI_TABLE", "IA32", "MSFT"][1])
+ print
+ print str(Br[".s", "SEC", "IPF", "COMMON"][1])
+ print
+ print str(Br[".s", "SEC"][1])
+
diff --git a/BaseTools/Source/Python/AutoGen/GenC.py b/BaseTools/Source/Python/AutoGen/GenC.py
index 621b57282d..2646b29697 100644
--- a/BaseTools/Source/Python/AutoGen/GenC.py
+++ b/BaseTools/Source/Python/AutoGen/GenC.py
@@ -1,1573 +1,1573 @@
-## @file
-# Routines for generating AutoGen.h and AutoGen.c
-#
-# Copyright (c) 2007 - 2013, 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 string
-
-from Common import EdkLogger
-
-from Common.BuildToolError import *
-from Common.DataType import *
-from Common.Misc import *
-from Common.String import StringToArray
-from StrGather import *
-from GenPcdDb import CreatePcdDatabaseCode
-
-## PCD type string
-gItemTypeStringDatabase = {
- TAB_PCDS_FEATURE_FLAG : 'FixedAtBuild',
- TAB_PCDS_FIXED_AT_BUILD : 'FixedAtBuild',
- TAB_PCDS_PATCHABLE_IN_MODULE: 'BinaryPatch',
- TAB_PCDS_DYNAMIC : '',
- TAB_PCDS_DYNAMIC_DEFAULT : '',
- TAB_PCDS_DYNAMIC_VPD : '',
- TAB_PCDS_DYNAMIC_HII : '',
- TAB_PCDS_DYNAMIC_EX : '',
- TAB_PCDS_DYNAMIC_EX_DEFAULT : '',
- TAB_PCDS_DYNAMIC_EX_VPD : '',
- TAB_PCDS_DYNAMIC_EX_HII : '',
-}
-
-## Dynamic PCD types
-gDynamicPcd = [TAB_PCDS_DYNAMIC, TAB_PCDS_DYNAMIC_DEFAULT, TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_HII]
-
-## Dynamic-ex PCD types
-gDynamicExPcd = [TAB_PCDS_DYNAMIC_EX, TAB_PCDS_DYNAMIC_EX_DEFAULT, TAB_PCDS_DYNAMIC_EX_VPD, TAB_PCDS_DYNAMIC_EX_HII]
-
-## Datum size
-gDatumSizeStringDatabase = {'UINT8':'8','UINT16':'16','UINT32':'32','UINT64':'64','BOOLEAN':'BOOLEAN','VOID*':'8'}
-gDatumSizeStringDatabaseH = {'UINT8':'8','UINT16':'16','UINT32':'32','UINT64':'64','BOOLEAN':'BOOL','VOID*':'PTR'}
-gDatumSizeStringDatabaseLib = {'UINT8':'8','UINT16':'16','UINT32':'32','UINT64':'64','BOOLEAN':'Bool','VOID*':'Ptr'}
-
-## AutoGen File Header Templates
-gAutoGenHeaderString = TemplateString("""\
-/**
- DO NOT EDIT
- FILE auto-generated
- Module name:
- ${FileName}
- Abstract: Auto-generated ${FileName} for building module or library.
-**/
-""")
-
-gAutoGenHPrologueString = TemplateString("""
-#ifndef _${File}_${Guid}
-#define _${File}_${Guid}
-
-""")
-
-gAutoGenHCppPrologueString = """\
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-"""
-
-gAutoGenHEpilogueString = """
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-"""
-
-## PEI Core Entry Point Templates
-gPeiCoreEntryPointPrototype = TemplateString("""
-${BEGIN}
-VOID
-EFIAPI
-${Function} (
- IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
- IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList,
- IN VOID *Context
- );
-${END}
-""")
-
-gPeiCoreEntryPointString = TemplateString("""
-${BEGIN}
-VOID
-EFIAPI
-ProcessModuleEntryPointList (
- IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
- IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList,
- IN VOID *Context
- )
-
-{
- ${Function} (SecCoreData, PpiList, Context);
-}
-${END}
-""")
-
-
-## DXE Core Entry Point Templates
-gDxeCoreEntryPointPrototype = TemplateString("""
-${BEGIN}
-VOID
-EFIAPI
-${Function} (
- IN VOID *HobStart
- );
-${END}
-""")
-
-gDxeCoreEntryPointString = TemplateString("""
-${BEGIN}
-VOID
-EFIAPI
-ProcessModuleEntryPointList (
- IN VOID *HobStart
- )
-
-{
- ${Function} (HobStart);
-}
-${END}
-""")
-
-## PEIM Entry Point Templates
-gPeimEntryPointPrototype = TemplateString("""
-${BEGIN}
-EFI_STATUS
-EFIAPI
-${Function} (
- IN EFI_PEI_FILE_HANDLE FileHandle,
- IN CONST EFI_PEI_SERVICES **PeiServices
- );
-${END}
-""")
-
-gPeimEntryPointString = [
-TemplateString("""
-GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = ${PiSpecVersion};
-
-EFI_STATUS
-EFIAPI
-ProcessModuleEntryPointList (
- IN EFI_PEI_FILE_HANDLE FileHandle,
- IN CONST EFI_PEI_SERVICES **PeiServices
- )
-
-{
- return EFI_SUCCESS;
-}
-"""),
-TemplateString("""
-GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = ${PiSpecVersion};
-${BEGIN}
-EFI_STATUS
-EFIAPI
-ProcessModuleEntryPointList (
- IN EFI_PEI_FILE_HANDLE FileHandle,
- IN CONST EFI_PEI_SERVICES **PeiServices
- )
-
-{
- return ${Function} (FileHandle, PeiServices);
-}
-${END}
-"""),
-TemplateString("""
-GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = ${PiSpecVersion};
-
-EFI_STATUS
-EFIAPI
-ProcessModuleEntryPointList (
- IN EFI_PEI_FILE_HANDLE FileHandle,
- IN CONST EFI_PEI_SERVICES **PeiServices
- )
-
-{
- EFI_STATUS Status;
- EFI_STATUS CombinedStatus;
-
- CombinedStatus = EFI_LOAD_ERROR;
-${BEGIN}
- Status = ${Function} (FileHandle, PeiServices);
- if (!EFI_ERROR (Status) || EFI_ERROR (CombinedStatus)) {
- CombinedStatus = Status;
- }
-${END}
- return CombinedStatus;
-}
-""")
-]
-
-## SMM_CORE Entry Point Templates
-gSmmCoreEntryPointPrototype = TemplateString("""
-${BEGIN}
-EFI_STATUS
-EFIAPI
-${Function} (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-${END}
-""")
-
-gSmmCoreEntryPointString = TemplateString("""
-${BEGIN}
-const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
-const UINT32 _gDxeRevision = ${PiSpecVersion};
-
-EFI_STATUS
-EFIAPI
-ProcessModuleEntryPointList (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- return ${Function} (ImageHandle, SystemTable);
-}
-${END}
-""")
-
-## DXE SMM Entry Point Templates
-gDxeSmmEntryPointPrototype = TemplateString("""
-${BEGIN}
-EFI_STATUS
-EFIAPI
-${Function} (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-${END}
-""")
-
-gDxeSmmEntryPointString = [
-TemplateString("""
-const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
-const UINT32 _gDxeRevision = ${PiSpecVersion};
-
-EFI_STATUS
-EFIAPI
-ProcessModuleEntryPointList (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-
-{
- return EFI_SUCCESS;
-}
-"""),
-TemplateString("""
-const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
-const UINT32 _gDxeRevision = ${PiSpecVersion};
-
-static BASE_LIBRARY_JUMP_BUFFER mJumpContext;
-static EFI_STATUS mDriverEntryPointStatus;
-
-VOID
-EFIAPI
-ExitDriver (
- IN EFI_STATUS Status
- )
-{
- if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {
- mDriverEntryPointStatus = Status;
- }
- LongJump (&mJumpContext, (UINTN)-1);
- ASSERT (FALSE);
-}
-
-EFI_STATUS
-EFIAPI
-ProcessModuleEntryPointList (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- mDriverEntryPointStatus = EFI_LOAD_ERROR;
-
-${BEGIN}
- if (SetJump (&mJumpContext) == 0) {
- ExitDriver (${Function} (ImageHandle, SystemTable));
- ASSERT (FALSE);
- }
-${END}
-
- return mDriverEntryPointStatus;
-}
-""")
-]
-
-## UEFI Driver Entry Point Templates
-gUefiDriverEntryPointPrototype = TemplateString("""
-${BEGIN}
-EFI_STATUS
-EFIAPI
-${Function} (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-${END}
-""")
-
-gUefiDriverEntryPointString = [
-TemplateString("""
-const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
-const UINT32 _gDxeRevision = ${PiSpecVersion};
-
-EFI_STATUS
-EFIAPI
-ProcessModuleEntryPointList (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- return EFI_SUCCESS;
-}
-"""),
-TemplateString("""
-const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
-const UINT32 _gDxeRevision = ${PiSpecVersion};
-
-${BEGIN}
-EFI_STATUS
-EFIAPI
-ProcessModuleEntryPointList (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-
-{
- return ${Function} (ImageHandle, SystemTable);
-}
-${END}
-VOID
-EFIAPI
-ExitDriver (
- IN EFI_STATUS Status
- )
-{
- if (EFI_ERROR (Status)) {
- ProcessLibraryDestructorList (gImageHandle, gST);
- }
- gBS->Exit (gImageHandle, Status, 0, NULL);
-}
-"""),
-TemplateString("""
-const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
-const UINT32 _gDxeRevision = ${PiSpecVersion};
-
-static BASE_LIBRARY_JUMP_BUFFER mJumpContext;
-static EFI_STATUS mDriverEntryPointStatus;
-
-EFI_STATUS
-EFIAPI
-ProcessModuleEntryPointList (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- mDriverEntryPointStatus = EFI_LOAD_ERROR;
- ${BEGIN}
- if (SetJump (&mJumpContext) == 0) {
- ExitDriver (${Function} (ImageHandle, SystemTable));
- ASSERT (FALSE);
- }
- ${END}
- return mDriverEntryPointStatus;
-}
-
-VOID
-EFIAPI
-ExitDriver (
- IN EFI_STATUS Status
- )
-{
- if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {
- mDriverEntryPointStatus = Status;
- }
- LongJump (&mJumpContext, (UINTN)-1);
- ASSERT (FALSE);
-}
-""")
-]
-
-
-## UEFI Application Entry Point Templates
-gUefiApplicationEntryPointPrototype = TemplateString("""
-${BEGIN}
-EFI_STATUS
-EFIAPI
-${Function} (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-${END}
-""")
-
-gUefiApplicationEntryPointString = [
-TemplateString("""
-const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
-
-EFI_STATUS
-EFIAPI
-ProcessModuleEntryPointList (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- return EFI_SUCCESS;
-}
-"""),
-TemplateString("""
-const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
-
-${BEGIN}
-EFI_STATUS
-EFIAPI
-ProcessModuleEntryPointList (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-
-{
- return ${Function} (ImageHandle, SystemTable);
-}
-${END}
-VOID
-EFIAPI
-ExitDriver (
- IN EFI_STATUS Status
- )
-{
- if (EFI_ERROR (Status)) {
- ProcessLibraryDestructorList (gImageHandle, gST);
- }
- gBS->Exit (gImageHandle, Status, 0, NULL);
-}
-"""),
-TemplateString("""
-const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
-
-EFI_STATUS
-EFIAPI
-ProcessModuleEntryPointList (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-
-{
- ${BEGIN}
- if (SetJump (&mJumpContext) == 0) {
- ExitDriver (${Function} (ImageHandle, SystemTable));
- ASSERT (FALSE);
- }
- ${END}
- return mDriverEntryPointStatus;
-}
-
-static BASE_LIBRARY_JUMP_BUFFER mJumpContext;
-static EFI_STATUS mDriverEntryPointStatus = EFI_LOAD_ERROR;
-
-VOID
-EFIAPI
-ExitDriver (
- IN EFI_STATUS Status
- )
-{
- if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {
- mDriverEntryPointStatus = Status;
- }
- LongJump (&mJumpContext, (UINTN)-1);
- ASSERT (FALSE);
-}
-""")
-]
-
-## UEFI Unload Image Templates
-gUefiUnloadImagePrototype = TemplateString("""
-${BEGIN}
-EFI_STATUS
-EFIAPI
-${Function} (
- IN EFI_HANDLE ImageHandle
- );
-${END}
-""")
-
-gUefiUnloadImageString = [
-TemplateString("""
-GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ${Count};
-
-EFI_STATUS
-EFIAPI
-ProcessModuleUnloadList (
- IN EFI_HANDLE ImageHandle
- )
-{
- return EFI_SUCCESS;
-}
-"""),
-TemplateString("""
-GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ${Count};
-
-${BEGIN}
-EFI_STATUS
-EFIAPI
-ProcessModuleUnloadList (
- IN EFI_HANDLE ImageHandle
- )
-{
- return ${Function} (ImageHandle);
-}
-${END}
-"""),
-TemplateString("""
-GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ${Count};
-
-EFI_STATUS
-EFIAPI
-ProcessModuleUnloadList (
- IN EFI_HANDLE ImageHandle
- )
-{
- EFI_STATUS Status;
-
- Status = EFI_SUCCESS;
-${BEGIN}
- if (EFI_ERROR (Status)) {
- ${Function} (ImageHandle);
- } else {
- Status = ${Function} (ImageHandle);
- }
-${END}
- return Status;
-}
-""")
-]
-
-gLibraryStructorPrototype = {
-'BASE' : TemplateString("""${BEGIN}
-RETURN_STATUS
-EFIAPI
-${Function} (
- VOID
- );${END}
-"""),
-
-'PEI' : TemplateString("""${BEGIN}
-EFI_STATUS
-EFIAPI
-${Function} (
- IN EFI_PEI_FILE_HANDLE FileHandle,
- IN CONST EFI_PEI_SERVICES **PeiServices
- );${END}
-"""),
-
-'DXE' : TemplateString("""${BEGIN}
-EFI_STATUS
-EFIAPI
-${Function} (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );${END}
-"""),
-}
-
-gLibraryStructorCall = {
-'BASE' : TemplateString("""${BEGIN}
- Status = ${Function} ();
- ASSERT_EFI_ERROR (Status);${END}
-"""),
-
-'PEI' : TemplateString("""${BEGIN}
- Status = ${Function} (FileHandle, PeiServices);
- ASSERT_EFI_ERROR (Status);${END}
-"""),
-
-'DXE' : TemplateString("""${BEGIN}
- Status = ${Function} (ImageHandle, SystemTable);
- ASSERT_EFI_ERROR (Status);${END}
-"""),
-}
-
-## Library Constructor and Destructor Templates
-gLibraryString = {
-'BASE' : TemplateString("""
-${BEGIN}${FunctionPrototype}${END}
-
-VOID
-EFIAPI
-ProcessLibrary${Type}List (
- VOID
- )
-{
-${BEGIN} EFI_STATUS Status;
-${FunctionCall}${END}
-}
-"""),
-
-'PEI' : TemplateString("""
-${BEGIN}${FunctionPrototype}${END}
-
-VOID
-EFIAPI
-ProcessLibrary${Type}List (
- IN EFI_PEI_FILE_HANDLE FileHandle,
- IN CONST EFI_PEI_SERVICES **PeiServices
- )
-{
-${BEGIN} EFI_STATUS Status;
-${FunctionCall}${END}
-}
-"""),
-
-'DXE' : TemplateString("""
-${BEGIN}${FunctionPrototype}${END}
-
-VOID
-EFIAPI
-ProcessLibrary${Type}List (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
-${BEGIN} EFI_STATUS Status;
-${FunctionCall}${END}
-}
-"""),
-}
-
-gBasicHeaderFile = "Base.h"
-
-gModuleTypeHeaderFile = {
- "BASE" : [gBasicHeaderFile],
- "SEC" : ["PiPei.h", "Library/DebugLib.h"],
- "PEI_CORE" : ["PiPei.h", "Library/DebugLib.h", "Library/PeiCoreEntryPoint.h"],
- "PEIM" : ["PiPei.h", "Library/DebugLib.h", "Library/PeimEntryPoint.h"],
- "DXE_CORE" : ["PiDxe.h", "Library/DebugLib.h", "Library/DxeCoreEntryPoint.h"],
- "DXE_DRIVER" : ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"],
- "DXE_SMM_DRIVER" : ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"],
- "DXE_RUNTIME_DRIVER": ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"],
- "DXE_SAL_DRIVER" : ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"],
- "UEFI_DRIVER" : ["Uefi.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"],
- "UEFI_APPLICATION" : ["Uefi.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiApplicationEntryPoint.h"],
- "SMM_CORE" : ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiDriverEntryPoint.h"],
- "USER_DEFINED" : [gBasicHeaderFile]
-}
-
-## Autogen internal worker macro to define DynamicEx PCD name includes both the TokenSpaceGuidName
-# the TokenName and Guid comparison to avoid define name collisions.
-#
-# @param Info The ModuleAutoGen object
-# @param AutoGenH The TemplateString object for header file
-#
-#
-def DynExPcdTokenNumberMapping(Info, AutoGenH):
- ExTokenCNameList = []
- PcdExList = []
- if Info.IsLibrary:
- PcdList = Info.LibraryPcdList
- else:
- PcdList = Info.ModulePcdList
- for Pcd in PcdList:
- if Pcd.Type in gDynamicExPcd:
- ExTokenCNameList.append(Pcd.TokenCName)
- PcdExList.append(Pcd)
- if len(ExTokenCNameList) == 0:
- return
- AutoGenH.Append('\n#define COMPAREGUID(Guid1, Guid2) (BOOLEAN)(*(CONST UINT64*)Guid1 == *(CONST UINT64*)Guid2 && *((CONST UINT64*)Guid1 + 1) == *((CONST UINT64*)Guid2 + 1))\n')
- # AutoGen for each PCD listed in a [PcdEx] section of a Module/Lib INF file.
- # Auto generate a macro for each TokenName that takes a Guid pointer as a parameter.
- # Use the Guid pointer to see if it matches any of the token space GUIDs.
- TokenCNameList = []
- for TokenCName in ExTokenCNameList:
- if TokenCName in TokenCNameList:
- continue
- Index = 0
- Count = ExTokenCNameList.count(TokenCName)
- for Pcd in PcdExList:
- if Pcd.TokenCName == TokenCName:
- Index = Index + 1
- if Index == 1:
- AutoGenH.Append('\n#define __PCD_%s_ADDR_CMP(GuidPtr) (' % (Pcd.TokenCName))
- AutoGenH.Append('\\\n (GuidPtr == &%s) ? _PCD_TOKEN_%s_%s:'
- % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
- else:
- AutoGenH.Append('\\\n (GuidPtr == &%s) ? _PCD_TOKEN_%s_%s:'
- % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
- if Index == Count:
- AutoGenH.Append('0 \\\n )\n')
- TokenCNameList.append(TokenCName)
-
- TokenCNameList = []
- for TokenCName in ExTokenCNameList:
- if TokenCName in TokenCNameList:
- continue
- Index = 0
- Count = ExTokenCNameList.count(TokenCName)
- for Pcd in PcdExList:
- if Pcd.Type in gDynamicExPcd and Pcd.TokenCName == TokenCName:
- Index = Index + 1
- if Index == 1:
- AutoGenH.Append('\n#define __PCD_%s_VAL_CMP(GuidPtr) (' % (Pcd.TokenCName))
- AutoGenH.Append('\\\n COMPAREGUID (GuidPtr, &%s) ? _PCD_TOKEN_%s_%s:'
- % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
- else:
- AutoGenH.Append('\\\n COMPAREGUID (GuidPtr, &%s) ? _PCD_TOKEN_%s_%s:'
- % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
- if Index == Count:
- AutoGenH.Append('0 \\\n )\n')
- # Autogen internal worker macro to compare GUIDs. Guid1 is a pointer to a GUID.
- # Guid2 is a C name for a GUID. Compare pointers first because optimizing compiler
- # can do this at build time on CONST GUID pointers and optimize away call to COMPAREGUID().
- # COMPAREGUID() will only be used if the Guid passed in is local to the module.
- AutoGenH.Append('#define _PCD_TOKEN_EX_%s(GuidPtr) __PCD_%s_ADDR_CMP(GuidPtr) ? __PCD_%s_ADDR_CMP(GuidPtr) : __PCD_%s_VAL_CMP(GuidPtr) \n'
- % (Pcd.TokenCName, Pcd.TokenCName, Pcd.TokenCName, Pcd.TokenCName))
- TokenCNameList.append(TokenCName)
-
-## Create code for module PCDs
-#
-# @param Info The ModuleAutoGen object
-# @param AutoGenC The TemplateString object for C code
-# @param AutoGenH The TemplateString object for header file
-# @param Pcd The PCD object
-#
-def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
- TokenSpaceGuidValue = Pcd.TokenSpaceGuidValue #Info.GuidList[Pcd.TokenSpaceGuidCName]
- PcdTokenNumber = Info.PlatformInfo.PcdTokenNumber
- #
- # Write PCDs
- #
- PcdTokenName = '_PCD_TOKEN_' + Pcd.TokenCName
- if Pcd.Type in gDynamicExPcd:
- TokenNumber = int(Pcd.TokenValue, 0)
- # Add TokenSpaceGuidValue value to PcdTokenName to discriminate the DynamicEx PCDs with
- # different Guids but same TokenCName
- PcdExTokenName = '_PCD_TOKEN_' + Pcd.TokenSpaceGuidCName + '_' + Pcd.TokenCName
- AutoGenH.Append('\n#define %s %dU\n' % (PcdExTokenName, TokenNumber))
- else:
- if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) not in PcdTokenNumber:
- # If one of the Source built modules listed in the DSC is not listed in FDF modules,
- # and the INF lists a PCD can only use the PcdsDynamic access method (it is only
- # listed in the DEC file that declares the PCD as PcdsDynamic), then build tool will
- # report warning message notify the PI that they are attempting to build a module
- # that must be included in a flash image in order to be functional. These Dynamic PCD
- # will not be added into the Database unless it is used by other modules that are
- # included in the FDF file.
- # In this case, just assign an invalid token number to make it pass build.
- if Pcd.Type in PCD_DYNAMIC_TYPE_LIST:
- TokenNumber = 0
- else:
- EdkLogger.error("build", AUTOGEN_ERROR,
- "No generated token number for %s.%s\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
- ExtraData="[%s]" % str(Info))
- else:
- TokenNumber = PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName]
- AutoGenH.Append('\n#define %s %dU\n' % (PcdTokenName, TokenNumber))
-
- EdkLogger.debug(EdkLogger.DEBUG_3, "Creating code for " + Pcd.TokenCName + "." + Pcd.TokenSpaceGuidCName)
- if Pcd.Type not in gItemTypeStringDatabase:
- EdkLogger.error("build", AUTOGEN_ERROR,
- "Unknown PCD type [%s] of PCD %s.%s" % (Pcd.Type, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
- ExtraData="[%s]" % str(Info))
- if Pcd.DatumType not in gDatumSizeStringDatabase:
- EdkLogger.error("build", AUTOGEN_ERROR,
- "Unknown datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
- ExtraData="[%s]" % str(Info))
-
- DatumSize = gDatumSizeStringDatabase[Pcd.DatumType]
- DatumSizeLib = gDatumSizeStringDatabaseLib[Pcd.DatumType]
- GetModeName = '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + Pcd.TokenCName
- SetModeName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + Pcd.TokenCName
-
- PcdExCNameList = []
- if Pcd.Type in gDynamicExPcd:
- if Info.IsLibrary:
- PcdList = Info.LibraryPcdList
- else:
- PcdList = Info.ModulePcdList
- for PcdModule in PcdList:
- if PcdModule.Type in gDynamicExPcd:
- PcdExCNameList.append(PcdModule.TokenCName)
- # Be compatible with the current code which using PcdToken and PcdGet/Set for DynamicEx Pcd.
- # If only PcdToken and PcdGet/Set used in all Pcds with different CName, it should succeed to build.
- # If PcdToken and PcdGet/Set used in the Pcds with different Guids but same CName, it should failed to build.
- if PcdExCNameList.count(Pcd.TokenCName) > 1:
- AutoGenH.Append('// Disabled the macros, as PcdToken and PcdGet/Set are not allowed in the case that more than one DynamicEx Pcds are different Guids but same CName.\n')
- AutoGenH.Append('// #define %s %s\n' % (PcdTokenName, PcdExTokenName))
- AutoGenH.Append('// #define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
- if Pcd.DatumType == 'VOID*':
- AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
- else:
- AutoGenH.Append('// #define %s(Value) LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
- else:
- AutoGenH.Append('#define %s %s\n' % (PcdTokenName, PcdExTokenName))
- AutoGenH.Append('#define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
- if Pcd.DatumType == 'VOID*':
- AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
- else:
- AutoGenH.Append('#define %s(Value) LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
- elif Pcd.Type in gDynamicPcd:
- AutoGenH.Append('#define %s LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))
- if Pcd.DatumType == 'VOID*':
- AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName))
- else:
- AutoGenH.Append('#define %s(Value) LibPcdSet%s(%s, (Value))\n' % (SetModeName, DatumSizeLib, PcdTokenName))
- else:
- PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[Pcd.Type] + '_' + Pcd.TokenCName
- Const = 'const'
- if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
- Const = ''
- Type = ''
- Array = ''
- Value = Pcd.DefaultValue
- Unicode = False
- ValueNumber = 0
-
- if Pcd.DatumType == 'BOOLEAN':
- BoolValue = Value.upper()
- if BoolValue == 'TRUE' or BoolValue == '1':
- Value = '1U'
- elif BoolValue == 'FALSE' or BoolValue == '0':
- Value = '0U'
-
- if Pcd.DatumType in ['UINT64', 'UINT32', 'UINT16', 'UINT8']:
- try:
- if Value.upper().startswith('0X'):
- ValueNumber = int (Value, 16)
- else:
- ValueNumber = int (Value)
- except:
- EdkLogger.error("build", AUTOGEN_ERROR,
- "PCD value is not valid dec or hex number for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
- ExtraData="[%s]" % str(Info))
- if Pcd.DatumType == 'UINT64':
- if ValueNumber < 0:
- EdkLogger.error("build", AUTOGEN_ERROR,
- "PCD can't be set to negative value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
- ExtraData="[%s]" % str(Info))
- elif ValueNumber >= 0x10000000000000000:
- EdkLogger.error("build", AUTOGEN_ERROR,
- "Too large PCD value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
- ExtraData="[%s]" % str(Info))
- if not Value.endswith('ULL'):
- Value += 'ULL'
- elif Pcd.DatumType == 'UINT32':
- if ValueNumber < 0:
- EdkLogger.error("build", AUTOGEN_ERROR,
- "PCD can't be set to negative value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
- ExtraData="[%s]" % str(Info))
- elif ValueNumber >= 0x100000000:
- EdkLogger.error("build", AUTOGEN_ERROR,
- "Too large PCD value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
- ExtraData="[%s]" % str(Info))
- if not Value.endswith('U'):
- Value += 'U'
- elif Pcd.DatumType == 'UINT16':
- if ValueNumber < 0:
- EdkLogger.error("build", AUTOGEN_ERROR,
- "PCD can't be set to negative value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
- ExtraData="[%s]" % str(Info))
- elif ValueNumber >= 0x10000:
- EdkLogger.error("build", AUTOGEN_ERROR,
- "Too large PCD value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
- ExtraData="[%s]" % str(Info))
- if not Value.endswith('U'):
- Value += 'U'
- elif Pcd.DatumType == 'UINT8':
- if ValueNumber < 0:
- EdkLogger.error("build", AUTOGEN_ERROR,
- "PCD can't be set to negative value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
- ExtraData="[%s]" % str(Info))
- elif ValueNumber >= 0x100:
- EdkLogger.error("build", AUTOGEN_ERROR,
- "Too large PCD value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
- ExtraData="[%s]" % str(Info))
- if not Value.endswith('U'):
- Value += 'U'
- if Pcd.DatumType == 'VOID*':
- if Pcd.MaxDatumSize == None or Pcd.MaxDatumSize == '':
- EdkLogger.error("build", AUTOGEN_ERROR,
- "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
- ExtraData="[%s]" % str(Info))
-
- ArraySize = int(Pcd.MaxDatumSize, 0)
- if Value[0] == '{':
- Type = '(VOID *)'
- else:
- if Value[0] == 'L':
- Unicode = True
- Value = Value.lstrip('L') #.strip('"')
- Value = eval(Value) # translate escape character
- NewValue = '{'
- for Index in range(0,len(Value)):
- if Unicode:
- NewValue = NewValue + str(ord(Value[Index]) % 0x10000) + ', '
- else:
- NewValue = NewValue + str(ord(Value[Index]) % 0x100) + ', '
- if Unicode:
- ArraySize = ArraySize / 2;
-
- if ArraySize < (len(Value) + 1):
- EdkLogger.error("build", AUTOGEN_ERROR,
- "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
- ExtraData="[%s]" % str(Info))
- Value = NewValue + '0 }'
- Array = '[%d]' % ArraySize
- #
- # skip casting for fixed at build since it breaks ARM assembly.
- # Long term we need PCD macros that work in assembly
- #
- elif Pcd.Type != TAB_PCDS_FIXED_AT_BUILD:
- Value = "((%s)%s)" % (Pcd.DatumType, Value)
-
- if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
- PcdValueName = '_PCD_PATCHABLE_VALUE_' + Pcd.TokenCName
- else:
- PcdValueName = '_PCD_VALUE_' + Pcd.TokenCName
-
- if Pcd.DatumType == 'VOID*':
- #
- # For unicode, UINT16 array will be generated, so the alignment of unicode is guaranteed.
- #
- if Unicode:
- AutoGenH.Append('#define _PCD_PATCHABLE_%s_SIZE %s\n' % (Pcd.TokenCName, Pcd.MaxDatumSize))
- AutoGenH.Append('#define %s %s%s\n' %(PcdValueName, Type, PcdVariableName))
- AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s UINT16 %s%s = %s;\n' % (Const, PcdVariableName, Array, Value))
- AutoGenH.Append('extern %s UINT16 %s%s;\n' %(Const, PcdVariableName, Array))
- AutoGenH.Append('#define %s %s%s\n' %(GetModeName, Type, PcdVariableName))
- else:
- AutoGenH.Append('#define _PCD_PATCHABLE_%s_SIZE %s\n' % (Pcd.TokenCName, Pcd.MaxDatumSize))
- AutoGenH.Append('#define %s %s%s\n' %(PcdValueName, Type, PcdVariableName))
- AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s UINT8 %s%s = %s;\n' % (Const, PcdVariableName, Array, Value))
- AutoGenH.Append('extern %s UINT8 %s%s;\n' %(Const, PcdVariableName, Array))
- AutoGenH.Append('#define %s %s%s\n' %(GetModeName, Type, PcdVariableName))
- elif Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
- AutoGenH.Append('#define %s %s\n' %(PcdValueName, Value))
- AutoGenC.Append('volatile %s %s %s = %s;\n' %(Const, Pcd.DatumType, PcdVariableName, PcdValueName))
- AutoGenH.Append('extern volatile %s %s %s%s;\n' % (Const, Pcd.DatumType, PcdVariableName, Array))
- AutoGenH.Append('#define %s %s%s\n' % (GetModeName, Type, PcdVariableName))
- else:
- AutoGenH.Append('#define %s %s\n' %(PcdValueName, Value))
- AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s %s = %s;\n' %(Const, Pcd.DatumType, PcdVariableName, PcdValueName))
- AutoGenH.Append('extern %s %s %s%s;\n' % (Const, Pcd.DatumType, PcdVariableName, Array))
- AutoGenH.Append('#define %s %s%s\n' % (GetModeName, Type, PcdVariableName))
-
- if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
- if Pcd.DatumType == 'VOID*':
- AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPatchPcdSetPtr(_gPcd_BinaryPatch_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeName, Pcd.TokenCName, Pcd.TokenCName))
- else:
- AutoGenH.Append('#define %s(Value) (%s = (Value))\n' % (SetModeName, PcdVariableName))
- else:
- AutoGenH.Append('//#define %s ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD\n' % SetModeName)
-
-## Create code for library module PCDs
-#
-# @param Info The ModuleAutoGen object
-# @param AutoGenC The TemplateString object for C code
-# @param AutoGenH The TemplateString object for header file
-# @param Pcd The PCD object
-#
-def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
- PcdTokenNumber = Info.PlatformInfo.PcdTokenNumber
- TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName
- TokenCName = Pcd.TokenCName
- PcdTokenName = '_PCD_TOKEN_' + TokenCName
- #
- # Write PCDs
- #
- if Pcd.Type in gDynamicExPcd:
- TokenNumber = int(Pcd.TokenValue, 0)
- else:
- if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) not in PcdTokenNumber:
- # If one of the Source built modules listed in the DSC is not listed in FDF modules,
- # and the INF lists a PCD can only use the PcdsDynamic access method (it is only
- # listed in the DEC file that declares the PCD as PcdsDynamic), then build tool will
- # report warning message notify the PI that they are attempting to build a module
- # that must be included in a flash image in order to be functional. These Dynamic PCD
- # will not be added into the Database unless it is used by other modules that are
- # included in the FDF file.
- # In this case, just assign an invalid token number to make it pass build.
- if Pcd.Type in PCD_DYNAMIC_TYPE_LIST:
- TokenNumber = 0
- else:
- EdkLogger.error("build", AUTOGEN_ERROR,
- "No generated token number for %s.%s\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
- ExtraData="[%s]" % str(Info))
- else:
- TokenNumber = PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName]
-
- if Pcd.Type not in gItemTypeStringDatabase:
- EdkLogger.error("build", AUTOGEN_ERROR,
- "Unknown PCD type [%s] of PCD %s.%s" % (Pcd.Type, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
- ExtraData="[%s]" % str(Info))
- if Pcd.DatumType not in gDatumSizeStringDatabase:
- EdkLogger.error("build", AUTOGEN_ERROR,
- "Unknown datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
- ExtraData="[%s]" % str(Info))
-
- DatumType = Pcd.DatumType
- DatumSize = gDatumSizeStringDatabaseH[DatumType]
- DatumSizeLib= gDatumSizeStringDatabaseLib[DatumType]
- GetModeName = '_PCD_GET_MODE_' + DatumSize + '_' + TokenCName
- SetModeName = '_PCD_SET_MODE_' + DatumSize + '_' + TokenCName
-
- Type = ''
- Array = ''
- if Pcd.DatumType == 'VOID*':
- Type = '(VOID *)'
- Array = '[]'
- PcdItemType = Pcd.Type
- PcdExCNameList = []
- if PcdItemType in gDynamicExPcd:
- PcdExTokenName = '_PCD_TOKEN_' + TokenSpaceGuidCName + '_' + Pcd.TokenCName
- AutoGenH.Append('\n#define %s %dU\n' % (PcdExTokenName, TokenNumber))
-
- if Info.IsLibrary:
- PcdList = Info.LibraryPcdList
- else:
- PcdList = Info.ModulePcdList
- for PcdModule in PcdList:
- if PcdModule.Type in gDynamicExPcd:
- PcdExCNameList.append(PcdModule.TokenCName)
- # Be compatible with the current code which using PcdGet/Set for DynamicEx Pcd.
- # If only PcdGet/Set used in all Pcds with different CName, it should succeed to build.
- # If PcdGet/Set used in the Pcds with different Guids but same CName, it should failed to build.
- if PcdExCNameList.count(Pcd.TokenCName) > 1:
- AutoGenH.Append('// Disabled the macros, as PcdToken and PcdGet/Set are not allowed in the case that more than one DynamicEx Pcds are different Guids but same CName.\n')
- AutoGenH.Append('// #define %s %s\n' % (PcdTokenName, PcdExTokenName))
- AutoGenH.Append('// #define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
- if Pcd.DatumType == 'VOID*':
- AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
- else:
- AutoGenH.Append('// #define %s(Value) LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
- else:
- AutoGenH.Append('#define %s %s\n' % (PcdTokenName, PcdExTokenName))
- AutoGenH.Append('#define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
- if Pcd.DatumType == 'VOID*':
- AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
- else:
- AutoGenH.Append('#define %s(Value) LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
- else:
- AutoGenH.Append('#define _PCD_TOKEN_%s %dU\n' % (TokenCName, TokenNumber))
- if PcdItemType in gDynamicPcd:
- AutoGenH.Append('#define %s LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))
- if DatumType == 'VOID*':
- AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName))
- else:
- AutoGenH.Append('#define %s(Value) LibPcdSet%s(%s, (Value))\n' % (SetModeName, DatumSizeLib, PcdTokenName))
- if PcdItemType == TAB_PCDS_PATCHABLE_IN_MODULE:
- PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[TAB_PCDS_PATCHABLE_IN_MODULE] + '_' + TokenCName
- AutoGenH.Append('extern volatile %s _gPcd_BinaryPatch_%s%s;\n' %(DatumType, TokenCName, Array) )
- AutoGenH.Append('#define %s %s_gPcd_BinaryPatch_%s\n' %(GetModeName, Type, TokenCName))
- AutoGenH.Append('#define %s(Value) (%s = (Value))\n' % (SetModeName, PcdVariableName))
- if PcdItemType == TAB_PCDS_FIXED_AT_BUILD or PcdItemType == TAB_PCDS_FEATURE_FLAG:
- key = ".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName))
-
- AutoGenH.Append('extern const %s _gPcd_FixedAtBuild_%s%s;\n' %(DatumType, TokenCName, Array))
- AutoGenH.Append('#define %s %s_gPcd_FixedAtBuild_%s\n' %(GetModeName, Type, TokenCName))
- AutoGenH.Append('//#define %s ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD\n' % SetModeName)
-
- if PcdItemType == TAB_PCDS_FIXED_AT_BUILD and key in Info.ConstPcd:
- AutoGenH.Append('#define _PCD_VALUE_%s %s\n' %(TokenCName, Pcd.DefaultValue))
-
-
-
-## Create code for library constructor
-#
-# @param Info The ModuleAutoGen object
-# @param AutoGenC The TemplateString object for C code
-# @param AutoGenH The TemplateString object for header file
-#
-def CreateLibraryConstructorCode(Info, AutoGenC, AutoGenH):
- #
- # Library Constructors
- #
- ConstructorPrototypeString = TemplateString()
- ConstructorCallingString = TemplateString()
- if Info.IsLibrary:
- DependentLibraryList = [Info.Module]
- else:
- DependentLibraryList = Info.DependentLibraryList
- for Lib in DependentLibraryList:
- if len(Lib.ConstructorList) <= 0:
- continue
- Dict = {'Function':Lib.ConstructorList}
- if Lib.ModuleType in ['BASE', 'SEC']:
- ConstructorPrototypeString.Append(gLibraryStructorPrototype['BASE'].Replace(Dict))
- ConstructorCallingString.Append(gLibraryStructorCall['BASE'].Replace(Dict))
- elif Lib.ModuleType in ['PEI_CORE','PEIM']:
- ConstructorPrototypeString.Append(gLibraryStructorPrototype['PEI'].Replace(Dict))
- ConstructorCallingString.Append(gLibraryStructorCall['PEI'].Replace(Dict))
- elif Lib.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER',
- 'DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION','SMM_CORE']:
- ConstructorPrototypeString.Append(gLibraryStructorPrototype['DXE'].Replace(Dict))
- ConstructorCallingString.Append(gLibraryStructorCall['DXE'].Replace(Dict))
-
- if str(ConstructorPrototypeString) == '':
- ConstructorPrototypeList = []
- else:
- ConstructorPrototypeList = [str(ConstructorPrototypeString)]
- if str(ConstructorCallingString) == '':
- ConstructorCallingList = []
- else:
- ConstructorCallingList = [str(ConstructorCallingString)]
-
- Dict = {
- 'Type' : 'Constructor',
- 'FunctionPrototype' : ConstructorPrototypeList,
- 'FunctionCall' : ConstructorCallingList
- }
- if Info.IsLibrary:
- AutoGenH.Append("${BEGIN}${FunctionPrototype}${END}", Dict)
- else:
- if Info.ModuleType in ['BASE', 'SEC']:
- AutoGenC.Append(gLibraryString['BASE'].Replace(Dict))
- elif Info.ModuleType in ['PEI_CORE','PEIM']:
- AutoGenC.Append(gLibraryString['PEI'].Replace(Dict))
- elif Info.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER',
- 'DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION','SMM_CORE']:
- AutoGenC.Append(gLibraryString['DXE'].Replace(Dict))
-
-## Create code for library destructor
-#
-# @param Info The ModuleAutoGen object
-# @param AutoGenC The TemplateString object for C code
-# @param AutoGenH The TemplateString object for header file
-#
-def CreateLibraryDestructorCode(Info, AutoGenC, AutoGenH):
- #
- # Library Destructors
- #
- DestructorPrototypeString = TemplateString()
- DestructorCallingString = TemplateString()
- if Info.IsLibrary:
- DependentLibraryList = [Info.Module]
- else:
- DependentLibraryList = Info.DependentLibraryList
- for Index in range(len(DependentLibraryList)-1, -1, -1):
- Lib = DependentLibraryList[Index]
- if len(Lib.DestructorList) <= 0:
- continue
- Dict = {'Function':Lib.DestructorList}
- if Lib.ModuleType in ['BASE', 'SEC']:
- DestructorPrototypeString.Append(gLibraryStructorPrototype['BASE'].Replace(Dict))
- DestructorCallingString.Append(gLibraryStructorCall['BASE'].Replace(Dict))
- elif Lib.ModuleType in ['PEI_CORE','PEIM']:
- DestructorPrototypeString.Append(gLibraryStructorPrototype['PEI'].Replace(Dict))
- DestructorCallingString.Append(gLibraryStructorCall['PEI'].Replace(Dict))
- elif Lib.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER',
- 'DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION', 'SMM_CORE']:
- DestructorPrototypeString.Append(gLibraryStructorPrototype['DXE'].Replace(Dict))
- DestructorCallingString.Append(gLibraryStructorCall['DXE'].Replace(Dict))
-
- if str(DestructorPrototypeString) == '':
- DestructorPrototypeList = []
- else:
- DestructorPrototypeList = [str(DestructorPrototypeString)]
- if str(DestructorCallingString) == '':
- DestructorCallingList = []
- else:
- DestructorCallingList = [str(DestructorCallingString)]
-
- Dict = {
- 'Type' : 'Destructor',
- 'FunctionPrototype' : DestructorPrototypeList,
- 'FunctionCall' : DestructorCallingList
- }
- if Info.IsLibrary:
- AutoGenH.Append("${BEGIN}${FunctionPrototype}${END}", Dict)
- else:
- if Info.ModuleType in ['BASE', 'SEC']:
- AutoGenC.Append(gLibraryString['BASE'].Replace(Dict))
- elif Info.ModuleType in ['PEI_CORE','PEIM']:
- AutoGenC.Append(gLibraryString['PEI'].Replace(Dict))
- elif Info.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER',
- 'DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION','SMM_CORE']:
- AutoGenC.Append(gLibraryString['DXE'].Replace(Dict))
-
-
-## Create code for ModuleEntryPoint
-#
-# @param Info The ModuleAutoGen object
-# @param AutoGenC The TemplateString object for C code
-# @param AutoGenH The TemplateString object for header file
-#
-def CreateModuleEntryPointCode(Info, AutoGenC, AutoGenH):
- if Info.IsLibrary or Info.ModuleType in ['USER_DEFINED', 'SEC']:
- return
- #
- # Module Entry Points
- #
- NumEntryPoints = len(Info.Module.ModuleEntryPointList)
- if 'PI_SPECIFICATION_VERSION' in Info.Module.Specification:
- PiSpecVersion = Info.Module.Specification['PI_SPECIFICATION_VERSION']
- else:
- PiSpecVersion = '0x00000000'
- if 'UEFI_SPECIFICATION_VERSION' in Info.Module.Specification:
- UefiSpecVersion = Info.Module.Specification['UEFI_SPECIFICATION_VERSION']
- else:
- UefiSpecVersion = '0x00000000'
- Dict = {
- 'Function' : Info.Module.ModuleEntryPointList,
- 'PiSpecVersion' : PiSpecVersion + 'U',
- 'UefiSpecVersion': UefiSpecVersion + 'U'
- }
-
- if Info.ModuleType in ['PEI_CORE', 'DXE_CORE', 'SMM_CORE']:
- if Info.SourceFileList <> None and Info.SourceFileList <> []:
- if NumEntryPoints != 1:
- EdkLogger.error(
- "build",
- AUTOGEN_ERROR,
- '%s must have exactly one entry point' % Info.ModuleType,
- File=str(Info),
- ExtraData= ", ".join(Info.Module.ModuleEntryPointList)
- )
- if Info.ModuleType == 'PEI_CORE':
- AutoGenC.Append(gPeiCoreEntryPointString.Replace(Dict))
- AutoGenH.Append(gPeiCoreEntryPointPrototype.Replace(Dict))
- elif Info.ModuleType == 'DXE_CORE':
- AutoGenC.Append(gDxeCoreEntryPointString.Replace(Dict))
- AutoGenH.Append(gDxeCoreEntryPointPrototype.Replace(Dict))
- elif Info.ModuleType == 'SMM_CORE':
- AutoGenC.Append(gSmmCoreEntryPointString.Replace(Dict))
- AutoGenH.Append(gSmmCoreEntryPointPrototype.Replace(Dict))
- elif Info.ModuleType == 'PEIM':
- if NumEntryPoints < 2:
- AutoGenC.Append(gPeimEntryPointString[NumEntryPoints].Replace(Dict))
- else:
- AutoGenC.Append(gPeimEntryPointString[2].Replace(Dict))
- AutoGenH.Append(gPeimEntryPointPrototype.Replace(Dict))
- elif Info.ModuleType in ['DXE_RUNTIME_DRIVER','DXE_DRIVER','DXE_SAL_DRIVER','UEFI_DRIVER']:
- if NumEntryPoints < 2:
- AutoGenC.Append(gUefiDriverEntryPointString[NumEntryPoints].Replace(Dict))
- else:
- AutoGenC.Append(gUefiDriverEntryPointString[2].Replace(Dict))
- AutoGenH.Append(gUefiDriverEntryPointPrototype.Replace(Dict))
- elif Info.ModuleType == 'DXE_SMM_DRIVER':
- if NumEntryPoints == 0:
- AutoGenC.Append(gDxeSmmEntryPointString[0].Replace(Dict))
- else:
- AutoGenC.Append(gDxeSmmEntryPointString[1].Replace(Dict))
- AutoGenH.Append(gDxeSmmEntryPointPrototype.Replace(Dict))
- elif Info.ModuleType == 'UEFI_APPLICATION':
- if NumEntryPoints < 2:
- AutoGenC.Append(gUefiApplicationEntryPointString[NumEntryPoints].Replace(Dict))
- else:
- AutoGenC.Append(gUefiApplicationEntryPointString[2].Replace(Dict))
- AutoGenH.Append(gUefiApplicationEntryPointPrototype.Replace(Dict))
-
-## Create code for ModuleUnloadImage
-#
-# @param Info The ModuleAutoGen object
-# @param AutoGenC The TemplateString object for C code
-# @param AutoGenH The TemplateString object for header file
-#
-def CreateModuleUnloadImageCode(Info, AutoGenC, AutoGenH):
- if Info.IsLibrary or Info.ModuleType in ['USER_DEFINED', 'SEC']:
- return
- #
- # Unload Image Handlers
- #
- NumUnloadImage = len(Info.Module.ModuleUnloadImageList)
- Dict = {'Count':str(NumUnloadImage) + 'U', 'Function':Info.Module.ModuleUnloadImageList}
- if NumUnloadImage < 2:
- AutoGenC.Append(gUefiUnloadImageString[NumUnloadImage].Replace(Dict))
- else:
- AutoGenC.Append(gUefiUnloadImageString[2].Replace(Dict))
- AutoGenH.Append(gUefiUnloadImagePrototype.Replace(Dict))
-
-## Create code for GUID
-#
-# @param Info The ModuleAutoGen object
-# @param AutoGenC The TemplateString object for C code
-# @param AutoGenH The TemplateString object for header file
-#
-def CreateGuidDefinitionCode(Info, AutoGenC, AutoGenH):
- if Info.IsLibrary:
- return
-
- if Info.ModuleType in ["USER_DEFINED", "BASE"]:
- GuidType = "GUID"
- else:
- GuidType = "EFI_GUID"
-
- if Info.GuidList:
- AutoGenC.Append("\n// Guids\n")
- #
- # GUIDs
- #
- for Key in Info.GuidList:
- AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s = %s;\n' % (GuidType, Key, Info.GuidList[Key]))
-
-## Create code for protocol
-#
-# @param Info The ModuleAutoGen object
-# @param AutoGenC The TemplateString object for C code
-# @param AutoGenH The TemplateString object for header file
-#
-def CreateProtocolDefinitionCode(Info, AutoGenC, AutoGenH):
- if Info.IsLibrary:
- return
-
- if Info.ModuleType in ["USER_DEFINED", "BASE"]:
- GuidType = "GUID"
- else:
- GuidType = "EFI_GUID"
-
- if Info.ProtocolList:
- AutoGenC.Append("\n// Protocols\n")
- #
- # Protocol GUIDs
- #
- for Key in Info.ProtocolList:
- AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s = %s;\n' % (GuidType, Key, Info.ProtocolList[Key]))
-
-## Create code for PPI
-#
-# @param Info The ModuleAutoGen object
-# @param AutoGenC The TemplateString object for C code
-# @param AutoGenH The TemplateString object for header file
-#
-def CreatePpiDefinitionCode(Info, AutoGenC, AutoGenH):
- if Info.IsLibrary:
- return
-
- if Info.ModuleType in ["USER_DEFINED", "BASE"]:
- GuidType = "GUID"
- else:
- GuidType = "EFI_GUID"
-
- if Info.PpiList:
- AutoGenC.Append("\n// PPIs\n")
- #
- # PPI GUIDs
- #
- for Key in Info.PpiList:
- AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s = %s;\n' % (GuidType, Key, Info.PpiList[Key]))
-
-## Create code for PCD
-#
-# @param Info The ModuleAutoGen object
-# @param AutoGenC The TemplateString object for C code
-# @param AutoGenH The TemplateString object for header file
-#
-def CreatePcdCode(Info, AutoGenC, AutoGenH):
-
- # Collect Token Space GUIDs used by DynamicEc PCDs
- TokenSpaceList = []
- for Pcd in Info.ModulePcdList:
- if Pcd.Type in gDynamicExPcd and Pcd.TokenSpaceGuidCName not in TokenSpaceList:
- TokenSpaceList += [Pcd.TokenSpaceGuidCName]
-
- # Add extern declarations to AutoGen.h if one or more Token Space GUIDs were found
- if TokenSpaceList <> []:
- AutoGenH.Append("\n// Definition of PCD Token Space GUIDs used in this module\n\n")
- if Info.ModuleType in ["USER_DEFINED", "BASE"]:
- GuidType = "GUID"
- else:
- GuidType = "EFI_GUID"
- for Item in TokenSpaceList:
- AutoGenH.Append('extern %s %s;\n' % (GuidType, Item))
-
- if Info.IsLibrary:
- if Info.ModulePcdList:
- AutoGenH.Append("\n// PCD definitions\n")
- for Pcd in Info.ModulePcdList:
- CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd)
- DynExPcdTokenNumberMapping (Info, AutoGenH)
- else:
- if Info.ModulePcdList:
- AutoGenH.Append("\n// Definition of PCDs used in this module\n")
- AutoGenC.Append("\n// Definition of PCDs used in this module\n")
- for Pcd in Info.ModulePcdList:
- CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd)
- DynExPcdTokenNumberMapping (Info, AutoGenH)
- if Info.LibraryPcdList:
- AutoGenH.Append("\n// Definition of PCDs used in libraries is in AutoGen.c\n")
- AutoGenC.Append("\n// Definition of PCDs used in libraries\n")
- for Pcd in Info.LibraryPcdList:
- CreateModulePcdCode(Info, AutoGenC, AutoGenC, Pcd)
- CreatePcdDatabaseCode(Info, AutoGenC, AutoGenH)
-
-## Create code for unicode string definition
-#
-# @param Info The ModuleAutoGen object
-# @param AutoGenC The TemplateString object for C code
-# @param AutoGenH The TemplateString object for header file
-# @param UniGenCFlag UniString is generated into AutoGen C file when it is set to True
-# @param UniGenBinBuffer Buffer to store uni string package data
-#
-def CreateUnicodeStringCode(Info, AutoGenC, AutoGenH, UniGenCFlag, UniGenBinBuffer):
- WorkingDir = os.getcwd()
- os.chdir(Info.WorkspaceDir)
-
- IncList = [Info.MetaFile.Dir]
- # Get all files under [Sources] section in inf file for EDK-II module
- EDK2Module = True
- SrcList = [F for F in Info.SourceFileList]
- if Info.AutoGenVersion < 0x00010005:
- EDK2Module = False
- # Get all files under the module directory for EDK-I module
- Cwd = os.getcwd()
- os.chdir(Info.MetaFile.Dir)
- for Root, Dirs, Files in os.walk("."):
- if 'CVS' in Dirs:
- Dirs.remove('CVS')
- if '.svn' in Dirs:
- Dirs.remove('.svn')
- for File in Files:
- File = PathClass(os.path.join(Root, File), Info.MetaFile.Dir)
- if File in SrcList:
- continue
- SrcList.append(File)
- os.chdir(Cwd)
-
- if 'BUILD' in Info.BuildOption and Info.BuildOption['BUILD']['FLAGS'].find('-c') > -1:
- CompatibleMode = True
- else:
- CompatibleMode = False
-
- #
- # -s is a temporary option dedicated for building .UNI files with ISO 639-2 language codes of EDK Shell in EDK2
- #
- if 'BUILD' in Info.BuildOption and Info.BuildOption['BUILD']['FLAGS'].find('-s') > -1:
- if CompatibleMode:
- EdkLogger.error("build", AUTOGEN_ERROR,
- "-c and -s build options should be used exclusively",
- ExtraData="[%s]" % str(Info))
- ShellMode = True
- else:
- ShellMode = False
-
- #RFC4646 is only for EDKII modules and ISO639-2 for EDK modules
- if EDK2Module:
- FilterInfo = [EDK2Module] + [Info.PlatformInfo.Platform.RFCLanguages]
- else:
- FilterInfo = [EDK2Module] + [Info.PlatformInfo.Platform.ISOLanguages]
- Header, Code = GetStringFiles(Info.UnicodeFileList, SrcList, IncList, Info.IncludePathList, ['.uni', '.inf'], Info.Name, CompatibleMode, ShellMode, UniGenCFlag, UniGenBinBuffer, FilterInfo)
- if CompatibleMode or UniGenCFlag:
- AutoGenC.Append("\n//\n//Unicode String Pack Definition\n//\n")
- AutoGenC.Append(Code)
- AutoGenC.Append("\n")
- AutoGenH.Append("\n//\n//Unicode String ID\n//\n")
- AutoGenH.Append(Header)
- if CompatibleMode or UniGenCFlag:
- AutoGenH.Append("\n#define STRING_ARRAY_NAME %sStrings\n" % Info.Name)
- os.chdir(WorkingDir)
-
-## Create common code
-#
-# @param Info The ModuleAutoGen object
-# @param AutoGenC The TemplateString object for C code
-# @param AutoGenH The TemplateString object for header file
-#
-def CreateHeaderCode(Info, AutoGenC, AutoGenH):
- # file header
- AutoGenH.Append(gAutoGenHeaderString.Replace({'FileName':'AutoGen.h'}))
- # header file Prologue
- AutoGenH.Append(gAutoGenHPrologueString.Replace({'File':'AUTOGENH','Guid':Info.Guid.replace('-','_')}))
- AutoGenH.Append(gAutoGenHCppPrologueString)
- if Info.AutoGenVersion >= 0x00010005:
- # header files includes
- AutoGenH.Append("#include <%s>\n" % gBasicHeaderFile)
- if Info.ModuleType in gModuleTypeHeaderFile \
- and gModuleTypeHeaderFile[Info.ModuleType][0] != gBasicHeaderFile:
- AutoGenH.Append("#include <%s>\n" % gModuleTypeHeaderFile[Info.ModuleType][0])
- #
- # if either PcdLib in [LibraryClasses] sections or there exist Pcd section, add PcdLib.h
- # As if modules only uses FixedPcd, then PcdLib is not needed in [LibraryClasses] section.
- #
- if 'PcdLib' in Info.Module.LibraryClasses or Info.Module.Pcds:
- AutoGenH.Append("#include <Library/PcdLib.h>\n")
-
- AutoGenH.Append('\nextern GUID gEfiCallerIdGuid;')
- AutoGenH.Append('\nextern CHAR8 *gEfiCallerBaseName;\n\n')
-
- if Info.IsLibrary:
- return
-
- AutoGenH.Append("#define EFI_CALLER_ID_GUID \\\n %s\n" % GuidStringToGuidStructureString(Info.Guid))
-
- if Info.IsLibrary:
- return
- # C file header
- AutoGenC.Append(gAutoGenHeaderString.Replace({'FileName':'AutoGen.c'}))
- if Info.AutoGenVersion >= 0x00010005:
- # C file header files includes
- if Info.ModuleType in gModuleTypeHeaderFile:
- for Inc in gModuleTypeHeaderFile[Info.ModuleType]:
- AutoGenC.Append("#include <%s>\n" % Inc)
- else:
- AutoGenC.Append("#include <%s>\n" % gBasicHeaderFile)
-
- #
- # Publish the CallerId Guid
- #
- AutoGenC.Append('\nGLOBAL_REMOVE_IF_UNREFERENCED GUID gEfiCallerIdGuid = %s;\n' % GuidStringToGuidStructureString(Info.Guid))
- AutoGenC.Append('\nGLOBAL_REMOVE_IF_UNREFERENCED CHAR8 *gEfiCallerBaseName = "%s";\n' % Info.Name)
-
-## Create common code for header file
-#
-# @param Info The ModuleAutoGen object
-# @param AutoGenC The TemplateString object for C code
-# @param AutoGenH The TemplateString object for header file
-#
-def CreateFooterCode(Info, AutoGenC, AutoGenH):
- AutoGenH.Append(gAutoGenHEpilogueString)
-
-## Create code for a module
-#
-# @param Info The ModuleAutoGen object
-# @param AutoGenC The TemplateString object for C code
-# @param AutoGenH The TemplateString object for header file
-# @param UniGenCFlag UniString is generated into AutoGen C file when it is set to True
-# @param UniGenBinBuffer Buffer to store uni string package data
-#
-def CreateCode(Info, AutoGenC, AutoGenH, StringH, UniGenCFlag, UniGenBinBuffer):
- CreateHeaderCode(Info, AutoGenC, AutoGenH)
-
- if Info.AutoGenVersion >= 0x00010005:
- CreateGuidDefinitionCode(Info, AutoGenC, AutoGenH)
- CreateProtocolDefinitionCode(Info, AutoGenC, AutoGenH)
- CreatePpiDefinitionCode(Info, AutoGenC, AutoGenH)
- CreatePcdCode(Info, AutoGenC, AutoGenH)
- CreateLibraryConstructorCode(Info, AutoGenC, AutoGenH)
- CreateLibraryDestructorCode(Info, AutoGenC, AutoGenH)
- CreateModuleEntryPointCode(Info, AutoGenC, AutoGenH)
- CreateModuleUnloadImageCode(Info, AutoGenC, AutoGenH)
-
- if Info.UnicodeFileList:
- FileName = "%sStrDefs.h" % Info.Name
- StringH.Append(gAutoGenHeaderString.Replace({'FileName':FileName}))
- StringH.Append(gAutoGenHPrologueString.Replace({'File':'STRDEFS', 'Guid':Info.Guid.replace('-','_')}))
- CreateUnicodeStringCode(Info, AutoGenC, StringH, UniGenCFlag, UniGenBinBuffer)
- StringH.Append("\n#endif\n")
- AutoGenH.Append('#include "%s"\n' % FileName)
-
- CreateFooterCode(Info, AutoGenC, AutoGenH)
-
- # no generation of AutoGen.c for Edk modules without unicode file
- if Info.AutoGenVersion < 0x00010005 and len(Info.UnicodeFileList) == 0:
- AutoGenC.String = ''
-
-## Create the code file
-#
-# @param FilePath The path of code file
-# @param Content The content of code file
-# @param IsBinaryFile The flag indicating if the file is binary file or not
-#
-# @retval True If file content is changed or file doesn't exist
-# @retval False If the file exists and the content is not changed
-#
-def Generate(FilePath, Content, IsBinaryFile):
- return SaveFileOnChange(FilePath, Content, IsBinaryFile)
-
+## @file
+# Routines for generating AutoGen.h and AutoGen.c
+#
+# Copyright (c) 2007 - 2013, 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 string
+
+from Common import EdkLogger
+
+from Common.BuildToolError import *
+from Common.DataType import *
+from Common.Misc import *
+from Common.String import StringToArray
+from StrGather import *
+from GenPcdDb import CreatePcdDatabaseCode
+
+## PCD type string
+gItemTypeStringDatabase = {
+ TAB_PCDS_FEATURE_FLAG : 'FixedAtBuild',
+ TAB_PCDS_FIXED_AT_BUILD : 'FixedAtBuild',
+ TAB_PCDS_PATCHABLE_IN_MODULE: 'BinaryPatch',
+ TAB_PCDS_DYNAMIC : '',
+ TAB_PCDS_DYNAMIC_DEFAULT : '',
+ TAB_PCDS_DYNAMIC_VPD : '',
+ TAB_PCDS_DYNAMIC_HII : '',
+ TAB_PCDS_DYNAMIC_EX : '',
+ TAB_PCDS_DYNAMIC_EX_DEFAULT : '',
+ TAB_PCDS_DYNAMIC_EX_VPD : '',
+ TAB_PCDS_DYNAMIC_EX_HII : '',
+}
+
+## Dynamic PCD types
+gDynamicPcd = [TAB_PCDS_DYNAMIC, TAB_PCDS_DYNAMIC_DEFAULT, TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_HII]
+
+## Dynamic-ex PCD types
+gDynamicExPcd = [TAB_PCDS_DYNAMIC_EX, TAB_PCDS_DYNAMIC_EX_DEFAULT, TAB_PCDS_DYNAMIC_EX_VPD, TAB_PCDS_DYNAMIC_EX_HII]
+
+## Datum size
+gDatumSizeStringDatabase = {'UINT8':'8','UINT16':'16','UINT32':'32','UINT64':'64','BOOLEAN':'BOOLEAN','VOID*':'8'}
+gDatumSizeStringDatabaseH = {'UINT8':'8','UINT16':'16','UINT32':'32','UINT64':'64','BOOLEAN':'BOOL','VOID*':'PTR'}
+gDatumSizeStringDatabaseLib = {'UINT8':'8','UINT16':'16','UINT32':'32','UINT64':'64','BOOLEAN':'Bool','VOID*':'Ptr'}
+
+## AutoGen File Header Templates
+gAutoGenHeaderString = TemplateString("""\
+/**
+ DO NOT EDIT
+ FILE auto-generated
+ Module name:
+ ${FileName}
+ Abstract: Auto-generated ${FileName} for building module or library.
+**/
+""")
+
+gAutoGenHPrologueString = TemplateString("""
+#ifndef _${File}_${Guid}
+#define _${File}_${Guid}
+
+""")
+
+gAutoGenHCppPrologueString = """\
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+"""
+
+gAutoGenHEpilogueString = """
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+"""
+
+## PEI Core Entry Point Templates
+gPeiCoreEntryPointPrototype = TemplateString("""
+${BEGIN}
+VOID
+EFIAPI
+${Function} (
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList,
+ IN VOID *Context
+ );
+${END}
+""")
+
+gPeiCoreEntryPointString = TemplateString("""
+${BEGIN}
+VOID
+EFIAPI
+ProcessModuleEntryPointList (
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList,
+ IN VOID *Context
+ )
+
+{
+ ${Function} (SecCoreData, PpiList, Context);
+}
+${END}
+""")
+
+
+## DXE Core Entry Point Templates
+gDxeCoreEntryPointPrototype = TemplateString("""
+${BEGIN}
+VOID
+EFIAPI
+${Function} (
+ IN VOID *HobStart
+ );
+${END}
+""")
+
+gDxeCoreEntryPointString = TemplateString("""
+${BEGIN}
+VOID
+EFIAPI
+ProcessModuleEntryPointList (
+ IN VOID *HobStart
+ )
+
+{
+ ${Function} (HobStart);
+}
+${END}
+""")
+
+## PEIM Entry Point Templates
+gPeimEntryPointPrototype = TemplateString("""
+${BEGIN}
+EFI_STATUS
+EFIAPI
+${Function} (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ );
+${END}
+""")
+
+gPeimEntryPointString = [
+TemplateString("""
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = ${PiSpecVersion};
+
+EFI_STATUS
+EFIAPI
+ProcessModuleEntryPointList (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+
+{
+ return EFI_SUCCESS;
+}
+"""),
+TemplateString("""
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = ${PiSpecVersion};
+${BEGIN}
+EFI_STATUS
+EFIAPI
+ProcessModuleEntryPointList (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+
+{
+ return ${Function} (FileHandle, PeiServices);
+}
+${END}
+"""),
+TemplateString("""
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = ${PiSpecVersion};
+
+EFI_STATUS
+EFIAPI
+ProcessModuleEntryPointList (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+
+{
+ EFI_STATUS Status;
+ EFI_STATUS CombinedStatus;
+
+ CombinedStatus = EFI_LOAD_ERROR;
+${BEGIN}
+ Status = ${Function} (FileHandle, PeiServices);
+ if (!EFI_ERROR (Status) || EFI_ERROR (CombinedStatus)) {
+ CombinedStatus = Status;
+ }
+${END}
+ return CombinedStatus;
+}
+""")
+]
+
+## SMM_CORE Entry Point Templates
+gSmmCoreEntryPointPrototype = TemplateString("""
+${BEGIN}
+EFI_STATUS
+EFIAPI
+${Function} (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+${END}
+""")
+
+gSmmCoreEntryPointString = TemplateString("""
+${BEGIN}
+const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
+const UINT32 _gDxeRevision = ${PiSpecVersion};
+
+EFI_STATUS
+EFIAPI
+ProcessModuleEntryPointList (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return ${Function} (ImageHandle, SystemTable);
+}
+${END}
+""")
+
+## DXE SMM Entry Point Templates
+gDxeSmmEntryPointPrototype = TemplateString("""
+${BEGIN}
+EFI_STATUS
+EFIAPI
+${Function} (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+${END}
+""")
+
+gDxeSmmEntryPointString = [
+TemplateString("""
+const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
+const UINT32 _gDxeRevision = ${PiSpecVersion};
+
+EFI_STATUS
+EFIAPI
+ProcessModuleEntryPointList (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+
+{
+ return EFI_SUCCESS;
+}
+"""),
+TemplateString("""
+const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
+const UINT32 _gDxeRevision = ${PiSpecVersion};
+
+static BASE_LIBRARY_JUMP_BUFFER mJumpContext;
+static EFI_STATUS mDriverEntryPointStatus;
+
+VOID
+EFIAPI
+ExitDriver (
+ IN EFI_STATUS Status
+ )
+{
+ if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {
+ mDriverEntryPointStatus = Status;
+ }
+ LongJump (&mJumpContext, (UINTN)-1);
+ ASSERT (FALSE);
+}
+
+EFI_STATUS
+EFIAPI
+ProcessModuleEntryPointList (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ mDriverEntryPointStatus = EFI_LOAD_ERROR;
+
+${BEGIN}
+ if (SetJump (&mJumpContext) == 0) {
+ ExitDriver (${Function} (ImageHandle, SystemTable));
+ ASSERT (FALSE);
+ }
+${END}
+
+ return mDriverEntryPointStatus;
+}
+""")
+]
+
+## UEFI Driver Entry Point Templates
+gUefiDriverEntryPointPrototype = TemplateString("""
+${BEGIN}
+EFI_STATUS
+EFIAPI
+${Function} (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+${END}
+""")
+
+gUefiDriverEntryPointString = [
+TemplateString("""
+const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
+const UINT32 _gDxeRevision = ${PiSpecVersion};
+
+EFI_STATUS
+EFIAPI
+ProcessModuleEntryPointList (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return EFI_SUCCESS;
+}
+"""),
+TemplateString("""
+const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
+const UINT32 _gDxeRevision = ${PiSpecVersion};
+
+${BEGIN}
+EFI_STATUS
+EFIAPI
+ProcessModuleEntryPointList (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+
+{
+ return ${Function} (ImageHandle, SystemTable);
+}
+${END}
+VOID
+EFIAPI
+ExitDriver (
+ IN EFI_STATUS Status
+ )
+{
+ if (EFI_ERROR (Status)) {
+ ProcessLibraryDestructorList (gImageHandle, gST);
+ }
+ gBS->Exit (gImageHandle, Status, 0, NULL);
+}
+"""),
+TemplateString("""
+const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
+const UINT32 _gDxeRevision = ${PiSpecVersion};
+
+static BASE_LIBRARY_JUMP_BUFFER mJumpContext;
+static EFI_STATUS mDriverEntryPointStatus;
+
+EFI_STATUS
+EFIAPI
+ProcessModuleEntryPointList (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ mDriverEntryPointStatus = EFI_LOAD_ERROR;
+ ${BEGIN}
+ if (SetJump (&mJumpContext) == 0) {
+ ExitDriver (${Function} (ImageHandle, SystemTable));
+ ASSERT (FALSE);
+ }
+ ${END}
+ return mDriverEntryPointStatus;
+}
+
+VOID
+EFIAPI
+ExitDriver (
+ IN EFI_STATUS Status
+ )
+{
+ if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {
+ mDriverEntryPointStatus = Status;
+ }
+ LongJump (&mJumpContext, (UINTN)-1);
+ ASSERT (FALSE);
+}
+""")
+]
+
+
+## UEFI Application Entry Point Templates
+gUefiApplicationEntryPointPrototype = TemplateString("""
+${BEGIN}
+EFI_STATUS
+EFIAPI
+${Function} (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+${END}
+""")
+
+gUefiApplicationEntryPointString = [
+TemplateString("""
+const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
+
+EFI_STATUS
+EFIAPI
+ProcessModuleEntryPointList (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return EFI_SUCCESS;
+}
+"""),
+TemplateString("""
+const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
+
+${BEGIN}
+EFI_STATUS
+EFIAPI
+ProcessModuleEntryPointList (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+
+{
+ return ${Function} (ImageHandle, SystemTable);
+}
+${END}
+VOID
+EFIAPI
+ExitDriver (
+ IN EFI_STATUS Status
+ )
+{
+ if (EFI_ERROR (Status)) {
+ ProcessLibraryDestructorList (gImageHandle, gST);
+ }
+ gBS->Exit (gImageHandle, Status, 0, NULL);
+}
+"""),
+TemplateString("""
+const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
+
+EFI_STATUS
+EFIAPI
+ProcessModuleEntryPointList (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+
+{
+ ${BEGIN}
+ if (SetJump (&mJumpContext) == 0) {
+ ExitDriver (${Function} (ImageHandle, SystemTable));
+ ASSERT (FALSE);
+ }
+ ${END}
+ return mDriverEntryPointStatus;
+}
+
+static BASE_LIBRARY_JUMP_BUFFER mJumpContext;
+static EFI_STATUS mDriverEntryPointStatus = EFI_LOAD_ERROR;
+
+VOID
+EFIAPI
+ExitDriver (
+ IN EFI_STATUS Status
+ )
+{
+ if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {
+ mDriverEntryPointStatus = Status;
+ }
+ LongJump (&mJumpContext, (UINTN)-1);
+ ASSERT (FALSE);
+}
+""")
+]
+
+## UEFI Unload Image Templates
+gUefiUnloadImagePrototype = TemplateString("""
+${BEGIN}
+EFI_STATUS
+EFIAPI
+${Function} (
+ IN EFI_HANDLE ImageHandle
+ );
+${END}
+""")
+
+gUefiUnloadImageString = [
+TemplateString("""
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ${Count};
+
+EFI_STATUS
+EFIAPI
+ProcessModuleUnloadList (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ return EFI_SUCCESS;
+}
+"""),
+TemplateString("""
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ${Count};
+
+${BEGIN}
+EFI_STATUS
+EFIAPI
+ProcessModuleUnloadList (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ return ${Function} (ImageHandle);
+}
+${END}
+"""),
+TemplateString("""
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ${Count};
+
+EFI_STATUS
+EFIAPI
+ProcessModuleUnloadList (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+${BEGIN}
+ if (EFI_ERROR (Status)) {
+ ${Function} (ImageHandle);
+ } else {
+ Status = ${Function} (ImageHandle);
+ }
+${END}
+ return Status;
+}
+""")
+]
+
+gLibraryStructorPrototype = {
+'BASE' : TemplateString("""${BEGIN}
+RETURN_STATUS
+EFIAPI
+${Function} (
+ VOID
+ );${END}
+"""),
+
+'PEI' : TemplateString("""${BEGIN}
+EFI_STATUS
+EFIAPI
+${Function} (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ );${END}
+"""),
+
+'DXE' : TemplateString("""${BEGIN}
+EFI_STATUS
+EFIAPI
+${Function} (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );${END}
+"""),
+}
+
+gLibraryStructorCall = {
+'BASE' : TemplateString("""${BEGIN}
+ Status = ${Function} ();
+ ASSERT_EFI_ERROR (Status);${END}
+"""),
+
+'PEI' : TemplateString("""${BEGIN}
+ Status = ${Function} (FileHandle, PeiServices);
+ ASSERT_EFI_ERROR (Status);${END}
+"""),
+
+'DXE' : TemplateString("""${BEGIN}
+ Status = ${Function} (ImageHandle, SystemTable);
+ ASSERT_EFI_ERROR (Status);${END}
+"""),
+}
+
+## Library Constructor and Destructor Templates
+gLibraryString = {
+'BASE' : TemplateString("""
+${BEGIN}${FunctionPrototype}${END}
+
+VOID
+EFIAPI
+ProcessLibrary${Type}List (
+ VOID
+ )
+{
+${BEGIN} EFI_STATUS Status;
+${FunctionCall}${END}
+}
+"""),
+
+'PEI' : TemplateString("""
+${BEGIN}${FunctionPrototype}${END}
+
+VOID
+EFIAPI
+ProcessLibrary${Type}List (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+${BEGIN} EFI_STATUS Status;
+${FunctionCall}${END}
+}
+"""),
+
+'DXE' : TemplateString("""
+${BEGIN}${FunctionPrototype}${END}
+
+VOID
+EFIAPI
+ProcessLibrary${Type}List (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+${BEGIN} EFI_STATUS Status;
+${FunctionCall}${END}
+}
+"""),
+}
+
+gBasicHeaderFile = "Base.h"
+
+gModuleTypeHeaderFile = {
+ "BASE" : [gBasicHeaderFile],
+ "SEC" : ["PiPei.h", "Library/DebugLib.h"],
+ "PEI_CORE" : ["PiPei.h", "Library/DebugLib.h", "Library/PeiCoreEntryPoint.h"],
+ "PEIM" : ["PiPei.h", "Library/DebugLib.h", "Library/PeimEntryPoint.h"],
+ "DXE_CORE" : ["PiDxe.h", "Library/DebugLib.h", "Library/DxeCoreEntryPoint.h"],
+ "DXE_DRIVER" : ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"],
+ "DXE_SMM_DRIVER" : ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"],
+ "DXE_RUNTIME_DRIVER": ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"],
+ "DXE_SAL_DRIVER" : ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"],
+ "UEFI_DRIVER" : ["Uefi.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"],
+ "UEFI_APPLICATION" : ["Uefi.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiApplicationEntryPoint.h"],
+ "SMM_CORE" : ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiDriverEntryPoint.h"],
+ "USER_DEFINED" : [gBasicHeaderFile]
+}
+
+## Autogen internal worker macro to define DynamicEx PCD name includes both the TokenSpaceGuidName
+# the TokenName and Guid comparison to avoid define name collisions.
+#
+# @param Info The ModuleAutoGen object
+# @param AutoGenH The TemplateString object for header file
+#
+#
+def DynExPcdTokenNumberMapping(Info, AutoGenH):
+ ExTokenCNameList = []
+ PcdExList = []
+ if Info.IsLibrary:
+ PcdList = Info.LibraryPcdList
+ else:
+ PcdList = Info.ModulePcdList
+ for Pcd in PcdList:
+ if Pcd.Type in gDynamicExPcd:
+ ExTokenCNameList.append(Pcd.TokenCName)
+ PcdExList.append(Pcd)
+ if len(ExTokenCNameList) == 0:
+ return
+ AutoGenH.Append('\n#define COMPAREGUID(Guid1, Guid2) (BOOLEAN)(*(CONST UINT64*)Guid1 == *(CONST UINT64*)Guid2 && *((CONST UINT64*)Guid1 + 1) == *((CONST UINT64*)Guid2 + 1))\n')
+ # AutoGen for each PCD listed in a [PcdEx] section of a Module/Lib INF file.
+ # Auto generate a macro for each TokenName that takes a Guid pointer as a parameter.
+ # Use the Guid pointer to see if it matches any of the token space GUIDs.
+ TokenCNameList = []
+ for TokenCName in ExTokenCNameList:
+ if TokenCName in TokenCNameList:
+ continue
+ Index = 0
+ Count = ExTokenCNameList.count(TokenCName)
+ for Pcd in PcdExList:
+ if Pcd.TokenCName == TokenCName:
+ Index = Index + 1
+ if Index == 1:
+ AutoGenH.Append('\n#define __PCD_%s_ADDR_CMP(GuidPtr) (' % (Pcd.TokenCName))
+ AutoGenH.Append('\\\n (GuidPtr == &%s) ? _PCD_TOKEN_%s_%s:'
+ % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
+ else:
+ AutoGenH.Append('\\\n (GuidPtr == &%s) ? _PCD_TOKEN_%s_%s:'
+ % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
+ if Index == Count:
+ AutoGenH.Append('0 \\\n )\n')
+ TokenCNameList.append(TokenCName)
+
+ TokenCNameList = []
+ for TokenCName in ExTokenCNameList:
+ if TokenCName in TokenCNameList:
+ continue
+ Index = 0
+ Count = ExTokenCNameList.count(TokenCName)
+ for Pcd in PcdExList:
+ if Pcd.Type in gDynamicExPcd and Pcd.TokenCName == TokenCName:
+ Index = Index + 1
+ if Index == 1:
+ AutoGenH.Append('\n#define __PCD_%s_VAL_CMP(GuidPtr) (' % (Pcd.TokenCName))
+ AutoGenH.Append('\\\n COMPAREGUID (GuidPtr, &%s) ? _PCD_TOKEN_%s_%s:'
+ % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
+ else:
+ AutoGenH.Append('\\\n COMPAREGUID (GuidPtr, &%s) ? _PCD_TOKEN_%s_%s:'
+ % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
+ if Index == Count:
+ AutoGenH.Append('0 \\\n )\n')
+ # Autogen internal worker macro to compare GUIDs. Guid1 is a pointer to a GUID.
+ # Guid2 is a C name for a GUID. Compare pointers first because optimizing compiler
+ # can do this at build time on CONST GUID pointers and optimize away call to COMPAREGUID().
+ # COMPAREGUID() will only be used if the Guid passed in is local to the module.
+ AutoGenH.Append('#define _PCD_TOKEN_EX_%s(GuidPtr) __PCD_%s_ADDR_CMP(GuidPtr) ? __PCD_%s_ADDR_CMP(GuidPtr) : __PCD_%s_VAL_CMP(GuidPtr) \n'
+ % (Pcd.TokenCName, Pcd.TokenCName, Pcd.TokenCName, Pcd.TokenCName))
+ TokenCNameList.append(TokenCName)
+
+## Create code for module PCDs
+#
+# @param Info The ModuleAutoGen object
+# @param AutoGenC The TemplateString object for C code
+# @param AutoGenH The TemplateString object for header file
+# @param Pcd The PCD object
+#
+def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
+ TokenSpaceGuidValue = Pcd.TokenSpaceGuidValue #Info.GuidList[Pcd.TokenSpaceGuidCName]
+ PcdTokenNumber = Info.PlatformInfo.PcdTokenNumber
+ #
+ # Write PCDs
+ #
+ PcdTokenName = '_PCD_TOKEN_' + Pcd.TokenCName
+ if Pcd.Type in gDynamicExPcd:
+ TokenNumber = int(Pcd.TokenValue, 0)
+ # Add TokenSpaceGuidValue value to PcdTokenName to discriminate the DynamicEx PCDs with
+ # different Guids but same TokenCName
+ PcdExTokenName = '_PCD_TOKEN_' + Pcd.TokenSpaceGuidCName + '_' + Pcd.TokenCName
+ AutoGenH.Append('\n#define %s %dU\n' % (PcdExTokenName, TokenNumber))
+ else:
+ if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) not in PcdTokenNumber:
+ # If one of the Source built modules listed in the DSC is not listed in FDF modules,
+ # and the INF lists a PCD can only use the PcdsDynamic access method (it is only
+ # listed in the DEC file that declares the PCD as PcdsDynamic), then build tool will
+ # report warning message notify the PI that they are attempting to build a module
+ # that must be included in a flash image in order to be functional. These Dynamic PCD
+ # will not be added into the Database unless it is used by other modules that are
+ # included in the FDF file.
+ # In this case, just assign an invalid token number to make it pass build.
+ if Pcd.Type in PCD_DYNAMIC_TYPE_LIST:
+ TokenNumber = 0
+ else:
+ EdkLogger.error("build", AUTOGEN_ERROR,
+ "No generated token number for %s.%s\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+ ExtraData="[%s]" % str(Info))
+ else:
+ TokenNumber = PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName]
+ AutoGenH.Append('\n#define %s %dU\n' % (PcdTokenName, TokenNumber))
+
+ EdkLogger.debug(EdkLogger.DEBUG_3, "Creating code for " + Pcd.TokenCName + "." + Pcd.TokenSpaceGuidCName)
+ if Pcd.Type not in gItemTypeStringDatabase:
+ EdkLogger.error("build", AUTOGEN_ERROR,
+ "Unknown PCD type [%s] of PCD %s.%s" % (Pcd.Type, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+ ExtraData="[%s]" % str(Info))
+ if Pcd.DatumType not in gDatumSizeStringDatabase:
+ EdkLogger.error("build", AUTOGEN_ERROR,
+ "Unknown datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+ ExtraData="[%s]" % str(Info))
+
+ DatumSize = gDatumSizeStringDatabase[Pcd.DatumType]
+ DatumSizeLib = gDatumSizeStringDatabaseLib[Pcd.DatumType]
+ GetModeName = '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + Pcd.TokenCName
+ SetModeName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + Pcd.TokenCName
+
+ PcdExCNameList = []
+ if Pcd.Type in gDynamicExPcd:
+ if Info.IsLibrary:
+ PcdList = Info.LibraryPcdList
+ else:
+ PcdList = Info.ModulePcdList
+ for PcdModule in PcdList:
+ if PcdModule.Type in gDynamicExPcd:
+ PcdExCNameList.append(PcdModule.TokenCName)
+ # Be compatible with the current code which using PcdToken and PcdGet/Set for DynamicEx Pcd.
+ # If only PcdToken and PcdGet/Set used in all Pcds with different CName, it should succeed to build.
+ # If PcdToken and PcdGet/Set used in the Pcds with different Guids but same CName, it should failed to build.
+ if PcdExCNameList.count(Pcd.TokenCName) > 1:
+ AutoGenH.Append('// Disabled the macros, as PcdToken and PcdGet/Set are not allowed in the case that more than one DynamicEx Pcds are different Guids but same CName.\n')
+ AutoGenH.Append('// #define %s %s\n' % (PcdTokenName, PcdExTokenName))
+ AutoGenH.Append('// #define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+ if Pcd.DatumType == 'VOID*':
+ AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+ else:
+ AutoGenH.Append('// #define %s(Value) LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+ else:
+ AutoGenH.Append('#define %s %s\n' % (PcdTokenName, PcdExTokenName))
+ AutoGenH.Append('#define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+ if Pcd.DatumType == 'VOID*':
+ AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+ else:
+ AutoGenH.Append('#define %s(Value) LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+ elif Pcd.Type in gDynamicPcd:
+ AutoGenH.Append('#define %s LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))
+ if Pcd.DatumType == 'VOID*':
+ AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName))
+ else:
+ AutoGenH.Append('#define %s(Value) LibPcdSet%s(%s, (Value))\n' % (SetModeName, DatumSizeLib, PcdTokenName))
+ else:
+ PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[Pcd.Type] + '_' + Pcd.TokenCName
+ Const = 'const'
+ if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
+ Const = ''
+ Type = ''
+ Array = ''
+ Value = Pcd.DefaultValue
+ Unicode = False
+ ValueNumber = 0
+
+ if Pcd.DatumType == 'BOOLEAN':
+ BoolValue = Value.upper()
+ if BoolValue == 'TRUE' or BoolValue == '1':
+ Value = '1U'
+ elif BoolValue == 'FALSE' or BoolValue == '0':
+ Value = '0U'
+
+ if Pcd.DatumType in ['UINT64', 'UINT32', 'UINT16', 'UINT8']:
+ try:
+ if Value.upper().startswith('0X'):
+ ValueNumber = int (Value, 16)
+ else:
+ ValueNumber = int (Value)
+ except:
+ EdkLogger.error("build", AUTOGEN_ERROR,
+ "PCD value is not valid dec or hex number for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+ ExtraData="[%s]" % str(Info))
+ if Pcd.DatumType == 'UINT64':
+ if ValueNumber < 0:
+ EdkLogger.error("build", AUTOGEN_ERROR,
+ "PCD can't be set to negative value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+ ExtraData="[%s]" % str(Info))
+ elif ValueNumber >= 0x10000000000000000:
+ EdkLogger.error("build", AUTOGEN_ERROR,
+ "Too large PCD value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+ ExtraData="[%s]" % str(Info))
+ if not Value.endswith('ULL'):
+ Value += 'ULL'
+ elif Pcd.DatumType == 'UINT32':
+ if ValueNumber < 0:
+ EdkLogger.error("build", AUTOGEN_ERROR,
+ "PCD can't be set to negative value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+ ExtraData="[%s]" % str(Info))
+ elif ValueNumber >= 0x100000000:
+ EdkLogger.error("build", AUTOGEN_ERROR,
+ "Too large PCD value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+ ExtraData="[%s]" % str(Info))
+ if not Value.endswith('U'):
+ Value += 'U'
+ elif Pcd.DatumType == 'UINT16':
+ if ValueNumber < 0:
+ EdkLogger.error("build", AUTOGEN_ERROR,
+ "PCD can't be set to negative value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+ ExtraData="[%s]" % str(Info))
+ elif ValueNumber >= 0x10000:
+ EdkLogger.error("build", AUTOGEN_ERROR,
+ "Too large PCD value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+ ExtraData="[%s]" % str(Info))
+ if not Value.endswith('U'):
+ Value += 'U'
+ elif Pcd.DatumType == 'UINT8':
+ if ValueNumber < 0:
+ EdkLogger.error("build", AUTOGEN_ERROR,
+ "PCD can't be set to negative value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+ ExtraData="[%s]" % str(Info))
+ elif ValueNumber >= 0x100:
+ EdkLogger.error("build", AUTOGEN_ERROR,
+ "Too large PCD value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+ ExtraData="[%s]" % str(Info))
+ if not Value.endswith('U'):
+ Value += 'U'
+ if Pcd.DatumType == 'VOID*':
+ if Pcd.MaxDatumSize == None or Pcd.MaxDatumSize == '':
+ EdkLogger.error("build", AUTOGEN_ERROR,
+ "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+ ExtraData="[%s]" % str(Info))
+
+ ArraySize = int(Pcd.MaxDatumSize, 0)
+ if Value[0] == '{':
+ Type = '(VOID *)'
+ else:
+ if Value[0] == 'L':
+ Unicode = True
+ Value = Value.lstrip('L') #.strip('"')
+ Value = eval(Value) # translate escape character
+ NewValue = '{'
+ for Index in range(0,len(Value)):
+ if Unicode:
+ NewValue = NewValue + str(ord(Value[Index]) % 0x10000) + ', '
+ else:
+ NewValue = NewValue + str(ord(Value[Index]) % 0x100) + ', '
+ if Unicode:
+ ArraySize = ArraySize / 2;
+
+ if ArraySize < (len(Value) + 1):
+ EdkLogger.error("build", AUTOGEN_ERROR,
+ "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+ ExtraData="[%s]" % str(Info))
+ Value = NewValue + '0 }'
+ Array = '[%d]' % ArraySize
+ #
+ # skip casting for fixed at build since it breaks ARM assembly.
+ # Long term we need PCD macros that work in assembly
+ #
+ elif Pcd.Type != TAB_PCDS_FIXED_AT_BUILD:
+ Value = "((%s)%s)" % (Pcd.DatumType, Value)
+
+ if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
+ PcdValueName = '_PCD_PATCHABLE_VALUE_' + Pcd.TokenCName
+ else:
+ PcdValueName = '_PCD_VALUE_' + Pcd.TokenCName
+
+ if Pcd.DatumType == 'VOID*':
+ #
+ # For unicode, UINT16 array will be generated, so the alignment of unicode is guaranteed.
+ #
+ if Unicode:
+ AutoGenH.Append('#define _PCD_PATCHABLE_%s_SIZE %s\n' % (Pcd.TokenCName, Pcd.MaxDatumSize))
+ AutoGenH.Append('#define %s %s%s\n' %(PcdValueName, Type, PcdVariableName))
+ AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s UINT16 %s%s = %s;\n' % (Const, PcdVariableName, Array, Value))
+ AutoGenH.Append('extern %s UINT16 %s%s;\n' %(Const, PcdVariableName, Array))
+ AutoGenH.Append('#define %s %s%s\n' %(GetModeName, Type, PcdVariableName))
+ else:
+ AutoGenH.Append('#define _PCD_PATCHABLE_%s_SIZE %s\n' % (Pcd.TokenCName, Pcd.MaxDatumSize))
+ AutoGenH.Append('#define %s %s%s\n' %(PcdValueName, Type, PcdVariableName))
+ AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s UINT8 %s%s = %s;\n' % (Const, PcdVariableName, Array, Value))
+ AutoGenH.Append('extern %s UINT8 %s%s;\n' %(Const, PcdVariableName, Array))
+ AutoGenH.Append('#define %s %s%s\n' %(GetModeName, Type, PcdVariableName))
+ elif Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
+ AutoGenH.Append('#define %s %s\n' %(PcdValueName, Value))
+ AutoGenC.Append('volatile %s %s %s = %s;\n' %(Const, Pcd.DatumType, PcdVariableName, PcdValueName))
+ AutoGenH.Append('extern volatile %s %s %s%s;\n' % (Const, Pcd.DatumType, PcdVariableName, Array))
+ AutoGenH.Append('#define %s %s%s\n' % (GetModeName, Type, PcdVariableName))
+ else:
+ AutoGenH.Append('#define %s %s\n' %(PcdValueName, Value))
+ AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s %s = %s;\n' %(Const, Pcd.DatumType, PcdVariableName, PcdValueName))
+ AutoGenH.Append('extern %s %s %s%s;\n' % (Const, Pcd.DatumType, PcdVariableName, Array))
+ AutoGenH.Append('#define %s %s%s\n' % (GetModeName, Type, PcdVariableName))
+
+ if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
+ if Pcd.DatumType == 'VOID*':
+ AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPatchPcdSetPtr(_gPcd_BinaryPatch_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeName, Pcd.TokenCName, Pcd.TokenCName))
+ else:
+ AutoGenH.Append('#define %s(Value) (%s = (Value))\n' % (SetModeName, PcdVariableName))
+ else:
+ AutoGenH.Append('//#define %s ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD\n' % SetModeName)
+
+## Create code for library module PCDs
+#
+# @param Info The ModuleAutoGen object
+# @param AutoGenC The TemplateString object for C code
+# @param AutoGenH The TemplateString object for header file
+# @param Pcd The PCD object
+#
+def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
+ PcdTokenNumber = Info.PlatformInfo.PcdTokenNumber
+ TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName
+ TokenCName = Pcd.TokenCName
+ PcdTokenName = '_PCD_TOKEN_' + TokenCName
+ #
+ # Write PCDs
+ #
+ if Pcd.Type in gDynamicExPcd:
+ TokenNumber = int(Pcd.TokenValue, 0)
+ else:
+ if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) not in PcdTokenNumber:
+ # If one of the Source built modules listed in the DSC is not listed in FDF modules,
+ # and the INF lists a PCD can only use the PcdsDynamic access method (it is only
+ # listed in the DEC file that declares the PCD as PcdsDynamic), then build tool will
+ # report warning message notify the PI that they are attempting to build a module
+ # that must be included in a flash image in order to be functional. These Dynamic PCD
+ # will not be added into the Database unless it is used by other modules that are
+ # included in the FDF file.
+ # In this case, just assign an invalid token number to make it pass build.
+ if Pcd.Type in PCD_DYNAMIC_TYPE_LIST:
+ TokenNumber = 0
+ else:
+ EdkLogger.error("build", AUTOGEN_ERROR,
+ "No generated token number for %s.%s\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+ ExtraData="[%s]" % str(Info))
+ else:
+ TokenNumber = PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName]
+
+ if Pcd.Type not in gItemTypeStringDatabase:
+ EdkLogger.error("build", AUTOGEN_ERROR,
+ "Unknown PCD type [%s] of PCD %s.%s" % (Pcd.Type, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+ ExtraData="[%s]" % str(Info))
+ if Pcd.DatumType not in gDatumSizeStringDatabase:
+ EdkLogger.error("build", AUTOGEN_ERROR,
+ "Unknown datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+ ExtraData="[%s]" % str(Info))
+
+ DatumType = Pcd.DatumType
+ DatumSize = gDatumSizeStringDatabaseH[DatumType]
+ DatumSizeLib= gDatumSizeStringDatabaseLib[DatumType]
+ GetModeName = '_PCD_GET_MODE_' + DatumSize + '_' + TokenCName
+ SetModeName = '_PCD_SET_MODE_' + DatumSize + '_' + TokenCName
+
+ Type = ''
+ Array = ''
+ if Pcd.DatumType == 'VOID*':
+ Type = '(VOID *)'
+ Array = '[]'
+ PcdItemType = Pcd.Type
+ PcdExCNameList = []
+ if PcdItemType in gDynamicExPcd:
+ PcdExTokenName = '_PCD_TOKEN_' + TokenSpaceGuidCName + '_' + Pcd.TokenCName
+ AutoGenH.Append('\n#define %s %dU\n' % (PcdExTokenName, TokenNumber))
+
+ if Info.IsLibrary:
+ PcdList = Info.LibraryPcdList
+ else:
+ PcdList = Info.ModulePcdList
+ for PcdModule in PcdList:
+ if PcdModule.Type in gDynamicExPcd:
+ PcdExCNameList.append(PcdModule.TokenCName)
+ # Be compatible with the current code which using PcdGet/Set for DynamicEx Pcd.
+ # If only PcdGet/Set used in all Pcds with different CName, it should succeed to build.
+ # If PcdGet/Set used in the Pcds with different Guids but same CName, it should failed to build.
+ if PcdExCNameList.count(Pcd.TokenCName) > 1:
+ AutoGenH.Append('// Disabled the macros, as PcdToken and PcdGet/Set are not allowed in the case that more than one DynamicEx Pcds are different Guids but same CName.\n')
+ AutoGenH.Append('// #define %s %s\n' % (PcdTokenName, PcdExTokenName))
+ AutoGenH.Append('// #define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+ if Pcd.DatumType == 'VOID*':
+ AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+ else:
+ AutoGenH.Append('// #define %s(Value) LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+ else:
+ AutoGenH.Append('#define %s %s\n' % (PcdTokenName, PcdExTokenName))
+ AutoGenH.Append('#define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+ if Pcd.DatumType == 'VOID*':
+ AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+ else:
+ AutoGenH.Append('#define %s(Value) LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+ else:
+ AutoGenH.Append('#define _PCD_TOKEN_%s %dU\n' % (TokenCName, TokenNumber))
+ if PcdItemType in gDynamicPcd:
+ AutoGenH.Append('#define %s LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))
+ if DatumType == 'VOID*':
+ AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName))
+ else:
+ AutoGenH.Append('#define %s(Value) LibPcdSet%s(%s, (Value))\n' % (SetModeName, DatumSizeLib, PcdTokenName))
+ if PcdItemType == TAB_PCDS_PATCHABLE_IN_MODULE:
+ PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[TAB_PCDS_PATCHABLE_IN_MODULE] + '_' + TokenCName
+ AutoGenH.Append('extern volatile %s _gPcd_BinaryPatch_%s%s;\n' %(DatumType, TokenCName, Array) )
+ AutoGenH.Append('#define %s %s_gPcd_BinaryPatch_%s\n' %(GetModeName, Type, TokenCName))
+ AutoGenH.Append('#define %s(Value) (%s = (Value))\n' % (SetModeName, PcdVariableName))
+ if PcdItemType == TAB_PCDS_FIXED_AT_BUILD or PcdItemType == TAB_PCDS_FEATURE_FLAG:
+ key = ".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName))
+
+ AutoGenH.Append('extern const %s _gPcd_FixedAtBuild_%s%s;\n' %(DatumType, TokenCName, Array))
+ AutoGenH.Append('#define %s %s_gPcd_FixedAtBuild_%s\n' %(GetModeName, Type, TokenCName))
+ AutoGenH.Append('//#define %s ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD\n' % SetModeName)
+
+ if PcdItemType == TAB_PCDS_FIXED_AT_BUILD and key in Info.ConstPcd:
+ AutoGenH.Append('#define _PCD_VALUE_%s %s\n' %(TokenCName, Pcd.DefaultValue))
+
+
+
+## Create code for library constructor
+#
+# @param Info The ModuleAutoGen object
+# @param AutoGenC The TemplateString object for C code
+# @param AutoGenH The TemplateString object for header file
+#
+def CreateLibraryConstructorCode(Info, AutoGenC, AutoGenH):
+ #
+ # Library Constructors
+ #
+ ConstructorPrototypeString = TemplateString()
+ ConstructorCallingString = TemplateString()
+ if Info.IsLibrary:
+ DependentLibraryList = [Info.Module]
+ else:
+ DependentLibraryList = Info.DependentLibraryList
+ for Lib in DependentLibraryList:
+ if len(Lib.ConstructorList) <= 0:
+ continue
+ Dict = {'Function':Lib.ConstructorList}
+ if Lib.ModuleType in ['BASE', 'SEC']:
+ ConstructorPrototypeString.Append(gLibraryStructorPrototype['BASE'].Replace(Dict))
+ ConstructorCallingString.Append(gLibraryStructorCall['BASE'].Replace(Dict))
+ elif Lib.ModuleType in ['PEI_CORE','PEIM']:
+ ConstructorPrototypeString.Append(gLibraryStructorPrototype['PEI'].Replace(Dict))
+ ConstructorCallingString.Append(gLibraryStructorCall['PEI'].Replace(Dict))
+ elif Lib.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER',
+ 'DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION','SMM_CORE']:
+ ConstructorPrototypeString.Append(gLibraryStructorPrototype['DXE'].Replace(Dict))
+ ConstructorCallingString.Append(gLibraryStructorCall['DXE'].Replace(Dict))
+
+ if str(ConstructorPrototypeString) == '':
+ ConstructorPrototypeList = []
+ else:
+ ConstructorPrototypeList = [str(ConstructorPrototypeString)]
+ if str(ConstructorCallingString) == '':
+ ConstructorCallingList = []
+ else:
+ ConstructorCallingList = [str(ConstructorCallingString)]
+
+ Dict = {
+ 'Type' : 'Constructor',
+ 'FunctionPrototype' : ConstructorPrototypeList,
+ 'FunctionCall' : ConstructorCallingList
+ }
+ if Info.IsLibrary:
+ AutoGenH.Append("${BEGIN}${FunctionPrototype}${END}", Dict)
+ else:
+ if Info.ModuleType in ['BASE', 'SEC']:
+ AutoGenC.Append(gLibraryString['BASE'].Replace(Dict))
+ elif Info.ModuleType in ['PEI_CORE','PEIM']:
+ AutoGenC.Append(gLibraryString['PEI'].Replace(Dict))
+ elif Info.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER',
+ 'DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION','SMM_CORE']:
+ AutoGenC.Append(gLibraryString['DXE'].Replace(Dict))
+
+## Create code for library destructor
+#
+# @param Info The ModuleAutoGen object
+# @param AutoGenC The TemplateString object for C code
+# @param AutoGenH The TemplateString object for header file
+#
+def CreateLibraryDestructorCode(Info, AutoGenC, AutoGenH):
+ #
+ # Library Destructors
+ #
+ DestructorPrototypeString = TemplateString()
+ DestructorCallingString = TemplateString()
+ if Info.IsLibrary:
+ DependentLibraryList = [Info.Module]
+ else:
+ DependentLibraryList = Info.DependentLibraryList
+ for Index in range(len(DependentLibraryList)-1, -1, -1):
+ Lib = DependentLibraryList[Index]
+ if len(Lib.DestructorList) <= 0:
+ continue
+ Dict = {'Function':Lib.DestructorList}
+ if Lib.ModuleType in ['BASE', 'SEC']:
+ DestructorPrototypeString.Append(gLibraryStructorPrototype['BASE'].Replace(Dict))
+ DestructorCallingString.Append(gLibraryStructorCall['BASE'].Replace(Dict))
+ elif Lib.ModuleType in ['PEI_CORE','PEIM']:
+ DestructorPrototypeString.Append(gLibraryStructorPrototype['PEI'].Replace(Dict))
+ DestructorCallingString.Append(gLibraryStructorCall['PEI'].Replace(Dict))
+ elif Lib.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER',
+ 'DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION', 'SMM_CORE']:
+ DestructorPrototypeString.Append(gLibraryStructorPrototype['DXE'].Replace(Dict))
+ DestructorCallingString.Append(gLibraryStructorCall['DXE'].Replace(Dict))
+
+ if str(DestructorPrototypeString) == '':
+ DestructorPrototypeList = []
+ else:
+ DestructorPrototypeList = [str(DestructorPrototypeString)]
+ if str(DestructorCallingString) == '':
+ DestructorCallingList = []
+ else:
+ DestructorCallingList = [str(DestructorCallingString)]
+
+ Dict = {
+ 'Type' : 'Destructor',
+ 'FunctionPrototype' : DestructorPrototypeList,
+ 'FunctionCall' : DestructorCallingList
+ }
+ if Info.IsLibrary:
+ AutoGenH.Append("${BEGIN}${FunctionPrototype}${END}", Dict)
+ else:
+ if Info.ModuleType in ['BASE', 'SEC']:
+ AutoGenC.Append(gLibraryString['BASE'].Replace(Dict))
+ elif Info.ModuleType in ['PEI_CORE','PEIM']:
+ AutoGenC.Append(gLibraryString['PEI'].Replace(Dict))
+ elif Info.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER',
+ 'DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION','SMM_CORE']:
+ AutoGenC.Append(gLibraryString['DXE'].Replace(Dict))
+
+
+## Create code for ModuleEntryPoint
+#
+# @param Info The ModuleAutoGen object
+# @param AutoGenC The TemplateString object for C code
+# @param AutoGenH The TemplateString object for header file
+#
+def CreateModuleEntryPointCode(Info, AutoGenC, AutoGenH):
+ if Info.IsLibrary or Info.ModuleType in ['USER_DEFINED', 'SEC']:
+ return
+ #
+ # Module Entry Points
+ #
+ NumEntryPoints = len(Info.Module.ModuleEntryPointList)
+ if 'PI_SPECIFICATION_VERSION' in Info.Module.Specification:
+ PiSpecVersion = Info.Module.Specification['PI_SPECIFICATION_VERSION']
+ else:
+ PiSpecVersion = '0x00000000'
+ if 'UEFI_SPECIFICATION_VERSION' in Info.Module.Specification:
+ UefiSpecVersion = Info.Module.Specification['UEFI_SPECIFICATION_VERSION']
+ else:
+ UefiSpecVersion = '0x00000000'
+ Dict = {
+ 'Function' : Info.Module.ModuleEntryPointList,
+ 'PiSpecVersion' : PiSpecVersion + 'U',
+ 'UefiSpecVersion': UefiSpecVersion + 'U'
+ }
+
+ if Info.ModuleType in ['PEI_CORE', 'DXE_CORE', 'SMM_CORE']:
+ if Info.SourceFileList <> None and Info.SourceFileList <> []:
+ if NumEntryPoints != 1:
+ EdkLogger.error(
+ "build",
+ AUTOGEN_ERROR,
+ '%s must have exactly one entry point' % Info.ModuleType,
+ File=str(Info),
+ ExtraData= ", ".join(Info.Module.ModuleEntryPointList)
+ )
+ if Info.ModuleType == 'PEI_CORE':
+ AutoGenC.Append(gPeiCoreEntryPointString.Replace(Dict))
+ AutoGenH.Append(gPeiCoreEntryPointPrototype.Replace(Dict))
+ elif Info.ModuleType == 'DXE_CORE':
+ AutoGenC.Append(gDxeCoreEntryPointString.Replace(Dict))
+ AutoGenH.Append(gDxeCoreEntryPointPrototype.Replace(Dict))
+ elif Info.ModuleType == 'SMM_CORE':
+ AutoGenC.Append(gSmmCoreEntryPointString.Replace(Dict))
+ AutoGenH.Append(gSmmCoreEntryPointPrototype.Replace(Dict))
+ elif Info.ModuleType == 'PEIM':
+ if NumEntryPoints < 2:
+ AutoGenC.Append(gPeimEntryPointString[NumEntryPoints].Replace(Dict))
+ else:
+ AutoGenC.Append(gPeimEntryPointString[2].Replace(Dict))
+ AutoGenH.Append(gPeimEntryPointPrototype.Replace(Dict))
+ elif Info.ModuleType in ['DXE_RUNTIME_DRIVER','DXE_DRIVER','DXE_SAL_DRIVER','UEFI_DRIVER']:
+ if NumEntryPoints < 2:
+ AutoGenC.Append(gUefiDriverEntryPointString[NumEntryPoints].Replace(Dict))
+ else:
+ AutoGenC.Append(gUefiDriverEntryPointString[2].Replace(Dict))
+ AutoGenH.Append(gUefiDriverEntryPointPrototype.Replace(Dict))
+ elif Info.ModuleType == 'DXE_SMM_DRIVER':
+ if NumEntryPoints == 0:
+ AutoGenC.Append(gDxeSmmEntryPointString[0].Replace(Dict))
+ else:
+ AutoGenC.Append(gDxeSmmEntryPointString[1].Replace(Dict))
+ AutoGenH.Append(gDxeSmmEntryPointPrototype.Replace(Dict))
+ elif Info.ModuleType == 'UEFI_APPLICATION':
+ if NumEntryPoints < 2:
+ AutoGenC.Append(gUefiApplicationEntryPointString[NumEntryPoints].Replace(Dict))
+ else:
+ AutoGenC.Append(gUefiApplicationEntryPointString[2].Replace(Dict))
+ AutoGenH.Append(gUefiApplicationEntryPointPrototype.Replace(Dict))
+
+## Create code for ModuleUnloadImage
+#
+# @param Info The ModuleAutoGen object
+# @param AutoGenC The TemplateString object for C code
+# @param AutoGenH The TemplateString object for header file
+#
+def CreateModuleUnloadImageCode(Info, AutoGenC, AutoGenH):
+ if Info.IsLibrary or Info.ModuleType in ['USER_DEFINED', 'SEC']:
+ return
+ #
+ # Unload Image Handlers
+ #
+ NumUnloadImage = len(Info.Module.ModuleUnloadImageList)
+ Dict = {'Count':str(NumUnloadImage) + 'U', 'Function':Info.Module.ModuleUnloadImageList}
+ if NumUnloadImage < 2:
+ AutoGenC.Append(gUefiUnloadImageString[NumUnloadImage].Replace(Dict))
+ else:
+ AutoGenC.Append(gUefiUnloadImageString[2].Replace(Dict))
+ AutoGenH.Append(gUefiUnloadImagePrototype.Replace(Dict))
+
+## Create code for GUID
+#
+# @param Info The ModuleAutoGen object
+# @param AutoGenC The TemplateString object for C code
+# @param AutoGenH The TemplateString object for header file
+#
+def CreateGuidDefinitionCode(Info, AutoGenC, AutoGenH):
+ if Info.IsLibrary:
+ return
+
+ if Info.ModuleType in ["USER_DEFINED", "BASE"]:
+ GuidType = "GUID"
+ else:
+ GuidType = "EFI_GUID"
+
+ if Info.GuidList:
+ AutoGenC.Append("\n// Guids\n")
+ #
+ # GUIDs
+ #
+ for Key in Info.GuidList:
+ AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s = %s;\n' % (GuidType, Key, Info.GuidList[Key]))
+
+## Create code for protocol
+#
+# @param Info The ModuleAutoGen object
+# @param AutoGenC The TemplateString object for C code
+# @param AutoGenH The TemplateString object for header file
+#
+def CreateProtocolDefinitionCode(Info, AutoGenC, AutoGenH):
+ if Info.IsLibrary:
+ return
+
+ if Info.ModuleType in ["USER_DEFINED", "BASE"]:
+ GuidType = "GUID"
+ else:
+ GuidType = "EFI_GUID"
+
+ if Info.ProtocolList:
+ AutoGenC.Append("\n// Protocols\n")
+ #
+ # Protocol GUIDs
+ #
+ for Key in Info.ProtocolList:
+ AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s = %s;\n' % (GuidType, Key, Info.ProtocolList[Key]))
+
+## Create code for PPI
+#
+# @param Info The ModuleAutoGen object
+# @param AutoGenC The TemplateString object for C code
+# @param AutoGenH The TemplateString object for header file
+#
+def CreatePpiDefinitionCode(Info, AutoGenC, AutoGenH):
+ if Info.IsLibrary:
+ return
+
+ if Info.ModuleType in ["USER_DEFINED", "BASE"]:
+ GuidType = "GUID"
+ else:
+ GuidType = "EFI_GUID"
+
+ if Info.PpiList:
+ AutoGenC.Append("\n// PPIs\n")
+ #
+ # PPI GUIDs
+ #
+ for Key in Info.PpiList:
+ AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s = %s;\n' % (GuidType, Key, Info.PpiList[Key]))
+
+## Create code for PCD
+#
+# @param Info The ModuleAutoGen object
+# @param AutoGenC The TemplateString object for C code
+# @param AutoGenH The TemplateString object for header file
+#
+def CreatePcdCode(Info, AutoGenC, AutoGenH):
+
+ # Collect Token Space GUIDs used by DynamicEc PCDs
+ TokenSpaceList = []
+ for Pcd in Info.ModulePcdList:
+ if Pcd.Type in gDynamicExPcd and Pcd.TokenSpaceGuidCName not in TokenSpaceList:
+ TokenSpaceList += [Pcd.TokenSpaceGuidCName]
+
+ # Add extern declarations to AutoGen.h if one or more Token Space GUIDs were found
+ if TokenSpaceList <> []:
+ AutoGenH.Append("\n// Definition of PCD Token Space GUIDs used in this module\n\n")
+ if Info.ModuleType in ["USER_DEFINED", "BASE"]:
+ GuidType = "GUID"
+ else:
+ GuidType = "EFI_GUID"
+ for Item in TokenSpaceList:
+ AutoGenH.Append('extern %s %s;\n' % (GuidType, Item))
+
+ if Info.IsLibrary:
+ if Info.ModulePcdList:
+ AutoGenH.Append("\n// PCD definitions\n")
+ for Pcd in Info.ModulePcdList:
+ CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd)
+ DynExPcdTokenNumberMapping (Info, AutoGenH)
+ else:
+ if Info.ModulePcdList:
+ AutoGenH.Append("\n// Definition of PCDs used in this module\n")
+ AutoGenC.Append("\n// Definition of PCDs used in this module\n")
+ for Pcd in Info.ModulePcdList:
+ CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd)
+ DynExPcdTokenNumberMapping (Info, AutoGenH)
+ if Info.LibraryPcdList:
+ AutoGenH.Append("\n// Definition of PCDs used in libraries is in AutoGen.c\n")
+ AutoGenC.Append("\n// Definition of PCDs used in libraries\n")
+ for Pcd in Info.LibraryPcdList:
+ CreateModulePcdCode(Info, AutoGenC, AutoGenC, Pcd)
+ CreatePcdDatabaseCode(Info, AutoGenC, AutoGenH)
+
+## Create code for unicode string definition
+#
+# @param Info The ModuleAutoGen object
+# @param AutoGenC The TemplateString object for C code
+# @param AutoGenH The TemplateString object for header file
+# @param UniGenCFlag UniString is generated into AutoGen C file when it is set to True
+# @param UniGenBinBuffer Buffer to store uni string package data
+#
+def CreateUnicodeStringCode(Info, AutoGenC, AutoGenH, UniGenCFlag, UniGenBinBuffer):
+ WorkingDir = os.getcwd()
+ os.chdir(Info.WorkspaceDir)
+
+ IncList = [Info.MetaFile.Dir]
+ # Get all files under [Sources] section in inf file for EDK-II module
+ EDK2Module = True
+ SrcList = [F for F in Info.SourceFileList]
+ if Info.AutoGenVersion < 0x00010005:
+ EDK2Module = False
+ # Get all files under the module directory for EDK-I module
+ Cwd = os.getcwd()
+ os.chdir(Info.MetaFile.Dir)
+ for Root, Dirs, Files in os.walk("."):
+ if 'CVS' in Dirs:
+ Dirs.remove('CVS')
+ if '.svn' in Dirs:
+ Dirs.remove('.svn')
+ for File in Files:
+ File = PathClass(os.path.join(Root, File), Info.MetaFile.Dir)
+ if File in SrcList:
+ continue
+ SrcList.append(File)
+ os.chdir(Cwd)
+
+ if 'BUILD' in Info.BuildOption and Info.BuildOption['BUILD']['FLAGS'].find('-c') > -1:
+ CompatibleMode = True
+ else:
+ CompatibleMode = False
+
+ #
+ # -s is a temporary option dedicated for building .UNI files with ISO 639-2 language codes of EDK Shell in EDK2
+ #
+ if 'BUILD' in Info.BuildOption and Info.BuildOption['BUILD']['FLAGS'].find('-s') > -1:
+ if CompatibleMode:
+ EdkLogger.error("build", AUTOGEN_ERROR,
+ "-c and -s build options should be used exclusively",
+ ExtraData="[%s]" % str(Info))
+ ShellMode = True
+ else:
+ ShellMode = False
+
+ #RFC4646 is only for EDKII modules and ISO639-2 for EDK modules
+ if EDK2Module:
+ FilterInfo = [EDK2Module] + [Info.PlatformInfo.Platform.RFCLanguages]
+ else:
+ FilterInfo = [EDK2Module] + [Info.PlatformInfo.Platform.ISOLanguages]
+ Header, Code = GetStringFiles(Info.UnicodeFileList, SrcList, IncList, Info.IncludePathList, ['.uni', '.inf'], Info.Name, CompatibleMode, ShellMode, UniGenCFlag, UniGenBinBuffer, FilterInfo)
+ if CompatibleMode or UniGenCFlag:
+ AutoGenC.Append("\n//\n//Unicode String Pack Definition\n//\n")
+ AutoGenC.Append(Code)
+ AutoGenC.Append("\n")
+ AutoGenH.Append("\n//\n//Unicode String ID\n//\n")
+ AutoGenH.Append(Header)
+ if CompatibleMode or UniGenCFlag:
+ AutoGenH.Append("\n#define STRING_ARRAY_NAME %sStrings\n" % Info.Name)
+ os.chdir(WorkingDir)
+
+## Create common code
+#
+# @param Info The ModuleAutoGen object
+# @param AutoGenC The TemplateString object for C code
+# @param AutoGenH The TemplateString object for header file
+#
+def CreateHeaderCode(Info, AutoGenC, AutoGenH):
+ # file header
+ AutoGenH.Append(gAutoGenHeaderString.Replace({'FileName':'AutoGen.h'}))
+ # header file Prologue
+ AutoGenH.Append(gAutoGenHPrologueString.Replace({'File':'AUTOGENH','Guid':Info.Guid.replace('-','_')}))
+ AutoGenH.Append(gAutoGenHCppPrologueString)
+ if Info.AutoGenVersion >= 0x00010005:
+ # header files includes
+ AutoGenH.Append("#include <%s>\n" % gBasicHeaderFile)
+ if Info.ModuleType in gModuleTypeHeaderFile \
+ and gModuleTypeHeaderFile[Info.ModuleType][0] != gBasicHeaderFile:
+ AutoGenH.Append("#include <%s>\n" % gModuleTypeHeaderFile[Info.ModuleType][0])
+ #
+ # if either PcdLib in [LibraryClasses] sections or there exist Pcd section, add PcdLib.h
+ # As if modules only uses FixedPcd, then PcdLib is not needed in [LibraryClasses] section.
+ #
+ if 'PcdLib' in Info.Module.LibraryClasses or Info.Module.Pcds:
+ AutoGenH.Append("#include <Library/PcdLib.h>\n")
+
+ AutoGenH.Append('\nextern GUID gEfiCallerIdGuid;')
+ AutoGenH.Append('\nextern CHAR8 *gEfiCallerBaseName;\n\n')
+
+ if Info.IsLibrary:
+ return
+
+ AutoGenH.Append("#define EFI_CALLER_ID_GUID \\\n %s\n" % GuidStringToGuidStructureString(Info.Guid))
+
+ if Info.IsLibrary:
+ return
+ # C file header
+ AutoGenC.Append(gAutoGenHeaderString.Replace({'FileName':'AutoGen.c'}))
+ if Info.AutoGenVersion >= 0x00010005:
+ # C file header files includes
+ if Info.ModuleType in gModuleTypeHeaderFile:
+ for Inc in gModuleTypeHeaderFile[Info.ModuleType]:
+ AutoGenC.Append("#include <%s>\n" % Inc)
+ else:
+ AutoGenC.Append("#include <%s>\n" % gBasicHeaderFile)
+
+ #
+ # Publish the CallerId Guid
+ #
+ AutoGenC.Append('\nGLOBAL_REMOVE_IF_UNREFERENCED GUID gEfiCallerIdGuid = %s;\n' % GuidStringToGuidStructureString(Info.Guid))
+ AutoGenC.Append('\nGLOBAL_REMOVE_IF_UNREFERENCED CHAR8 *gEfiCallerBaseName = "%s";\n' % Info.Name)
+
+## Create common code for header file
+#
+# @param Info The ModuleAutoGen object
+# @param AutoGenC The TemplateString object for C code
+# @param AutoGenH The TemplateString object for header file
+#
+def CreateFooterCode(Info, AutoGenC, AutoGenH):
+ AutoGenH.Append(gAutoGenHEpilogueString)
+
+## Create code for a module
+#
+# @param Info The ModuleAutoGen object
+# @param AutoGenC The TemplateString object for C code
+# @param AutoGenH The TemplateString object for header file
+# @param UniGenCFlag UniString is generated into AutoGen C file when it is set to True
+# @param UniGenBinBuffer Buffer to store uni string package data
+#
+def CreateCode(Info, AutoGenC, AutoGenH, StringH, UniGenCFlag, UniGenBinBuffer):
+ CreateHeaderCode(Info, AutoGenC, AutoGenH)
+
+ if Info.AutoGenVersion >= 0x00010005:
+ CreateGuidDefinitionCode(Info, AutoGenC, AutoGenH)
+ CreateProtocolDefinitionCode(Info, AutoGenC, AutoGenH)
+ CreatePpiDefinitionCode(Info, AutoGenC, AutoGenH)
+ CreatePcdCode(Info, AutoGenC, AutoGenH)
+ CreateLibraryConstructorCode(Info, AutoGenC, AutoGenH)
+ CreateLibraryDestructorCode(Info, AutoGenC, AutoGenH)
+ CreateModuleEntryPointCode(Info, AutoGenC, AutoGenH)
+ CreateModuleUnloadImageCode(Info, AutoGenC, AutoGenH)
+
+ if Info.UnicodeFileList:
+ FileName = "%sStrDefs.h" % Info.Name
+ StringH.Append(gAutoGenHeaderString.Replace({'FileName':FileName}))
+ StringH.Append(gAutoGenHPrologueString.Replace({'File':'STRDEFS', 'Guid':Info.Guid.replace('-','_')}))
+ CreateUnicodeStringCode(Info, AutoGenC, StringH, UniGenCFlag, UniGenBinBuffer)
+ StringH.Append("\n#endif\n")
+ AutoGenH.Append('#include "%s"\n' % FileName)
+
+ CreateFooterCode(Info, AutoGenC, AutoGenH)
+
+ # no generation of AutoGen.c for Edk modules without unicode file
+ if Info.AutoGenVersion < 0x00010005 and len(Info.UnicodeFileList) == 0:
+ AutoGenC.String = ''
+
+## Create the code file
+#
+# @param FilePath The path of code file
+# @param Content The content of code file
+# @param IsBinaryFile The flag indicating if the file is binary file or not
+#
+# @retval True If file content is changed or file doesn't exist
+# @retval False If the file exists and the content is not changed
+#
+def Generate(FilePath, Content, IsBinaryFile):
+ return SaveFileOnChange(FilePath, Content, IsBinaryFile)
+
diff --git a/BaseTools/Source/Python/AutoGen/GenMake.py b/BaseTools/Source/Python/AutoGen/GenMake.py
index b2ebff324d..00d0af0cb7 100644
--- a/BaseTools/Source/Python/AutoGen/GenMake.py
+++ b/BaseTools/Source/Python/AutoGen/GenMake.py
@@ -1,1411 +1,1411 @@
-## @file
-# Create makefile for MS nmake and GNU make
-#
-# 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 string
-import re
-import os.path as path
-
-from Common.BuildToolError import *
-from Common.Misc import *
-from Common.String import *
-from BuildEngine import *
-import Common.GlobalData as GlobalData
-
-## Regular expression for finding header file inclusions
-gIncludePattern = re.compile(r"^[ \t]*#?[ \t]*include(?:[ \t]*(?:\\(?:\r\n|\r|\n))*[ \t]*)*(?:\(?[\"<]?[ \t]*)([-\w.\\/() \t]+)(?:[ \t]*[\">]?\)?)", re.MULTILINE|re.UNICODE|re.IGNORECASE)
-
-## Regular expression for matching macro used in header file inclusion
-gMacroPattern = re.compile("([_A-Z][_A-Z0-9]*)[ \t]*\((.+)\)", re.UNICODE)
-
-gIsFileMap = {}
-
-## pattern for include style in Edk.x code
-gProtocolDefinition = "Protocol/%(HeaderKey)s/%(HeaderKey)s.h"
-gGuidDefinition = "Guid/%(HeaderKey)s/%(HeaderKey)s.h"
-gArchProtocolDefinition = "ArchProtocol/%(HeaderKey)s/%(HeaderKey)s.h"
-gPpiDefinition = "Ppi/%(HeaderKey)s/%(HeaderKey)s.h"
-gIncludeMacroConversion = {
- "EFI_PROTOCOL_DEFINITION" : gProtocolDefinition,
- "EFI_GUID_DEFINITION" : gGuidDefinition,
- "EFI_ARCH_PROTOCOL_DEFINITION" : gArchProtocolDefinition,
- "EFI_PROTOCOL_PRODUCER" : gProtocolDefinition,
- "EFI_PROTOCOL_CONSUMER" : gProtocolDefinition,
- "EFI_PROTOCOL_DEPENDENCY" : gProtocolDefinition,
- "EFI_ARCH_PROTOCOL_PRODUCER" : gArchProtocolDefinition,
- "EFI_ARCH_PROTOCOL_CONSUMER" : gArchProtocolDefinition,
- "EFI_ARCH_PROTOCOL_DEPENDENCY" : gArchProtocolDefinition,
- "EFI_PPI_DEFINITION" : gPpiDefinition,
- "EFI_PPI_PRODUCER" : gPpiDefinition,
- "EFI_PPI_CONSUMER" : gPpiDefinition,
- "EFI_PPI_DEPENDENCY" : gPpiDefinition,
-}
-
-## default makefile type
-gMakeType = ""
-if sys.platform == "win32":
- gMakeType = "nmake"
-else:
- gMakeType = "gmake"
-
-
-## BuildFile class
-#
-# This base class encapsules build file and its generation. It uses template to generate
-# the content of build file. The content of build file will be got from AutoGen objects.
-#
-class BuildFile(object):
- ## template used to generate the build file (i.e. makefile if using make)
- _TEMPLATE_ = TemplateString('')
-
- _DEFAULT_FILE_NAME_ = "Makefile"
-
- ## default file name for each type of build file
- _FILE_NAME_ = {
- "nmake" : "Makefile",
- "gmake" : "GNUmakefile"
- }
-
- ## Fixed header string for makefile
- _MAKEFILE_HEADER = '''#
-# DO NOT EDIT
-# This file is auto-generated by build utility
-#
-# Module Name:
-#
-# %s
-#
-# Abstract:
-#
-# Auto-generated makefile for building modules, libraries or platform
-#
- '''
-
- ## Header string for each type of build file
- _FILE_HEADER_ = {
- "nmake" : _MAKEFILE_HEADER % _FILE_NAME_["nmake"],
- "gmake" : _MAKEFILE_HEADER % _FILE_NAME_["gmake"]
- }
-
- ## shell commands which can be used in build file in the form of macro
- # $(CP) copy file command
- # $(MV) move file command
- # $(RM) remove file command
- # $(MD) create dir command
- # $(RD) remove dir command
- #
- _SHELL_CMD_ = {
- "nmake" : {
- "CP" : "copy /y",
- "MV" : "move /y",
- "RM" : "del /f /q",
- "MD" : "mkdir",
- "RD" : "rmdir /s /q",
- },
-
- "gmake" : {
- "CP" : "cp -f",
- "MV" : "mv -f",
- "RM" : "rm -f",
- "MD" : "mkdir -p",
- "RD" : "rm -r -f",
- }
- }
-
- ## directory separator
- _SEP_ = {
- "nmake" : "\\",
- "gmake" : "/"
- }
-
- ## directory creation template
- _MD_TEMPLATE_ = {
- "nmake" : 'if not exist %(dir)s $(MD) %(dir)s',
- "gmake" : "$(MD) %(dir)s"
- }
-
- ## directory removal template
- _RD_TEMPLATE_ = {
- "nmake" : 'if exist %(dir)s $(RD) %(dir)s',
- "gmake" : "$(RD) %(dir)s"
- }
-
- _CD_TEMPLATE_ = {
- "nmake" : 'if exist %(dir)s cd %(dir)s',
- "gmake" : "test -e %(dir)s && cd %(dir)s"
- }
-
- _MAKE_TEMPLATE_ = {
- "nmake" : 'if exist %(file)s "$(MAKE)" $(MAKE_FLAGS) -f %(file)s',
- "gmake" : 'test -e %(file)s && "$(MAKE)" $(MAKE_FLAGS) -f %(file)s'
- }
-
- _INCLUDE_CMD_ = {
- "nmake" : '!INCLUDE',
- "gmake" : "include"
- }
-
- _INC_FLAG_ = {"MSFT" : "/I", "GCC" : "-I", "INTEL" : "-I", "RVCT" : "-I"}
-
- ## Constructor of BuildFile
- #
- # @param AutoGenObject Object of AutoGen class
- #
- def __init__(self, AutoGenObject):
- self._AutoGenObject = AutoGenObject
- self._FileType = gMakeType
-
- ## Create build file
- #
- # @param FileType Type of build file. Only nmake and gmake are supported now.
- #
- # @retval TRUE The build file is created or re-created successfully
- # @retval FALSE The build file exists and is the same as the one to be generated
- #
- def Generate(self, FileType=gMakeType):
- if FileType not in self._FILE_NAME_:
- EdkLogger.error("build", PARAMETER_INVALID, "Invalid build type [%s]" % FileType,
- ExtraData="[%s]" % str(self._AutoGenObject))
- self._FileType = FileType
- FileContent = self._TEMPLATE_.Replace(self._TemplateDict)
- FileName = self._FILE_NAME_[FileType]
- return SaveFileOnChange(os.path.join(self._AutoGenObject.MakeFileDir, FileName), FileContent, False)
-
- ## Return a list of directory creation command string
- #
- # @param DirList The list of directory to be created
- #
- # @retval list The directory creation command list
- #
- def GetCreateDirectoryCommand(self, DirList):
- return [self._MD_TEMPLATE_[self._FileType] % {'dir':Dir} for Dir in DirList]
-
- ## Return a list of directory removal command string
- #
- # @param DirList The list of directory to be removed
- #
- # @retval list The directory removal command list
- #
- def GetRemoveDirectoryCommand(self, DirList):
- return [self._RD_TEMPLATE_[self._FileType] % {'dir':Dir} for Dir in DirList]
-
- def PlaceMacro(self, Path, MacroDefinitions={}):
- if Path.startswith("$("):
- return Path
- else:
- PathLength = len(Path)
- for MacroName in MacroDefinitions:
- MacroValue = MacroDefinitions[MacroName]
- MacroValueLength = len(MacroValue)
- if MacroValueLength <= PathLength and Path.startswith(MacroValue):
- Path = "$(%s)%s" % (MacroName, Path[MacroValueLength:])
- break
- return Path
-
-## ModuleMakefile class
-#
-# This class encapsules makefie and its generation for module. It uses template to generate
-# the content of makefile. The content of makefile will be got from ModuleAutoGen object.
-#
-class ModuleMakefile(BuildFile):
- ## template used to generate the makefile for module
- _TEMPLATE_ = TemplateString('''\
-${makefile_header}
-
-#
-# Platform Macro Definition
-#
-PLATFORM_NAME = ${platform_name}
-PLATFORM_GUID = ${platform_guid}
-PLATFORM_VERSION = ${platform_version}
-PLATFORM_RELATIVE_DIR = ${platform_relative_directory}
-PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}
-PLATFORM_OUTPUT_DIR = ${platform_output_directory}
-
-#
-# Module Macro Definition
-#
-MODULE_NAME = ${module_name}
-MODULE_GUID = ${module_guid}
-MODULE_VERSION = ${module_version}
-MODULE_TYPE = ${module_type}
-MODULE_FILE = ${module_file}
-MODULE_FILE_BASE_NAME = ${module_file_base_name}
-BASE_NAME = $(MODULE_NAME)
-MODULE_RELATIVE_DIR = ${module_relative_directory}
-MODULE_DIR = $(WORKSPACE)${separator}${module_relative_directory}
-
-MODULE_ENTRY_POINT = ${module_entry_point}
-ARCH_ENTRY_POINT = ${arch_entry_point}
-IMAGE_ENTRY_POINT = ${image_entry_point}
-
-${BEGIN}${module_extra_defines}
-${END}
-#
-# Build Configuration Macro Definition
-#
-ARCH = ${architecture}
-TOOLCHAIN = ${toolchain_tag}
-TOOLCHAIN_TAG = ${toolchain_tag}
-TARGET = ${build_target}
-
-#
-# Build Directory Macro Definition
-#
-# PLATFORM_BUILD_DIR = ${platform_build_directory}
-BUILD_DIR = ${platform_build_directory}
-BIN_DIR = $(BUILD_DIR)${separator}${architecture}
-LIB_DIR = $(BIN_DIR)
-MODULE_BUILD_DIR = ${module_build_directory}
-OUTPUT_DIR = ${module_output_directory}
-DEBUG_DIR = ${module_debug_directory}
-DEST_DIR_OUTPUT = $(OUTPUT_DIR)
-DEST_DIR_DEBUG = $(DEBUG_DIR)
-
-#
-# Shell Command Macro
-#
-${BEGIN}${shell_command_code} = ${shell_command}
-${END}
-
-#
-# Tools definitions specific to this module
-#
-${BEGIN}${module_tool_definitions}
-${END}
-MAKE_FILE = ${makefile_path}
-
-#
-# Build Macro
-#
-${BEGIN}${file_macro}
-${END}
-
-COMMON_DEPS = ${BEGIN}${common_dependency_file} \\
- ${END}
-
-#
-# Overridable Target Macro Definitions
-#
-FORCE_REBUILD = force_build
-INIT_TARGET = init
-PCH_TARGET =
-BC_TARGET = ${BEGIN}${backward_compatible_target} ${END}
-CODA_TARGET = ${BEGIN}${remaining_build_target} \\
- ${END}
-
-#
-# Default target, which will build dependent libraries in addition to source files
-#
-
-all: mbuild
-
-
-#
-# Target used when called from platform makefile, which will bypass the build of dependent libraries
-#
-
-pbuild: $(INIT_TARGET) $(BC_TARGET) $(PCH_TARGET) $(CODA_TARGET)
-
-#
-# ModuleTarget
-#
-
-mbuild: $(INIT_TARGET) $(BC_TARGET) gen_libs $(PCH_TARGET) $(CODA_TARGET)
-
-#
-# Build Target used in multi-thread build mode, which will bypass the init and gen_libs targets
-#
-
-tbuild: $(BC_TARGET) $(PCH_TARGET) $(CODA_TARGET)
-
-#
-# Phony target which is used to force executing commands for a target
-#
-force_build:
-\t-@
-
-#
-# Target to update the FD
-#
-
-fds: mbuild gen_fds
-
-#
-# Initialization target: print build information and create necessary directories
-#
-init: info dirs
-
-info:
-\t-@echo Building ... $(MODULE_DIR)${separator}$(MODULE_FILE) [$(ARCH)]
-
-dirs:
-${BEGIN}\t-@${create_directory_command}\n${END}
-
-strdefs:
-\t-@$(CP) $(DEBUG_DIR)${separator}AutoGen.h $(DEBUG_DIR)${separator}$(MODULE_NAME)StrDefs.h
-
-#
-# GenLibsTarget
-#
-gen_libs:
-\t${BEGIN}@"$(MAKE)" $(MAKE_FLAGS) -f ${dependent_library_build_directory}${separator}${makefile_name}
-\t${END}@cd $(MODULE_BUILD_DIR)
-
-#
-# Build Flash Device Image
-#
-gen_fds:
-\t@"$(MAKE)" $(MAKE_FLAGS) -f $(BUILD_DIR)${separator}${makefile_name} fds
-\t@cd $(MODULE_BUILD_DIR)
-
-#
-# Individual Object Build Targets
-#
-${BEGIN}${file_build_target}
-${END}
-
-#
-# clean all intermediate files
-#
-clean:
-\t${BEGIN}${clean_command}
-\t${END}
-
-#
-# clean all generated files
-#
-cleanall:
-${BEGIN}\t${cleanall_command}
-${END}\t$(RM) *.pdb *.idb > NUL 2>&1
-\t$(RM) $(BIN_DIR)${separator}$(MODULE_NAME).efi
-
-#
-# clean all dependent libraries built
-#
-cleanlib:
-\t${BEGIN}-@${library_build_command} cleanall
-\t${END}@cd $(MODULE_BUILD_DIR)\n\n''')
-
- _FILE_MACRO_TEMPLATE = TemplateString("${macro_name} = ${BEGIN} \\\n ${source_file}${END}\n")
- _BUILD_TARGET_TEMPLATE = TemplateString("${BEGIN}${target} : ${deps}\n${END}\t${cmd}\n")
-
- ## Constructor of ModuleMakefile
- #
- # @param ModuleAutoGen Object of ModuleAutoGen class
- #
- def __init__(self, ModuleAutoGen):
- BuildFile.__init__(self, ModuleAutoGen)
- self.PlatformInfo = self._AutoGenObject.PlatformInfo
-
- self.ResultFileList = []
- self.IntermediateDirectoryList = ["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]
-
- self.SourceFileDatabase = {} # {file type : file path}
- self.DestFileDatabase = {} # {file type : file path}
- self.FileBuildTargetList = [] # [(src, target string)]
- self.BuildTargetList = [] # [target string]
- self.PendingBuildTargetList = [] # [FileBuildRule objects]
- self.CommonFileDependency = []
- self.FileListMacros = {}
- self.ListFileMacros = {}
-
- self.FileCache = {}
- self.FileDependency = []
- self.LibraryBuildCommandList = []
- self.LibraryFileList = []
- self.LibraryMakefileList = []
- self.LibraryBuildDirectoryList = []
- self.SystemLibraryList = []
- self.Macros = sdict()
- self.Macros["OUTPUT_DIR" ] = self._AutoGenObject.Macros["OUTPUT_DIR"]
- self.Macros["DEBUG_DIR" ] = self._AutoGenObject.Macros["DEBUG_DIR"]
- self.Macros["MODULE_BUILD_DIR"] = self._AutoGenObject.Macros["MODULE_BUILD_DIR"]
- self.Macros["BIN_DIR" ] = self._AutoGenObject.Macros["BIN_DIR"]
- self.Macros["BUILD_DIR" ] = self._AutoGenObject.Macros["BUILD_DIR"]
- self.Macros["WORKSPACE" ] = self._AutoGenObject.Macros["WORKSPACE"]
-
- # Compose a dict object containing information used to do replacement in template
- def _CreateTemplateDict(self):
- if self._FileType not in self._SEP_:
- EdkLogger.error("build", PARAMETER_INVALID, "Invalid Makefile type [%s]" % self._FileType,
- ExtraData="[%s]" % str(self._AutoGenObject))
- Separator = self._SEP_[self._FileType]
-
- # break build if no source files and binary files are found
- if len(self._AutoGenObject.SourceFileList) == 0 and len(self._AutoGenObject.BinaryFileList) == 0:
- EdkLogger.error("build", AUTOGEN_ERROR, "No files to be built in module [%s, %s, %s]"
- % (self._AutoGenObject.BuildTarget, self._AutoGenObject.ToolChain, self._AutoGenObject.Arch),
- ExtraData="[%s]" % str(self._AutoGenObject))
-
- # convert dependent libraries to build command
- self.ProcessDependentLibrary()
- if len(self._AutoGenObject.Module.ModuleEntryPointList) > 0:
- ModuleEntryPoint = self._AutoGenObject.Module.ModuleEntryPointList[0]
- else:
- ModuleEntryPoint = "_ModuleEntryPoint"
-
- # Intel EBC compiler enforces EfiMain
- if self._AutoGenObject.AutoGenVersion < 0x00010005 and self._AutoGenObject.Arch == "EBC":
- ArchEntryPoint = "EfiMain"
- else:
- ArchEntryPoint = ModuleEntryPoint
-
- if self._AutoGenObject.Arch == "EBC":
- # EBC compiler always use "EfiStart" as entry point. Only applies to EdkII modules
- ImageEntryPoint = "EfiStart"
- elif self._AutoGenObject.AutoGenVersion < 0x00010005:
- # Edk modules use entry point specified in INF file
- ImageEntryPoint = ModuleEntryPoint
- else:
- # EdkII modules always use "_ModuleEntryPoint" as entry point
- ImageEntryPoint = "_ModuleEntryPoint"
-
- # tools definitions
- ToolsDef = []
- IncPrefix = self._INC_FLAG_[self._AutoGenObject.ToolChainFamily]
- for Tool in self._AutoGenObject.BuildOption:
- for Attr in self._AutoGenObject.BuildOption[Tool]:
- Value = self._AutoGenObject.BuildOption[Tool][Attr]
- if Attr == "FAMILY":
- continue
- elif Attr == "PATH":
- ToolsDef.append("%s = %s" % (Tool, Value))
- else:
- # Don't generate MAKE_FLAGS in makefile. It's put in environment variable.
- if Tool == "MAKE":
- continue
- # Remove duplicated include path, if any
- if Attr == "FLAGS":
- Value = RemoveDupOption(Value, IncPrefix, self._AutoGenObject.IncludePathList)
- ToolsDef.append("%s_%s = %s" % (Tool, Attr, Value))
- ToolsDef.append("")
-
- # convert source files and binary files to build targets
- self.ResultFileList = [str(T.Target) for T in self._AutoGenObject.CodaTargetList]
- if len(self.ResultFileList) == 0 and len(self._AutoGenObject.SourceFileList) <> 0:
- EdkLogger.error("build", AUTOGEN_ERROR, "Nothing to build",
- ExtraData="[%s]" % str(self._AutoGenObject))
-
- self.ProcessBuildTargetList()
-
- # Generate macros used to represent input files
- FileMacroList = [] # macro name = file list
- for FileListMacro in self.FileListMacros:
- FileMacro = self._FILE_MACRO_TEMPLATE.Replace(
- {
- "macro_name" : FileListMacro,
- "source_file" : self.FileListMacros[FileListMacro]
- }
- )
- FileMacroList.append(FileMacro)
-
- # INC_LIST is special
- FileMacro = ""
- IncludePathList = []
- for P in self._AutoGenObject.IncludePathList:
- IncludePathList.append(IncPrefix+self.PlaceMacro(P, self.Macros))
- if FileBuildRule.INC_LIST_MACRO in self.ListFileMacros:
- self.ListFileMacros[FileBuildRule.INC_LIST_MACRO].append(IncPrefix+P)
- FileMacro += self._FILE_MACRO_TEMPLATE.Replace(
- {
- "macro_name" : "INC",
- "source_file" : IncludePathList
- }
- )
- FileMacroList.append(FileMacro)
-
- # Generate macros used to represent files containing list of input files
- for ListFileMacro in self.ListFileMacros:
- ListFileName = os.path.join(self._AutoGenObject.OutputDir, "%s.lst" % ListFileMacro.lower()[:len(ListFileMacro)-5])
- FileMacroList.append("%s = %s" % (ListFileMacro, ListFileName))
- SaveFileOnChange(
- ListFileName,
- "\n".join(self.ListFileMacros[ListFileMacro]),
- False
- )
-
- # Edk modules need <BaseName>StrDefs.h for string ID
- #if self._AutoGenObject.AutoGenVersion < 0x00010005 and len(self._AutoGenObject.UnicodeFileList) > 0:
- # BcTargetList = ['strdefs']
- #else:
- # BcTargetList = []
- BcTargetList = []
-
- MakefileName = self._FILE_NAME_[self._FileType]
- LibraryMakeCommandList = []
- for D in self.LibraryBuildDirectoryList:
- Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":os.path.join(D, MakefileName)}
- LibraryMakeCommandList.append(Command)
-
- MakefileTemplateDict = {
- "makefile_header" : self._FILE_HEADER_[self._FileType],
- "makefile_path" : os.path.join("$(MODULE_BUILD_DIR)", MakefileName),
- "makefile_name" : MakefileName,
- "platform_name" : self.PlatformInfo.Name,
- "platform_guid" : self.PlatformInfo.Guid,
- "platform_version" : self.PlatformInfo.Version,
- "platform_relative_directory": self.PlatformInfo.SourceDir,
- "platform_output_directory" : self.PlatformInfo.OutputDir,
-
- "module_name" : self._AutoGenObject.Name,
- "module_guid" : self._AutoGenObject.Guid,
- "module_version" : self._AutoGenObject.Version,
- "module_type" : self._AutoGenObject.ModuleType,
- "module_file" : self._AutoGenObject.MetaFile.Name,
- "module_file_base_name" : self._AutoGenObject.MetaFile.BaseName,
- "module_relative_directory" : self._AutoGenObject.SourceDir,
- "module_extra_defines" : ["%s = %s" % (k, v) for k,v in self._AutoGenObject.Module.Defines.iteritems()],
-
- "architecture" : self._AutoGenObject.Arch,
- "toolchain_tag" : self._AutoGenObject.ToolChain,
- "build_target" : self._AutoGenObject.BuildTarget,
-
- "platform_build_directory" : self.PlatformInfo.BuildDir,
- "module_build_directory" : self._AutoGenObject.BuildDir,
- "module_output_directory" : self._AutoGenObject.OutputDir,
- "module_debug_directory" : self._AutoGenObject.DebugDir,
-
- "separator" : Separator,
- "module_tool_definitions" : ToolsDef,
-
- "shell_command_code" : self._SHELL_CMD_[self._FileType].keys(),
- "shell_command" : self._SHELL_CMD_[self._FileType].values(),
-
- "module_entry_point" : ModuleEntryPoint,
- "image_entry_point" : ImageEntryPoint,
- "arch_entry_point" : ArchEntryPoint,
- "remaining_build_target" : self.ResultFileList,
- "common_dependency_file" : self.CommonFileDependency,
- "create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
- "clean_command" : self.GetRemoveDirectoryCommand(["$(OUTPUT_DIR)"]),
- "cleanall_command" : self.GetRemoveDirectoryCommand(["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]),
- "dependent_library_build_directory" : self.LibraryBuildDirectoryList,
- "library_build_command" : LibraryMakeCommandList,
- "file_macro" : FileMacroList,
- "file_build_target" : self.BuildTargetList,
- "backward_compatible_target": BcTargetList,
- }
-
- return MakefileTemplateDict
-
- def ProcessBuildTargetList(self):
- #
- # Search dependency file list for each source file
- #
- ForceIncludedFile = []
- for File in self._AutoGenObject.AutoGenFileList:
- if File.Ext == '.h':
- ForceIncludedFile.append(File)
- SourceFileList = []
- for Target in self._AutoGenObject.IntroTargetList:
- SourceFileList.extend(Target.Inputs)
-
- self.FileDependency = self.GetFileDependency(
- SourceFileList,
- ForceIncludedFile,
- self._AutoGenObject.IncludePathList + self._AutoGenObject.BuildOptionIncPathList
- )
- DepSet = None
- for File in self.FileDependency:
- if not self.FileDependency[File]:
- self.FileDependency[File] = ['$(FORCE_REBUILD)']
- continue
- # skip non-C files
- if File.Ext not in [".c", ".C"] or File.Name == "AutoGen.c":
- continue
- elif DepSet == None:
- DepSet = set(self.FileDependency[File])
- else:
- DepSet &= set(self.FileDependency[File])
- # in case nothing in SourceFileList
- if DepSet == None:
- DepSet = set()
- #
- # Extract common files list in the dependency files
- #
- for File in DepSet:
- self.CommonFileDependency.append(self.PlaceMacro(File.Path, self.Macros))
-
- for File in self.FileDependency:
- # skip non-C files
- if File.Ext not in [".c", ".C"] or File.Name == "AutoGen.c":
- continue
- NewDepSet = set(self.FileDependency[File])
- NewDepSet -= DepSet
- self.FileDependency[File] = ["$(COMMON_DEPS)"] + list(NewDepSet)
-
- # Convert target description object to target string in makefile
- for Type in self._AutoGenObject.Targets:
- for T in self._AutoGenObject.Targets[Type]:
- # Generate related macros if needed
- if T.GenFileListMacro and T.FileListMacro not in self.FileListMacros:
- self.FileListMacros[T.FileListMacro] = []
- if T.GenListFile and T.ListFileMacro not in self.ListFileMacros:
- self.ListFileMacros[T.ListFileMacro] = []
- if T.GenIncListFile and T.IncListFileMacro not in self.ListFileMacros:
- self.ListFileMacros[T.IncListFileMacro] = []
-
- Deps = []
- # Add force-dependencies
- for Dep in T.Dependencies:
- Deps.append(self.PlaceMacro(str(Dep), self.Macros))
- # Add inclusion-dependencies
- if len(T.Inputs) == 1 and T.Inputs[0] in self.FileDependency:
- for F in self.FileDependency[T.Inputs[0]]:
- Deps.append(self.PlaceMacro(str(F), self.Macros))
- # Add source-dependencies
- for F in T.Inputs:
- NewFile = self.PlaceMacro(str(F), self.Macros)
- # In order to use file list macro as dependency
- if T.GenListFile:
- self.ListFileMacros[T.ListFileMacro].append(str(F))
- self.FileListMacros[T.FileListMacro].append(NewFile)
- elif T.GenFileListMacro:
- self.FileListMacros[T.FileListMacro].append(NewFile)
- else:
- Deps.append(NewFile)
-
- # Use file list macro as dependency
- if T.GenFileListMacro:
- Deps.append("$(%s)" % T.FileListMacro)
-
- TargetDict = {
- "target" : self.PlaceMacro(T.Target.Path, self.Macros),
- "cmd" : "\n\t".join(T.Commands),
- "deps" : Deps
- }
- self.BuildTargetList.append(self._BUILD_TARGET_TEMPLATE.Replace(TargetDict))
-
- ## For creating makefile targets for dependent libraries
- def ProcessDependentLibrary(self):
- for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:
- self.LibraryBuildDirectoryList.append(self.PlaceMacro(LibraryAutoGen.BuildDir, self.Macros))
-
- ## Return a list containing source file's dependencies
- #
- # @param FileList The list of source files
- # @param ForceInculeList The list of files which will be included forcely
- # @param SearchPathList The list of search path
- #
- # @retval dict The mapping between source file path and its dependencies
- #
- def GetFileDependency(self, FileList, ForceInculeList, SearchPathList):
- Dependency = {}
- for F in FileList:
- Dependency[F] = self.GetDependencyList(F, ForceInculeList, SearchPathList)
- return Dependency
-
- ## Find dependencies for one source file
- #
- # By searching recursively "#include" directive in file, find out all the
- # files needed by given source file. The dependecies will be only searched
- # in given search path list.
- #
- # @param File The source file
- # @param ForceInculeList The list of files which will be included forcely
- # @param SearchPathList The list of search path
- #
- # @retval list The list of files the given source file depends on
- #
- def GetDependencyList(self, File, ForceList, SearchPathList):
- EdkLogger.debug(EdkLogger.DEBUG_1, "Try to get dependency files for %s" % File)
- FileStack = [File] + ForceList
- DependencySet = set()
-
- if self._AutoGenObject.Arch not in gDependencyDatabase:
- gDependencyDatabase[self._AutoGenObject.Arch] = {}
- DepDb = gDependencyDatabase[self._AutoGenObject.Arch]
-
- while len(FileStack) > 0:
- F = FileStack.pop()
-
- FullPathDependList = []
- if F in self.FileCache:
- for CacheFile in self.FileCache[F]:
- FullPathDependList.append(CacheFile)
- if CacheFile not in DependencySet:
- FileStack.append(CacheFile)
- DependencySet.update(FullPathDependList)
- continue
-
- CurrentFileDependencyList = []
- if F in DepDb:
- CurrentFileDependencyList = DepDb[F]
- else:
- try:
- Fd = open(F.Path, 'r')
- except BaseException, X:
- EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=F.Path+"\n\t"+str(X))
-
- FileContent = Fd.read()
- Fd.close()
- if len(FileContent) == 0:
- continue
-
- if FileContent[0] == 0xff or FileContent[0] == 0xfe:
- FileContent = unicode(FileContent, "utf-16")
- IncludedFileList = gIncludePattern.findall(FileContent)
-
- for Inc in IncludedFileList:
- Inc = Inc.strip()
- # if there's macro used to reference header file, expand it
- HeaderList = gMacroPattern.findall(Inc)
- if len(HeaderList) == 1 and len(HeaderList[0]) == 2:
- HeaderType = HeaderList[0][0]
- HeaderKey = HeaderList[0][1]
- if HeaderType in gIncludeMacroConversion:
- Inc = gIncludeMacroConversion[HeaderType] % {"HeaderKey" : HeaderKey}
- else:
- # not known macro used in #include, always build the file by
- # returning a empty dependency
- self.FileCache[File] = []
- return []
- Inc = os.path.normpath(Inc)
- CurrentFileDependencyList.append(Inc)
- DepDb[F] = CurrentFileDependencyList
-
- CurrentFilePath = F.Dir
- PathList = [CurrentFilePath] + SearchPathList
- for Inc in CurrentFileDependencyList:
- for SearchPath in PathList:
- FilePath = os.path.join(SearchPath, Inc)
- if FilePath in gIsFileMap:
- if not gIsFileMap[FilePath]:
- continue
- # If isfile is called too many times, the performance is slow down.
- elif not os.path.isfile(FilePath):
- gIsFileMap[FilePath] = False
- continue
- else:
- gIsFileMap[FilePath] = True
- FilePath = PathClass(FilePath)
- FullPathDependList.append(FilePath)
- if FilePath not in DependencySet:
- FileStack.append(FilePath)
- break
- else:
- EdkLogger.debug(EdkLogger.DEBUG_9, "%s included by %s was not found "\
- "in any given path:\n\t%s" % (Inc, F, "\n\t".join(SearchPathList)))
-
- self.FileCache[F] = FullPathDependList
- DependencySet.update(FullPathDependList)
-
- DependencySet.update(ForceList)
- if File in DependencySet:
- DependencySet.remove(File)
- DependencyList = list(DependencySet) # remove duplicate ones
-
- return DependencyList
-
- _TemplateDict = property(_CreateTemplateDict)
-
-## CustomMakefile class
-#
-# This class encapsules makefie and its generation for module. It uses template to generate
-# the content of makefile. The content of makefile will be got from ModuleAutoGen object.
-#
-class CustomMakefile(BuildFile):
- ## template used to generate the makefile for module with custom makefile
- _TEMPLATE_ = TemplateString('''\
-${makefile_header}
-
-#
-# Platform Macro Definition
-#
-PLATFORM_NAME = ${platform_name}
-PLATFORM_GUID = ${platform_guid}
-PLATFORM_VERSION = ${platform_version}
-PLATFORM_RELATIVE_DIR = ${platform_relative_directory}
-PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}
-PLATFORM_OUTPUT_DIR = ${platform_output_directory}
-
-#
-# Module Macro Definition
-#
-MODULE_NAME = ${module_name}
-MODULE_GUID = ${module_guid}
-MODULE_VERSION = ${module_version}
-MODULE_TYPE = ${module_type}
-MODULE_FILE = ${module_file}
-MODULE_FILE_BASE_NAME = ${module_file_base_name}
-BASE_NAME = $(MODULE_NAME)
-MODULE_RELATIVE_DIR = ${module_relative_directory}
-MODULE_DIR = $(WORKSPACE)${separator}${module_relative_directory}
-
-#
-# Build Configuration Macro Definition
-#
-ARCH = ${architecture}
-TOOLCHAIN = ${toolchain_tag}
-TOOLCHAIN_TAG = ${toolchain_tag}
-TARGET = ${build_target}
-
-#
-# Build Directory Macro Definition
-#
-# PLATFORM_BUILD_DIR = ${platform_build_directory}
-BUILD_DIR = ${platform_build_directory}
-BIN_DIR = $(BUILD_DIR)${separator}${architecture}
-LIB_DIR = $(BIN_DIR)
-MODULE_BUILD_DIR = ${module_build_directory}
-OUTPUT_DIR = ${module_output_directory}
-DEBUG_DIR = ${module_debug_directory}
-DEST_DIR_OUTPUT = $(OUTPUT_DIR)
-DEST_DIR_DEBUG = $(DEBUG_DIR)
-
-#
-# Tools definitions specific to this module
-#
-${BEGIN}${module_tool_definitions}
-${END}
-MAKE_FILE = ${makefile_path}
-
-#
-# Shell Command Macro
-#
-${BEGIN}${shell_command_code} = ${shell_command}
-${END}
-
-${custom_makefile_content}
-
-#
-# Target used when called from platform makefile, which will bypass the build of dependent libraries
-#
-
-pbuild: init all
-
-
-#
-# ModuleTarget
-#
-
-mbuild: init all
-
-#
-# Build Target used in multi-thread build mode, which no init target is needed
-#
-
-tbuild: all
-
-#
-# Initialization target: print build information and create necessary directories
-#
-init:
-\t-@echo Building ... $(MODULE_DIR)${separator}$(MODULE_FILE) [$(ARCH)]
-${BEGIN}\t-@${create_directory_command}\n${END}\
-
-''')
-
- ## Constructor of CustomMakefile
- #
- # @param ModuleAutoGen Object of ModuleAutoGen class
- #
- def __init__(self, ModuleAutoGen):
- BuildFile.__init__(self, ModuleAutoGen)
- self.PlatformInfo = self._AutoGenObject.PlatformInfo
- self.IntermediateDirectoryList = ["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]
-
- # Compose a dict object containing information used to do replacement in template
- def _CreateTemplateDict(self):
- Separator = self._SEP_[self._FileType]
- if self._FileType not in self._AutoGenObject.CustomMakefile:
- EdkLogger.error('build', OPTION_NOT_SUPPORTED, "No custom makefile for %s" % self._FileType,
- ExtraData="[%s]" % str(self._AutoGenObject))
- MakefilePath = os.path.join(
- self._AutoGenObject.WorkspaceDir,
- self._AutoGenObject.CustomMakefile[self._FileType]
- )
- try:
- CustomMakefile = open(MakefilePath, 'r').read()
- except:
- EdkLogger.error('build', FILE_OPEN_FAILURE, File=str(self._AutoGenObject),
- ExtraData=self._AutoGenObject.CustomMakefile[self._FileType])
-
- # tools definitions
- ToolsDef = []
- for Tool in self._AutoGenObject.BuildOption:
- # Don't generate MAKE_FLAGS in makefile. It's put in environment variable.
- if Tool == "MAKE":
- continue
- for Attr in self._AutoGenObject.BuildOption[Tool]:
- if Attr == "FAMILY":
- continue
- elif Attr == "PATH":
- ToolsDef.append("%s = %s" % (Tool, self._AutoGenObject.BuildOption[Tool][Attr]))
- else:
- ToolsDef.append("%s_%s = %s" % (Tool, Attr, self._AutoGenObject.BuildOption[Tool][Attr]))
- ToolsDef.append("")
-
- MakefileName = self._FILE_NAME_[self._FileType]
- MakefileTemplateDict = {
- "makefile_header" : self._FILE_HEADER_[self._FileType],
- "makefile_path" : os.path.join("$(MODULE_BUILD_DIR)", MakefileName),
- "platform_name" : self.PlatformInfo.Name,
- "platform_guid" : self.PlatformInfo.Guid,
- "platform_version" : self.PlatformInfo.Version,
- "platform_relative_directory": self.PlatformInfo.SourceDir,
- "platform_output_directory" : self.PlatformInfo.OutputDir,
-
- "module_name" : self._AutoGenObject.Name,
- "module_guid" : self._AutoGenObject.Guid,
- "module_version" : self._AutoGenObject.Version,
- "module_type" : self._AutoGenObject.ModuleType,
- "module_file" : self._AutoGenObject.MetaFile,
- "module_file_base_name" : self._AutoGenObject.MetaFile.BaseName,
- "module_relative_directory" : self._AutoGenObject.SourceDir,
-
- "architecture" : self._AutoGenObject.Arch,
- "toolchain_tag" : self._AutoGenObject.ToolChain,
- "build_target" : self._AutoGenObject.BuildTarget,
-
- "platform_build_directory" : self.PlatformInfo.BuildDir,
- "module_build_directory" : self._AutoGenObject.BuildDir,
- "module_output_directory" : self._AutoGenObject.OutputDir,
- "module_debug_directory" : self._AutoGenObject.DebugDir,
-
- "separator" : Separator,
- "module_tool_definitions" : ToolsDef,
-
- "shell_command_code" : self._SHELL_CMD_[self._FileType].keys(),
- "shell_command" : self._SHELL_CMD_[self._FileType].values(),
-
- "create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
- "custom_makefile_content" : CustomMakefile
- }
-
- return MakefileTemplateDict
-
- _TemplateDict = property(_CreateTemplateDict)
-
-## PlatformMakefile class
-#
-# This class encapsules makefie and its generation for platform. It uses
-# template to generate the content of makefile. The content of makefile will be
-# got from PlatformAutoGen object.
-#
-class PlatformMakefile(BuildFile):
- ## template used to generate the makefile for platform
- _TEMPLATE_ = TemplateString('''\
-${makefile_header}
-
-#
-# Platform Macro Definition
-#
-PLATFORM_NAME = ${platform_name}
-PLATFORM_GUID = ${platform_guid}
-PLATFORM_VERSION = ${platform_version}
-PLATFORM_FILE = ${platform_file}
-PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}
-PLATFORM_OUTPUT_DIR = ${platform_output_directory}
-
-#
-# Build Configuration Macro Definition
-#
-TOOLCHAIN = ${toolchain_tag}
-TOOLCHAIN_TAG = ${toolchain_tag}
-TARGET = ${build_target}
-
-#
-# Build Directory Macro Definition
-#
-BUILD_DIR = ${platform_build_directory}
-FV_DIR = ${platform_build_directory}${separator}FV
-
-#
-# Shell Command Macro
-#
-${BEGIN}${shell_command_code} = ${shell_command}
-${END}
-
-MAKE = ${make_path}
-MAKE_FILE = ${makefile_path}
-
-#
-# Default target
-#
-all: init build_libraries build_modules
-
-#
-# Initialization target: print build information and create necessary directories
-#
-init:
-\t-@echo Building ... $(PLATFORM_FILE) [${build_architecture_list}]
-\t${BEGIN}-@${create_directory_command}
-\t${END}
-#
-# library build target
-#
-libraries: init build_libraries
-
-#
-# module build target
-#
-modules: init build_libraries build_modules
-
-#
-# Build all libraries:
-#
-build_libraries:
-${BEGIN}\t@"$(MAKE)" $(MAKE_FLAGS) -f ${library_makefile_list} pbuild
-${END}\t@cd $(BUILD_DIR)
-
-#
-# Build all modules:
-#
-build_modules:
-${BEGIN}\t@"$(MAKE)" $(MAKE_FLAGS) -f ${module_makefile_list} pbuild
-${END}\t@cd $(BUILD_DIR)
-
-#
-# Clean intermediate files
-#
-clean:
-\t${BEGIN}-@${library_build_command} clean
-\t${END}${BEGIN}-@${module_build_command} clean
-\t${END}@cd $(BUILD_DIR)
-
-#
-# Clean all generated files except to makefile
-#
-cleanall:
-${BEGIN}\t${cleanall_command}
-${END}
-
-#
-# Clean all library files
-#
-cleanlib:
-\t${BEGIN}-@${library_build_command} cleanall
-\t${END}@cd $(BUILD_DIR)\n
-''')
-
- ## Constructor of PlatformMakefile
- #
- # @param ModuleAutoGen Object of PlatformAutoGen class
- #
- def __init__(self, PlatformAutoGen):
- BuildFile.__init__(self, PlatformAutoGen)
- self.ModuleBuildCommandList = []
- self.ModuleMakefileList = []
- self.IntermediateDirectoryList = []
- self.ModuleBuildDirectoryList = []
- self.LibraryBuildDirectoryList = []
-
- # Compose a dict object containing information used to do replacement in template
- def _CreateTemplateDict(self):
- Separator = self._SEP_[self._FileType]
-
- PlatformInfo = self._AutoGenObject
- if "MAKE" not in PlatformInfo.ToolDefinition or "PATH" not in PlatformInfo.ToolDefinition["MAKE"]:
- EdkLogger.error("build", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!",
- ExtraData="[%s]" % str(self._AutoGenObject))
-
- self.IntermediateDirectoryList = ["$(BUILD_DIR)"]
- self.ModuleBuildDirectoryList = self.GetModuleBuildDirectoryList()
- self.LibraryBuildDirectoryList = self.GetLibraryBuildDirectoryList()
-
- MakefileName = self._FILE_NAME_[self._FileType]
- LibraryMakefileList = []
- LibraryMakeCommandList = []
- for D in self.LibraryBuildDirectoryList:
- D = self.PlaceMacro(D, {"BUILD_DIR":PlatformInfo.BuildDir})
- Makefile = os.path.join(D, MakefileName)
- Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":Makefile}
- LibraryMakefileList.append(Makefile)
- LibraryMakeCommandList.append(Command)
-
- ModuleMakefileList = []
- ModuleMakeCommandList = []
- for D in self.ModuleBuildDirectoryList:
- D = self.PlaceMacro(D, {"BUILD_DIR":PlatformInfo.BuildDir})
- Makefile = os.path.join(D, MakefileName)
- Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":Makefile}
- ModuleMakefileList.append(Makefile)
- ModuleMakeCommandList.append(Command)
-
- MakefileTemplateDict = {
- "makefile_header" : self._FILE_HEADER_[self._FileType],
- "makefile_path" : os.path.join("$(BUILD_DIR)", MakefileName),
- "make_path" : PlatformInfo.ToolDefinition["MAKE"]["PATH"],
- "makefile_name" : MakefileName,
- "platform_name" : PlatformInfo.Name,
- "platform_guid" : PlatformInfo.Guid,
- "platform_version" : PlatformInfo.Version,
- "platform_file" : self._AutoGenObject.MetaFile,
- "platform_relative_directory": PlatformInfo.SourceDir,
- "platform_output_directory" : PlatformInfo.OutputDir,
- "platform_build_directory" : PlatformInfo.BuildDir,
-
- "toolchain_tag" : PlatformInfo.ToolChain,
- "build_target" : PlatformInfo.BuildTarget,
- "shell_command_code" : self._SHELL_CMD_[self._FileType].keys(),
- "shell_command" : self._SHELL_CMD_[self._FileType].values(),
- "build_architecture_list" : self._AutoGenObject.Arch,
- "architecture" : self._AutoGenObject.Arch,
- "separator" : Separator,
- "create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
- "cleanall_command" : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList),
- "library_makefile_list" : LibraryMakefileList,
- "module_makefile_list" : ModuleMakefileList,
- "library_build_command" : LibraryMakeCommandList,
- "module_build_command" : ModuleMakeCommandList,
- }
-
- return MakefileTemplateDict
-
- ## Get the root directory list for intermediate files of all modules build
- #
- # @retval list The list of directory
- #
- def GetModuleBuildDirectoryList(self):
- DirList = []
- for ModuleAutoGen in self._AutoGenObject.ModuleAutoGenList:
- DirList.append(os.path.join(self._AutoGenObject.BuildDir, ModuleAutoGen.BuildDir))
- return DirList
-
- ## Get the root directory list for intermediate files of all libraries build
- #
- # @retval list The list of directory
- #
- def GetLibraryBuildDirectoryList(self):
- DirList = []
- for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:
- DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))
- return DirList
-
- _TemplateDict = property(_CreateTemplateDict)
-
-## TopLevelMakefile class
-#
-# This class encapsules makefie and its generation for entrance makefile. It
-# uses template to generate the content of makefile. The content of makefile
-# will be got from WorkspaceAutoGen object.
-#
-class TopLevelMakefile(BuildFile):
- ## template used to generate toplevel makefile
- _TEMPLATE_ = TemplateString('''\
-${makefile_header}
-
-#
-# Platform Macro Definition
-#
-PLATFORM_NAME = ${platform_name}
-PLATFORM_GUID = ${platform_guid}
-PLATFORM_VERSION = ${platform_version}
-
-#
-# Build Configuration Macro Definition
-#
-TOOLCHAIN = ${toolchain_tag}
-TOOLCHAIN_TAG = ${toolchain_tag}
-TARGET = ${build_target}
-
-#
-# Build Directory Macro Definition
-#
-BUILD_DIR = ${platform_build_directory}
-FV_DIR = ${platform_build_directory}${separator}FV
-
-#
-# Shell Command Macro
-#
-${BEGIN}${shell_command_code} = ${shell_command}
-${END}
-
-MAKE = ${make_path}
-MAKE_FILE = ${makefile_path}
-
-#
-# Default target
-#
-all: modules fds
-
-#
-# Initialization target: print build information and create necessary directories
-#
-init:
-\t-@
-\t${BEGIN}-@${create_directory_command}
-\t${END}
-#
-# library build target
-#
-libraries: init
-${BEGIN}\t@cd $(BUILD_DIR)${separator}${arch} && "$(MAKE)" $(MAKE_FLAGS) libraries
-${END}\t@cd $(BUILD_DIR)
-
-#
-# module build target
-#
-modules: init
-${BEGIN}\t@cd $(BUILD_DIR)${separator}${arch} && "$(MAKE)" $(MAKE_FLAGS) modules
-${END}\t@cd $(BUILD_DIR)
-
-#
-# Flash Device Image Target
-#
-fds: init
-\t-@cd $(FV_DIR)
-${BEGIN}\tGenFds -f ${fdf_file} -o $(BUILD_DIR) -t $(TOOLCHAIN) -b $(TARGET) -p ${active_platform} -a ${build_architecture_list} ${extra_options}${END}${BEGIN} -r ${fd} ${END}${BEGIN} -i ${fv} ${END}${BEGIN} -C ${cap} ${END}${BEGIN} -D ${macro} ${END}
-
-#
-# run command for emulator platform only
-#
-run:
-\tcd $(BUILD_DIR)${separator}IA32 && ".${separator}SecMain"
-\tcd $(BUILD_DIR)
-
-#
-# Clean intermediate files
-#
-clean:
-${BEGIN}\t-@${sub_build_command} clean
-${END}\t@cd $(BUILD_DIR)
-
-#
-# Clean all generated files except to makefile
-#
-cleanall:
-${BEGIN}\t${cleanall_command}
-${END}
-
-#
-# Clean all library files
-#
-cleanlib:
-${BEGIN}\t-@${sub_build_command} cleanlib
-${END}\t@cd $(BUILD_DIR)\n
-''')
-
- ## Constructor of TopLevelMakefile
- #
- # @param Workspace Object of WorkspaceAutoGen class
- #
- def __init__(self, Workspace):
- BuildFile.__init__(self, Workspace)
- self.IntermediateDirectoryList = []
-
- # Compose a dict object containing information used to do replacement in template
- def _CreateTemplateDict(self):
- Separator = self._SEP_[self._FileType]
-
- # any platform autogen object is ok because we just need common information
- PlatformInfo = self._AutoGenObject
-
- if "MAKE" not in PlatformInfo.ToolDefinition or "PATH" not in PlatformInfo.ToolDefinition["MAKE"]:
- EdkLogger.error("build", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!",
- ExtraData="[%s]" % str(self._AutoGenObject))
-
- for Arch in PlatformInfo.ArchList:
- self.IntermediateDirectoryList.append(Separator.join(["$(BUILD_DIR)", Arch]))
- self.IntermediateDirectoryList.append("$(FV_DIR)")
-
- # TRICK: for not generating GenFds call in makefile if no FDF file
- MacroList = []
- if PlatformInfo.FdfFile != None and PlatformInfo.FdfFile != "":
- FdfFileList = [PlatformInfo.FdfFile]
- # macros passed to GenFds
- MacroList.append('"%s=%s"' % ("EFI_SOURCE", GlobalData.gEfiSource.replace('\\', '\\\\')))
- MacroList.append('"%s=%s"' % ("EDK_SOURCE", GlobalData.gEdkSource.replace('\\', '\\\\')))
- MacroDict = {}
- MacroDict.update(GlobalData.gGlobalDefines)
- MacroDict.update(GlobalData.gCommandLineDefines)
- MacroDict.pop("EFI_SOURCE", "dummy")
- MacroDict.pop("EDK_SOURCE", "dummy")
- for MacroName in MacroDict:
- if MacroDict[MacroName] != "":
- MacroList.append('"%s=%s"' % (MacroName, MacroDict[MacroName].replace('\\', '\\\\')))
- else:
- MacroList.append('"%s"' % MacroName)
- else:
- FdfFileList = []
-
- # pass extra common options to external program called in makefile, currently GenFds.exe
- ExtraOption = ''
- LogLevel = EdkLogger.GetLevel()
- if LogLevel == EdkLogger.VERBOSE:
- ExtraOption += " -v"
- elif LogLevel <= EdkLogger.DEBUG_9:
- ExtraOption += " -d %d" % (LogLevel - 1)
- elif LogLevel == EdkLogger.QUIET:
- ExtraOption += " -q"
-
- if GlobalData.gCaseInsensitive:
- ExtraOption += " -c"
-
- MakefileName = self._FILE_NAME_[self._FileType]
- SubBuildCommandList = []
- for A in PlatformInfo.ArchList:
- Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":os.path.join("$(BUILD_DIR)", A, MakefileName)}
- SubBuildCommandList.append(Command)
-
- MakefileTemplateDict = {
- "makefile_header" : self._FILE_HEADER_[self._FileType],
- "makefile_path" : os.path.join("$(BUILD_DIR)", MakefileName),
- "make_path" : PlatformInfo.ToolDefinition["MAKE"]["PATH"],
- "platform_name" : PlatformInfo.Name,
- "platform_guid" : PlatformInfo.Guid,
- "platform_version" : PlatformInfo.Version,
- "platform_build_directory" : PlatformInfo.BuildDir,
-
- "toolchain_tag" : PlatformInfo.ToolChain,
- "build_target" : PlatformInfo.BuildTarget,
- "shell_command_code" : self._SHELL_CMD_[self._FileType].keys(),
- "shell_command" : self._SHELL_CMD_[self._FileType].values(),
- 'arch' : list(PlatformInfo.ArchList),
- "build_architecture_list" : ','.join(PlatformInfo.ArchList),
- "separator" : Separator,
- "create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
- "cleanall_command" : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList),
- "sub_build_command" : SubBuildCommandList,
- "fdf_file" : FdfFileList,
- "active_platform" : str(PlatformInfo),
- "fd" : PlatformInfo.FdTargetList,
- "fv" : PlatformInfo.FvTargetList,
- "cap" : PlatformInfo.CapTargetList,
- "extra_options" : ExtraOption,
- "macro" : MacroList,
- }
-
- return MakefileTemplateDict
-
- ## Get the root directory list for intermediate files of all modules build
- #
- # @retval list The list of directory
- #
- def GetModuleBuildDirectoryList(self):
- DirList = []
- for ModuleAutoGen in self._AutoGenObject.ModuleAutoGenList:
- DirList.append(os.path.join(self._AutoGenObject.BuildDir, ModuleAutoGen.BuildDir))
- return DirList
-
- ## Get the root directory list for intermediate files of all libraries build
- #
- # @retval list The list of directory
- #
- def GetLibraryBuildDirectoryList(self):
- DirList = []
- for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:
- DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))
- return DirList
-
- _TemplateDict = property(_CreateTemplateDict)
-
-# This acts like the main() function for the script, unless it is 'import'ed into another script.
-if __name__ == '__main__':
- pass
-
+## @file
+# Create makefile for MS nmake and GNU make
+#
+# 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 string
+import re
+import os.path as path
+
+from Common.BuildToolError import *
+from Common.Misc import *
+from Common.String import *
+from BuildEngine import *
+import Common.GlobalData as GlobalData
+
+## Regular expression for finding header file inclusions
+gIncludePattern = re.compile(r"^[ \t]*#?[ \t]*include(?:[ \t]*(?:\\(?:\r\n|\r|\n))*[ \t]*)*(?:\(?[\"<]?[ \t]*)([-\w.\\/() \t]+)(?:[ \t]*[\">]?\)?)", re.MULTILINE|re.UNICODE|re.IGNORECASE)
+
+## Regular expression for matching macro used in header file inclusion
+gMacroPattern = re.compile("([_A-Z][_A-Z0-9]*)[ \t]*\((.+)\)", re.UNICODE)
+
+gIsFileMap = {}
+
+## pattern for include style in Edk.x code
+gProtocolDefinition = "Protocol/%(HeaderKey)s/%(HeaderKey)s.h"
+gGuidDefinition = "Guid/%(HeaderKey)s/%(HeaderKey)s.h"
+gArchProtocolDefinition = "ArchProtocol/%(HeaderKey)s/%(HeaderKey)s.h"
+gPpiDefinition = "Ppi/%(HeaderKey)s/%(HeaderKey)s.h"
+gIncludeMacroConversion = {
+ "EFI_PROTOCOL_DEFINITION" : gProtocolDefinition,
+ "EFI_GUID_DEFINITION" : gGuidDefinition,
+ "EFI_ARCH_PROTOCOL_DEFINITION" : gArchProtocolDefinition,
+ "EFI_PROTOCOL_PRODUCER" : gProtocolDefinition,
+ "EFI_PROTOCOL_CONSUMER" : gProtocolDefinition,
+ "EFI_PROTOCOL_DEPENDENCY" : gProtocolDefinition,
+ "EFI_ARCH_PROTOCOL_PRODUCER" : gArchProtocolDefinition,
+ "EFI_ARCH_PROTOCOL_CONSUMER" : gArchProtocolDefinition,
+ "EFI_ARCH_PROTOCOL_DEPENDENCY" : gArchProtocolDefinition,
+ "EFI_PPI_DEFINITION" : gPpiDefinition,
+ "EFI_PPI_PRODUCER" : gPpiDefinition,
+ "EFI_PPI_CONSUMER" : gPpiDefinition,
+ "EFI_PPI_DEPENDENCY" : gPpiDefinition,
+}
+
+## default makefile type
+gMakeType = ""
+if sys.platform == "win32":
+ gMakeType = "nmake"
+else:
+ gMakeType = "gmake"
+
+
+## BuildFile class
+#
+# This base class encapsules build file and its generation. It uses template to generate
+# the content of build file. The content of build file will be got from AutoGen objects.
+#
+class BuildFile(object):
+ ## template used to generate the build file (i.e. makefile if using make)
+ _TEMPLATE_ = TemplateString('')
+
+ _DEFAULT_FILE_NAME_ = "Makefile"
+
+ ## default file name for each type of build file
+ _FILE_NAME_ = {
+ "nmake" : "Makefile",
+ "gmake" : "GNUmakefile"
+ }
+
+ ## Fixed header string for makefile
+ _MAKEFILE_HEADER = '''#
+# DO NOT EDIT
+# This file is auto-generated by build utility
+#
+# Module Name:
+#
+# %s
+#
+# Abstract:
+#
+# Auto-generated makefile for building modules, libraries or platform
+#
+ '''
+
+ ## Header string for each type of build file
+ _FILE_HEADER_ = {
+ "nmake" : _MAKEFILE_HEADER % _FILE_NAME_["nmake"],
+ "gmake" : _MAKEFILE_HEADER % _FILE_NAME_["gmake"]
+ }
+
+ ## shell commands which can be used in build file in the form of macro
+ # $(CP) copy file command
+ # $(MV) move file command
+ # $(RM) remove file command
+ # $(MD) create dir command
+ # $(RD) remove dir command
+ #
+ _SHELL_CMD_ = {
+ "nmake" : {
+ "CP" : "copy /y",
+ "MV" : "move /y",
+ "RM" : "del /f /q",
+ "MD" : "mkdir",
+ "RD" : "rmdir /s /q",
+ },
+
+ "gmake" : {
+ "CP" : "cp -f",
+ "MV" : "mv -f",
+ "RM" : "rm -f",
+ "MD" : "mkdir -p",
+ "RD" : "rm -r -f",
+ }
+ }
+
+ ## directory separator
+ _SEP_ = {
+ "nmake" : "\\",
+ "gmake" : "/"
+ }
+
+ ## directory creation template
+ _MD_TEMPLATE_ = {
+ "nmake" : 'if not exist %(dir)s $(MD) %(dir)s',
+ "gmake" : "$(MD) %(dir)s"
+ }
+
+ ## directory removal template
+ _RD_TEMPLATE_ = {
+ "nmake" : 'if exist %(dir)s $(RD) %(dir)s',
+ "gmake" : "$(RD) %(dir)s"
+ }
+
+ _CD_TEMPLATE_ = {
+ "nmake" : 'if exist %(dir)s cd %(dir)s',
+ "gmake" : "test -e %(dir)s && cd %(dir)s"
+ }
+
+ _MAKE_TEMPLATE_ = {
+ "nmake" : 'if exist %(file)s "$(MAKE)" $(MAKE_FLAGS) -f %(file)s',
+ "gmake" : 'test -e %(file)s && "$(MAKE)" $(MAKE_FLAGS) -f %(file)s'
+ }
+
+ _INCLUDE_CMD_ = {
+ "nmake" : '!INCLUDE',
+ "gmake" : "include"
+ }
+
+ _INC_FLAG_ = {"MSFT" : "/I", "GCC" : "-I", "INTEL" : "-I", "RVCT" : "-I"}
+
+ ## Constructor of BuildFile
+ #
+ # @param AutoGenObject Object of AutoGen class
+ #
+ def __init__(self, AutoGenObject):
+ self._AutoGenObject = AutoGenObject
+ self._FileType = gMakeType
+
+ ## Create build file
+ #
+ # @param FileType Type of build file. Only nmake and gmake are supported now.
+ #
+ # @retval TRUE The build file is created or re-created successfully
+ # @retval FALSE The build file exists and is the same as the one to be generated
+ #
+ def Generate(self, FileType=gMakeType):
+ if FileType not in self._FILE_NAME_:
+ EdkLogger.error("build", PARAMETER_INVALID, "Invalid build type [%s]" % FileType,
+ ExtraData="[%s]" % str(self._AutoGenObject))
+ self._FileType = FileType
+ FileContent = self._TEMPLATE_.Replace(self._TemplateDict)
+ FileName = self._FILE_NAME_[FileType]
+ return SaveFileOnChange(os.path.join(self._AutoGenObject.MakeFileDir, FileName), FileContent, False)
+
+ ## Return a list of directory creation command string
+ #
+ # @param DirList The list of directory to be created
+ #
+ # @retval list The directory creation command list
+ #
+ def GetCreateDirectoryCommand(self, DirList):
+ return [self._MD_TEMPLATE_[self._FileType] % {'dir':Dir} for Dir in DirList]
+
+ ## Return a list of directory removal command string
+ #
+ # @param DirList The list of directory to be removed
+ #
+ # @retval list The directory removal command list
+ #
+ def GetRemoveDirectoryCommand(self, DirList):
+ return [self._RD_TEMPLATE_[self._FileType] % {'dir':Dir} for Dir in DirList]
+
+ def PlaceMacro(self, Path, MacroDefinitions={}):
+ if Path.startswith("$("):
+ return Path
+ else:
+ PathLength = len(Path)
+ for MacroName in MacroDefinitions:
+ MacroValue = MacroDefinitions[MacroName]
+ MacroValueLength = len(MacroValue)
+ if MacroValueLength <= PathLength and Path.startswith(MacroValue):
+ Path = "$(%s)%s" % (MacroName, Path[MacroValueLength:])
+ break
+ return Path
+
+## ModuleMakefile class
+#
+# This class encapsules makefie and its generation for module. It uses template to generate
+# the content of makefile. The content of makefile will be got from ModuleAutoGen object.
+#
+class ModuleMakefile(BuildFile):
+ ## template used to generate the makefile for module
+ _TEMPLATE_ = TemplateString('''\
+${makefile_header}
+
+#
+# Platform Macro Definition
+#
+PLATFORM_NAME = ${platform_name}
+PLATFORM_GUID = ${platform_guid}
+PLATFORM_VERSION = ${platform_version}
+PLATFORM_RELATIVE_DIR = ${platform_relative_directory}
+PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}
+PLATFORM_OUTPUT_DIR = ${platform_output_directory}
+
+#
+# Module Macro Definition
+#
+MODULE_NAME = ${module_name}
+MODULE_GUID = ${module_guid}
+MODULE_VERSION = ${module_version}
+MODULE_TYPE = ${module_type}
+MODULE_FILE = ${module_file}
+MODULE_FILE_BASE_NAME = ${module_file_base_name}
+BASE_NAME = $(MODULE_NAME)
+MODULE_RELATIVE_DIR = ${module_relative_directory}
+MODULE_DIR = $(WORKSPACE)${separator}${module_relative_directory}
+
+MODULE_ENTRY_POINT = ${module_entry_point}
+ARCH_ENTRY_POINT = ${arch_entry_point}
+IMAGE_ENTRY_POINT = ${image_entry_point}
+
+${BEGIN}${module_extra_defines}
+${END}
+#
+# Build Configuration Macro Definition
+#
+ARCH = ${architecture}
+TOOLCHAIN = ${toolchain_tag}
+TOOLCHAIN_TAG = ${toolchain_tag}
+TARGET = ${build_target}
+
+#
+# Build Directory Macro Definition
+#
+# PLATFORM_BUILD_DIR = ${platform_build_directory}
+BUILD_DIR = ${platform_build_directory}
+BIN_DIR = $(BUILD_DIR)${separator}${architecture}
+LIB_DIR = $(BIN_DIR)
+MODULE_BUILD_DIR = ${module_build_directory}
+OUTPUT_DIR = ${module_output_directory}
+DEBUG_DIR = ${module_debug_directory}
+DEST_DIR_OUTPUT = $(OUTPUT_DIR)
+DEST_DIR_DEBUG = $(DEBUG_DIR)
+
+#
+# Shell Command Macro
+#
+${BEGIN}${shell_command_code} = ${shell_command}
+${END}
+
+#
+# Tools definitions specific to this module
+#
+${BEGIN}${module_tool_definitions}
+${END}
+MAKE_FILE = ${makefile_path}
+
+#
+# Build Macro
+#
+${BEGIN}${file_macro}
+${END}
+
+COMMON_DEPS = ${BEGIN}${common_dependency_file} \\
+ ${END}
+
+#
+# Overridable Target Macro Definitions
+#
+FORCE_REBUILD = force_build
+INIT_TARGET = init
+PCH_TARGET =
+BC_TARGET = ${BEGIN}${backward_compatible_target} ${END}
+CODA_TARGET = ${BEGIN}${remaining_build_target} \\
+ ${END}
+
+#
+# Default target, which will build dependent libraries in addition to source files
+#
+
+all: mbuild
+
+
+#
+# Target used when called from platform makefile, which will bypass the build of dependent libraries
+#
+
+pbuild: $(INIT_TARGET) $(BC_TARGET) $(PCH_TARGET) $(CODA_TARGET)
+
+#
+# ModuleTarget
+#
+
+mbuild: $(INIT_TARGET) $(BC_TARGET) gen_libs $(PCH_TARGET) $(CODA_TARGET)
+
+#
+# Build Target used in multi-thread build mode, which will bypass the init and gen_libs targets
+#
+
+tbuild: $(BC_TARGET) $(PCH_TARGET) $(CODA_TARGET)
+
+#
+# Phony target which is used to force executing commands for a target
+#
+force_build:
+\t-@
+
+#
+# Target to update the FD
+#
+
+fds: mbuild gen_fds
+
+#
+# Initialization target: print build information and create necessary directories
+#
+init: info dirs
+
+info:
+\t-@echo Building ... $(MODULE_DIR)${separator}$(MODULE_FILE) [$(ARCH)]
+
+dirs:
+${BEGIN}\t-@${create_directory_command}\n${END}
+
+strdefs:
+\t-@$(CP) $(DEBUG_DIR)${separator}AutoGen.h $(DEBUG_DIR)${separator}$(MODULE_NAME)StrDefs.h
+
+#
+# GenLibsTarget
+#
+gen_libs:
+\t${BEGIN}@"$(MAKE)" $(MAKE_FLAGS) -f ${dependent_library_build_directory}${separator}${makefile_name}
+\t${END}@cd $(MODULE_BUILD_DIR)
+
+#
+# Build Flash Device Image
+#
+gen_fds:
+\t@"$(MAKE)" $(MAKE_FLAGS) -f $(BUILD_DIR)${separator}${makefile_name} fds
+\t@cd $(MODULE_BUILD_DIR)
+
+#
+# Individual Object Build Targets
+#
+${BEGIN}${file_build_target}
+${END}
+
+#
+# clean all intermediate files
+#
+clean:
+\t${BEGIN}${clean_command}
+\t${END}
+
+#
+# clean all generated files
+#
+cleanall:
+${BEGIN}\t${cleanall_command}
+${END}\t$(RM) *.pdb *.idb > NUL 2>&1
+\t$(RM) $(BIN_DIR)${separator}$(MODULE_NAME).efi
+
+#
+# clean all dependent libraries built
+#
+cleanlib:
+\t${BEGIN}-@${library_build_command} cleanall
+\t${END}@cd $(MODULE_BUILD_DIR)\n\n''')
+
+ _FILE_MACRO_TEMPLATE = TemplateString("${macro_name} = ${BEGIN} \\\n ${source_file}${END}\n")
+ _BUILD_TARGET_TEMPLATE = TemplateString("${BEGIN}${target} : ${deps}\n${END}\t${cmd}\n")
+
+ ## Constructor of ModuleMakefile
+ #
+ # @param ModuleAutoGen Object of ModuleAutoGen class
+ #
+ def __init__(self, ModuleAutoGen):
+ BuildFile.__init__(self, ModuleAutoGen)
+ self.PlatformInfo = self._AutoGenObject.PlatformInfo
+
+ self.ResultFileList = []
+ self.IntermediateDirectoryList = ["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]
+
+ self.SourceFileDatabase = {} # {file type : file path}
+ self.DestFileDatabase = {} # {file type : file path}
+ self.FileBuildTargetList = [] # [(src, target string)]
+ self.BuildTargetList = [] # [target string]
+ self.PendingBuildTargetList = [] # [FileBuildRule objects]
+ self.CommonFileDependency = []
+ self.FileListMacros = {}
+ self.ListFileMacros = {}
+
+ self.FileCache = {}
+ self.FileDependency = []
+ self.LibraryBuildCommandList = []
+ self.LibraryFileList = []
+ self.LibraryMakefileList = []
+ self.LibraryBuildDirectoryList = []
+ self.SystemLibraryList = []
+ self.Macros = sdict()
+ self.Macros["OUTPUT_DIR" ] = self._AutoGenObject.Macros["OUTPUT_DIR"]
+ self.Macros["DEBUG_DIR" ] = self._AutoGenObject.Macros["DEBUG_DIR"]
+ self.Macros["MODULE_BUILD_DIR"] = self._AutoGenObject.Macros["MODULE_BUILD_DIR"]
+ self.Macros["BIN_DIR" ] = self._AutoGenObject.Macros["BIN_DIR"]
+ self.Macros["BUILD_DIR" ] = self._AutoGenObject.Macros["BUILD_DIR"]
+ self.Macros["WORKSPACE" ] = self._AutoGenObject.Macros["WORKSPACE"]
+
+ # Compose a dict object containing information used to do replacement in template
+ def _CreateTemplateDict(self):
+ if self._FileType not in self._SEP_:
+ EdkLogger.error("build", PARAMETER_INVALID, "Invalid Makefile type [%s]" % self._FileType,
+ ExtraData="[%s]" % str(self._AutoGenObject))
+ Separator = self._SEP_[self._FileType]
+
+ # break build if no source files and binary files are found
+ if len(self._AutoGenObject.SourceFileList) == 0 and len(self._AutoGenObject.BinaryFileList) == 0:
+ EdkLogger.error("build", AUTOGEN_ERROR, "No files to be built in module [%s, %s, %s]"
+ % (self._AutoGenObject.BuildTarget, self._AutoGenObject.ToolChain, self._AutoGenObject.Arch),
+ ExtraData="[%s]" % str(self._AutoGenObject))
+
+ # convert dependent libraries to build command
+ self.ProcessDependentLibrary()
+ if len(self._AutoGenObject.Module.ModuleEntryPointList) > 0:
+ ModuleEntryPoint = self._AutoGenObject.Module.ModuleEntryPointList[0]
+ else:
+ ModuleEntryPoint = "_ModuleEntryPoint"
+
+ # Intel EBC compiler enforces EfiMain
+ if self._AutoGenObject.AutoGenVersion < 0x00010005 and self._AutoGenObject.Arch == "EBC":
+ ArchEntryPoint = "EfiMain"
+ else:
+ ArchEntryPoint = ModuleEntryPoint
+
+ if self._AutoGenObject.Arch == "EBC":
+ # EBC compiler always use "EfiStart" as entry point. Only applies to EdkII modules
+ ImageEntryPoint = "EfiStart"
+ elif self._AutoGenObject.AutoGenVersion < 0x00010005:
+ # Edk modules use entry point specified in INF file
+ ImageEntryPoint = ModuleEntryPoint
+ else:
+ # EdkII modules always use "_ModuleEntryPoint" as entry point
+ ImageEntryPoint = "_ModuleEntryPoint"
+
+ # tools definitions
+ ToolsDef = []
+ IncPrefix = self._INC_FLAG_[self._AutoGenObject.ToolChainFamily]
+ for Tool in self._AutoGenObject.BuildOption:
+ for Attr in self._AutoGenObject.BuildOption[Tool]:
+ Value = self._AutoGenObject.BuildOption[Tool][Attr]
+ if Attr == "FAMILY":
+ continue
+ elif Attr == "PATH":
+ ToolsDef.append("%s = %s" % (Tool, Value))
+ else:
+ # Don't generate MAKE_FLAGS in makefile. It's put in environment variable.
+ if Tool == "MAKE":
+ continue
+ # Remove duplicated include path, if any
+ if Attr == "FLAGS":
+ Value = RemoveDupOption(Value, IncPrefix, self._AutoGenObject.IncludePathList)
+ ToolsDef.append("%s_%s = %s" % (Tool, Attr, Value))
+ ToolsDef.append("")
+
+ # convert source files and binary files to build targets
+ self.ResultFileList = [str(T.Target) for T in self._AutoGenObject.CodaTargetList]
+ if len(self.ResultFileList) == 0 and len(self._AutoGenObject.SourceFileList) <> 0:
+ EdkLogger.error("build", AUTOGEN_ERROR, "Nothing to build",
+ ExtraData="[%s]" % str(self._AutoGenObject))
+
+ self.ProcessBuildTargetList()
+
+ # Generate macros used to represent input files
+ FileMacroList = [] # macro name = file list
+ for FileListMacro in self.FileListMacros:
+ FileMacro = self._FILE_MACRO_TEMPLATE.Replace(
+ {
+ "macro_name" : FileListMacro,
+ "source_file" : self.FileListMacros[FileListMacro]
+ }
+ )
+ FileMacroList.append(FileMacro)
+
+ # INC_LIST is special
+ FileMacro = ""
+ IncludePathList = []
+ for P in self._AutoGenObject.IncludePathList:
+ IncludePathList.append(IncPrefix+self.PlaceMacro(P, self.Macros))
+ if FileBuildRule.INC_LIST_MACRO in self.ListFileMacros:
+ self.ListFileMacros[FileBuildRule.INC_LIST_MACRO].append(IncPrefix+P)
+ FileMacro += self._FILE_MACRO_TEMPLATE.Replace(
+ {
+ "macro_name" : "INC",
+ "source_file" : IncludePathList
+ }
+ )
+ FileMacroList.append(FileMacro)
+
+ # Generate macros used to represent files containing list of input files
+ for ListFileMacro in self.ListFileMacros:
+ ListFileName = os.path.join(self._AutoGenObject.OutputDir, "%s.lst" % ListFileMacro.lower()[:len(ListFileMacro)-5])
+ FileMacroList.append("%s = %s" % (ListFileMacro, ListFileName))
+ SaveFileOnChange(
+ ListFileName,
+ "\n".join(self.ListFileMacros[ListFileMacro]),
+ False
+ )
+
+ # Edk modules need <BaseName>StrDefs.h for string ID
+ #if self._AutoGenObject.AutoGenVersion < 0x00010005 and len(self._AutoGenObject.UnicodeFileList) > 0:
+ # BcTargetList = ['strdefs']
+ #else:
+ # BcTargetList = []
+ BcTargetList = []
+
+ MakefileName = self._FILE_NAME_[self._FileType]
+ LibraryMakeCommandList = []
+ for D in self.LibraryBuildDirectoryList:
+ Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":os.path.join(D, MakefileName)}
+ LibraryMakeCommandList.append(Command)
+
+ MakefileTemplateDict = {
+ "makefile_header" : self._FILE_HEADER_[self._FileType],
+ "makefile_path" : os.path.join("$(MODULE_BUILD_DIR)", MakefileName),
+ "makefile_name" : MakefileName,
+ "platform_name" : self.PlatformInfo.Name,
+ "platform_guid" : self.PlatformInfo.Guid,
+ "platform_version" : self.PlatformInfo.Version,
+ "platform_relative_directory": self.PlatformInfo.SourceDir,
+ "platform_output_directory" : self.PlatformInfo.OutputDir,
+
+ "module_name" : self._AutoGenObject.Name,
+ "module_guid" : self._AutoGenObject.Guid,
+ "module_version" : self._AutoGenObject.Version,
+ "module_type" : self._AutoGenObject.ModuleType,
+ "module_file" : self._AutoGenObject.MetaFile.Name,
+ "module_file_base_name" : self._AutoGenObject.MetaFile.BaseName,
+ "module_relative_directory" : self._AutoGenObject.SourceDir,
+ "module_extra_defines" : ["%s = %s" % (k, v) for k,v in self._AutoGenObject.Module.Defines.iteritems()],
+
+ "architecture" : self._AutoGenObject.Arch,
+ "toolchain_tag" : self._AutoGenObject.ToolChain,
+ "build_target" : self._AutoGenObject.BuildTarget,
+
+ "platform_build_directory" : self.PlatformInfo.BuildDir,
+ "module_build_directory" : self._AutoGenObject.BuildDir,
+ "module_output_directory" : self._AutoGenObject.OutputDir,
+ "module_debug_directory" : self._AutoGenObject.DebugDir,
+
+ "separator" : Separator,
+ "module_tool_definitions" : ToolsDef,
+
+ "shell_command_code" : self._SHELL_CMD_[self._FileType].keys(),
+ "shell_command" : self._SHELL_CMD_[self._FileType].values(),
+
+ "module_entry_point" : ModuleEntryPoint,
+ "image_entry_point" : ImageEntryPoint,
+ "arch_entry_point" : ArchEntryPoint,
+ "remaining_build_target" : self.ResultFileList,
+ "common_dependency_file" : self.CommonFileDependency,
+ "create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
+ "clean_command" : self.GetRemoveDirectoryCommand(["$(OUTPUT_DIR)"]),
+ "cleanall_command" : self.GetRemoveDirectoryCommand(["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]),
+ "dependent_library_build_directory" : self.LibraryBuildDirectoryList,
+ "library_build_command" : LibraryMakeCommandList,
+ "file_macro" : FileMacroList,
+ "file_build_target" : self.BuildTargetList,
+ "backward_compatible_target": BcTargetList,
+ }
+
+ return MakefileTemplateDict
+
+ def ProcessBuildTargetList(self):
+ #
+ # Search dependency file list for each source file
+ #
+ ForceIncludedFile = []
+ for File in self._AutoGenObject.AutoGenFileList:
+ if File.Ext == '.h':
+ ForceIncludedFile.append(File)
+ SourceFileList = []
+ for Target in self._AutoGenObject.IntroTargetList:
+ SourceFileList.extend(Target.Inputs)
+
+ self.FileDependency = self.GetFileDependency(
+ SourceFileList,
+ ForceIncludedFile,
+ self._AutoGenObject.IncludePathList + self._AutoGenObject.BuildOptionIncPathList
+ )
+ DepSet = None
+ for File in self.FileDependency:
+ if not self.FileDependency[File]:
+ self.FileDependency[File] = ['$(FORCE_REBUILD)']
+ continue
+ # skip non-C files
+ if File.Ext not in [".c", ".C"] or File.Name == "AutoGen.c":
+ continue
+ elif DepSet == None:
+ DepSet = set(self.FileDependency[File])
+ else:
+ DepSet &= set(self.FileDependency[File])
+ # in case nothing in SourceFileList
+ if DepSet == None:
+ DepSet = set()
+ #
+ # Extract common files list in the dependency files
+ #
+ for File in DepSet:
+ self.CommonFileDependency.append(self.PlaceMacro(File.Path, self.Macros))
+
+ for File in self.FileDependency:
+ # skip non-C files
+ if File.Ext not in [".c", ".C"] or File.Name == "AutoGen.c":
+ continue
+ NewDepSet = set(self.FileDependency[File])
+ NewDepSet -= DepSet
+ self.FileDependency[File] = ["$(COMMON_DEPS)"] + list(NewDepSet)
+
+ # Convert target description object to target string in makefile
+ for Type in self._AutoGenObject.Targets:
+ for T in self._AutoGenObject.Targets[Type]:
+ # Generate related macros if needed
+ if T.GenFileListMacro and T.FileListMacro not in self.FileListMacros:
+ self.FileListMacros[T.FileListMacro] = []
+ if T.GenListFile and T.ListFileMacro not in self.ListFileMacros:
+ self.ListFileMacros[T.ListFileMacro] = []
+ if T.GenIncListFile and T.IncListFileMacro not in self.ListFileMacros:
+ self.ListFileMacros[T.IncListFileMacro] = []
+
+ Deps = []
+ # Add force-dependencies
+ for Dep in T.Dependencies:
+ Deps.append(self.PlaceMacro(str(Dep), self.Macros))
+ # Add inclusion-dependencies
+ if len(T.Inputs) == 1 and T.Inputs[0] in self.FileDependency:
+ for F in self.FileDependency[T.Inputs[0]]:
+ Deps.append(self.PlaceMacro(str(F), self.Macros))
+ # Add source-dependencies
+ for F in T.Inputs:
+ NewFile = self.PlaceMacro(str(F), self.Macros)
+ # In order to use file list macro as dependency
+ if T.GenListFile:
+ self.ListFileMacros[T.ListFileMacro].append(str(F))
+ self.FileListMacros[T.FileListMacro].append(NewFile)
+ elif T.GenFileListMacro:
+ self.FileListMacros[T.FileListMacro].append(NewFile)
+ else:
+ Deps.append(NewFile)
+
+ # Use file list macro as dependency
+ if T.GenFileListMacro:
+ Deps.append("$(%s)" % T.FileListMacro)
+
+ TargetDict = {
+ "target" : self.PlaceMacro(T.Target.Path, self.Macros),
+ "cmd" : "\n\t".join(T.Commands),
+ "deps" : Deps
+ }
+ self.BuildTargetList.append(self._BUILD_TARGET_TEMPLATE.Replace(TargetDict))
+
+ ## For creating makefile targets for dependent libraries
+ def ProcessDependentLibrary(self):
+ for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:
+ self.LibraryBuildDirectoryList.append(self.PlaceMacro(LibraryAutoGen.BuildDir, self.Macros))
+
+ ## Return a list containing source file's dependencies
+ #
+ # @param FileList The list of source files
+ # @param ForceInculeList The list of files which will be included forcely
+ # @param SearchPathList The list of search path
+ #
+ # @retval dict The mapping between source file path and its dependencies
+ #
+ def GetFileDependency(self, FileList, ForceInculeList, SearchPathList):
+ Dependency = {}
+ for F in FileList:
+ Dependency[F] = self.GetDependencyList(F, ForceInculeList, SearchPathList)
+ return Dependency
+
+ ## Find dependencies for one source file
+ #
+ # By searching recursively "#include" directive in file, find out all the
+ # files needed by given source file. The dependecies will be only searched
+ # in given search path list.
+ #
+ # @param File The source file
+ # @param ForceInculeList The list of files which will be included forcely
+ # @param SearchPathList The list of search path
+ #
+ # @retval list The list of files the given source file depends on
+ #
+ def GetDependencyList(self, File, ForceList, SearchPathList):
+ EdkLogger.debug(EdkLogger.DEBUG_1, "Try to get dependency files for %s" % File)
+ FileStack = [File] + ForceList
+ DependencySet = set()
+
+ if self._AutoGenObject.Arch not in gDependencyDatabase:
+ gDependencyDatabase[self._AutoGenObject.Arch] = {}
+ DepDb = gDependencyDatabase[self._AutoGenObject.Arch]
+
+ while len(FileStack) > 0:
+ F = FileStack.pop()
+
+ FullPathDependList = []
+ if F in self.FileCache:
+ for CacheFile in self.FileCache[F]:
+ FullPathDependList.append(CacheFile)
+ if CacheFile not in DependencySet:
+ FileStack.append(CacheFile)
+ DependencySet.update(FullPathDependList)
+ continue
+
+ CurrentFileDependencyList = []
+ if F in DepDb:
+ CurrentFileDependencyList = DepDb[F]
+ else:
+ try:
+ Fd = open(F.Path, 'r')
+ except BaseException, X:
+ EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=F.Path+"\n\t"+str(X))
+
+ FileContent = Fd.read()
+ Fd.close()
+ if len(FileContent) == 0:
+ continue
+
+ if FileContent[0] == 0xff or FileContent[0] == 0xfe:
+ FileContent = unicode(FileContent, "utf-16")
+ IncludedFileList = gIncludePattern.findall(FileContent)
+
+ for Inc in IncludedFileList:
+ Inc = Inc.strip()
+ # if there's macro used to reference header file, expand it
+ HeaderList = gMacroPattern.findall(Inc)
+ if len(HeaderList) == 1 and len(HeaderList[0]) == 2:
+ HeaderType = HeaderList[0][0]
+ HeaderKey = HeaderList[0][1]
+ if HeaderType in gIncludeMacroConversion:
+ Inc = gIncludeMacroConversion[HeaderType] % {"HeaderKey" : HeaderKey}
+ else:
+ # not known macro used in #include, always build the file by
+ # returning a empty dependency
+ self.FileCache[File] = []
+ return []
+ Inc = os.path.normpath(Inc)
+ CurrentFileDependencyList.append(Inc)
+ DepDb[F] = CurrentFileDependencyList
+
+ CurrentFilePath = F.Dir
+ PathList = [CurrentFilePath] + SearchPathList
+ for Inc in CurrentFileDependencyList:
+ for SearchPath in PathList:
+ FilePath = os.path.join(SearchPath, Inc)
+ if FilePath in gIsFileMap:
+ if not gIsFileMap[FilePath]:
+ continue
+ # If isfile is called too many times, the performance is slow down.
+ elif not os.path.isfile(FilePath):
+ gIsFileMap[FilePath] = False
+ continue
+ else:
+ gIsFileMap[FilePath] = True
+ FilePath = PathClass(FilePath)
+ FullPathDependList.append(FilePath)
+ if FilePath not in DependencySet:
+ FileStack.append(FilePath)
+ break
+ else:
+ EdkLogger.debug(EdkLogger.DEBUG_9, "%s included by %s was not found "\
+ "in any given path:\n\t%s" % (Inc, F, "\n\t".join(SearchPathList)))
+
+ self.FileCache[F] = FullPathDependList
+ DependencySet.update(FullPathDependList)
+
+ DependencySet.update(ForceList)
+ if File in DependencySet:
+ DependencySet.remove(File)
+ DependencyList = list(DependencySet) # remove duplicate ones
+
+ return DependencyList
+
+ _TemplateDict = property(_CreateTemplateDict)
+
+## CustomMakefile class
+#
+# This class encapsules makefie and its generation for module. It uses template to generate
+# the content of makefile. The content of makefile will be got from ModuleAutoGen object.
+#
+class CustomMakefile(BuildFile):
+ ## template used to generate the makefile for module with custom makefile
+ _TEMPLATE_ = TemplateString('''\
+${makefile_header}
+
+#
+# Platform Macro Definition
+#
+PLATFORM_NAME = ${platform_name}
+PLATFORM_GUID = ${platform_guid}
+PLATFORM_VERSION = ${platform_version}
+PLATFORM_RELATIVE_DIR = ${platform_relative_directory}
+PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}
+PLATFORM_OUTPUT_DIR = ${platform_output_directory}
+
+#
+# Module Macro Definition
+#
+MODULE_NAME = ${module_name}
+MODULE_GUID = ${module_guid}
+MODULE_VERSION = ${module_version}
+MODULE_TYPE = ${module_type}
+MODULE_FILE = ${module_file}
+MODULE_FILE_BASE_NAME = ${module_file_base_name}
+BASE_NAME = $(MODULE_NAME)
+MODULE_RELATIVE_DIR = ${module_relative_directory}
+MODULE_DIR = $(WORKSPACE)${separator}${module_relative_directory}
+
+#
+# Build Configuration Macro Definition
+#
+ARCH = ${architecture}
+TOOLCHAIN = ${toolchain_tag}
+TOOLCHAIN_TAG = ${toolchain_tag}
+TARGET = ${build_target}
+
+#
+# Build Directory Macro Definition
+#
+# PLATFORM_BUILD_DIR = ${platform_build_directory}
+BUILD_DIR = ${platform_build_directory}
+BIN_DIR = $(BUILD_DIR)${separator}${architecture}
+LIB_DIR = $(BIN_DIR)
+MODULE_BUILD_DIR = ${module_build_directory}
+OUTPUT_DIR = ${module_output_directory}
+DEBUG_DIR = ${module_debug_directory}
+DEST_DIR_OUTPUT = $(OUTPUT_DIR)
+DEST_DIR_DEBUG = $(DEBUG_DIR)
+
+#
+# Tools definitions specific to this module
+#
+${BEGIN}${module_tool_definitions}
+${END}
+MAKE_FILE = ${makefile_path}
+
+#
+# Shell Command Macro
+#
+${BEGIN}${shell_command_code} = ${shell_command}
+${END}
+
+${custom_makefile_content}
+
+#
+# Target used when called from platform makefile, which will bypass the build of dependent libraries
+#
+
+pbuild: init all
+
+
+#
+# ModuleTarget
+#
+
+mbuild: init all
+
+#
+# Build Target used in multi-thread build mode, which no init target is needed
+#
+
+tbuild: all
+
+#
+# Initialization target: print build information and create necessary directories
+#
+init:
+\t-@echo Building ... $(MODULE_DIR)${separator}$(MODULE_FILE) [$(ARCH)]
+${BEGIN}\t-@${create_directory_command}\n${END}\
+
+''')
+
+ ## Constructor of CustomMakefile
+ #
+ # @param ModuleAutoGen Object of ModuleAutoGen class
+ #
+ def __init__(self, ModuleAutoGen):
+ BuildFile.__init__(self, ModuleAutoGen)
+ self.PlatformInfo = self._AutoGenObject.PlatformInfo
+ self.IntermediateDirectoryList = ["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]
+
+ # Compose a dict object containing information used to do replacement in template
+ def _CreateTemplateDict(self):
+ Separator = self._SEP_[self._FileType]
+ if self._FileType not in self._AutoGenObject.CustomMakefile:
+ EdkLogger.error('build', OPTION_NOT_SUPPORTED, "No custom makefile for %s" % self._FileType,
+ ExtraData="[%s]" % str(self._AutoGenObject))
+ MakefilePath = os.path.join(
+ self._AutoGenObject.WorkspaceDir,
+ self._AutoGenObject.CustomMakefile[self._FileType]
+ )
+ try:
+ CustomMakefile = open(MakefilePath, 'r').read()
+ except:
+ EdkLogger.error('build', FILE_OPEN_FAILURE, File=str(self._AutoGenObject),
+ ExtraData=self._AutoGenObject.CustomMakefile[self._FileType])
+
+ # tools definitions
+ ToolsDef = []
+ for Tool in self._AutoGenObject.BuildOption:
+ # Don't generate MAKE_FLAGS in makefile. It's put in environment variable.
+ if Tool == "MAKE":
+ continue
+ for Attr in self._AutoGenObject.BuildOption[Tool]:
+ if Attr == "FAMILY":
+ continue
+ elif Attr == "PATH":
+ ToolsDef.append("%s = %s" % (Tool, self._AutoGenObject.BuildOption[Tool][Attr]))
+ else:
+ ToolsDef.append("%s_%s = %s" % (Tool, Attr, self._AutoGenObject.BuildOption[Tool][Attr]))
+ ToolsDef.append("")
+
+ MakefileName = self._FILE_NAME_[self._FileType]
+ MakefileTemplateDict = {
+ "makefile_header" : self._FILE_HEADER_[self._FileType],
+ "makefile_path" : os.path.join("$(MODULE_BUILD_DIR)", MakefileName),
+ "platform_name" : self.PlatformInfo.Name,
+ "platform_guid" : self.PlatformInfo.Guid,
+ "platform_version" : self.PlatformInfo.Version,
+ "platform_relative_directory": self.PlatformInfo.SourceDir,
+ "platform_output_directory" : self.PlatformInfo.OutputDir,
+
+ "module_name" : self._AutoGenObject.Name,
+ "module_guid" : self._AutoGenObject.Guid,
+ "module_version" : self._AutoGenObject.Version,
+ "module_type" : self._AutoGenObject.ModuleType,
+ "module_file" : self._AutoGenObject.MetaFile,
+ "module_file_base_name" : self._AutoGenObject.MetaFile.BaseName,
+ "module_relative_directory" : self._AutoGenObject.SourceDir,
+
+ "architecture" : self._AutoGenObject.Arch,
+ "toolchain_tag" : self._AutoGenObject.ToolChain,
+ "build_target" : self._AutoGenObject.BuildTarget,
+
+ "platform_build_directory" : self.PlatformInfo.BuildDir,
+ "module_build_directory" : self._AutoGenObject.BuildDir,
+ "module_output_directory" : self._AutoGenObject.OutputDir,
+ "module_debug_directory" : self._AutoGenObject.DebugDir,
+
+ "separator" : Separator,
+ "module_tool_definitions" : ToolsDef,
+
+ "shell_command_code" : self._SHELL_CMD_[self._FileType].keys(),
+ "shell_command" : self._SHELL_CMD_[self._FileType].values(),
+
+ "create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
+ "custom_makefile_content" : CustomMakefile
+ }
+
+ return MakefileTemplateDict
+
+ _TemplateDict = property(_CreateTemplateDict)
+
+## PlatformMakefile class
+#
+# This class encapsules makefie and its generation for platform. It uses
+# template to generate the content of makefile. The content of makefile will be
+# got from PlatformAutoGen object.
+#
+class PlatformMakefile(BuildFile):
+ ## template used to generate the makefile for platform
+ _TEMPLATE_ = TemplateString('''\
+${makefile_header}
+
+#
+# Platform Macro Definition
+#
+PLATFORM_NAME = ${platform_name}
+PLATFORM_GUID = ${platform_guid}
+PLATFORM_VERSION = ${platform_version}
+PLATFORM_FILE = ${platform_file}
+PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}
+PLATFORM_OUTPUT_DIR = ${platform_output_directory}
+
+#
+# Build Configuration Macro Definition
+#
+TOOLCHAIN = ${toolchain_tag}
+TOOLCHAIN_TAG = ${toolchain_tag}
+TARGET = ${build_target}
+
+#
+# Build Directory Macro Definition
+#
+BUILD_DIR = ${platform_build_directory}
+FV_DIR = ${platform_build_directory}${separator}FV
+
+#
+# Shell Command Macro
+#
+${BEGIN}${shell_command_code} = ${shell_command}
+${END}
+
+MAKE = ${make_path}
+MAKE_FILE = ${makefile_path}
+
+#
+# Default target
+#
+all: init build_libraries build_modules
+
+#
+# Initialization target: print build information and create necessary directories
+#
+init:
+\t-@echo Building ... $(PLATFORM_FILE) [${build_architecture_list}]
+\t${BEGIN}-@${create_directory_command}
+\t${END}
+#
+# library build target
+#
+libraries: init build_libraries
+
+#
+# module build target
+#
+modules: init build_libraries build_modules
+
+#
+# Build all libraries:
+#
+build_libraries:
+${BEGIN}\t@"$(MAKE)" $(MAKE_FLAGS) -f ${library_makefile_list} pbuild
+${END}\t@cd $(BUILD_DIR)
+
+#
+# Build all modules:
+#
+build_modules:
+${BEGIN}\t@"$(MAKE)" $(MAKE_FLAGS) -f ${module_makefile_list} pbuild
+${END}\t@cd $(BUILD_DIR)
+
+#
+# Clean intermediate files
+#
+clean:
+\t${BEGIN}-@${library_build_command} clean
+\t${END}${BEGIN}-@${module_build_command} clean
+\t${END}@cd $(BUILD_DIR)
+
+#
+# Clean all generated files except to makefile
+#
+cleanall:
+${BEGIN}\t${cleanall_command}
+${END}
+
+#
+# Clean all library files
+#
+cleanlib:
+\t${BEGIN}-@${library_build_command} cleanall
+\t${END}@cd $(BUILD_DIR)\n
+''')
+
+ ## Constructor of PlatformMakefile
+ #
+ # @param ModuleAutoGen Object of PlatformAutoGen class
+ #
+ def __init__(self, PlatformAutoGen):
+ BuildFile.__init__(self, PlatformAutoGen)
+ self.ModuleBuildCommandList = []
+ self.ModuleMakefileList = []
+ self.IntermediateDirectoryList = []
+ self.ModuleBuildDirectoryList = []
+ self.LibraryBuildDirectoryList = []
+
+ # Compose a dict object containing information used to do replacement in template
+ def _CreateTemplateDict(self):
+ Separator = self._SEP_[self._FileType]
+
+ PlatformInfo = self._AutoGenObject
+ if "MAKE" not in PlatformInfo.ToolDefinition or "PATH" not in PlatformInfo.ToolDefinition["MAKE"]:
+ EdkLogger.error("build", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!",
+ ExtraData="[%s]" % str(self._AutoGenObject))
+
+ self.IntermediateDirectoryList = ["$(BUILD_DIR)"]
+ self.ModuleBuildDirectoryList = self.GetModuleBuildDirectoryList()
+ self.LibraryBuildDirectoryList = self.GetLibraryBuildDirectoryList()
+
+ MakefileName = self._FILE_NAME_[self._FileType]
+ LibraryMakefileList = []
+ LibraryMakeCommandList = []
+ for D in self.LibraryBuildDirectoryList:
+ D = self.PlaceMacro(D, {"BUILD_DIR":PlatformInfo.BuildDir})
+ Makefile = os.path.join(D, MakefileName)
+ Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":Makefile}
+ LibraryMakefileList.append(Makefile)
+ LibraryMakeCommandList.append(Command)
+
+ ModuleMakefileList = []
+ ModuleMakeCommandList = []
+ for D in self.ModuleBuildDirectoryList:
+ D = self.PlaceMacro(D, {"BUILD_DIR":PlatformInfo.BuildDir})
+ Makefile = os.path.join(D, MakefileName)
+ Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":Makefile}
+ ModuleMakefileList.append(Makefile)
+ ModuleMakeCommandList.append(Command)
+
+ MakefileTemplateDict = {
+ "makefile_header" : self._FILE_HEADER_[self._FileType],
+ "makefile_path" : os.path.join("$(BUILD_DIR)", MakefileName),
+ "make_path" : PlatformInfo.ToolDefinition["MAKE"]["PATH"],
+ "makefile_name" : MakefileName,
+ "platform_name" : PlatformInfo.Name,
+ "platform_guid" : PlatformInfo.Guid,
+ "platform_version" : PlatformInfo.Version,
+ "platform_file" : self._AutoGenObject.MetaFile,
+ "platform_relative_directory": PlatformInfo.SourceDir,
+ "platform_output_directory" : PlatformInfo.OutputDir,
+ "platform_build_directory" : PlatformInfo.BuildDir,
+
+ "toolchain_tag" : PlatformInfo.ToolChain,
+ "build_target" : PlatformInfo.BuildTarget,
+ "shell_command_code" : self._SHELL_CMD_[self._FileType].keys(),
+ "shell_command" : self._SHELL_CMD_[self._FileType].values(),
+ "build_architecture_list" : self._AutoGenObject.Arch,
+ "architecture" : self._AutoGenObject.Arch,
+ "separator" : Separator,
+ "create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
+ "cleanall_command" : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList),
+ "library_makefile_list" : LibraryMakefileList,
+ "module_makefile_list" : ModuleMakefileList,
+ "library_build_command" : LibraryMakeCommandList,
+ "module_build_command" : ModuleMakeCommandList,
+ }
+
+ return MakefileTemplateDict
+
+ ## Get the root directory list for intermediate files of all modules build
+ #
+ # @retval list The list of directory
+ #
+ def GetModuleBuildDirectoryList(self):
+ DirList = []
+ for ModuleAutoGen in self._AutoGenObject.ModuleAutoGenList:
+ DirList.append(os.path.join(self._AutoGenObject.BuildDir, ModuleAutoGen.BuildDir))
+ return DirList
+
+ ## Get the root directory list for intermediate files of all libraries build
+ #
+ # @retval list The list of directory
+ #
+ def GetLibraryBuildDirectoryList(self):
+ DirList = []
+ for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:
+ DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))
+ return DirList
+
+ _TemplateDict = property(_CreateTemplateDict)
+
+## TopLevelMakefile class
+#
+# This class encapsules makefie and its generation for entrance makefile. It
+# uses template to generate the content of makefile. The content of makefile
+# will be got from WorkspaceAutoGen object.
+#
+class TopLevelMakefile(BuildFile):
+ ## template used to generate toplevel makefile
+ _TEMPLATE_ = TemplateString('''\
+${makefile_header}
+
+#
+# Platform Macro Definition
+#
+PLATFORM_NAME = ${platform_name}
+PLATFORM_GUID = ${platform_guid}
+PLATFORM_VERSION = ${platform_version}
+
+#
+# Build Configuration Macro Definition
+#
+TOOLCHAIN = ${toolchain_tag}
+TOOLCHAIN_TAG = ${toolchain_tag}
+TARGET = ${build_target}
+
+#
+# Build Directory Macro Definition
+#
+BUILD_DIR = ${platform_build_directory}
+FV_DIR = ${platform_build_directory}${separator}FV
+
+#
+# Shell Command Macro
+#
+${BEGIN}${shell_command_code} = ${shell_command}
+${END}
+
+MAKE = ${make_path}
+MAKE_FILE = ${makefile_path}
+
+#
+# Default target
+#
+all: modules fds
+
+#
+# Initialization target: print build information and create necessary directories
+#
+init:
+\t-@
+\t${BEGIN}-@${create_directory_command}
+\t${END}
+#
+# library build target
+#
+libraries: init
+${BEGIN}\t@cd $(BUILD_DIR)${separator}${arch} && "$(MAKE)" $(MAKE_FLAGS) libraries
+${END}\t@cd $(BUILD_DIR)
+
+#
+# module build target
+#
+modules: init
+${BEGIN}\t@cd $(BUILD_DIR)${separator}${arch} && "$(MAKE)" $(MAKE_FLAGS) modules
+${END}\t@cd $(BUILD_DIR)
+
+#
+# Flash Device Image Target
+#
+fds: init
+\t-@cd $(FV_DIR)
+${BEGIN}\tGenFds -f ${fdf_file} -o $(BUILD_DIR) -t $(TOOLCHAIN) -b $(TARGET) -p ${active_platform} -a ${build_architecture_list} ${extra_options}${END}${BEGIN} -r ${fd} ${END}${BEGIN} -i ${fv} ${END}${BEGIN} -C ${cap} ${END}${BEGIN} -D ${macro} ${END}
+
+#
+# run command for emulator platform only
+#
+run:
+\tcd $(BUILD_DIR)${separator}IA32 && ".${separator}SecMain"
+\tcd $(BUILD_DIR)
+
+#
+# Clean intermediate files
+#
+clean:
+${BEGIN}\t-@${sub_build_command} clean
+${END}\t@cd $(BUILD_DIR)
+
+#
+# Clean all generated files except to makefile
+#
+cleanall:
+${BEGIN}\t${cleanall_command}
+${END}
+
+#
+# Clean all library files
+#
+cleanlib:
+${BEGIN}\t-@${sub_build_command} cleanlib
+${END}\t@cd $(BUILD_DIR)\n
+''')
+
+ ## Constructor of TopLevelMakefile
+ #
+ # @param Workspace Object of WorkspaceAutoGen class
+ #
+ def __init__(self, Workspace):
+ BuildFile.__init__(self, Workspace)
+ self.IntermediateDirectoryList = []
+
+ # Compose a dict object containing information used to do replacement in template
+ def _CreateTemplateDict(self):
+ Separator = self._SEP_[self._FileType]
+
+ # any platform autogen object is ok because we just need common information
+ PlatformInfo = self._AutoGenObject
+
+ if "MAKE" not in PlatformInfo.ToolDefinition or "PATH" not in PlatformInfo.ToolDefinition["MAKE"]:
+ EdkLogger.error("build", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!",
+ ExtraData="[%s]" % str(self._AutoGenObject))
+
+ for Arch in PlatformInfo.ArchList:
+ self.IntermediateDirectoryList.append(Separator.join(["$(BUILD_DIR)", Arch]))
+ self.IntermediateDirectoryList.append("$(FV_DIR)")
+
+ # TRICK: for not generating GenFds call in makefile if no FDF file
+ MacroList = []
+ if PlatformInfo.FdfFile != None and PlatformInfo.FdfFile != "":
+ FdfFileList = [PlatformInfo.FdfFile]
+ # macros passed to GenFds
+ MacroList.append('"%s=%s"' % ("EFI_SOURCE", GlobalData.gEfiSource.replace('\\', '\\\\')))
+ MacroList.append('"%s=%s"' % ("EDK_SOURCE", GlobalData.gEdkSource.replace('\\', '\\\\')))
+ MacroDict = {}
+ MacroDict.update(GlobalData.gGlobalDefines)
+ MacroDict.update(GlobalData.gCommandLineDefines)
+ MacroDict.pop("EFI_SOURCE", "dummy")
+ MacroDict.pop("EDK_SOURCE", "dummy")
+ for MacroName in MacroDict:
+ if MacroDict[MacroName] != "":
+ MacroList.append('"%s=%s"' % (MacroName, MacroDict[MacroName].replace('\\', '\\\\')))
+ else:
+ MacroList.append('"%s"' % MacroName)
+ else:
+ FdfFileList = []
+
+ # pass extra common options to external program called in makefile, currently GenFds.exe
+ ExtraOption = ''
+ LogLevel = EdkLogger.GetLevel()
+ if LogLevel == EdkLogger.VERBOSE:
+ ExtraOption += " -v"
+ elif LogLevel <= EdkLogger.DEBUG_9:
+ ExtraOption += " -d %d" % (LogLevel - 1)
+ elif LogLevel == EdkLogger.QUIET:
+ ExtraOption += " -q"
+
+ if GlobalData.gCaseInsensitive:
+ ExtraOption += " -c"
+
+ MakefileName = self._FILE_NAME_[self._FileType]
+ SubBuildCommandList = []
+ for A in PlatformInfo.ArchList:
+ Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":os.path.join("$(BUILD_DIR)", A, MakefileName)}
+ SubBuildCommandList.append(Command)
+
+ MakefileTemplateDict = {
+ "makefile_header" : self._FILE_HEADER_[self._FileType],
+ "makefile_path" : os.path.join("$(BUILD_DIR)", MakefileName),
+ "make_path" : PlatformInfo.ToolDefinition["MAKE"]["PATH"],
+ "platform_name" : PlatformInfo.Name,
+ "platform_guid" : PlatformInfo.Guid,
+ "platform_version" : PlatformInfo.Version,
+ "platform_build_directory" : PlatformInfo.BuildDir,
+
+ "toolchain_tag" : PlatformInfo.ToolChain,
+ "build_target" : PlatformInfo.BuildTarget,
+ "shell_command_code" : self._SHELL_CMD_[self._FileType].keys(),
+ "shell_command" : self._SHELL_CMD_[self._FileType].values(),
+ 'arch' : list(PlatformInfo.ArchList),
+ "build_architecture_list" : ','.join(PlatformInfo.ArchList),
+ "separator" : Separator,
+ "create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
+ "cleanall_command" : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList),
+ "sub_build_command" : SubBuildCommandList,
+ "fdf_file" : FdfFileList,
+ "active_platform" : str(PlatformInfo),
+ "fd" : PlatformInfo.FdTargetList,
+ "fv" : PlatformInfo.FvTargetList,
+ "cap" : PlatformInfo.CapTargetList,
+ "extra_options" : ExtraOption,
+ "macro" : MacroList,
+ }
+
+ return MakefileTemplateDict
+
+ ## Get the root directory list for intermediate files of all modules build
+ #
+ # @retval list The list of directory
+ #
+ def GetModuleBuildDirectoryList(self):
+ DirList = []
+ for ModuleAutoGen in self._AutoGenObject.ModuleAutoGenList:
+ DirList.append(os.path.join(self._AutoGenObject.BuildDir, ModuleAutoGen.BuildDir))
+ return DirList
+
+ ## Get the root directory list for intermediate files of all libraries build
+ #
+ # @retval list The list of directory
+ #
+ def GetLibraryBuildDirectoryList(self):
+ DirList = []
+ for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:
+ DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))
+ return DirList
+
+ _TemplateDict = property(_CreateTemplateDict)
+
+# This acts like the main() function for the script, unless it is 'import'ed into another script.
+if __name__ == '__main__':
+ pass
+