]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/AutoGen/AutoGen.py
BaseTools: small cleanup
[mirror_edk2.git] / BaseTools / Source / Python / AutoGen / AutoGen.py
index 1787decd1d9e8127fc0f70149a63d3feebad302e..6b47aa2a8f904c98ca650992566f1ab65ab4acae 100644 (file)
@@ -45,10 +45,21 @@ import InfSectionParser
 import datetime\r
 import hashlib\r
 from GenVar import VariableMgr,var_info\r
+from collections import OrderedDict\r
 \r
 ## Regular expression for splitting Dependency Expression string into tokens\r
 gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)")\r
 \r
+## Regular expression for match: PCD(xxxx.yyy)\r
+gPCDAsGuidPattern = re.compile(r"^PCD\(.+\..+\)$")\r
+\r
+#\r
+# Regular expression for finding Include Directories, the difference between MSFT and INTEL/GCC/RVCT\r
+# is the former use /I , the Latter used -I to specify include directories\r
+#\r
+gBuildOptIncludePatternMsft = re.compile(r"(?:.*?)/I[ \t]*([^ ]*)", re.MULTILINE | re.DOTALL)\r
+gBuildOptIncludePatternOther = re.compile(r"(?:.*?)-I[ \t]*([^ ]*)", re.MULTILINE | re.DOTALL)\r
+\r
 #\r
 # Match name = variable\r
 #\r
@@ -159,8 +170,8 @@ ${tail_comments}
 #   This class just implements the cache mechanism of AutoGen objects.\r
 #\r
 class AutoGen(object):\r
-    # database to maintain the objects of xxxAutoGen\r
-    _CACHE_ = {}    # (BuildTarget, ToolChain) : {ARCH : {platform file: AutoGen object}}}\r
+    # database to maintain the objects in each child class\r
+    __ObjectCache = {}    # (BuildTarget, ToolChain, ARCH, platform file): AutoGen object\r
 \r
     ## Factory method\r
     #\r
@@ -174,24 +185,19 @@ class AutoGen(object):
     #   @param  *args           The specific class related parameters\r
     #   @param  **kwargs        The specific class related dict parameters\r
     #\r
-    def __new__(Class, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):\r
+    def __new__(cls, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):\r
         # check if the object has been created\r
-        Key = (Target, Toolchain)\r
-        if Key not in Class._CACHE_ or Arch not in Class._CACHE_[Key] \\r
-           or MetaFile not in Class._CACHE_[Key][Arch]:\r
-            AutoGenObject = super(AutoGen, Class).__new__(Class)\r
-            # call real constructor\r
-            if not AutoGenObject._Init(Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):\r
-                return None\r
-            if Key not in Class._CACHE_:\r
-                Class._CACHE_[Key] = {}\r
-            if Arch not in Class._CACHE_[Key]:\r
-                Class._CACHE_[Key][Arch] = {}\r
-            Class._CACHE_[Key][Arch][MetaFile] = AutoGenObject\r
-        else:\r
-            AutoGenObject = Class._CACHE_[Key][Arch][MetaFile]\r
+        Key = (Target, Toolchain, Arch, MetaFile)\r
+        try:\r
+            # if it exists, just return it directly\r
+            return cls.__ObjectCache[Key]\r
+        except:\r
+            # it didnt exist. create it, cache it, then return it\r
+            cls.__ObjectCache[Key] = super(AutoGen, cls).__new__(cls)\r
+            return cls.__ObjectCache[Key]\r
 \r
-        return AutoGenObject\r
+    def __init__ (self, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):\r
+        super(AutoGen, self).__init__(self, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs)\r
 \r
     ## hash() operator\r
     #\r
@@ -221,10 +227,16 @@ class AutoGen(object):
 # architecture. This class will generate top level makefile.\r
 #\r
 class WorkspaceAutoGen(AutoGen):\r
-    ## Real constructor of WorkspaceAutoGen\r
-    #\r
-    # This method behaves the same as __init__ except that it needs explicit invoke\r
-    # (in super class's __new__ method)\r
+    # call super().__init__ then call the worker function with different parameter count\r
+    def __init__(self, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):\r
+        try:\r
+            self._Init\r
+        except:\r
+            super(WorkspaceAutoGen, self).__init__(Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs)\r
+            self._InitWorker(Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs)\r
+            self._Init = True\r
+    \r
+    ## Initialize WorkspaceAutoGen\r
     #\r
     #   @param  WorkspaceDir            Root directory of workspace\r
     #   @param  ActivePlatform          Meta-file of active platform\r
@@ -240,7 +252,7 @@ class WorkspaceAutoGen(AutoGen):
     #   @param  Caps                    Capsule list to be generated\r
     #   @param  SkuId                   SKU id from command line\r
     #\r
-    def _Init(self, WorkspaceDir, ActivePlatform, Target, Toolchain, ArchList, MetaFileDb,\r
+    def _InitWorker(self, WorkspaceDir, ActivePlatform, Target, Toolchain, ArchList, MetaFileDb,\r
               BuildConfig, ToolDefinition, FlashDefinitionFile='', Fds=None, Fvs=None, Caps=None, SkuId='', UniFlag=None,\r
               Progress=None, BuildModule=None):\r
         if Fds is None:\r
@@ -398,13 +410,8 @@ class WorkspaceAutoGen(AutoGen):
         for Arch in self.ArchList:\r
             Platform = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]\r
 \r
-\r
-\r
-\r
-\r
-\r
-            SourcePcdDict = {'DynamicEx':[], 'PatchableInModule':[],'Dynamic':[],'FixedAtBuild':[]}\r
-            BinaryPcdDict = {'DynamicEx':[], 'PatchableInModule':[]}\r
+            SourcePcdDict = {'DynamicEx':set(), 'PatchableInModule':set(),'Dynamic':set(),'FixedAtBuild':set()}\r
+            BinaryPcdDict = {'DynamicEx':set(), 'PatchableInModule':set()}\r
             SourcePcdDict_Keys = SourcePcdDict.keys()\r
             BinaryPcdDict_Keys = BinaryPcdDict.keys()\r
 \r
@@ -430,27 +437,21 @@ class WorkspaceAutoGen(AutoGen):
 \r
                         if 'DynamicEx' in BuildData.Pcds[key].Type:\r
                             if BuildData.IsBinaryModule:\r
