| ## @file | |
| # The engine for building files | |
| # | |
| # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> | |
| # SPDX-License-Identifier: BSD-2-Clause-Patent | |
| # | |
| ## | |
| # Import Modules | |
| # | |
| from __future__ import print_function | |
| import Common.LongFilePathOs as os | |
| import re | |
| import copy | |
| import string | |
| from Common.LongFilePathSupport import OpenLongFilePath as open | |
| from Common.GlobalData import * | |
| from Common.BuildToolError import * | |
| from Common.Misc import tdict, PathClass | |
| from Common.StringUtils import NormPath | |
| from Common.DataType import * | |
| from Common.TargetTxtClassObject import TargetTxtDict | |
| gDefaultBuildRuleFile = 'build_rule.txt' | |
| AutoGenReqBuildRuleVerNum = '0.1' | |
| 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): | |
| def __init__(self, Inputs, Outputs, Commands, Dependencies): | |
| self.InitWorker(Inputs, Outputs, Commands, Dependencies) | |
| def InitWorker(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 isinstance(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 | |
| ## 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 representing input file(s) for a rule | |
| # @param Output The list representing 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 TAB_STAR 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 = set() | |
| for File in Input: | |
| Base, Ext = os.path.splitext(File) | |
| if Base.find(TAB_STAR) >= 0: | |
| # There's TAB_STAR in the file name | |
| self.IsMultipleInput = True | |
| self.GenFileListMacro = True | |
| elif Base.find("?") < 0: | |
| # There's no TAB_STAR and "?" in file name | |
| self.ExtraSourceFileList.append(File) | |
| continue | |
| self.SourceFileExtList.add(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([str(i) for i in self.DestFileList]) | |
| CommandString = "\n\t".join(self.CommandList) | |
| return "%s : %s\n\t%s" % (DestString, SourceString, CommandString) | |
| def Instantiate(self, Macros = None): | |
| if Macros is None: | |
| 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, Destination file, List of build commands) | |
| # | |
| def Apply(self, SourceFile, BuildRuleOrder=None): | |
| 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]] | |
| if BuildRuleOrder and SourceFile.Ext in BuildRuleOrder: | |
| Index = BuildRuleOrder.index(SourceFile.Ext) | |
| for Input in TargetDesc.Inputs: | |
| if Input.Ext not in BuildRuleOrder or BuildRuleOrder.index(Input.Ext) > Index: | |
| # | |
| # Command line should be regenerated since some macros are different | |
| # | |
| CommandList = self._BuildCommand(BuildRulePlaceholderDict) | |
| TargetDesc.InitWorker([SourceFile], DstFile, CommandList, self.ExtraSourceFileList) | |
| break | |
| else: | |
| TargetDesc.AddInput(SourceFile) | |
| else: | |
| CommandList = self._BuildCommand(BuildRulePlaceholderDict) | |
| 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 | |
| def _BuildCommand(self, Macros): | |
| CommandList = [] | |
| for CommandString in self.CommandList: | |
| CommandString = string.Template(CommandString).safe_substitute(Macros) | |
| CommandString = string.Template(CommandString).safe_substitute(Macros) | |
| CommandList.append(CommandString) | |
| return CommandList | |
| ## 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=[TAB_COMPILER_MSFT, "INTEL", "GCC"]): | |
| self.RuleFile = File | |
| # Read build rules from file if it's not none | |
| if File is not None: | |
| try: | |
| self.RuleContent = open(File, 'r').readlines() | |
| except: | |
| EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=File) | |
| elif Content is not 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 = set() | |
| self._ArchList = set() | |
| self._FamilyList = [] | |
| self._TotalToolChainFamilySet = set() | |
| self._RuleObjectList = [] # FileBuildRule object list | |
| self._FileVersion = "" | |
| self.Parse() | |
| # some intrinsic rules | |
| self.RuleDatabase[TAB_DEFAULT_BINARY_FILE, TAB_COMMON, TAB_COMMON, TAB_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): | |
| # currently 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 toolchain family, 'COMMON' doesn't make sense any more | |
| if len(self._TotalToolChainFamilySet) > 1 and TAB_COMMON in self._TotalToolChainFamilySet: | |
| self._TotalToolChainFamilySet.remove(TAB_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 = set() | |
| self._ArchList = set() | |
| self._FamilyList = [] | |
| self._TotalToolChainFamilySet = set() | |
| FileType = '' | |
| RuleNameList = self.RuleContent[LineIndex][1:-1].split(',') | |
| for RuleName in RuleNameList: | |
| Arch = TAB_COMMON | |
| BuildType = TAB_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) is 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] | |
| self._BuildTypeList.add(BuildType) | |
| self._ArchList.add(Arch) | |
| if TAB_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 TAB_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 = TAB_COMMON | |
| if Family not in FamilyList: | |
| FamilyList.append(Family) | |
| self._FamilyList = FamilyList | |
| self._TotalToolChainFamilySet.update(FamilyList) | |
| self._State = SectionType.upper() | |
| if TAB_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 ParseInputFileSubSection(self, LineIndex): | |
| FileList = [File.strip() for File in self.RuleContent[LineIndex].split(",")] | |
| for ToolChainFamily in self._FamilyList: | |
| if self._RuleInfo[ToolChainFamily, self._State] is None: | |
| self._RuleInfo[ToolChainFamily, self._State] = [] | |
| self._RuleInfo[ToolChainFamily, self._State].extend(FileList) | |
| ## Parse <ExtraDependency> sub-section | |
| ## Parse <OutputFile> sub-section | |
| ## Parse <Command> sub-section | |
| # | |
| # @param LineIndex The line index of build rule text | |
| # | |
| def ParseCommonSubSection(self, LineIndex): | |
| for ToolChainFamily in self._FamilyList: | |
| if self._RuleInfo[ToolChainFamily, self._State] is None: | |
| self._RuleInfo[ToolChainFamily, self._State] = [] | |
| self._RuleInfo[ToolChainFamily, self._State].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. TAB_STAR means any rule | |
| # is applicable. | |
| # | |
| # @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 : ParseInputFileSubSection, | |
| _OutputFile : ParseCommonSubSection, | |
| _ExtraDependency : ParseCommonSubSection, | |
| _Command : ParseCommonSubSection, | |
| _UnknownSection : SkipSection, | |
| } | |
| class ToolBuildRule(): | |
| def __new__(cls, *args, **kw): | |
| if not hasattr(cls, '_instance'): | |
| orig = super(ToolBuildRule, cls) | |
| cls._instance = orig.__new__(cls, *args, **kw) | |
| return cls._instance | |
| def __init__(self): | |
| if not hasattr(self, 'ToolBuildRule'): | |
| self._ToolBuildRule = None | |
| @property | |
| def ToolBuildRule(self): | |
| if not self._ToolBuildRule: | |
| self._GetBuildRule() | |
| return self._ToolBuildRule | |
| def _GetBuildRule(self): | |
| BuildRuleFile = None | |
| TargetObj = TargetTxtDict() | |
| TargetTxt = TargetObj.Target | |
| if TAB_TAT_DEFINES_BUILD_RULE_CONF in TargetTxt.TargetTxtDictionary: | |
| BuildRuleFile = TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_BUILD_RULE_CONF] | |
| if not BuildRuleFile: | |
| BuildRuleFile = gDefaultBuildRuleFile | |
| RetVal = BuildRule(BuildRuleFile) | |
| if RetVal._FileVersion == "": | |
| RetVal._FileVersion = AutoGenReqBuildRuleVerNum | |
| else: | |
| if RetVal._FileVersion < AutoGenReqBuildRuleVerNum : | |
| # If Build Rule's version is less than the version number required by the tools, halting the build. | |
| EdkLogger.error("build", AUTOGEN_ERROR, | |
| ExtraData="The version number [%s] of build_rule.txt is less than the version number required by the AutoGen.(the minimum required version number is [%s])"\ | |
| % (RetVal._FileVersion, AutoGenReqBuildRuleVerNum)) | |
| self._ToolBuildRule = RetVal | |
| # 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", SUP_MODULE_DXE_DRIVER, "IA32", TAB_COMPILER_MSFT][1])) | |
| print() | |
| print(str(Br[".c", SUP_MODULE_DXE_DRIVER, "IA32", "INTEL"][1])) | |
| print() | |
| print(str(Br[".c", SUP_MODULE_DXE_DRIVER, "IA32", "GCC"][1])) | |
| print() | |
| print(str(Br[".ac", "ACPI_TABLE", "IA32", TAB_COMPILER_MSFT][1])) | |
| print() | |
| print(str(Br[".h", "ACPI_TABLE", "IA32", "INTEL"][1])) | |
| print() | |
| print(str(Br[".ac", "ACPI_TABLE", "IA32", TAB_COMPILER_MSFT][1])) | |
| print() | |
| print(str(Br[".s", SUP_MODULE_SEC, "IPF", "COMMON"][1])) | |
| print() | |
| print(str(Br[".s", SUP_MODULE_SEC][1])) | |