1. Enhanced the format of build_rule.txt to allow module type and arch information.
authorjwang36 <jwang36@7335b38e-4728-0410-8992-fb3ffe349368>
Tue, 12 Aug 2008 07:18:52 +0000 (07:18 +0000)
committerjwang36 <jwang36@7335b38e-4728-0410-8992-fb3ffe349368>
Tue, 12 Aug 2008 07:18:52 +0000 (07:18 +0000)
2. Enhanced Trim to convert ASL style of include to C style of include
3. Enhanced Trim to convert some EDK coding convention to EDK2 ECP convention
4. Added warning message when encountering unrecognized content in DSC/DEC/INF File

git-svn-id: https://buildtools.tianocore.org/svn/buildtools/trunk/BaseTools@1300 7335b38e-4728-0410-8992-fb3ffe349368

Source/Python/AutoGen/AutoGen.py
Source/Python/AutoGen/BuildEngine.py
Source/Python/AutoGen/GenMake.py
Source/Python/Common/Misc.py
Source/Python/Trim/Trim.py
Source/Python/Workspace/MetaFileParser.py
Source/Python/Workspace/WorkspaceDatabase.py
Source/Python/build/build.py

index 7a0a8e3..b565724 100755 (executable)
@@ -1240,6 +1240,10 @@ class ModuleAutoGen(AutoGen):
     def _GetComponentType(self):
         return self.Module.ComponentType
 
+    ## Return the build type
+    def _GetBuildType(self):
+        return self.Module.BuildType
+
     ## Return the PCD_IS_DRIVER setting
     def _GetPcdIsDriver(self):
         return self.Module.PcdIsDriver
@@ -1405,17 +1409,17 @@ class ModuleAutoGen(AutoGen):
             Base, Ext = path.splitext(SourceFile)
 
             # skip file which needs a tool having no matching toolchain family
-            FileType, RuleObject = BuildRule.Get(Ext, ToolChainFamily)
+            FileType, RuleObject = BuildRule[Ext, self.BuildType, self.Arch, ToolChainFamily]
             # unicode must be processed by AutoGen
-            if FileType == "Unicode-Text-File":
+            if FileType == "UNICODE-TEXT-FILE":
                 self._UnicodeFileList.append(os.path.join(self.WorkspaceDir, self.SourceDir, SourceFile))
 
             # if there's dxs file, don't use content in [depex] section to generate .depex file
-            if FileType == "Dependency-Expression-File":
+            if FileType == "DEPENDENCY-EXPRESSION-FILE":
                 self._DepexList = []
 
             # no command, no build
-            if RuleObject != None and RuleObject.CommandList == []:
+            if RuleObject != None and len(RuleObject.CommandList) == 0:
                 RuleObject = None
             if [SourceFile, FileType, RuleObject] not in self._SourceFileList:
                 self._SourceFileList.append([SourceFile, FileType, RuleObject])
@@ -1668,6 +1672,7 @@ class ModuleAutoGen(AutoGen):
     Version         = property(_GetVersion)
     ModuleType      = property(_GetModuleType)
     ComponentType   = property(_GetComponentType)
+    BuildType       = property(_GetBuildType)
     PcdIsDriver     = property(_GetPcdIsDriver)
     AutoGenVersion  = property(_GetAutoGenVersion)
     Macro           = property(_GetMacroList)
index a869b5f..58b9765 100644 (file)
@@ -19,6 +19,7 @@ import re
 import string
 
 from Common.BuildToolError import *
+from Common.Misc import tdict
 import Common.EdkLogger as EdkLogger
 
 ## Convert file type to makefile macro name
@@ -43,40 +44,45 @@ class FileBuildRule:
     #   @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, Input, Output, Command):
+    def __init__(self, Type, Input, Output, Command, ExtraDependency=None):
         # The Input should not be empty
-        if Input == {}:
+        if Input == None or len(Input) == 0:
             EdkLogger.error("AutoGen", AUTOGEN_ERROR, "No input files for a build rule")
-        # The Output should not be empty
-        if Output == []:
-            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "No output files for a build rule")
+        if Output == None:
+            Output = []
 
-        self.SourceFileType = {}
+        self.SourceFileType = [Type]
         self.SourceFileExtList = []
         # source files listed not in "*" or "?" pattern format
-        self.ExtraSourceFileList = []
+        if ExtraDependency == None:
+            self.ExtraSourceFileList = []
+        else:
+            self.ExtraSourceFileList = ExtraDependency
         self.IsMultipleInput = False