-                                if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in BinaryPcdDict['DynamicEx']:\r
-                                    BinaryPcdDict['DynamicEx'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r
+                                BinaryPcdDict['DynamicEx'].add((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r
                             else:\r
-                                if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in SourcePcdDict['DynamicEx']:\r
-                                    SourcePcdDict['DynamicEx'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r
+                                SourcePcdDict['DynamicEx'].add((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r
 \r
                         elif 'PatchableInModule' in BuildData.Pcds[key].Type:\r
                             if BuildData.MetaFile.Ext == '.inf':\r
                                 if BuildData.IsBinaryModule:\r
-                                    if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in BinaryPcdDict['PatchableInModule']:\r
-                                        BinaryPcdDict['PatchableInModule'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r
+                                    BinaryPcdDict['PatchableInModule'].add((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r
                                 else:\r
-                                    if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in SourcePcdDict['PatchableInModule']:\r
-                                        SourcePcdDict['PatchableInModule'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r
+                                    SourcePcdDict['PatchableInModule'].add((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r
 \r
                         elif 'Dynamic' in BuildData.Pcds[key].Type:\r
-                            if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in SourcePcdDict['Dynamic']:\r
-                                SourcePcdDict['Dynamic'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r
+                            SourcePcdDict['Dynamic'].add((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r
                         elif 'FixedAtBuild' in BuildData.Pcds[key].Type:\r
-                            if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in SourcePcdDict['FixedAtBuild']:\r
-                                SourcePcdDict['FixedAtBuild'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r
+                            SourcePcdDict['FixedAtBuild'].add((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r
                 else:\r
                     pass\r
             #\r
@@ -459,16 +460,14 @@ class WorkspaceAutoGen(AutoGen):
             for i in SourcePcdDict_Keys:\r
                 for j in SourcePcdDict_Keys:\r
                     if i != j:\r
-                        IntersectionList = list(set(SourcePcdDict[i]).intersection(set(SourcePcdDict[j])))\r
-                        if len(IntersectionList) > 0:\r
+                        Intersections = SourcePcdDict[i].intersection(SourcePcdDict[j])\r
+                        if len(Intersections) > 0:\r
                             EdkLogger.error(\r
                             'build',\r
                             FORMAT_INVALID,\r
                             "Building modules from source INFs, following PCD use %s and %s access method. It must be corrected to use only one access method." % (i, j),\r
-                            ExtraData="%s" % '\n\t'.join([str(P[1]+'.'+P[0]) for P in IntersectionList])\r
+                            ExtraData="%s" % '\n\t'.join([str(P[1]+'.'+P[0]) for P in Intersections])\r
                             )\r
-                    else:\r
-                        pass\r
 \r
             #\r
             # intersection the BinaryPCD for Mixed PCD\r
@@ -476,8 +475,8 @@ class WorkspaceAutoGen(AutoGen):
             for i in BinaryPcdDict_Keys:\r
                 for j in BinaryPcdDict_Keys:\r
                     if i != j:\r
-                        IntersectionList = list(set(BinaryPcdDict[i]).intersection(set(BinaryPcdDict[j])))\r
-                        for item in IntersectionList:\r
+                        Intersections = BinaryPcdDict[i].intersection(BinaryPcdDict[j])\r
+                        for item in Intersections:\r
                             NewPcd1 = (item[0] + '_' + i, item[1])\r
                             NewPcd2 = (item[0] + '_' + j, item[1])\r
                             if item not in GlobalData.MixedPcd:\r
@@ -487,8 +486,6 @@ class WorkspaceAutoGen(AutoGen):
                                     GlobalData.MixedPcd[item].append(NewPcd1)\r
                                 if NewPcd2 not in GlobalData.MixedPcd[item]:\r
                                     GlobalData.MixedPcd[item].append(NewPcd2)\r
-                    else:\r
-                        pass\r
 \r
             #\r
             # intersection the SourcePCD and BinaryPCD for Mixed PCD\r
@@ -496,8 +493,8 @@ class WorkspaceAutoGen(AutoGen):
             for i in SourcePcdDict_Keys:\r
                 for j in BinaryPcdDict_Keys:\r
                     if i != j:\r
-                        IntersectionList = list(set(SourcePcdDict[i]).intersection(set(BinaryPcdDict[j])))\r
-                        for item in IntersectionList:\r
+                        Intersections = SourcePcdDict[i].intersection(BinaryPcdDict[j])\r
+                        for item in Intersections:\r
                             NewPcd1 = (item[0] + '_' + i, item[1])\r
                             NewPcd2 = (item[0] + '_' + j, item[1])\r
                             if item not in GlobalData.MixedPcd:\r
@@ -507,8 +504,6 @@ class WorkspaceAutoGen(AutoGen):
                                     GlobalData.MixedPcd[item].append(NewPcd1)\r
                                 if NewPcd2 not in GlobalData.MixedPcd[item]:\r
                                     GlobalData.MixedPcd[item].append(NewPcd2)\r
-                    else:\r
-                        pass\r
 \r
             for BuildData in PGen.BuildDatabase._CACHE_.values():\r
                 if BuildData.Arch != Arch:\r
@@ -529,11 +524,7 @@ class WorkspaceAutoGen(AutoGen):
                                     del BuildData.Pcds[key]\r
                                     BuildData.Pcds[newkey] = Value\r
                                     break\r
-                                else:\r
-                                    pass\r
                             break\r
-                        else:\r
-                            pass\r
 \r
             # handle the mixed pcd in FDF file\r
             for key in PcdSet:\r
@@ -765,7 +756,7 @@ class WorkspaceAutoGen(AutoGen):
         for Fv in Fdf.Profile.FvDict:\r
             _GuidDict = {}\r
             for FfsFile in Fdf.Profile.FvDict[Fv].FfsList:\r
-                if FfsFile.InfFileName and FfsFile.NameGuid == None:\r
+                if FfsFile.InfFileName and FfsFile.NameGuid is None:\r
                     #\r
                     # Get INF file GUID\r
                     #\r
@@ -816,14 +807,12 @@ class WorkspaceAutoGen(AutoGen):
                                                 ExtraData=self.FdfFile)\r
                         InfFoundFlag = False\r
 \r
-                if FfsFile.NameGuid != None:\r
-                    _CheckPCDAsGuidPattern = re.compile("^PCD\(.+\..+\)$")\r
-\r
+                if FfsFile.NameGuid is not None:\r
                     #\r
                     # If the NameGuid reference a PCD name. \r
                     # The style must match: PCD(xxxx.yyy)\r
                     #\r
-                    if _CheckPCDAsGuidPattern.match(FfsFile.NameGuid):\r
+                    if gPCDAsGuidPattern.match(FfsFile.NameGuid):\r
                         #\r
                         # Replace the PCD value.\r
                         #\r
@@ -891,7 +880,7 @@ class WorkspaceAutoGen(AutoGen):
         ]\r
 \r
         # This dict store PCDs which are not used by any modules with specified arches\r
-        UnusedPcd = sdict()\r
+        UnusedPcd = OrderedDict()\r
         for Pa in self.AutoGenObjectList:\r
             # Key of DSC's Pcds dictionary is PcdCName, TokenSpaceGuid\r
             for Pcd in Pa.Platform.Pcds:\r
@@ -938,13 +927,13 @@ class WorkspaceAutoGen(AutoGen):
 \r
     ## Return the directory to store FV files\r
     def _GetFvDir(self):\r
-        if self._FvDir == None:\r
+        if self._FvDir is None:\r
             self._FvDir = path.join(self.BuildDir, 'FV')\r
         return self._FvDir\r
 \r
     ## Return the directory to store all intermediate and final files built\r
     def _GetBuildDir(self):\r
-        if self._BuildDir == None:\r
+        if self._BuildDir is None:\r
             return self.AutoGenObjectList[0].BuildDir\r
 \r
     ## Return the build output directory platform specifies\r
@@ -972,7 +961,7 @@ class WorkspaceAutoGen(AutoGen):
     #   @retval     string  Makefile directory\r
     #\r
     def _GetMakeFileDir(self):\r
-        if self._MakeFileDir == None:\r
+        if self._MakeFileDir is None:\r
             self._MakeFileDir = self.BuildDir\r
         return self._MakeFileDir\r
 \r
@@ -981,7 +970,7 @@ class WorkspaceAutoGen(AutoGen):
     #   @retval     string  Build command string\r
     #\r
     def _GetBuildCommand(self):\r
-        if self._BuildCommand == None:\r
+        if self._BuildCommand is None:\r
             # BuildCommand should be all the same. So just get one from platform AutoGen\r
             self._BuildCommand = self.AutoGenObjectList[0].BuildCommand\r
         return self._BuildCommand\r
@@ -1111,6 +1100,14 @@ class WorkspaceAutoGen(AutoGen):
 #  file in order to generate makefile for platform.\r
 #\r
 class PlatformAutoGen(AutoGen):\r
+    # call super().__init__ then call the worker function with different parameter count\r
+    def __init__(self, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):\r
+        try:\r
+            self._Init\r
+        except:\r
+            super(PlatformAutoGen, self).__init__(self, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs)\r
+            self._InitWorker(Workspace, MetaFile, Target, Toolchain, Arch)\r
+            self._Init = True\r
     #\r
     # Used to store all PCDs for both PEI and DXE phase, in order to generate \r
     # correct PCD database\r
@@ -1139,11 +1136,8 @@ class PlatformAutoGen(AutoGen):
                 "0x10001"  : 2,      #  TARGET_*********_****_***********_ATTRIBUTE\r
                 "0x00001"  : 1}      #  ******_*********_****_***********_ATTRIBUTE (Lowest)\r
 \r
-    ## The real constructor of PlatformAutoGen\r
+    ## Initialize PlatformAutoGen\r
     #\r
-    #  This method is not supposed to be called by users of PlatformAutoGen. It's\r
-    #  only used by factory method __new__() to do real initialization work for an\r
-    #  object of PlatformAutoGen\r
     #\r
     #   @param      Workspace       WorkspaceAutoGen object\r
     #   @param      PlatformFile    Platform file (DSC file)\r
@@ -1151,7 +1145,7 @@ class PlatformAutoGen(AutoGen):
     #   @param      Toolchain       Name of tool chain\r
     #   @param      Arch            arch of the platform supports\r
     #\r
-    def _Init(self, Workspace, PlatformFile, Target, Toolchain, Arch):\r
+    def _InitWorker(self, Workspace, PlatformFile, Target, Toolchain, Arch):\r
         EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen platform [%s] [%s]" % (PlatformFile, Arch))\r
         GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (PlatformFile, Arch, Toolchain, Target)\r
 \r
@@ -1209,7 +1203,7 @@ class PlatformAutoGen(AutoGen):
 \r
         self.VariableInfo = None\r
 \r
-        if GlobalData.gFdfParser != None:\r
+        if GlobalData.gFdfParser is not None:\r
             self._AsBuildInfList = GlobalData.gFdfParser.Profile.InfList\r
             for Inf in self._AsBuildInfList:\r
                 InfClass = PathClass(NormPath(Inf), GlobalData.gWorkspace, self.Arch)\r
@@ -1325,7 +1319,7 @@ class PlatformAutoGen(AutoGen):
             for SkuName in Pcd.SkuInfoList:\r
                 Sku = Pcd.SkuInfoList[SkuName]\r
                 SkuId = Sku.SkuId\r
-                if SkuId == None or SkuId == '':\r
+                if SkuId is None or SkuId == '':\r
                     continue\r
                 if len(Sku.VariableName) > 0:\r
                     VariableGuidStructure = Sku.VariableGuidValue\r
@@ -1368,27 +1362,6 @@ class PlatformAutoGen(AutoGen):
     #  This interface should be invoked explicitly when platform action is created.\r
     #\r
     def CollectPlatformDynamicPcds(self):\r
-        # Override the platform Pcd's value by build option\r
-        if GlobalData.BuildOptionPcd:\r
-            for PcdItem in GlobalData.BuildOptionPcd:\r
-                PlatformPcd = self.Platform.Pcds.get((PcdItem[1],PcdItem[0]))\r
-                if PlatformPcd:\r
-                    if PlatformPcd.DatumType in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64,'BOOLEAN']:\r
-                        for sku in PlatformPcd.SkuInfoList:\r
-                            PlatformPcd.SkuInfoList[sku].DefaultValue = PcdItem[2]\r
-                    else:\r
-                        PcdDefaultValue = StringToArray(PcdItem[2])\r
-                        for sku in PlatformPcd.SkuInfoList:\r
-                            skuinfo = PlatformPcd.SkuInfoList[sku]\r
-                            if skuinfo.VariableGuid:\r
-                                skuinfo.HiiDefaultValue = PcdDefaultValue\r
-                            else:\r
-                                skuinfo.DefaultValue = PcdDefaultValue\r
-                        PlatformPcd.DefaultValue = PcdDefaultValue\r
-                        if PlatformPcd.MaxDatumSize:\r
-                            PlatformPcd.MaxDatumSize = str(max([int(PlatformPcd.MaxDatumSize),len(PcdDefaultValue.split(","))]))\r
-                        else:\r
-                            PlatformPcd.MaxDatumSize = str(len(PcdDefaultValue.split(",")))\r
 \r
         for key in self.Platform.Pcds:\r
             for SinglePcd in GlobalData.MixedPcd:\r
@@ -1657,7 +1630,7 @@ class PlatformAutoGen(AutoGen):
                         # if the offset of a VPD is *, then it need to be fixed up by third party tool.\r
                         if not NeedProcessVpdMapFile and Sku.VpdOffset == "*":\r
                             NeedProcessVpdMapFile = True\r
-                            if self.Platform.VpdToolGuid == None or self.Platform.VpdToolGuid == '':\r
+                            if self.Platform.VpdToolGuid is None or self.Platform.VpdToolGuid == '':\r
                                 EdkLogger.error("Build", FILE_NOT_FOUND, \\r
                                                 "Fail to find third-party BPDG tool to process VPD PCDs. BPDG Guid tool need to be defined in tools_def.txt and VPD_TOOL_GUID need to be provided in DSC file.")\r
 \r
@@ -1669,7 +1642,7 @@ class PlatformAutoGen(AutoGen):
             for DscPcd in PlatformPcds:\r
                 DscPcdEntry = self._PlatformPcds[DscPcd]\r
                 if DscPcdEntry.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD]:\r
-                    if not (self.Platform.VpdToolGuid == None or self.Platform.VpdToolGuid == ''):\r
+                    if not (self.Platform.VpdToolGuid is None or self.Platform.VpdToolGuid == ''):\r
                         FoundFlag = False\r
                         for VpdPcd in VpdFile._VpdArray.keys():\r
                             # This PCD has been referenced by module\r
@@ -1749,7 +1722,7 @@ class PlatformAutoGen(AutoGen):
 \r
                                 # if the offset of a VPD is *, then it need to be fixed up by third party tool.\r
                             VpdSkuMap[DscPcd] = SkuValueMap\r
-            if (self.Platform.FlashDefinition == None or self.Platform.FlashDefinition == '') and \\r
+            if (self.Platform.FlashDefinition is None or self.Platform.FlashDefinition == '') and \\r
                VpdFile.GetCount() != 0:\r
                 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, \r
                                 "Fail to get FLASH_DEFINITION definition in DSC file %s which is required when DSC contains VPD PCD." % str(self.Platform.MetaFile))\r
@@ -1832,14 +1805,14 @@ class PlatformAutoGen(AutoGen):
                     BPDGToolName = ToolDef["PATH"]\r
                     break\r
             # Call third party GUID BPDG tool.\r
-            if BPDGToolName != None:\r
+            if BPDGToolName is not None:\r
                 VpdInfoFile.CallExtenalBPDGTool(BPDGToolName, VpdFilePath)\r
             else:\r
                 EdkLogger.error("Build", FILE_NOT_FOUND, "Fail to find third-party BPDG tool to process VPD PCDs. BPDG Guid tool need to be defined in tools_def.txt and VPD_TOOL_GUID need to be provided in DSC file.")\r
 \r
     ## Return the platform build data object\r
     def _GetPlatform(self):\r
-        if self._Platform == None:\r
+        if self._Platform is None:\r
             self._Platform = self.BuildDatabase[self.MetaFile, self.Arch, self.BuildTarget, self.ToolChain]\r
         return self._Platform\r
 \r
@@ -1857,7 +1830,7 @@ class PlatformAutoGen(AutoGen):
 \r
     ## Return the FDF file name\r
     def _GetFdfFile(self):\r
-        if self._FdfFile == None:\r
+        if self._FdfFile is None:\r
             if self.Workspace.FdfFile != "":\r
                 self._FdfFile= mws.join(self.WorkspaceDir, self.Workspace.FdfFile)\r
             else:\r
@@ -1870,7 +1843,7 @@ class PlatformAutoGen(AutoGen):
 \r
     ## Return the directory to store all intermediate and final files built\r
     def _GetBuildDir(self):\r
-        if self._BuildDir == None:\r
+        if self._BuildDir is None:\r
             if os.path.isabs(self.OutputDir):\r
                 self._BuildDir = path.join(\r
                                             path.abspath(self.OutputDir),\r
@@ -1890,7 +1863,7 @@ class PlatformAutoGen(AutoGen):
     #   @retval     string  Makefile directory\r
     #\r
     def _GetMakeFileDir(self):\r
-        if self._MakeFileDir == None:\r
+        if self._MakeFileDir is None:\r
             self._MakeFileDir = path.join(self.BuildDir, self.Arch)\r
         return self._MakeFileDir\r
 \r
@@ -1899,7 +1872,7 @@ class PlatformAutoGen(AutoGen):
     #   @retval     string  Build command string\r
     #\r
     def _GetBuildCommand(self):\r
-        if self._BuildCommand == None:\r
+        if self._BuildCommand is None:\r
             self._BuildCommand = []\r
             if "MAKE" in self.ToolDefinition and "PATH" in self.ToolDefinition["MAKE"]:\r
                 self._BuildCommand += SplitOption(self.ToolDefinition["MAKE"]["PATH"])\r
@@ -1921,7 +1894,7 @@ class PlatformAutoGen(AutoGen):
     #  Get each tool defition for given tool chain from tools_def.txt and platform\r
     #\r
     def _GetToolDefinition(self):\r
-        if self._ToolDefinitions == None:\r
+        if self._ToolDefinitions is None:\r
             ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDictionary\r
             if TAB_TOD_DEFINES_COMMAND_TYPE not in self.Workspace.ToolDef.ToolsDefTxtDatabase:\r
                 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No tools found in configuration",\r
@@ -1987,13 +1960,13 @@ class PlatformAutoGen(AutoGen):
 \r
     ## Return the paths of tools\r
     def _GetToolDefFile(self):\r
-        if self._ToolDefFile == None:\r
+        if self._ToolDefFile is None:\r
             self._ToolDefFile = os.path.join(self.MakeFileDir, "TOOLS_DEF." + self.Arch)\r
         return self._ToolDefFile\r
 \r
     ## Retrieve the toolchain family of given toolchain tag. Default to 'MSFT'.\r
     def _GetToolChainFamily(self):\r
-        if self._ToolChainFamily == None:\r
+        if self._ToolChainFamily is None:\r
             ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase\r
             if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \\r
                or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \\r
@@ -2006,7 +1979,7 @@ class PlatformAutoGen(AutoGen):
         return self._ToolChainFamily\r
 \r
     def _GetBuildRuleFamily(self):\r
-        if self._BuildRuleFamily == None:\r
+        if self._BuildRuleFamily is None:\r
             ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase\r
             if TAB_TOD_DEFINES_BUILDRULEFAMILY not in ToolDefinition \\r
                or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY] \\r
@@ -2020,19 +1993,19 @@ class PlatformAutoGen(AutoGen):
 \r
     ## Return the build options specific for all modules in this platform\r
     def _GetBuildOptions(self):\r
-        if self._BuildOption == None:\r
+        if self._BuildOption is None:\r
             self._BuildOption = self._ExpandBuildOption(self.Platform.BuildOptions)\r
         return self._BuildOption\r
 \r
     ## Return the build options specific for EDK modules in this platform\r
     def _GetEdkBuildOptions(self):\r
-        if self._EdkBuildOption == None:\r
+        if self._EdkBuildOption is None:\r
             self._EdkBuildOption = self._ExpandBuildOption(self.Platform.BuildOptions, EDK_NAME)\r
         return self._EdkBuildOption\r
 \r
     ## Return the build options specific for EDKII modules in this platform\r
     def _GetEdkIIBuildOptions(self):\r
-        if self._EdkIIBuildOption == None:\r
+        if self._EdkIIBuildOption is None:\r
             self._EdkIIBuildOption = self._ExpandBuildOption(self.Platform.BuildOptions, EDKII_NAME)\r
         return self._EdkIIBuildOption\r
 \r
@@ -2041,7 +2014,7 @@ class PlatformAutoGen(AutoGen):
     #   @retval     BuildRule object\r
     #\r
     def _GetBuildRule(self):\r
-        if self._BuildRule == None:\r
+        if self._BuildRule is None:\r
             BuildRuleFile = None\r
             if TAB_TAT_DEFINES_BUILD_RULE_CONF in self.Workspace.TargetTxt.TargetTxtDictionary:\r
                 BuildRuleFile = self.Workspace.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_BUILD_RULE_CONF]\r
@@ -2061,7 +2034,7 @@ class PlatformAutoGen(AutoGen):
 \r
     ## Summarize the packages used by modules in this platform\r
     def _GetPackageList(self):\r
-        if self._PackageList == None:\r
+        if self._PackageList is None:\r
             self._PackageList = set()\r
             for La in self.LibraryAutoGenList:\r
                 self._PackageList.update(La.DependentPackageList)\r
@@ -2086,20 +2059,20 @@ class PlatformAutoGen(AutoGen):
 \r
     ## Get list of non-dynamic PCDs\r
     def _GetNonDynamicPcdList(self):\r
-        if self._NonDynamicPcdList == None:\r
+        if self._NonDynamicPcdList is None:\r
             self.CollectPlatformDynamicPcds()\r
         return self._NonDynamicPcdList\r
 \r
     ## Get list of dynamic PCDs\r
     def _GetDynamicPcdList(self):\r
-        if self._DynamicPcdList == None:\r
+        if self._DynamicPcdList is None:\r
             self.CollectPlatformDynamicPcds()\r
         return self._DynamicPcdList\r
 \r
     ## Generate Token Number for all PCD\r
     def _GetPcdTokenNumbers(self):\r
-        if self._PcdTokenNumber == None:\r
-            self._PcdTokenNumber = sdict()\r
+        if self._PcdTokenNumber is None:\r
+            self._PcdTokenNumber = OrderedDict()\r
             TokenNumber = 1\r
             #\r
             # Make the Dynamic and DynamicEx PCD use within different TokenNumber area. \r
@@ -2166,13 +2139,13 @@ class PlatformAutoGen(AutoGen):
 \r
     ## Summarize ModuleAutoGen objects of all modules to be built for this platform\r
     def _GetModuleAutoGenList(self):\r
-        if self._ModuleAutoGenList == None:\r
+        if self._ModuleAutoGenList is None:\r
             self._GetAutoGenObjectList()\r
         return self._ModuleAutoGenList\r
 \r
     ## Summarize ModuleAutoGen objects of all libraries to be built for this platform\r
     def _GetLibraryAutoGenList(self):\r
-        if self._LibraryAutoGenList == None:\r
+        if self._LibraryAutoGenList is None:\r
             self._GetAutoGenObjectList()\r
         return self._LibraryAutoGenList\r
 \r
@@ -2222,8 +2195,8 @@ class PlatformAutoGen(AutoGen):
         # EdkII module\r
         LibraryConsumerList = [Module]\r
         Constructor         = []\r
-        ConsumedByList      = sdict()\r
-        LibraryInstance     = sdict()\r
+        ConsumedByList      = OrderedDict()\r
+        LibraryInstance     = OrderedDict()\r
 \r
         EdkLogger.verbose("")\r
         EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))\r
@@ -2236,9 +2209,9 @@ class PlatformAutoGen(AutoGen):
                         LibraryPath = PlatformModule.LibraryClasses[LibraryClassName]\r
                     else:\r
                         LibraryPath = self.Platform.LibraryClasses[LibraryClassName, ModuleType]\r
-                    if LibraryPath == None or LibraryPath == "":\r
+                    if LibraryPath is None or LibraryPath == "":\r
                         LibraryPath = M.LibraryClasses[LibraryClassName]\r
-                        if LibraryPath == None or LibraryPath == "":\r
+                        if LibraryPath is None or LibraryPath == "":\r
                             EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,\r
                                             "Instance of library class [%s] is not found" % LibraryClassName,\r
                                             File=self.MetaFile,\r
@@ -2248,7 +2221,7 @@ class PlatformAutoGen(AutoGen):
                     # for those forced library instance (NULL library), add a fake library class\r
                     if LibraryClassName.startswith("NULL"):\r
                         LibraryModule.LibraryClass.append(LibraryClassObject(LibraryClassName, [ModuleType]))\r
-                    elif LibraryModule.LibraryClass == None \\r
+                    elif LibraryModule.LibraryClass is None \\r
                          or len(LibraryModule.LibraryClass) == 0 \\r
                          or (ModuleType != 'USER_DEFINED'\r
                              and ModuleType not in LibraryModule.LibraryClass[0].SupModList):\r
@@ -2264,7 +2237,7 @@ class PlatformAutoGen(AutoGen):
                 else:\r
                     LibraryModule = LibraryInstance[LibraryClassName]\r
 \r
-                if LibraryModule == None:\r
+                if LibraryModule is None:\r
                     continue\r
 \r
                 if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor:\r
@@ -2372,12 +2345,7 @@ class PlatformAutoGen(AutoGen):
             if (ToPcd.TokenCName, ToPcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:\r
                 TokenCName = PcdItem[0]\r
                 break\r
-        if FromPcd != None:\r
-            if GlobalData.BuildOptionPcd:\r
-                for pcd in GlobalData.BuildOptionPcd:\r
-                    if (FromPcd.TokenSpaceGuidCName, FromPcd.TokenCName) == (pcd[0], pcd[1]):\r
-                        FromPcd.DefaultValue = pcd[2]\r
-                        break\r
+        if FromPcd is not None:\r
             if ToPcd.Pending and FromPcd.Type not in [None, '']:\r
                 ToPcd.Type = FromPcd.Type\r
             elif (ToPcd.Type not in [None, '']) and (FromPcd.Type not in [None, ''])\\r
@@ -2421,7 +2389,7 @@ class PlatformAutoGen(AutoGen):
             ToPcd.validlists = FromPcd.validlists\r
             ToPcd.expressions = FromPcd.expressions\r
 \r
-        if ToPcd.DatumType == "VOID*" and ToPcd.MaxDatumSize in ['', None]:\r
+        if FromPcd is not None and ToPcd.DatumType == "VOID*" and ToPcd.MaxDatumSize in ['', None]:\r
             EdkLogger.debug(EdkLogger.DEBUG_9, "No MaxDatumSize specified for PCD %s.%s" \\r
                             % (ToPcd.TokenSpaceGuidCName, TokenCName))\r
             Value = ToPcd.DefaultValue\r
@@ -2467,7 +2435,7 @@ class PlatformAutoGen(AutoGen):
                 Sku = PcdInModule.SkuInfoList[SkuId]\r
                 if Sku.VariableGuid == '': continue\r
                 Sku.VariableGuidValue = GuidValue(Sku.VariableGuid, self.PackageList, self.MetaFile.Path)\r
-                if Sku.VariableGuidValue == None:\r
+                if Sku.VariableGuidValue is None:\r
                     PackageList = "\n\t".join([str(P) for P in self.PackageList])\r
                     EdkLogger.error(\r
                                 'build',\r
@@ -2494,6 +2462,19 @@ class PlatformAutoGen(AutoGen):
                             break\r
                 if Flag:\r
                     self._OverridePcd(ToPcd, PlatformModule.Pcds[Key], Module)\r
+        # use PCD value to calculate the MaxDatumSize when it is not specified\r
+        for Name, Guid in Pcds:\r
+            Pcd = Pcds[Name, Guid]\r
+            if Pcd.DatumType == "VOID*" and Pcd.MaxDatumSize in ['', None]:\r
+                Value = Pcd.DefaultValue\r
+                if Value in [None, '']:\r
+                    Pcd.MaxDatumSize = '1'\r
+                elif Value[0] == 'L':\r
+                    Pcd.MaxDatumSize = str((len(Value) - 2) * 2)\r
+                elif Value[0] == '{':\r
+                    Pcd.MaxDatumSize = str(len(Value.split(',')))\r
+                else:\r
+                    Pcd.MaxDatumSize = str(len(Value) - 1)\r
         return Pcds.values()\r
 \r
     ## Resolve library names to library modules\r
@@ -2517,12 +2498,12 @@ class PlatformAutoGen(AutoGen):
             M = LibraryConsumerList.pop()\r
             for LibraryName in M.Libraries:\r
                 Library = self.Platform.LibraryClasses[LibraryName, ':dummy:']\r
-                if Library == None:\r
+                if Library is None:\r
                     for Key in self.Platform.LibraryClasses.data.keys():\r
                         if LibraryName.upper() == Key.upper():\r
                             Library = self.Platform.LibraryClasses[Key, ':dummy:']\r
                             break\r
-                    if Library == None:\r
+                    if Library is None:\r
                         EdkLogger.warn("build", "Library [%s] is not found" % LibraryName, File=str(M),\r
                             ExtraData="\t%s [%s]" % (str(Module), self.Arch))\r
                         continue\r
@@ -2577,13 +2558,13 @@ class PlatformAutoGen(AutoGen):
             # Key[1] -- TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE\r
             #\r
             if (Key[0] == self.BuildRuleFamily and\r
-                (ModuleStyle == None or len(Key) < 3 or (len(Key) > 2 and Key[2] == ModuleStyle))):\r
+                (ModuleStyle is None or len(Key) < 3 or (len(Key) > 2 and Key[2] == ModuleStyle))):\r
                 Target, ToolChain, Arch, CommandType, Attr = Key[1].split('_')\r
                 if Target == self.BuildTarget or Target == "*":\r
                     if ToolChain == self.ToolChain or ToolChain == "*":\r
                         if Arch == self.Arch or Arch == "*":\r
                             if Options[Key].startswith("="):\r
-                                if OverrideList.get(Key[1]) != None:\r
+                                if OverrideList.get(Key[1]) is not None:\r
                                     OverrideList.pop(Key[1])\r
                                 OverrideList[Key[1]] = Options[Key]\r
         \r
@@ -2607,14 +2588,14 @@ class PlatformAutoGen(AutoGen):
                                 if CommandType1 == CommandType2 or CommandType1 == "*" or CommandType2 == "*":\r
                                     if Attr1 == Attr2 or Attr1 == "*" or Attr2 == "*":\r
                                         if self.CalculatePriorityValue(NowKey) > self.CalculatePriorityValue(NextKey):\r
-                                            if Options.get((self.BuildRuleFamily, NextKey)) != None:\r
+                                            if Options.get((self.BuildRuleFamily, NextKey)) is not None:\r
                                                 Options.pop((self.BuildRuleFamily, NextKey))\r
                                         else:\r
-                                            if Options.get((self.BuildRuleFamily, NowKey)) != None:\r
+                                            if Options.get((self.BuildRuleFamily, NowKey)) is not None:\r
                                                 Options.pop((self.BuildRuleFamily, NowKey))\r
                                                            \r
         for Key in Options:\r
-            if ModuleStyle != None and len (Key) > 2:\r
+            if ModuleStyle is not None and len (Key) > 2:\r
                 # Check Module style is EDK or EDKII.\r
                 # Only append build option for the matched style module.\r
                 if ModuleStyle == EDK_NAME and Key[2] != EDK_NAME:\r
@@ -2651,7 +2632,7 @@ class PlatformAutoGen(AutoGen):
             return BuildOptions\r
 \r
         for Key in Options:\r
-            if ModuleStyle != None and len (Key) > 2:\r
+            if ModuleStyle is not None and len (Key) > 2:\r
                 # Check Module style is EDK or EDKII.\r
                 # Only append build option for the matched style module.\r
                 if ModuleStyle == EDK_NAME and Key[2] != EDK_NAME:\r
@@ -2743,7 +2724,7 @@ class PlatformAutoGen(AutoGen):
                             BuildOptions[Tool][Attr] += " " + Value\r
                         else:\r
                             BuildOptions[Tool][Attr] = Value\r
-        if Module.AutoGenVersion < 0x00010005 and self.Workspace.UniFlag != None:\r
+        if Module.AutoGenVersion < 0x00010005 and self.Workspace.UniFlag is not None:\r
             #\r
             # Override UNI flag only for EDK module.\r
             #\r
@@ -2789,15 +2770,29 @@ class PlatformAutoGen(AutoGen):
 # to the [depex] section in module's inf file.\r
 #\r
 class ModuleAutoGen(AutoGen):\r
+    # call super().__init__ then call the worker function with different parameter count\r
+    def __init__(self, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):\r
+        try:\r
+            self._Init\r
+        except:\r
+            super(ModuleAutoGen, self).__init__(Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs)\r
+            self._InitWorker(Workspace, MetaFile, Target, Toolchain, Arch, *args)\r
+            self._Init = True\r
+\r
     ## Cache the timestamps of metafiles of every module in a class variable\r
     #\r
     TimeDict = {}\r
 \r
-    ## The real constructor of ModuleAutoGen\r
-    #\r
-    #  This method is not supposed to be called by users of ModuleAutoGen. It's\r
-    #  only used by factory method __new__() to do real initialization work for an\r
-    #  object of ModuleAutoGen\r
+    def __new__(cls, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):\r
+        obj = super(ModuleAutoGen, cls).__new__(cls, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs)\r
+        # check if this module is employed by active platform\r
+        if not PlatformAutoGen(Workspace, args[0], Target, Toolchain, Arch).ValidModule(MetaFile):\r
+            EdkLogger.verbose("Module [%s] for [%s] is not employed by active platform\n" \\r
+                              % (MetaFile, Arch))\r
+            return None\r
+        return obj\r
+            \r
+    ## Initialize ModuleAutoGen\r
     #\r
     #   @param      Workspace           EdkIIWorkspaceBuild object\r
     #   @param      ModuleFile          The path of module file\r
@@ -2806,7 +2801,7 @@ class ModuleAutoGen(AutoGen):
     #   @param      Arch                The arch the module supports\r
     #   @param      PlatformFile        Platform meta-file\r
     #\r
-    def _Init(self, Workspace, ModuleFile, Target, Toolchain, Arch, PlatformFile):\r
+    def _InitWorker(self, Workspace, ModuleFile, Target, Toolchain, Arch, PlatformFile):\r
         EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen module [%s] [%s]" % (ModuleFile, Arch))\r
         GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (ModuleFile, Arch, Toolchain, Target)\r
 \r
@@ -2815,11 +2810,6 @@ class ModuleAutoGen(AutoGen):
 \r
         self.MetaFile = ModuleFile\r
         self.PlatformInfo = PlatformAutoGen(Workspace, PlatformFile, Target, Toolchain, Arch)\r
-        # check if this module is employed by active platform\r
-        if not self.PlatformInfo.ValidModule(self.MetaFile):\r
-            EdkLogger.verbose("Module [%s] for [%s] is not employed by active platform\n" \\r
-                              % (self.MetaFile, Arch))\r
-            return False\r
 \r
         self.SourceDir = self.MetaFile.SubDir\r
         self.SourceDir = mws.relpath(self.SourceDir, self.WorkspaceDir)\r
@@ -2878,14 +2868,14 @@ class ModuleAutoGen(AutoGen):
         self._DerivedPackageList      = None\r
         self._ModulePcdList           = None\r
         self._LibraryPcdList          = None\r
-        self._PcdComments = sdict()\r
+        self._PcdComments = OrderedDict()\r
         self._GuidList                = None\r
         self._GuidsUsedByPcd = None\r
-        self._GuidComments = sdict()\r
+        self._GuidComments = OrderedDict()\r
         self._ProtocolList            = None\r
-        self._ProtocolComments = sdict()\r
+        self._ProtocolComments = OrderedDict()\r
         self._PpiList                 = None\r
-        self._PpiComments = sdict()\r
+        self._PpiComments = OrderedDict()\r
         self._DepexList               = None\r
         self._DepexExpressionList     = None\r
         self._BuildOption             = None\r
@@ -2940,8 +2930,8 @@ class ModuleAutoGen(AutoGen):
 \r
     # Macros could be used in build_rule.txt (also Makefile)\r
     def _GetMacros(self):\r
-        if self._Macro == None:\r
-            self._Macro = sdict()\r
+        if self._Macro is None:\r
+            self._Macro = OrderedDict()\r
             self._Macro["WORKSPACE"             ] = self.WorkspaceDir\r
             self._Macro["MODULE_NAME"           ] = self.Name\r
             self._Macro["MODULE_NAME_GUID"      ] = self._GetUniqueBaseName()\r
@@ -2980,7 +2970,7 @@ class ModuleAutoGen(AutoGen):
 \r
     ## Return the module build data object\r
     def _GetModule(self):\r
-        if self._Module == None:\r
+        if self._Module is None:\r
             self._Module = self.Workspace.BuildDatabase[self.MetaFile, self.Arch, self.BuildTarget, self.ToolChain]\r
         return self._Module\r
 \r
@@ -3036,8 +3026,8 @@ class ModuleAutoGen(AutoGen):
 \r
     ## Check if the module is library or not\r
     def _IsLibrary(self):\r
-        if self._LibraryFlag == None:\r
-            if self.Module.LibraryClass != None and self.Module.LibraryClass != []:\r
+        if self._LibraryFlag is None:\r
+            if self.Module.LibraryClass is not None and self.Module.LibraryClass != []:\r
                 self._LibraryFlag = True\r
             else:\r
                 self._LibraryFlag = False\r
@@ -3049,7 +3039,7 @@ class ModuleAutoGen(AutoGen):
 \r
     ## Return the directory to store intermediate files of the module\r
     def _GetBuildDir(self):\r
-        if self._BuildDir == None:\r
+        if self._BuildDir is None:\r
             self._BuildDir = path.join(\r
                                     self.PlatformInfo.BuildDir,\r
                                     self.Arch,\r
@@ -3061,15 +3051,15 @@ class ModuleAutoGen(AutoGen):
 \r
     ## Return the directory to store the intermediate object files of the mdoule\r
     def _GetOutputDir(self):\r
-        if self._OutputDir == None:\r
+        if self._OutputDir is None:\r
             self._OutputDir = path.join(self.BuildDir, "OUTPUT")\r
             CreateDirectory(self._OutputDir)\r
         return self._OutputDir\r
 \r
     ## Return the directory to store ffs file\r
     def _GetFfsOutputDir(self):\r
-        if self._FfsOutputDir == None:\r
-            if GlobalData.gFdfParser != None:\r
+        if self._FfsOutputDir is None:\r
+            if GlobalData.gFdfParser is not None:\r
                 self._FfsOutputDir = path.join(self.PlatformInfo.BuildDir, "FV", "Ffs", self.Guid + self.Name)\r
             else:\r
                 self._FfsOutputDir = ''\r
@@ -3077,21 +3067,21 @@ class ModuleAutoGen(AutoGen):
 \r
     ## Return the directory to store auto-gened source files of the mdoule\r
     def _GetDebugDir(self):\r
-        if self._DebugDir == None:\r
+        if self._DebugDir is None:\r
             self._DebugDir = path.join(self.BuildDir, "DEBUG")\r
             CreateDirectory(self._DebugDir)\r
         return self._DebugDir\r
 \r
     ## Return the path of custom file\r
     def _GetCustomMakefile(self):\r
-        if self._CustomMakefile == None:\r
+        if self._CustomMakefile is None:\r
             self._CustomMakefile = {}\r
             for Type in self.Module.CustomMakefile:\r
                 if Type in gMakeTypeMap:\r
                     MakeType = gMakeTypeMap[Type]\r
                 else:\r
                     MakeType = 'nmake'\r
-                if self.SourceOverrideDir != None:\r
+                if self.SourceOverrideDir is not None:\r
                     File = os.path.join(self.SourceOverrideDir, self.Module.CustomMakefile[Type])\r
                     if not os.path.exists(File):\r
                         File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])\r
@@ -3192,7 +3182,7 @@ class ModuleAutoGen(AutoGen):
     #   @retval     list    The token list of the dependency expression after parsed\r
     #\r
     def _GetDepexTokenList(self):\r
-        if self._DepexList == None:\r
+        if self._DepexList is None:\r
             self._DepexList = {}\r
             if self.DxsFile or self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes:\r
                 return self._DepexList\r
@@ -3228,7 +3218,7 @@ class ModuleAutoGen(AutoGen):
     #   @retval     list    The token list of the dependency expression after parsed\r
     #\r
     def _GetDepexExpressionTokenList(self):\r
-        if self._DepexExpressionList == None:\r
+        if self._DepexExpressionList is None:\r
             self._DepexExpressionList = {}\r
             if self.DxsFile or self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes:\r
                 return self._DepexExpressionList\r
@@ -3296,7 +3286,7 @@ class ModuleAutoGen(AutoGen):
     #   @retval     dict            The dict containing valid options\r
     #\r
     def _GetModuleBuildOption(self):\r
-        if self._BuildOption == None:\r
+        if self._BuildOption is None:\r
             self._BuildOption, self.BuildRuleOrder = self.PlatformInfo.ApplyBuildOption(self.Module)\r
             if self.BuildRuleOrder:\r
                 self.BuildRuleOrder = ['.%s' % Ext for Ext in self.BuildRuleOrder.split()]\r
@@ -3307,15 +3297,15 @@ class ModuleAutoGen(AutoGen):
     #   @retval     list            The include path list\r
     #\r
     def _GetBuildOptionIncPathList(self):\r
-        if self._BuildOptionIncPathList == None:\r
+        if self._BuildOptionIncPathList is None:\r
             #\r
             # Regular expression for finding Include Directories, the difference between MSFT and INTEL/GCC/RVCT\r
             # is the former use /I , the Latter used -I to specify include directories\r
             #\r
             if self.PlatformInfo.ToolChainFamily in ('MSFT'):\r
-                gBuildOptIncludePattern = re.compile(r"(?:.*?)/I[ \t]*([^ ]*)", re.MULTILINE | re.DOTALL)\r
+                BuildOptIncludeRegEx = gBuildOptIncludePatternMsft\r
             elif self.PlatformInfo.ToolChainFamily in ('INTEL', 'GCC', 'RVCT'):\r
-                gBuildOptIncludePattern = re.compile(r"(?:.*?)-I[ \t]*([^ ]*)", re.MULTILINE | re.DOTALL)\r
+                BuildOptIncludeRegEx = gBuildOptIncludePatternOther\r
             else:\r
                 #\r
                 # New ToolChainFamily, don't known whether there is option to specify include directories\r
@@ -3332,13 +3322,13 @@ class ModuleAutoGen(AutoGen):
                     FlagOption = ''\r
                 \r
                 if self.PlatformInfo.ToolChainFamily != 'RVCT':\r
-                    IncPathList = [NormPath(Path, self.Macros) for Path in gBuildOptIncludePattern.findall(FlagOption)]\r
+                    IncPathList = [NormPath(Path, self.Macros) for Path in BuildOptIncludeRegEx.findall(FlagOption)]\r
                 else:\r
                     #\r
                     # RVCT may specify a list of directory seperated by commas\r
                     #\r
                     IncPathList = []\r
-                    for Path in gBuildOptIncludePattern.findall(FlagOption):\r
+                    for Path in BuildOptIncludeRegEx.findall(FlagOption):\r
                         PathList = GetSplitList(Path, TAB_COMMA_SPLIT)\r
                         IncPathList += [NormPath(PathEntry, self.Macros) for PathEntry in PathList]\r
 \r
@@ -3368,7 +3358,7 @@ class ModuleAutoGen(AutoGen):
     #  $(CONF_DIRECTORY)/build_rule.txt and toolchain family.\r
     #\r
     def _GetSourceFileList(self):\r
-        if self._SourceFileList == None:\r
+        if self._SourceFileList is None:\r
             self._SourceFileList = []\r
             for F in self.Module.Sources:\r
                 # match tool chain\r
@@ -3421,7 +3411,7 @@ class ModuleAutoGen(AutoGen):
 \r
     ## Return the list of unicode files\r
     def _GetUnicodeFileList(self):\r
-        if self._UnicodeFileList == None:\r
+        if self._UnicodeFileList is None:\r
             if TAB_UNICODE_FILE in self.FileTypes:\r
                 self._UnicodeFileList = self.FileTypes[TAB_UNICODE_FILE]\r
             else:\r
@@ -3430,7 +3420,7 @@ class ModuleAutoGen(AutoGen):
 \r
     ## Return the list of vfr files\r
     def _GetVfrFileList(self):\r
-        if self._VfrFileList == None:\r
+        if self._VfrFileList is None:\r
             if TAB_VFR_FILE in self.FileTypes:\r
                 self._VfrFileList = self.FileTypes[TAB_VFR_FILE]\r
             else:\r
@@ -3439,7 +3429,7 @@ class ModuleAutoGen(AutoGen):
 \r
     ## Return the list of Image Definition files\r
     def _GetIdfFileList(self):\r
-        if self._IdfFileList == None:\r
+        if self._IdfFileList is None:\r
             if TAB_IMAGE_FILE in self.FileTypes:\r
                 self._IdfFileList = self.FileTypes[TAB_IMAGE_FILE]\r
             else:\r
@@ -3453,7 +3443,7 @@ class ModuleAutoGen(AutoGen):
     #   @retval     list            The list of files which can be built later\r
     #\r
     def _GetBinaryFiles(self):\r
-        if self._BinaryFileList == None:\r
+        if self._BinaryFileList is None:\r
             self._BinaryFileList = []\r
             for F in self.Module.Binaries:\r
                 if F.Target not in ['COMMON', '*'] and F.Target != self.BuildTarget:\r
@@ -3463,7 +3453,7 @@ class ModuleAutoGen(AutoGen):
         return self._BinaryFileList\r
 \r
     def _GetBuildRules(self):\r
-        if self._BuildRules == None:\r
+        if self._BuildRules is None:\r
             BuildRules = {}\r
             BuildRuleDatabase = self.PlatformInfo.BuildRule\r
             for Type in BuildRuleDatabase.FileTypeList:\r
@@ -3490,7 +3480,7 @@ class ModuleAutoGen(AutoGen):
         return self._BuildRules\r
 \r
     def _ApplyBuildRule(self, File, FileType):\r
-        if self._BuildTargets == None:\r
+        if self._BuildTargets is None:\r
             self._IntroBuildTargetList = set()\r
             self._FinalBuildTargetList = set()\r
             self._BuildTargets = {}\r
@@ -3515,7 +3505,7 @@ class ModuleAutoGen(AutoGen):
             if Source != File:\r
                 CreateDirectory(Source.Dir)\r
 \r
-            if File.IsBinary and File == Source and self._BinaryFileList != None and File in self._BinaryFileList:\r
+            if File.IsBinary and File == Source and self._BinaryFileList is not None and File in self._BinaryFileList:\r
                 # Skip all files that are not binary libraries\r
                 if not self.IsLibrary:\r
                     continue\r
@@ -3567,7 +3557,7 @@ class ModuleAutoGen(AutoGen):
             FileType = TAB_UNKNOWN_FILE\r
 \r
     def _GetTargets(self):\r
-        if self._BuildTargets == None:\r
+        if self._BuildTargets is None:\r
             self._IntroBuildTargetList = set()\r
             self._FinalBuildTargetList = set()\r
             self._BuildTargets = {}\r
@@ -3614,7 +3604,7 @@ class ModuleAutoGen(AutoGen):
         if self.BuildType == 'UEFI_HII':\r
             UniStringAutoGenC = False\r
             IdfStringAutoGenC = False\r
-        if self._AutoGenFileList == None:\r
+        if self._AutoGenFileList is None:\r
             self._AutoGenFileList = {}\r
             AutoGenC = TemplateString()\r
             AutoGenH = TemplateString()\r
@@ -3637,29 +3627,29 @@ class ModuleAutoGen(AutoGen):
                 AutoFile = PathClass(gAutoGenStringFileName % {"module_name":self.Name}, self.DebugDir)\r
                 self._AutoGenFileList[AutoFile] = str(StringH)\r
                 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)\r
-            if UniStringBinBuffer != None and UniStringBinBuffer.getvalue() != "":\r
+            if UniStringBinBuffer is not None and UniStringBinBuffer.getvalue() != "":\r
                 AutoFile = PathClass(gAutoGenStringFormFileName % {"module_name":self.Name}, self.OutputDir)\r
                 self._AutoGenFileList[AutoFile] = UniStringBinBuffer.getvalue()\r
                 AutoFile.IsBinary = True\r
                 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)\r
-            if UniStringBinBuffer != None:\r
+            if UniStringBinBuffer is not None:\r
                 UniStringBinBuffer.close()\r
             if str(StringIdf) != "":\r
                 AutoFile = PathClass(gAutoGenImageDefFileName % {"module_name":self.Name}, self.DebugDir)\r
                 self._AutoGenFileList[AutoFile] = str(StringIdf)\r
                 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)\r
-            if IdfGenBinBuffer != None and IdfGenBinBuffer.getvalue() != "":\r
+            if IdfGenBinBuffer is not None and IdfGenBinBuffer.getvalue() != "":\r
                 AutoFile = PathClass(gAutoGenIdfFileName % {"module_name":self.Name}, self.OutputDir)\r
                 self._AutoGenFileList[AutoFile] = IdfGenBinBuffer.getvalue()\r
                 AutoFile.IsBinary = True\r
                 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)\r
-            if IdfGenBinBuffer != None:\r
+            if IdfGenBinBuffer is not None:\r
                 IdfGenBinBuffer.close()\r
         return self._AutoGenFileList\r
 \r
     ## Return the list of library modules explicitly or implicityly used by this module\r
     def _GetLibraryList(self):\r
-        if self._DependentLibraryList == None:\r
+        if self._DependentLibraryList is None:\r
             # only merge library classes and PCD for non-library module\r
             if self.IsLibrary:\r
                 self._DependentLibraryList = []\r
@@ -3681,7 +3671,7 @@ class ModuleAutoGen(AutoGen):
     #   @retval     list                    The list of PCD\r
     #\r
     def _GetModulePcdList(self):\r
-        if self._ModulePcdList == None:\r
+        if self._ModulePcdList is None:\r
             # apply PCD settings from platform\r
             self._ModulePcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, self.Module.Pcds)\r
             self.UpdateComments(self._PcdComments, self.Module.PcdComments)\r
@@ -3692,8 +3682,8 @@ class ModuleAutoGen(AutoGen):
     #   @retval     list                    The list of PCD\r
     #\r
     def _GetLibraryPcdList(self):\r
-        if self._LibraryPcdList == None:\r
-            Pcds = sdict()\r
+        if self._LibraryPcdList is None:\r
+            Pcds = OrderedDict()\r
             if not self.IsLibrary:\r
                 # get PCDs from dependent libraries\r
                 for Library in self.DependentLibraryList:\r
@@ -3714,8 +3704,8 @@ class ModuleAutoGen(AutoGen):
     #   @retval     dict    The mapping between GUID cname and its value\r
     #\r
     def _GetGuidList(self):\r
-        if self._GuidList == None:\r
-            self._GuidList = sdict()\r
+        if self._GuidList is None:\r
+            self._GuidList = OrderedDict()\r
             self._GuidList.update(self.Module.Guids)\r
             for Library in self.DependentLibraryList:\r
                 self._GuidList.update(Library.Guids)\r
@@ -3724,8 +3714,8 @@ class ModuleAutoGen(AutoGen):
         return self._GuidList\r
 \r
     def GetGuidsUsedByPcd(self):\r
-        if self._GuidsUsedByPcd == None:\r
-            self._GuidsUsedByPcd = sdict()\r
+        if self._GuidsUsedByPcd is None:\r
+            self._GuidsUsedByPcd = OrderedDict()\r
             self._GuidsUsedByPcd.update(self.Module.GetGuidsUsedByPcd())\r
             for Library in self.DependentLibraryList:\r
                 self._GuidsUsedByPcd.update(Library.GetGuidsUsedByPcd())\r
@@ -3735,8 +3725,8 @@ class ModuleAutoGen(AutoGen):
     #   @retval     dict    The mapping between protocol cname and its value\r
     #\r
     def _GetProtocolList(self):\r
-        if self._ProtocolList == None:\r
-            self._ProtocolList = sdict()\r
+        if self._ProtocolList is None:\r
+            self._ProtocolList = OrderedDict()\r
             self._ProtocolList.update(self.Module.Protocols)\r
             for Library in self.DependentLibraryList:\r
                 self._ProtocolList.update(Library.Protocols)\r
@@ -3749,8 +3739,8 @@ class ModuleAutoGen(AutoGen):
     #   @retval     dict    The mapping between PPI cname and its value\r
     #\r
     def _GetPpiList(self):\r
-        if self._PpiList == None:\r
-            self._PpiList = sdict()\r
+        if self._PpiList is None:\r
+            self._PpiList = OrderedDict()\r
             self._PpiList.update(self.Module.Ppis)\r
             for Library in self.DependentLibraryList:\r
                 self._PpiList.update(Library.Ppis)\r
@@ -3763,7 +3753,7 @@ class ModuleAutoGen(AutoGen):
     #   @retval     list                    The list path\r
     #\r
     def _GetIncludePathList(self):\r
-        if self._IncludePathList == None:\r
+        if self._IncludePathList is None:\r
             self._IncludePathList = []\r
             if self.AutoGenVersion < 0x00010005:\r
                 for Inc in self.Module.Includes:\r
@@ -3955,7 +3945,7 @@ class ModuleAutoGen(AutoGen):
             return\r
             \r
         # Skip the following code for modules with no source files\r
-        if self.SourceFileList == None or self.SourceFileList == []:\r
+        if self.SourceFileList is None or self.SourceFileList == []:\r
             return\r
 \r
         # Skip the following code for modules without any binary files\r
@@ -3981,7 +3971,7 @@ class ModuleAutoGen(AutoGen):
                     PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'DynamicEx'))\r
                     PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'Dynamic'))\r
                     PcdTokenSpaceList.append(Pcd.TokenSpaceGuidCName)\r
