X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2FAutoGen%2FBuildEngine.py;h=dd6301b01fce4dc3499b7847ae2b0a43631ae8c5;hb=a253d217ee3477fde46cadba0dfe364f9a826694;hp=b3083d0395f3f692e27f2156302029112b605108;hpb=f51461c829c124288a930829a78e2a5a799f4039;p=mirror_edk2.git diff --git a/BaseTools/Source/Python/AutoGen/BuildEngine.py b/BaseTools/Source/Python/AutoGen/BuildEngine.py index b3083d0395..dd6301b01f 100644 --- a/BaseTools/Source/Python/AutoGen/BuildEngine.py +++ b/BaseTools/Source/Python/AutoGen/BuildEngine.py @@ -1,7 +1,7 @@ ## @file # The engine for building files # -# Copyright (c) 2007, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
# This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License # which accompanies this distribution. The full text of the license may be found at @@ -14,10 +14,11 @@ ## # Import Modules # -import os +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 * @@ -46,21 +47,10 @@ 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.InitWorker(Inputs, Outputs, Commands, Dependencies) - def _Init(self, Inputs, Outputs, Commands, Dependencies): + def InitWorker(self, Inputs, Outputs, Commands, Dependencies): self.Inputs = Inputs self.Outputs = Outputs self.Commands = Commands @@ -89,10 +79,6 @@ class TargetDescBlock(object): 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 @@ -160,7 +146,7 @@ class FileBuildRule: # Check input files self.IsMultipleInput = False - self.SourceFileExtList = [] + self.SourceFileExtList = set() for File in Input: Base, Ext = os.path.splitext(File) if Base.find("*") >= 0: @@ -171,8 +157,7 @@ class FileBuildRule: # There's no "*" and "?" in file name self.ExtraSourceFileList.append(File) continue - if Ext not in self.SourceFileExtList: - self.SourceFileExtList.append(Ext) + self.SourceFileExtList.add(Ext) # Check output files self.DestFileList = [] @@ -193,16 +178,6 @@ class FileBuildRule: 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 = {} @@ -219,7 +194,7 @@ class FileBuildRule: # # @retval tuple (Source file in full path, List of individual sourcefiles, Destionation file, List of build commands) # - def Apply(self, SourceFile): + def Apply(self, SourceFile, BuildRuleOrder=None): if not self.CommandList or not self.DestFileList: return None @@ -280,13 +255,20 @@ class FileBuildRule: if DstFile[0] in self.BuildTargets: TargetDesc = self.BuildTargets[DstFile[0]] - TargetDesc.AddInput(SourceFile) + 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 = [] - for CommandString in self.CommandList: - CommandString = string.Template(CommandString).safe_substitute(BuildRulePlaceholderDict) - CommandString = string.Template(CommandString).safe_substitute(BuildRulePlaceholderDict) - CommandList.append(CommandString) + CommandList = self._BuildCommand(BuildRulePlaceholderDict) TargetDesc = TargetDescBlock([SourceFile], DstFile, CommandList, self.ExtraSourceFileList) TargetDesc.ListFileMacro = self.ListFileMacro TargetDesc.FileListMacro = self.FileListMacro @@ -297,6 +279,14 @@ class FileBuildRule: 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 @@ -330,12 +320,12 @@ class BuildRule: 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: + if File is not None: try: self.RuleContent = open(File, 'r').readlines() except: EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=File) - elif Content != None: + elif Content is not None: self.RuleContent = Content else: EdkLogger.error("build", PARAMETER_MISSING, ExtraData="No rule file or string given") @@ -349,8 +339,8 @@ class BuildRule: self._State = "" self._RuleInfo = tdict(True, 2) # {toolchain family : {"InputFile": {}, "OutputFile" : [], "Command" : []}} self._FileType = '' - self._BuildTypeList = [] - self._ArchList = [] + self._BuildTypeList = set() + self._ArchList = set() self._FamilyList = [] self._TotalToolChainFamilySet = set() self._RuleObjectList = [] # FileBuildRule object list @@ -359,7 +349,7 @@ class BuildRule: self.Parse() # some intrinsic rules - self.RuleDatabase[TAB_DEFAULT_BINARY_FILE, "COMMON", "COMMON", "COMMON"] = self._BinaryFileRule + 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 @@ -372,7 +362,7 @@ class BuildRule: # 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(): + 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] == "#": @@ -419,8 +409,8 @@ class BuildRule: 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') + 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] @@ -440,30 +430,30 @@ class BuildRule: # def ParseSectionHeader(self, LineIndex): self._RuleInfo = tdict(True, 2) - self._BuildTypeList = [] - self._ArchList = [] + self._BuildTypeList = set() + self._ArchList = set() self._FamilyList = [] self._TotalToolChainFamilySet = set() FileType = '' RuleNameList = self.RuleContent[LineIndex][1:-1].split(',') for RuleName in RuleNameList: - Arch = 'COMMON' - BuildType = 'COMMON' + 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, + 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, + 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, + 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: @@ -472,26 +462,24 @@ class BuildRule: 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, + 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) + self._BuildTypeList.add(BuildType) + self._ArchList.add(Arch) - if 'COMMON' in self._BuildTypeList and len(self._BuildTypeList) > 1: + 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, + File=self.RuleFile, Line=LineIndex + 1, ExtraData=self.RuleContent[LineIndex]) - if 'COMMON' in self._ArchList and len(self._ArchList) > 1: + 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, + File=self.RuleFile, Line=LineIndex + 1, ExtraData=self.RuleContent[LineIndex]) self._FileType = FileType @@ -515,13 +503,13 @@ class BuildRule: 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, + File=self.RuleFile, Line=LineIndex + 1, ExtraData=self.RuleContent[LineIndex]) if len(TokenList) > 1: Family = TokenList[1].strip().upper() else: - Family = "COMMON" + Family = TAB_COMMON if Family not in FamilyList: FamilyList.append(Family) @@ -529,13 +517,13 @@ class BuildRule: self._FamilyList = FamilyList self._TotalToolChainFamilySet.update(FamilyList) self._State = SectionType.upper() - if 'COMMON' in FamilyList and len(FamilyList) > 1: + 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, + 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, + EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex + 1, ExtraData="Unknown subsection: %s" % self.RuleContent[LineIndex]) ## Parse sub-section # @@ -545,7 +533,7 @@ class BuildRule: FileList = [File.strip() for File in self.RuleContent[LineIndex].split(",")] for ToolChainFamily in self._FamilyList: InputFiles = self._RuleInfo[ToolChainFamily, self._State] - if InputFiles == None: + if InputFiles is None: InputFiles = [] self._RuleInfo[ToolChainFamily, self._State] = InputFiles InputFiles.extend(FileList) @@ -557,7 +545,7 @@ class BuildRule: def ParseCommon(self, LineIndex): for ToolChainFamily in self._FamilyList: Items = self._RuleInfo[ToolChainFamily, self._State] - if Items == None: + if Items is None: Items = [] self._RuleInfo[ToolChainFamily, self._State] = Items Items.append(self.RuleContent[LineIndex]) @@ -609,11 +597,11 @@ if __name__ == '__main__': EdkLogger.Initialize() if len(sys.argv) > 1: Br = BuildRule(sys.argv[1]) - print str(Br[".c", "DXE_DRIVER", "IA32", "MSFT"][1]) + print str(Br[".c", SUP_MODULE_DXE_DRIVER, "IA32", "MSFT"][1]) print - print str(Br[".c", "DXE_DRIVER", "IA32", "INTEL"][1]) + print str(Br[".c", SUP_MODULE_DXE_DRIVER, "IA32", "INTEL"][1]) print - print str(Br[".c", "DXE_DRIVER", "IA32", "GCC"][1]) + print str(Br[".c", SUP_MODULE_DXE_DRIVER, "IA32", "GCC"][1]) print print str(Br[".ac", "ACPI_TABLE", "IA32", "MSFT"][1]) print @@ -621,7 +609,7 @@ if __name__ == '__main__': print print str(Br[".ac", "ACPI_TABLE", "IA32", "MSFT"][1]) print - print str(Br[".s", "SEC", "IPF", "COMMON"][1]) + print str(Br[".s", SUP_MODULE_SEC, "IPF", "COMMON"][1]) print - print str(Br[".s", "SEC"][1]) + print str(Br[".s", SUP_MODULE_SEC][1])