-        for FileType in Input:
-            if FileType not in self.SourceFileType:
-                self.SourceFileType[FileType] = []
-            for File in Input[FileType]:
-                Base, Ext = os.path.splitext(File)
-                if Base.find("*") >= 0:
-                    # There's "*" in the file name
-                    self.IsMultipleInput = True
-                elif Base.find("?") < 0:
-                    # There's no "*" and "?" in file name
-                    self.ExtraSourceFileList.append(File)
-                    continue
-                self.SourceFileType[FileType].append(Ext)
+        for File in Input:
+            Base, Ext = os.path.splitext(File)
+            if Base.find("*") >= 0:
+                # There's "*" in the file name
+                self.IsMultipleInput = 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)
 
         if len(self.SourceFileType) > 1:
             self.IsMultipleInput = True
 
+        if len(Command) == 0:
+            self.IsMultipleInput = False
+
         self.DestFileList = Output
         self.DestFile = ""
-        self.DestFileExt = os.path.splitext(Output[0])[1]
+        if len(Output) > 0:
+            self.DestFileExt = os.path.splitext(Output[0])[1]
+        else:
+            self.DestFileExt = ''
         self.DestPath = ""
         self.DestFileName = ""
         self.DestFileBase = ""
@@ -88,8 +94,7 @@ class FileBuildRule:
     #
     def __str__(self):
         SourceString = ""
-        for FileType in self.SourceFileType:
-            SourceString += " %s(%s)" % (FileType, " ".join(self.SourceFileType[FileType]))
+        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)
@@ -146,7 +151,7 @@ class FileBuildRule:
         for Index in range(len(self.CommandList)):
             self.CommandList[Index] = self.CommandList[Index].replace("(+)", PathSeparator)
 
-        if self.DestFile == "":
+        if self.DestFile == "" and len(self.DestFileList) > 0:
             self.DestFile = self.DestFileList[0]
         if self.DestPath == "":
             self.DestPath = os.path.dirname(self.DestFile)
@@ -171,18 +176,18 @@ class FileBuildRule:
             "d_ext"     :   self.DestFileExt,
         }
 
-        DstFileList = []
-        for FileString in self.DestFileList:
-            FileString = string.Template(FileString).safe_substitute(BuildRulePlaceholderDict)
-            FileString = string.Template(FileString).safe_substitute(BuildRulePlaceholderDict)
-            DstFileList.append(FileString)
+        DstFile = ''
+        if len(self.DestFileList) > 0:
+            DstFile = self.DestFileList[0]
+            DstFile = string.Template(DstFile).safe_substitute(BuildRulePlaceholderDict)
+            DstFile = string.Template(DstFile).safe_substitute(BuildRulePlaceholderDict)
         CommandList = []
         for CommandString in self.CommandList:
             CommandString = string.Template(CommandString).safe_substitute(BuildRulePlaceholderDict)
             CommandString = string.Template(CommandString).safe_substitute(BuildRulePlaceholderDict)
             CommandList.append(CommandString)
 
-        return SrcFile, self.ExtraSourceFileList, DstFileList[0], CommandList
+        return SrcFile, self.ExtraSourceFileList, DstFile, CommandList
 
 ## Class for build rules
 #
@@ -196,6 +201,7 @@ class BuildRule:
     _SubSection = "SUBSECTION"
     _InputFile = "INPUTFILE"
     _OutputFile = "OUTPUTFILE"
+    _ExtraDependency = "EXTRADEPENDENCY"
     _Command = "COMMAND"
     _UnknownSection = "UNKNOWNSECTION"
 
@@ -224,15 +230,17 @@ class BuildRule:
             EdkLogger.error("build", PARAMETER_MISSING, ExtraData="No rule file or string given")
 
         self.SupportedToolChainFamilyList = SupportedFamily
-        self.RuleDatabase = {}  # {version : {family : {file type : FileBuildRule object}}}
+        self.RuleDatabase = tdict(True, 4)  # {FileExt, ModuleType, Arch, Family : FileBuildRule object}
         self.FileTypeDict = {}  # {ext : file-type}
 
         self._LineIndex = LineIndex
-        self._BuildVersion = "*"
-        self._RuleInfo = {}     # {toolchain family : {"InputFile": {}, "OutputFile" : [], "Command" : []}}
-        self._FileTypeList = []
-        self._FamilyList = []
         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.Parse()
@@ -273,17 +281,7 @@ class BuildRule:
     #   @param  LineIndex   The line index of build rule text
     #
     def ParseSection(self, LineIndex):
-        TokenList = self.RuleContent[LineIndex].split("=", 1)
-        # currently only BUILD_VERSION is supported
-        if len(TokenList) != 2 or TokenList[0] != "BUILD_VERSION":
-            EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex+1,
-                            ExtraData="Invalid definition: " + self.RuleContent[LineIndex])
-
-        try:
-            self._BuildVersion = int(TokenList[1].strip(), 0)
-        except:
-            EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex+1,
-                            ExtraData="Version is not a valid number: " + self.RuleContent[LineIndex])
+        pass
 
     ## Parse definitions under a subsection
     #
@@ -302,106 +300,94 @@ class BuildRule:
 
     ## Merge section information just got into rule database
     def EndOfSection(self):