-        GuidList = sdict()\r
+        GuidList = OrderedDict()\r
         GuidList.update(self.GuidList)\r
         for TokenSpace in self.GetGuidsUsedByPcd():\r
             # If token space is not referred by patch PCD or Ex PCD, remove the GUID from GUID list\r
@@ -4077,7 +4067,7 @@ class ModuleAutoGen(AutoGen):
         OutputDir = self.OutputDir.replace('\\', '/').strip('/')\r
         DebugDir = self.DebugDir.replace('\\', '/').strip('/')\r
         for Item in self.CodaTargetList:\r
-            File = Item.Target.Path.replace('\\', '/').strip('/').replace(DebugDir, '').strip('/')\r
+            File = Item.Target.Path.replace('\\', '/').strip('/').replace(DebugDir, '').replace(OutputDir, '').strip('/')\r
             if File not in self.OutputFile:\r
                 self.OutputFile.append(File)\r
             if os.path.isabs(File):\r
@@ -4170,7 +4160,7 @@ class ModuleAutoGen(AutoGen):
                         HexFormat = '0x%016x'\r
                     PcdValue = HexFormat % int(Pcd.DefaultValue, 0)\r
                 else:\r
-                    if Pcd.MaxDatumSize == None or Pcd.MaxDatumSize == '':\r
+                    if Pcd.MaxDatumSize is None or Pcd.MaxDatumSize == '':\r
                         EdkLogger.error("build", AUTOGEN_ERROR,\r
                                         "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd.TokenSpaceGuidCName, TokenCName)\r
                                         )\r
@@ -4450,7 +4440,7 @@ class ModuleAutoGen(AutoGen):
 \r
     ## Summarize the ModuleAutoGen objects of all libraries used by this module\r
     def _GetLibraryAutoGenList(self):\r
-        if self._LibraryAutoGenList == None:\r
+        if self._LibraryAutoGenList is None:\r
             self._LibraryAutoGenList = []\r
             for Library in self.DependentLibraryList:\r
                 La = ModuleAutoGen(\r
@@ -4538,7 +4528,7 @@ class ModuleAutoGen(AutoGen):
         return True\r
 \r
     def GetTimeStampPath(self):\r
-        if self._TimeStampPath == None:\r
+        if self._TimeStampPath is None:\r
             self._TimeStampPath = os.path.join(self.MakeFileDir, 'AutoGenTimeStamp')\r
         return self._TimeStampPath\r
     def CreateTimeStamp(self, Makefile):\r