## @file\r
# The engine for building files\r
#\r
-# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\r
-# This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution. The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php\r
-#\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
#\r
\r
##\r
# Import Modules\r
#\r
+from __future__ import print_function\r
import Common.LongFilePathOs as os\r
import re\r
import copy\r
from Common.GlobalData import *\r
from Common.BuildToolError import *\r
from Common.Misc import tdict, PathClass\r
-from Common.String import NormPath\r
+from Common.StringUtils import NormPath\r
from Common.DataType import *\r
\r
import Common.EdkLogger as EdkLogger\r
return "%s_LIST" % FileListMacro(FileType)\r
\r
class TargetDescBlock(object):\r
- _Cache_ = {} # {TargetFile : TargetDescBlock object}\r
-\r
- # Factory method\r
- def __new__(Class, Inputs, Outputs, Commands, Dependencies):\r
- if Outputs[0] in Class._Cache_:\r
- Tdb = Class._Cache_[Outputs[0]]\r
- for File in Inputs:\r
- Tdb.AddInput(File)\r
- else:\r
- Tdb = super(TargetDescBlock, Class).__new__(Class)\r
- Tdb._Init(Inputs, Outputs, Commands, Dependencies)\r
- #Class._Cache_[Outputs[0]] = Tdb\r
- return Tdb\r
+ def __init__(self, Inputs, Outputs, Commands, Dependencies):\r
+ self.InitWorker(Inputs, Outputs, Commands, Dependencies)\r
\r
- def _Init(self, Inputs, Outputs, Commands, Dependencies):\r
+ def InitWorker(self, Inputs, Outputs, Commands, Dependencies):\r
self.Inputs = Inputs\r
self.Outputs = Outputs\r
self.Commands = Commands\r
return hash(self.Target.Path)\r
\r
def __eq__(self, Other):\r
- if type(Other) == type(self):\r
+ if isinstance(Other, type(self)):\r
return Other.Target.Path == self.Target.Path\r
else:\r
return str(Other) == self.Target.Path\r
def IsMultipleInput(self):\r
return len(self.Inputs) > 1\r
\r
- @staticmethod\r
- def Renew():\r
- TargetDescBlock._Cache_ = {}\r
-\r
## Class for one build rule\r
#\r
# This represents a build rule which can give out corresponding command list for\r
\r
## constructor\r
#\r
- # @param Input The dictionary represeting input file(s) for a rule\r
- # @param Output The list represeting output file(s) for a rule\r
+ # @param Input The dictionary representing input file(s) for a rule\r
+ # @param Output The list representing output file(s) for a rule\r
# @param Command The list containing commands to generate the output from input\r
#\r
def __init__(self, Type, Input, Output, Command, ExtraDependency=None):\r
self.IncListFileMacro = self.INC_LIST_MACRO\r
\r
self.SourceFileType = Type\r
- # source files listed not in "*" or "?" pattern format\r
+ # source files listed not in TAB_STAR or "?" pattern format\r
if not ExtraDependency:\r
self.ExtraSourceFileList = []\r
else:\r
\r
# Check input files\r
self.IsMultipleInput = False\r
- self.SourceFileExtList = []\r
+ self.SourceFileExtList = set()\r
for File in Input:\r
Base, Ext = os.path.splitext(File)\r
- if Base.find("*") >= 0:\r
- # There's "*" in the file name\r
+ if Base.find(TAB_STAR) >= 0:\r
+ # There's TAB_STAR in the file name\r
self.IsMultipleInput = True\r
self.GenFileListMacro = True\r
elif Base.find("?") < 0:\r
- # There's no "*" and "?" in file name\r
+ # There's no TAB_STAR and "?" in file name\r
self.ExtraSourceFileList.append(File)\r
continue\r
- if Ext not in self.SourceFileExtList:\r
- self.SourceFileExtList.append(Ext)\r
+ self.SourceFileExtList.add(Ext)\r
\r
# Check output files\r
self.DestFileList = []\r
CommandString = "\n\t".join(self.CommandList)\r
return "%s : %s\n\t%s" % (DestString, SourceString, CommandString)\r
\r
- ## Check if given file extension is supported by this rule\r
- #\r
- # @param FileExt The extension of a file\r
- #\r
- # @retval True If the extension is supported\r
- # @retval False If the extension is not supported\r
- #\r
- def IsSupported(self, FileExt):\r
- return FileExt in self.SourceFileExtList\r
-\r
def Instantiate(self, Macros={}):\r
NewRuleObject = copy.copy(self)\r
NewRuleObject.BuildTargets = {}\r
# @param RelativeToDir The relative path of the source file\r
# @param PathSeparator Path separator\r
#\r
- # @retval tuple (Source file in full path, List of individual sourcefiles, Destionation file, List of build commands)\r
+ # @retval tuple (Source file in full path, List of individual sourcefiles, Destination file, List of build commands)\r
#\r
def Apply(self, SourceFile, BuildRuleOrder=None):\r
if not self.CommandList or not self.DestFileList:\r
# Command line should be regenerated since some macros are different\r
#\r
CommandList = self._BuildCommand(BuildRulePlaceholderDict)\r
- TargetDesc._Init([SourceFile], DstFile, CommandList, self.ExtraSourceFileList)\r
+ TargetDesc.InitWorker([SourceFile], DstFile, CommandList, self.ExtraSourceFileList)\r
break\r
else:\r
TargetDesc.AddInput(SourceFile)\r
# @param LineIndex The line number from which the parsing will begin\r
# @param SupportedFamily The list of supported tool chain families\r
#\r
- def __init__(self, File=None, Content=None, LineIndex=0, SupportedFamily=["MSFT", "INTEL", "GCC", "RVCT"]):\r
+ def __init__(self, File=None, Content=None, LineIndex=0, SupportedFamily=[TAB_COMPILER_MSFT, "INTEL", "GCC", "RVCT"]):\r
self.RuleFile = File\r
# Read build rules from file if it's not none\r
- if File != None:\r
+ if File is not None:\r
try:\r
self.RuleContent = open(File, 'r').readlines()\r
except:\r
EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=File)\r
- elif Content != None:\r
+ elif Content is not None:\r
self.RuleContent = Content\r
else:\r
EdkLogger.error("build", PARAMETER_MISSING, ExtraData="No rule file or string given")\r
self._State = ""\r
self._RuleInfo = tdict(True, 2) # {toolchain family : {"InputFile": {}, "OutputFile" : [], "Command" : []}}\r
self._FileType = ''\r
- self._BuildTypeList = []\r
- self._ArchList = []\r
+ self._BuildTypeList = set()\r
+ self._ArchList = set()\r
self._FamilyList = []\r
self._TotalToolChainFamilySet = set()\r
self._RuleObjectList = [] # FileBuildRule object list\r
self.Parse()\r
\r
# some intrinsic rules\r
- self.RuleDatabase[TAB_DEFAULT_BINARY_FILE, "COMMON", "COMMON", "COMMON"] = self._BinaryFileRule\r
+ self.RuleDatabase[TAB_DEFAULT_BINARY_FILE, TAB_COMMON, TAB_COMMON, TAB_COMMON] = self._BinaryFileRule\r
self.FileTypeList.add(TAB_DEFAULT_BINARY_FILE)\r
\r
## Parse the build rule strings\r
# Clean up the line and replace path separator with native one\r
Line = self.RuleContent[Index].strip().replace(self._PATH_SEP, os.path.sep)\r
self.RuleContent[Index] = Line\r
- \r
+\r
# find the build_rule_version\r
- if Line and Line[0] == "#" and Line.find(TAB_BUILD_RULE_VERSION) <> -1:\r
- if Line.find("=") <> -1 and Line.find("=") < (len(Line) - 1) and (Line[(Line.find("=") + 1):]).split():\r
+ if Line and Line[0] == "#" and Line.find(TAB_BUILD_RULE_VERSION) != -1:\r
+ if Line.find("=") != -1 and Line.find("=") < (len(Line) - 1) and (Line[(Line.find("=") + 1):]).split():\r
self._FileVersion = (Line[(Line.find("=") + 1):]).split()[0]\r
# skip empty or comment line\r
if Line == "" or Line[0] == "#":\r
# @param LineIndex The line index of build rule text\r
#\r
def ParseSubSection(self, LineIndex):\r
- # currenly nothing here\r
+ # currently nothing here\r
pass\r
\r
## Placeholder for not supported sections\r
## Merge section information just got into rule database\r
def EndOfSection(self):\r
Database = self.RuleDatabase\r
- # if there's specific toochain family, 'COMMON' doesn't make sense any more\r
- if len(self._TotalToolChainFamilySet) > 1 and 'COMMON' in self._TotalToolChainFamilySet:\r
- self._TotalToolChainFamilySet.remove('COMMON')\r
+ # if there's specific toolchain family, 'COMMON' doesn't make sense any more\r
+ if len(self._TotalToolChainFamilySet) > 1 and TAB_COMMON in self._TotalToolChainFamilySet:\r
+ self._TotalToolChainFamilySet.remove(TAB_COMMON)\r
for Family in self._TotalToolChainFamilySet:\r
Input = self._RuleInfo[Family, self._InputFile]\r
Output = self._RuleInfo[Family, self._OutputFile]\r
#\r
def ParseSectionHeader(self, LineIndex):\r
self._RuleInfo = tdict(True, 2)\r
- self._BuildTypeList = []\r
- self._ArchList = []\r
+ self._BuildTypeList = set()\r
+ self._ArchList = set()\r
self._FamilyList = []\r
self._TotalToolChainFamilySet = set()\r
FileType = ''\r
RuleNameList = self.RuleContent[LineIndex][1:-1].split(',')\r
for RuleName in RuleNameList:\r
- Arch = 'COMMON'\r
- BuildType = 'COMMON'\r
+ Arch = TAB_COMMON\r
+ BuildType = TAB_COMMON\r
TokenList = [Token.strip().upper() for Token in RuleName.split('.')]\r
# old format: Build.File-Type\r
if TokenList[0] == "BUILD":\r
EdkLogger.error("build", FORMAT_INVALID, "No file type given",\r
File=self.RuleFile, Line=LineIndex + 1,\r
ExtraData=self.RuleContent[LineIndex])\r
- if self._FileTypePattern.match(FileType) == None:\r
+ if self._FileTypePattern.match(FileType) is None:\r
EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex + 1,\r
ExtraData="Only character, number (non-first character), '_' and '-' are allowed in file type")\r
# new format: File-Type.Build-Type.Arch\r
BuildType = TokenList[1]\r
if len(TokenList) > 2:\r
Arch = TokenList[2]\r
- if BuildType not in self._BuildTypeList:\r
- self._BuildTypeList.append(BuildType)\r
- if Arch not in self._ArchList:\r
- self._ArchList.append(Arch)\r
+ self._BuildTypeList.add(BuildType)\r
+ self._ArchList.add(Arch)\r
\r
- if 'COMMON' in self._BuildTypeList and len(self._BuildTypeList) > 1:\r
+ if TAB_COMMON in self._BuildTypeList and len(self._BuildTypeList) > 1:\r
EdkLogger.error("build", FORMAT_INVALID,\r
"Specific build types must not be mixed with common one",\r
File=self.RuleFile, Line=LineIndex + 1,\r
ExtraData=self.RuleContent[LineIndex])\r
- if 'COMMON' in self._ArchList and len(self._ArchList) > 1:\r
+ if TAB_COMMON in self._ArchList and len(self._ArchList) > 1:\r
EdkLogger.error("build", FORMAT_INVALID,\r
"Specific ARCH must not be mixed with common one",\r
File=self.RuleFile, Line=LineIndex + 1,\r
if len(TokenList) > 1:\r
Family = TokenList[1].strip().upper()\r
else:\r
- Family = "COMMON"\r
+ Family = TAB_COMMON\r
\r
if Family not in FamilyList:\r
FamilyList.append(Family)\r
self._FamilyList = FamilyList\r
self._TotalToolChainFamilySet.update(FamilyList)\r
self._State = SectionType.upper()\r
- if 'COMMON' in FamilyList and len(FamilyList) > 1:\r
+ if TAB_COMMON in FamilyList and len(FamilyList) > 1:\r
EdkLogger.error("build", FORMAT_INVALID,\r
"Specific tool chain family should not be mixed with general one",\r
File=self.RuleFile, Line=LineIndex + 1,\r
#\r
# @param LineIndex The line index of build rule text\r
#\r
- def ParseInputFile(self, LineIndex):\r
+ def ParseInputFileSubSection(self, LineIndex):\r
FileList = [File.strip() for File in self.RuleContent[LineIndex].split(",")]\r
for ToolChainFamily in self._FamilyList:\r
- InputFiles = self._RuleInfo[ToolChainFamily, self._State]\r
- if InputFiles == None:\r
- InputFiles = []\r
- self._RuleInfo[ToolChainFamily, self._State] = InputFiles\r
- InputFiles.extend(FileList)\r
+ if self._RuleInfo[ToolChainFamily, self._State] is None:\r
+ self._RuleInfo[ToolChainFamily, self._State] = []\r
+ self._RuleInfo[ToolChainFamily, self._State].extend(FileList)\r
\r
## Parse <ExtraDependency> sub-section\r
+ ## Parse <OutputFile> sub-section\r
+ ## Parse <Command> sub-section\r
#\r
# @param LineIndex The line index of build rule text\r
#\r
- def ParseCommon(self, LineIndex):\r
+ def ParseCommonSubSection(self, LineIndex):\r
for ToolChainFamily in self._FamilyList:\r
- Items = self._RuleInfo[ToolChainFamily, self._State]\r
- if Items == None:\r
- Items = []\r
- self._RuleInfo[ToolChainFamily, self._State] = Items\r
- Items.append(self.RuleContent[LineIndex])\r
+ if self._RuleInfo[ToolChainFamily, self._State] is None:\r
+ self._RuleInfo[ToolChainFamily, self._State] = []\r
+ self._RuleInfo[ToolChainFamily, self._State].append(self.RuleContent[LineIndex])\r
\r
## Get a build rule via [] operator\r
#\r
# @param FileExt The extension of a file\r
# @param ToolChainFamily The tool chain family name\r
- # @param BuildVersion The build version number. "*" means any rule\r
- # is applicalbe.\r
+ # @param BuildVersion The build version number. TAB_STAR means any rule\r
+ # is applicable.\r
#\r
# @retval FileType The file type string\r
# @retval FileBuildRule The object of FileBuildRule\r
_Section : ParseSection,\r
_SubSectionHeader : ParseSubSectionHeader,\r
_SubSection : ParseSubSection,\r
- _InputFile : ParseInputFile,\r
- _OutputFile : ParseCommon,\r
- _ExtraDependency : ParseCommon,\r
- _Command : ParseCommon,\r
+ _InputFile : ParseInputFileSubSection,\r
+ _OutputFile : ParseCommonSubSection,\r
+ _ExtraDependency : ParseCommonSubSection,\r
+ _Command : ParseCommonSubSection,\r
_UnknownSection : SkipSection,\r
}\r
\r
EdkLogger.Initialize()\r
if len(sys.argv) > 1:\r
Br = BuildRule(sys.argv[1])\r
- print str(Br[".c", "DXE_DRIVER", "IA32", "MSFT"][1])\r
- print\r
- print str(Br[".c", "DXE_DRIVER", "IA32", "INTEL"][1])\r
- print\r
- print str(Br[".c", "DXE_DRIVER", "IA32", "GCC"][1])\r
- print\r
- print str(Br[".ac", "ACPI_TABLE", "IA32", "MSFT"][1])\r
- print\r
- print str(Br[".h", "ACPI_TABLE", "IA32", "INTEL"][1])\r
- print\r
- print str(Br[".ac", "ACPI_TABLE", "IA32", "MSFT"][1])\r
- print\r
- print str(Br[".s", "SEC", "IPF", "COMMON"][1])\r
- print\r
- print str(Br[".s", "SEC"][1])\r
+ print(str(Br[".c", SUP_MODULE_DXE_DRIVER, "IA32", TAB_COMPILER_MSFT][1]))\r
+ print()\r
+ print(str(Br[".c", SUP_MODULE_DXE_DRIVER, "IA32", "INTEL"][1]))\r
+ print()\r
+ print(str(Br[".c", SUP_MODULE_DXE_DRIVER, "IA32", "GCC"][1]))\r
+ print()\r
+ print(str(Br[".ac", "ACPI_TABLE", "IA32", TAB_COMPILER_MSFT][1]))\r
+ print()\r
+ print(str(Br[".h", "ACPI_TABLE", "IA32", "INTEL"][1]))\r
+ print()\r
+ print(str(Br[".ac", "ACPI_TABLE", "IA32", TAB_COMPILER_MSFT][1]))\r
+ print()\r
+ print(str(Br[".s", SUP_MODULE_SEC, "IPF", "COMMON"][1]))\r
+ print()\r
+ print(str(Br[".s", SUP_MODULE_SEC][1]))\r
\r