-        if self._FileTypeList == [] or self._RuleInfo == {}:
-            return
-
         Database = self.RuleDatabase
-        if self._BuildVersion not in Database:
-            Database[self._BuildVersion] = {}
-        Database = self.RuleDatabase[self._BuildVersion]
-
-        # expand *
-        FamilyList = self._RuleInfo.keys()
-        if "*" in FamilyList and len(FamilyList) > 1:
-            FamilyList.remove("*")
-
-        NewRuleInfo = {}
-        for Family in self._RuleInfo:
-            Rule = self._RuleInfo[Family]
-            if Family == "*" and Family not in FamilyList:
-                NewFamilyList = FamilyList
-            else:
-                NewFamilyList = [Family]
-
-            for NewFamily in NewFamilyList:
-                if NewFamily not in NewRuleInfo:
-                    NewRuleInfo[NewFamily] = {}
-
-                if self._InputFile in Rule:
-                    NewRuleInfo[NewFamily][self._InputFile] = Rule[self._InputFile]
-                if self._OutputFile in Rule:
-                    NewRuleInfo[NewFamily][self._OutputFile] = Rule[self._OutputFile]
-                if self._Command in Rule:
-                    NewRuleInfo[NewFamily][self._Command] = Rule[self._Command]
-
-        for NewFamily in FamilyList:
-            Rule = NewRuleInfo[NewFamily]
-            if NewFamily not in Database:
-                Database[NewFamily] = {}
-
-            if self._InputFile in Rule:
-                Input = Rule[self._InputFile]
-            else:
+        # if there's specific toochain family, 'COMMON' doesnt make any 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]
+            if Input == None or len(Input) == 0:
                 EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile,
-                                ExtraData="No input files found for rule %s" % self._FileTypeList)
+                                ExtraData="No input files found for rule %s" % self._FileType)
 
-            if self._OutputFile in Rule:
-                Output = Rule[self._OutputFile]
-            else:
-                EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile,
-                                ExtraData="No output files found for rule %s" % self._FileTypeList)
+            Output = self._RuleInfo[Family, self._OutputFile]
+            if Output == None:
+                Output = []
 
-            if self._Command in Rule:
-                Command = Rule[self._Command]
-            else:
+            Command = self._RuleInfo[Family, self._Command]
+            if Command == None:
                 Command = []
 
-            if NewFamily == "*":
-                for Family in self.SupportedToolChainFamilyList:
-                    if Family not in Database:
-                        Database[Family] = {}
-                    RuleObject = FileBuildRule(Input, Output, Command)
-                    self._RuleObjectList.append(RuleObject)
-                    for FileType in RuleObject.SourceFileType:
-                        Database[Family][FileType] = RuleObject
-            else:
-                RuleObject = FileBuildRule(Input, Output, Command)
-                self._RuleObjectList.append(RuleObject)
-                for FileType in RuleObject.SourceFileType:
-                    Database[NewFamily][FileType] = RuleObject
-        # for new section
-        self._RuleInfo = {}
+            ExtraDependency = self._RuleInfo[Family, self._ExtraDependency]
+            if ExtraDependency == None:
+                ExtraDependency = []
+
+            BuildRule = FileBuildRule(self._FileType, Input, Output, Command, ExtraDependency)
+            for BuildType in self._BuildTypeList:
+                for Arch in self._ArchList:
+                    for FileExt in BuildRule.SourceFileExtList:
+                        Database[FileExt, BuildType, Arch, Family] = BuildRule
 
     ## Parse section header
     #
     #   @param  LineIndex   The line index of build rule text
     #
     def ParseSectionHeader(self, LineIndex):
-        BuildVersion = ""
-        FileTypeList = []
+        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:
-            TokenList = RuleName.split('.')
-            if len(TokenList) == 1:
-                EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex+1,
-                                ExtraData="Invalid rule section: " + self.RuleContent[LineIndex])
-
-            Rule = TokenList[0].strip()
-            if Rule.upper() != "BUILD":
-                self._State = self._UnknownSection
-                return
-
-            FileType = TokenList[1].strip()
-            if FileType == '':
-                EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex+1,
-                                ExtraData="No file type given: " + Line)
-            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")
-            FileTypeList.append(FileType)
-
-        self._FileTypeList = FileTypeList
-        self._BuildVersion = "*"
+            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, File=self.RuleFile, Line=LineIndex+1,
+                                    ExtraData="No file type given: " + Line)
+                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
 
     ## Parse sub-section header
@@ -419,19 +405,27 @@ class BuildRule:
             if SectionType == "":
                 SectionType = Type
             elif SectionType != Type:
-                EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex+1,
-                                ExtraData="Two different section types are not allowed: " + Line)
+                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 = "*"
+                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])
@@ -440,66 +434,27 @@ class BuildRule:
     #   @param  LineIndex   The line index of build rule text
     #
     def ParseInputFile(self, LineIndex):
-        Line = self.RuleContent[LineIndex]
-        TokenList = Line.split("=")
-        FileType = ""
-        if len(TokenList) > 1:
-            FileType = TokenList[0].strip()
-            if FileType not in self._FileTypeList:
-                EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile,  Line=LineIndex+1,
-                                ExtraData="File type must be one of %s: %s" % (self._FileTypeList, FileType))
-            FileString = TokenList[1]
-        else:
-            if len(self._FileTypeList) > 1:
-                EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex,
-                                ExtraData="File type must be given: " + Line)
-            else:
-                FileType = self._FileTypeList[0]
-            FileString = TokenList[0]
-
-        FileList = FileString.split(",")
-        for File in FileList:
-            File = File.strip()
-            for Family in self._FamilyList:
-                if Family not in self._RuleInfo:
-                    self._RuleInfo[Family] = {}
-                if self._State not in self._RuleInfo[Family]:
-                    self._RuleInfo[Family][self._State] = {}
-                if FileType not in self._RuleInfo[Family][self._State]:
-                    self._RuleInfo[Family][self._State][FileType] = []
-                self._RuleInfo[Family][self._State][FileType].append(File)
-
-    ## Parse <OutputFile> sub-section
+        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 ParseOutputFile(self, LineIndex):
-        FileList = self.RuleContent[LineIndex].split(",")
-        for File in FileList:
-            File = File.strip()
-            for Family in self._FamilyList:
-                if Family not in self._RuleInfo:
-                    self._RuleInfo[Family] = {}
-                    self._RuleInfo[Family][self._State] = []
-                if self._State not in self._RuleInfo[Family]:
-                    self._RuleInfo[Family][self._State] = []
-                self._RuleInfo[Family][self._State].append(File)
-
-    ## Parse <Command> sub-section
-    #
-    #   @param  LineIndex   The line index of build rule text
-    #
-    def ParseCommand(self, LineIndex):
-        Command = self.RuleContent[LineIndex]
-        for Family in self._FamilyList:
-            if Family not in self._RuleInfo:
-                self._RuleInfo[Family] = {}
-                self._RuleInfo[Family][self._State] = []
-            if self._State not in self._RuleInfo[Family]:
-                self._RuleInfo[Family][self._State] = []
-            self._RuleInfo[Family][self._State].append(Command)
-
-    ## Get a build rule
+    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
@@ -509,39 +464,12 @@ class BuildRule:
     #   @retval FileType        The file type string
     #   @retval FileBuildRule   The object of FileBuildRule
     #
-    def Get(self, FileExt, ToolChainFamily, BuildVersion="*"):
-        if FileExt not in self.FileTypeDict:
+    # Key = (FileExt, ModuleType, Arch, ToolChainFamily)
+    def __getitem__(self, Key):
+        RuleObj = self.RuleDatabase[Key]
+        if RuleObj == None:
             return None, None
-        FileType = self.FileTypeDict[FileExt]
-        Database = {}
-        BuildRuleObject = None
-        if BuildVersion in self.RuleDatabase:
-            Database = self.RuleDatabase[BuildVersion]
-        elif BuildVersion != "*":
-            if "*" not in self.RuleDatabase:
-                return FileType, None
-            Database = self.RuleDatabase["*"]
-        else:
-            # BuildVersion == "*" and "*" not in self.RuleDatabase
-            # try to match ToolChainFamily
-            for Ver in self.RuleDatabase:
-                Database = self.RuleDatabase[Ver]
-                if ToolChainFamily not in Database:
-                    continue
-                if FileType not in Database[ToolChainFamily]:
-                    continue
-                break
-            else:
-                return FileType, None
-
-        if ToolChainFamily not in Database:
-            return FileType, None
-        if FileType not in Database[ToolChainFamily]:
-            return FileType, None
-        if not Database[ToolChainFamily][FileType].IsSupported(FileExt):
-            return FileType, None
-
-        return FileType, Database[ToolChainFamily][FileType]
+        return RuleObj.SourceFileType[0], RuleObj
 
     _StateHandler = {
         _SectionHeader     : ParseSectionHeader,
@@ -549,13 +477,32 @@ class BuildRule:
         _SubSectionHeader  : ParseSubSectionHeader,
         _SubSection        : ParseSubSection,
         _InputFile         : ParseInputFile,
-        _OutputFile        : ParseOutputFile,
-        _Command           : ParseCommand,
+        _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__':
-    pass
+    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])
 
index d4ddbac..3982488 100755 (executable)
@@ -469,11 +469,11 @@ cleanlib:
                 ExtraData="[%s]" % str(self._AutoGenObject))
 
         if self._AutoGenObject.IsLibrary:
-            if "Static-Library-File" in self.DestFileDatabase:
-                self.ResultFileList = self.DestFileDatabase["Static-Library-File"]
+            if "STATIC-LIBRARY-FILE" in self.DestFileDatabase:
+                self.ResultFileList = self.DestFileDatabase["STATIC-LIBRARY-FILE"]
         elif self._AutoGenObject.ModuleType == "USER_DEFINED":
-            if "Dynamic-Library-File" in self.DestFileDatabase:
-                self.ResultFileList = self.DestFileDatabase["Dynamic-Library-File"]
+            if "DYNAMIC-LIBRARY-FILE" in self.DestFileDatabase:
+                self.ResultFileList = self.DestFileDatabase["DYNAMIC-LIBRARY-FILE"]
         if len(self.ResultFileList) == 0:
             EdkLogger.error("build", AUTOGEN_ERROR, "Nothing to build",
                             ExtraData="[%s]" % str(self._AutoGenObject))
@@ -580,6 +580,8 @@ cleanlib:
                             ExtraData="[%s]" % str(self._AutoGenObject))
         Family = self.PlatformInfo.ToolChainFamily["CC"]
         BuildRule = self.PlatformInfo.BuildRule
+        Arch = self._AutoGenObject.Arch
+        BuildType = self._AutoGenObject.BuildType
 
         CCodeFlag = False
         FileList = self._AutoGenObject.SourceFileList
@@ -589,7 +591,7 @@ cleanlib:
             # no rule, no build
             if SrcFileBuildRule == None:
                 continue
-            if SrcFileType == "C-Code-File":
+            if SrcFileType == "C-CODE-FILE":
                 CCodeFlag = True
             SrcFileName = path.basename(F)
             SrcFileBase, SrcFileExt = path.splitext(SrcFileName)
@@ -615,9 +617,9 @@ cleanlib:
 
             while True:
                 # next target
-                DstFileType, DstFileBuildRule = BuildRule.Get(SrcFileBuildRule.DestFileExt, Family)
+                DstFileType, DstFileBuildRule = BuildRule[SrcFileBuildRule.DestFileExt, BuildType, Arch, Family]
                 if DstFileType == None:
-                    DstFileType = "Unknown-Type-File"
+                    DstFileType = "UNKNOWN-TYPE-FILE"
 
                 if DstFileType  in self.SourceFileDatabase:
                     self.SourceFileDatabase[DstFileType].append(DstFile)
@@ -630,7 +632,7 @@ cleanlib:
                     if DstFileBuildRule not in self.PendingBuildTargetList:
                         self.PendingBuildTargetList.append(DstFileBuildRule)
                     break
-                elif DstFileBuildRule == None or DstFileBuildRule.CommandList == []:
+                elif DstFileBuildRule == None or len(DstFileBuildRule.CommandList) == 0:
                     self.ResultFileList.append(DstFile)
                     break
 
@@ -661,11 +663,11 @@ cleanlib:
 
                 # try to find next target
                 while True:
-                    DstFileType, DstFileBuildRule = BuildRule.Get(SrcFileBuildRule.DestFileExt, Family)
+                    DstFileType, DstFileBuildRule = BuildRule[SrcFileBuildRule.DestFileExt, BuildType, Arch, Family]
                     if DstFileType == None:
-                        DstFileType = "Unknown-Type-File"
+                        DstFileType = "UNKNOWN-TYPE-FILE"
 
-                    if DstFileType  in self.SourceFileDatabase:
+                    if DstFileType in self.SourceFileDatabase:
                         self.SourceFileDatabase[DstFileType].append(DstFile)
                     else:
                         if DstFileType not in self.DestFileDatabase:
@@ -675,7 +677,7 @@ cleanlib:
                     if DstFileBuildRule != None and DstFileBuildRule.IsMultipleInput:
                         TempBuildTargetList.append(DstFileBuildRule)
                         break
-                    elif DstFileBuildRule == None or DstFileBuildRule.CommandList == []:
+                    elif DstFileBuildRule == None or len(DstFileBuildRule.CommandList) == 0:
                         self.ResultFileList.append(DstFile)
                         break
 
@@ -703,10 +705,10 @@ cleanlib:
 
                 SrcFileRelativePath = os.path.join(self._AutoGenObject.DebugDir, F)
 
-                SrcFileType, SrcFileBuildRule = BuildRule.Get(SrcFileExt, Family)
-                if SrcFileType != None and SrcFileType == "C-Header-File":
+                SrcFileType, SrcFileBuildRule = BuildRule[SrcFileExt, BuildType, Arch, Family]
+                if SrcFileType != None and SrcFileType == "C-HEADER-FILE":
                     ForceIncludedFile.append(SrcFileRelativePath)
-                if SrcFileBuildRule == None or SrcFileBuildRule.CommandList == []:
+                if SrcFileBuildRule == None or len(SrcFileBuildRule.CommandList) == 0:
                     continue
 
                 SrcFile, ExtraSrcFileList, DstFile, CommandList = SrcFileBuildRule.Apply(F, self._AutoGenObject.DebugDir, Separator)
@@ -723,9 +725,9 @@ cleanlib:
 
                 while True:
                     # next target
-                    DstFileType, DstFileBuildRule = BuildRule.Get(SrcFileBuildRule.DestFileExt, Family)
+                    DstFileType, DstFileBuildRule = BuildRule[SrcFileBuildRule.DestFileExt, BuildType, Arch, Family]
                     if DstFileType == None:
-                        DstFileType = "Unknown-Type-File"
+                        DstFileType = "UNKNOWN-TYPE-FILE"
 
                     if DstFileType  in self.SourceFileDatabase:
                         self.SourceFileDatabase[DstFileType].append(DstFile)
@@ -738,7 +740,7 @@ cleanlib:
                         if DstFileBuildRule not in self.PendingBuildTargetList:
                             self.PendingBuildTargetList.append(DstFileBuildRule)
                         break
-                    elif DstFileBuildRule == None or DstFileBuildRule.CommandList == []:
+                    elif DstFileBuildRule == None or len(DstFileBuildRule.CommandList) == 0:
                         self.ResultFileList.append(DstFile)
                         break
 
@@ -789,7 +791,6 @@ cleanlib:
             Template.Append(TargetTemplate, {"deps" : self.FileDependency[File]})
             self.BuildTargetList.append(str(Template))
 
-
     ## Process binary files to generate makefile targets and dependencies
     #
     # All binary files are just copied to $(OUTPUT_DIR)
index 8fc8d33..08b20c2 100755 (executable)
@@ -602,7 +602,7 @@ class tdict:
     _ListType = type([])
     _TupleType = type(())
     _Wildcard = 'COMMON'
-    _ValidWildcardList = ['COMMON', 'DEFAULT', 'ALL', '', '*', 'PLATFORM']
+    _ValidWildcardList = ['COMMON', 'DEFAULT', 'ALL', '*', 'PLATFORM']
 
     def __init__(self, _Single_=False, _Level_=2):
         self._Level_ = _Level_
index 004c432..1c532a6 100644 (file)
@@ -21,13 +21,14 @@ import re
 from optparse import OptionParser
 from optparse import make_option
 from Common.BuildToolError import *
+from Common.Misc import *
 
 import Common.EdkLogger as EdkLogger
 
 # Version and Copyright
-__version_number__ = "0.02"
+__version_number__ = "0.04"
 __version__ = "%prog Version " + __version_number__
-__copyright__ = "Copyright (c) 2007, Intel Corporation. All rights reserved."
+__copyright__ = "Copyright (c) 2007-2008, Intel Corporation. All rights reserved."
 
 ## Regular expression for matching Line Control directive like "#line xxx"
 gLineControlDirective = re.compile('^\s*(#line|#)\s+([0-9]+)\s+"*([^"]*)"*')
@@ -39,6 +40,57 @@ gPragmaPattern = re.compile("^\s*#pragma\s+pack", re.MULTILINE)
 gHexNumberPattern = re.compile("0[xX]([0-9a-fA-F]+)", re.MULTILINE)
 ## Regular expression for matching "Include ()" in asl file
 gAslIncludePattern = re.compile("^\s*Include\s*\(([^\(\)]+)\)\s*$", re.MULTILINE)
+## Patterns used to convert EDK conventions to EDK2 ECP conventions
+gImportCodePatterns = [
+    [
+        re.compile('^(\s*)\(\*\*PeiServices\)\.PciCfg\s*=\s*([^;\s]+);', re.MULTILINE),
+        '''\\1{
+\\1  STATIC EFI_PEI_PPI_DESCRIPTOR gEcpPeiPciCfgPpiList = {
+\\1    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+\\1    &gEcpPeiPciCfgPpiGuid,
+\\1    \\2
+\\1  };
+\\1  (**PeiServices).InstallPpi (PeiServices, gEcpPeiPciCfgPpiList);
+\\1}'''
+    ],
+
+    [
+        re.compile('^(\s*)\(\*PeiServices\)->PciCfg\s*=\s*([^;\s]+);', re.MULTILINE),
+        '''\\1{
+\\1  STATIC EFI_PEI_PPI_DESCRIPTOR gEcpPeiPciCfgPpiList = {
+\\1    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+\\1    &gEcpPeiPciCfgPpiGuid,
+\\1    \\2
+\\1  };
+\\1  (**PeiServices).InstallPpi (PeiServices, gEcpPeiPciCfgPpiList);
+\\1}'''
+    ],
+
+    [
+        re.compile("(\s*).+->Modify[\s\n]*\(", re.MULTILINE),
+        '\\1PeiLibPciCfgModify ('
+    ],
+
+    [
+        re.compile("(\W*)gRT->ReportStatusCode[\s\n]*\(", re.MULTILINE),
+        '\\1EfiLibReportStatusCode ('
+    ],
+
+    [
+        re.compile('#include\s+["<]LoadFile\.h[">]', re.MULTILINE),
+        '#include <FvLoadFile.h>'
+    ],
+
+    [
+        re.compile("(\s*)\S*CreateEvent\s*\([\s\n]*EFI_EVENT_SIGNAL_READY_TO_BOOT[^,]*,((?:[^;]+\n)+)(\s*\));", re.MULTILINE),
+        '\\1EfiCreateEventReadyToBoot (\\2\\3;'
+    ],
+
+    [
+        re.compile("(\s*)\S*CreateEvent\s*\([\s\n]*EFI_EVENT_SIGNAL_LEGACY_BOOT[^,]*,((?:[^;]+\n)+)(\s*\));", re.MULTILINE),
+        '\\1EfiCreateEventLegacyBoot (\\2\\3;'
+    ]
+]
 
 ## Trim preprocessed source code
 #
@@ -198,6 +250,85 @@ def TrimAslFile(Source, Target):
     f.write(Lines)
     f.close()
 
+## Trim EDK source code file(s)
+#
+#
+# @param  Source    File or directory to be trimmed
+# @param  Target    File or directory to store the trimmed content
+#
+def TrimR8Sources(Source, Target):
+    if os.path.isdir(Source):
+        for CurrentDir, Dirs, Files in os.walk(Source):
+            if '.svn' in Dirs:
+                Dirs.remove('.svn')
+            elif "CVS" in Dirs:
+                Dirs.remove("CVS")
+
+            for FileName in Files:
+                Dummy, Ext = os.path.splitext(FileName)
+                if Ext.upper() not in ['.C', '.H']: continue
+                if Target == None or Target == '':
+                    TrimR8SourceCode(
+                        os.path.join(CurrentDir, FileName),
+                        os.path.join(CurrentDir, FileName)
+                        )
+                else:
+                    TrimR8SourceCode(
+                        os.path.join(CurrentDir, FileName),
+                        os.path.join(Target, CurrentDir[len(Source)+1:], FileName)
+                        )
+    else:
+        TrimR8SourceCode(Source, Target)
+
+## Trim one EDK source code file
+#
+# Do following replacement:
+#
+#   (**PeiServices\).PciCfg = <*>;
+#   =>  {
+#         STATIC EFI_PEI_PPI_DESCRIPTOR gEcpPeiPciCfgPpiList = {
+#         (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+#         &gEcpPeiPciCfgPpiGuid,
+#         <*>
+#       };
+#       (**PeiServices).InstallPpi (PeiServices, gEcpPeiPciCfgPpiList);
+#
+#   <*>Modify(<*>)
+#   =>  PeiLibPciCfgModify (<*>)
+#
+#   gRT->ReportStatusCode (<*>)
+#   => EfiLibReportStatusCode (<*>)
+#
+#   #include <LoadFile\.h>
+#   =>  #include <FvLoadFile.h>
+#
+#   CreateEvent (EFI_EVENT_SIGNAL_READY_TO_BOOT, <*>)
+#   => EfiCreateEventReadyToBoot (<*>)
+#
+#   CreateEvent (EFI_EVENT_SIGNAL_LEGACY_BOOT, <*>)
+#   =>  EfiCreateEventLegacyBoot (<*>)
+#
+# @param  Source    File to be trimmed
+# @param  Target    File to store the trimmed content
+#
+def TrimR8SourceCode(Source, Target):
+    EdkLogger.verbose("\t%s -> %s" % (Source, Target))
+    CreateDirectory(os.path.dirname(Target))
+
+    f = open (Source,'r')
+    # read whole file
+    Lines = f.read()
+    f.close()
+
+    for Re,Repl in gImportCodePatterns:
+        Lines = Re.sub(Repl, Lines)
+
+    # save all lines trimmed
+    f = open (Target,'w')
+    f.write(Lines)
+    f.close()
+
+
 ## Parse command line options
 #
 # Using standard Python module optparse to parse command line option of this tool.
@@ -213,6 +344,8 @@ def Options():
                           help="The input file is preprocessed VFR file"),
         make_option("-a", "--asl-file", dest="FileType", const="Asl", action="store_const",
                           help="The input file is ASL file"),
+        make_option("-8", "--r8-source-code", dest="FileType", const="R8SourceCode", action="store_const",
+                          help="The input file is source code for R8 to be trimmed for ECP"),
 
         make_option("-c", "--convert-hex", dest="ConvertHex", action="store_true",
                           help="Convert standard hex format (0xabcd) to MASM format (abcdh)"),
@@ -229,7 +362,7 @@ def Options():
     ]
 
     # use clearer usage to override default usage message
-    UsageString = "%prog [-s|-r] [-c] [-v|-d <debug_level>|-q] [-o <output_file>] <input_file>"
+    UsageString = "%prog [-s|-r|-a] [-c] [-v|-d <debug_level>|-q] [-o <output_file>] <input_file>"
 
     Parser = OptionParser(description=__copyright__, version=__version__, option_list=OptionList, usage=UsageString)
     Parser.set_defaults(FileType="Vfr")
@@ -245,9 +378,6 @@ def Options():
         EdkLogger.error("Trim", OPTION_NOT_SUPPORTED, ExtraData=Parser.get_usage())
 
     InputFile = Args[0]
-    if Options.OutputFile == None:
-        Options.OutputFile = os.path.splitext(InputFile)[0] + '.iii'
-
     return Options, InputFile
 
 ## Entrance method
@@ -269,10 +399,18 @@ def Main():
             EdkLogger.SetLevel(CommandOptions.LogLevel)
 
         if CommandOptions.FileType == "Vfr":
+            if CommandOptions.OutputFile == None:
+                CommandOptions.OutputFile = os.path.splitext(InputFile)[0] + '.iii'
             TrimPreprocessedVfr(InputFile, CommandOptions.OutputFile)
         elif CommandOptions.FileType == "Asl":
+            if CommandOptions.OutputFile == None:
+                CommandOptions.OutputFile = os.path.splitext(InputFile)[0] + '.iii'
             TrimAslFile(InputFile, CommandOptions.OutputFile)
+        elif CommandOptions.FileType == "R8SourceCode":
+            TrimR8Sources(InputFile, CommandOptions.OutputFile)
         else :
+            if CommandOptions.OutputFile == None:
+                CommandOptions.OutputFile = os.path.splitext(InputFile)[0] + '.iii'
             TrimPreprocessedFile(InputFile, CommandOptions.OutputFile, CommandOptions.ConvertHex)
     except Exception, e:
         print e
index 13807b0..020d9b7 100644 (file)
@@ -145,6 +145,8 @@ class MetaFileParser(object):
 
     ## Skip unsupported data
     def _Skip(self):
+        EdkLogger.warn("Parser", "Unrecognized content", File=self._FilePath,
+                        Line=self._LineIndex+1, ExtraData=self._CurrentLine);
         self._ValueList[0:1] = [self._CurrentLine]
 
     ## Section header parser
index d0f93ff..076f87d 100644 (file)
@@ -1125,6 +1125,7 @@ class InfBuildData(ModuleBuildClassObject):
         self._BaseName              = None
         self._ModuleType            = None
         self._ComponentType         = None
+        self._BuildType             = None
         self._Guid                  = None
         self._Version               = None
         self._PcdIsDriver           = None
@@ -1323,6 +1324,9 @@ class InfBuildData(ModuleBuildClassObject):
                 self._GetHeaderInfo()
             if self._ModuleType == None:
                 self._ModuleType = 'BASE'
+            self._BuildType = self._ModuleType
+            if self._ModuleType not in SUP_MODULE_LIST:
+                self._ModuleType = "USER_DEFINED"
         return self._ModuleType
 
     ## Retrieve COMPONENT_TYPE
@@ -1331,9 +1335,23 @@ class InfBuildData(ModuleBuildClassObject):
             if self._Header_ == None:
                 self._GetHeaderInfo()
             if self._ComponentType == None:
-                self._ComponentType = ''
+                self._ComponentType = 'USER_DEFINED'
+            self._BuildType = self._ComponentType
         return self._ComponentType
 
+    ## Retrieve "BUILD_TYPE"
+    def _GetBuildType(self):
+        if self._BuildType == None:
+            if self._Header_ == None:
+                self._GetHeaderInfo()
+            if self._ComponentType != None:
+                self._BuildType = self._ComponentType
+            elif self._ModuleType != None:
+                self._BuildType = self._ModuleType
+            else:
+                self._BuildType = 'USER_DEFINED'
+        return self._BuildType
+
     ## Retrieve file guid
     def _GetFileGuid(self):
         if self._Guid == None:
@@ -1715,6 +1733,7 @@ class InfBuildData(ModuleBuildClassObject):
     BaseName                = property(_GetBaseName)
     ModuleType              = property(_GetModuleType)
     ComponentType           = property(_GetComponentType)
+    BuildType               = property(_GetBuildType)
     Guid                    = property(_GetFileGuid)
     Version                 = property(_GetVersion)
     PcdIsDriver             = property(_GetPcdIsDriver)
index 65b9e07..a2ed74b 100644 (file)
@@ -1299,6 +1299,8 @@ def Main():
         ReturnCode = FORMAT_INVALID
     except KeyboardInterrupt:
         ReturnCode = ABORT_ERROR
+        if Option != None and Option.debug != None:
+            EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
     except:
         EdkLogger.SetLevel(EdkLogger.QUIET)
         if MyBuild != None: