]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/Workspace/InfBuildData.py
BaseTools: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / InfBuildData.py
index 836140759f2181a9b88180b290e6621c5d4b3993..e66b7c983278d0e73345e231756b844cd3d0618a 100644 (file)
@@ -3,23 +3,56 @@
 #\r
 # Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>\r
 # (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
-# This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution.  The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php\r
-#\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
 #\r
 \r
-from Common.StringUtils import *\r
+from __future__ import absolute_import\r
 from Common.DataType import *\r
 from Common.Misc import *\r
+from Common.caching import cached_property, cached_class_function\r
 from types import *\r
-from MetaFileParser import *\r
+from .MetaFileParser import *\r
 from collections import OrderedDict\r
-\r
 from Workspace.BuildClassObject import ModuleBuildClassObject, LibraryClassObject, PcdClassObject\r
+\r
+## Get Protocol value from given packages\r
+#\r
+#   @param      CName           The CName of the GUID\r
+#   @param      PackageList     List of packages looking-up in\r
+#   @param      Inffile         The driver file\r
+#\r
+#   @retval     GuidValue   if the CName is found in any given package\r
+#   @retval     None        if the CName is not found in all given packages\r
+#\r
+def _ProtocolValue(CName, PackageList, Inffile = None):\r
+    for P in PackageList:\r
+        ProtocolKeys = list(P.Protocols.keys())\r
+        if Inffile and P._PrivateProtocols:\r
+            if not Inffile.startswith(P.MetaFile.Dir):\r
+                ProtocolKeys = [x for x in P.Protocols if x not in P._PrivateProtocols]\r
+        if CName in ProtocolKeys:\r
+            return P.Protocols[CName]\r
+    return None\r
+\r
+## Get PPI value from given packages\r
+#\r
+#   @param      CName           The CName of the GUID\r
+#   @param      PackageList     List of packages looking-up in\r
+#   @param      Inffile         The driver file\r
+#\r
+#   @retval     GuidValue   if the CName is found in any given package\r
+#   @retval     None        if the CName is not found in all given packages\r
+#\r
+def _PpiValue(CName, PackageList, Inffile = None):\r
+    for P in PackageList:\r
+        PpiKeys = list(P.Ppis.keys())\r
+        if Inffile and P._PrivatePpis:\r
+            if not Inffile.startswith(P.MetaFile.Dir):\r
+                PpiKeys = [x for x in P.Ppis if x not in P._PrivatePpis]\r
+        if CName in PpiKeys:\r
+            return P.Ppis[CName]\r
+    return None\r
+\r
 ## Module build information from INF file\r
 #\r
 #  This class is used to retrieve information stored in database and convert them\r
@@ -61,9 +94,7 @@ class InfBuildData(ModuleBuildClassObject):
         TAB_INF_DEFINES_VERSION_STRING              : "_Version",\r
         TAB_INF_DEFINES_VERSION                     : "_Version",\r
         TAB_INF_DEFINES_PCD_IS_DRIVER               : "_PcdIsDriver",\r
-        TAB_INF_DEFINES_SHADOW                      : "_Shadow",\r
-\r
-        TAB_COMPONENTS_SOURCE_OVERRIDE_PATH         : "_SourceOverridePath",\r
+        TAB_INF_DEFINES_SHADOW                      : "_Shadow"\r
     }\r
 \r
     # regular expression for converting XXX_FLAGS in [nmake] section to new type\r
@@ -76,9 +107,9 @@ class InfBuildData(ModuleBuildClassObject):
     }\r
 \r
 \r
-    ## Constructor of DscBuildData\r
+    ## Constructor of InfBuildData\r
     #\r
-    #  Initialize object of DscBuildData\r
+    #  Initialize object of InfBuildData\r
     #\r
     #   @param      FilePath        The path of platform description file\r
     #   @param      RawData         The raw data of DSC file\r
@@ -96,10 +127,33 @@ class InfBuildData(ModuleBuildClassObject):
         self._Target = Target\r
         self._Toolchain = Toolchain\r
         self._Platform = TAB_COMMON\r
-        self._SourceOverridePath = None\r
-        if FilePath.Key in GlobalData.gOverrideDir:\r
-            self._SourceOverridePath = GlobalData.gOverrideDir[FilePath.Key]\r
-        self._Clear()\r
+        self._TailComments = None\r
+        self._BaseName = None\r
+        self._DxsFile = None\r
+        self._ModuleType = None\r
+        self._ComponentType = None\r
+        self._BuildType = None\r
+        self._Guid = None\r
+        self._Version = None\r
+        self._PcdIsDriver = None\r
+        self._BinaryModule = None\r
+        self._Shadow = None\r
+        self._MakefileName = None\r
+        self._CustomMakefile = None\r
+        self._Specification = None\r
+        self._LibraryClass = None\r
+        self._ModuleEntryPointList = None\r
+        self._ModuleUnloadImageList = None\r
+        self._ConstructorList = None\r
+        self._DestructorList = None\r
+        self._Defs = OrderedDict()\r
+        self._ProtocolComments = None\r
+        self._PpiComments = None\r
+        self._GuidsUsedByPcd = OrderedDict()\r
+        self._GuidComments = None\r
+        self._PcdComments = None\r
+        self._BuildOptions = None\r
+        self._DependencyFileList = None\r
 \r
     ## XXX[key] = value\r
     def __setitem__(self, key, value):\r
@@ -113,113 +167,35 @@ class InfBuildData(ModuleBuildClassObject):
     def __contains__(self, key):\r
         return key in self._PROPERTY_\r
 \r
-    ## Set all internal used members of InfBuildData to None\r
-    def _Clear(self):\r
-        self._HeaderComments = None\r
-        self._TailComments = None\r
-        self._Header_               = None\r
-        self._AutoGenVersion        = None\r
-        self._BaseName              = None\r
-        self._DxsFile               = None\r
-        self._ModuleType            = None\r
-        self._ComponentType         = None\r
-        self._BuildType             = None\r
-        self._Guid                  = None\r
-        self._Version               = None\r
-        self._PcdIsDriver           = None\r
-        self._BinaryModule          = None\r
-        self._Shadow                = None\r
-        self._MakefileName          = None\r
-        self._CustomMakefile        = None\r
-        self._Specification         = None\r
-        self._LibraryClass          = None\r
-        self._ModuleEntryPointList  = None\r
-        self._ModuleUnloadImageList = None\r
-        self._ConstructorList       = None\r
-        self._DestructorList        = None\r
-        self._Defs                  = OrderedDict()\r
-        self._Binaries              = None\r
-        self._Sources               = None\r
-        self._LibraryClasses        = None\r
-        self._Libraries             = None\r
-        self._Protocols             = None\r
-        self._ProtocolComments      = None\r
-        self._Ppis                  = None\r
-        self._PpiComments           = None\r
-        self._Guids                 = None\r
-        self._GuidsUsedByPcd        = OrderedDict()\r
-        self._GuidComments          = None\r
-        self._Includes              = None\r
-        self._Packages              = None\r
-        self._Pcds                  = None\r
-        self._PcdComments           = None\r
-        self._BuildOptions          = None\r
-        self._Depex                 = None\r
-        self._DepexExpression       = None\r
-        self.__Macros               = None\r
-\r
     ## Get current effective macros\r
-    def _GetMacros(self):\r
-        if self.__Macros is None:\r
-            self.__Macros = {}\r
-            # EDK_GLOBAL defined macros can be applied to EDK module\r
-            if self.AutoGenVersion < 0x00010005:\r
-                self.__Macros.update(GlobalData.gEdkGlobal)\r
-                self.__Macros.update(GlobalData.gGlobalDefines)\r
-        return self.__Macros\r
+    @cached_property\r
+    def _Macros(self):\r
+        RetVal = {}\r
+        return RetVal\r
 \r
     ## Get architecture\r
-    def _GetArch(self):\r
+    @cached_property\r
+    def Arch(self):\r
         return self._Arch\r
 \r
-    ## Set architecture\r
-    #\r
-    #   Changing the default ARCH to another may affect all other information\r
-    # because all information in a platform may be ARCH-related. That's\r
-    # why we need to clear all internal used members, in order to cause all\r
-    # information to be re-retrieved.\r
-    #\r
-    #   @param  Value   The value of ARCH\r
-    #\r
-    def _SetArch(self, Value):\r
-        if self._Arch == Value:\r
-            return\r
-        self._Arch = Value\r
-        self._Clear()\r
-\r
     ## Return the name of platform employing this module\r
-    def _GetPlatform(self):\r
+    @cached_property\r
+    def Platform(self):\r
         return self._Platform\r
 \r
-    ## Change the name of platform employing this module\r
-    #\r
-    #   Changing the default name of platform to another may affect some information\r
-    # because they may be PLATFORM-related. That's why we need to clear all internal\r
-    # used members, in order to cause all information to be re-retrieved.\r
-    #\r
-    def _SetPlatform(self, Value):\r
-        if self._Platform == Value:\r
-            return\r
-        self._Platform = Value\r
-        self._Clear()\r
-    def _GetHeaderComments(self):\r
-        if not self._HeaderComments:\r
-            self._HeaderComments = []\r
-            RecordList = self._RawData[MODEL_META_DATA_HEADER_COMMENT]\r
-            for Record in RecordList:\r
-                self._HeaderComments.append(Record[0])\r
-        return self._HeaderComments\r
-    def _GetTailComments(self):\r
-        if not self._TailComments:\r
-            self._TailComments = []\r
-            RecordList = self._RawData[MODEL_META_DATA_TAIL_COMMENT]\r
-            for Record in RecordList:\r
-                self._TailComments.append(Record[0])\r
-        return self._TailComments\r
+    @cached_property\r
+    def HeaderComments(self):\r
+        return [a[0] for a in self._RawData[MODEL_META_DATA_HEADER_COMMENT]]\r
+\r
+    @cached_property\r
+    def TailComments(self):\r
+        return [a[0] for a in self._RawData[MODEL_META_DATA_TAIL_COMMENT]]\r
+\r
     ## Retrieve all information in [Defines] section\r
     #\r
-    #   (Retriving all [Defines] information in one-shot is just to save time.)\r
+    #   (Retrieving all [Defines] information in one-shot is just to save time.)\r
     #\r
+    @cached_class_function\r
     def _GetHeaderInfo(self):\r
         RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
         for Record in RecordList:\r
@@ -277,10 +253,10 @@ class InfBuildData(ModuleBuildClassObject):
                 if self._CustomMakefile is None:\r
                     self._CustomMakefile = {}\r
                 if len(TokenList) < 2:\r
-                    self._CustomMakefile['MSFT'] = TokenList[0]\r
+                    self._CustomMakefile[TAB_COMPILER_MSFT] = TokenList[0]\r
                     self._CustomMakefile['GCC'] = TokenList[0]\r
                 else:\r
-                    if TokenList[0] not in ['MSFT', 'GCC']:\r
+                    if TokenList[0] not in [TAB_COMPILER_MSFT, 'GCC']:\r
                         EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
                                         "No supported family [%s]" % TokenList[0],\r
                                         File=self.MetaFile, Line=Record[-1])\r
@@ -292,154 +268,91 @@ class InfBuildData(ModuleBuildClassObject):
         #\r
         # Retrieve information in sections specific to Edk.x modules\r
         #\r
-        if self.AutoGenVersion >= 0x00010005:\r
-            if not self._ModuleType:\r
-                EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,\r
-                                "MODULE_TYPE is not given", File=self.MetaFile)\r
-            if self._ModuleType not in SUP_MODULE_LIST:\r
-                RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
-                for Record in RecordList:\r
-                    Name = Record[1]\r
-                    if Name == "MODULE_TYPE":\r
-                        LineNo = Record[6]\r
-                        break\r
-                EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
-                                "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self._ModuleType, ' '.join(l for l in SUP_MODULE_LIST)),\r
-                                File=self.MetaFile, Line=LineNo)\r
-            if (self._Specification is None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (int(self._Specification['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):\r
-                if self._ModuleType == SUP_MODULE_SMM_CORE:\r
-                    EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.MetaFile)\r
-            if (self._Specification is None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (int(self._Specification['PI_SPECIFICATION_VERSION'], 16) < 0x00010032):\r
-                if self._ModuleType == SUP_MODULE_MM_CORE_STANDALONE:\r
-                    EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "MM_CORE_STANDALONE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x00010032", File=self.MetaFile)\r
-                if self._ModuleType == SUP_MODULE_MM_STANDALONE:\r
-                    EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "MM_STANDALONE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x00010032", File=self.MetaFile)\r
-            if 'PCI_DEVICE_ID' in self._Defs and 'PCI_VENDOR_ID' in self._Defs \\r
-               and 'PCI_CLASS_CODE' in self._Defs and 'PCI_REVISION' in self._Defs:\r
-                self._BuildType = 'UEFI_OPTIONROM'\r
-                if 'PCI_COMPRESS' in self._Defs:\r
-                    if self._Defs['PCI_COMPRESS'] not in ('TRUE', 'FALSE'):\r
-                        EdkLogger.error("build", FORMAT_INVALID, "Expected TRUE/FALSE for PCI_COMPRESS: %s" % self.MetaFile)\r
-\r
-            elif 'UEFI_HII_RESOURCE_SECTION' in self._Defs \\r
-               and self._Defs['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':\r
-                self._BuildType = 'UEFI_HII'\r
-            else:\r
-                self._BuildType = self._ModuleType.upper()\r
-\r
-            if self._DxsFile:\r
-                File = PathClass(NormPath(self._DxsFile), self._ModuleDir, Arch=self._Arch)\r
-                # check the file validation\r
-                ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)\r
-                if ErrorCode != 0:\r
-                    EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,\r
-                                    File=self.MetaFile, Line=LineNo)\r
-                if self.Sources is None:\r
-                    self._Sources = []\r
-                self._Sources.append(File)\r
-        else:\r
-            if not self._ComponentType:\r
-                EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,\r
-                                "COMPONENT_TYPE is not given", File=self.MetaFile)\r
-            self._BuildType = self._ComponentType.upper()\r
-            if self._ComponentType in COMPONENT_TO_MODULE_MAP_DICT:\r
-                self._ModuleType = COMPONENT_TO_MODULE_MAP_DICT[self._ComponentType]\r
-            if self._ComponentType == EDK_COMPONENT_TYPE_LIBRARY:\r
-                self._LibraryClass = [LibraryClassObject(self._BaseName, SUP_MODULE_LIST)]\r
-            # make use some [nmake] section macros\r
-            Macros = self._Macros\r
-            Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
-            Macros['PROCESSOR'] = self._Arch\r
-            RecordList = self._RawData[MODEL_META_DATA_NMAKE, self._Arch, self._Platform]\r
-            for Name, Value, Dummy, Arch, Platform, ID, LineNo in RecordList:\r
-                Value = ReplaceMacro(Value, Macros, True)\r
-                if Name == "IMAGE_ENTRY_POINT":\r
-                    if self._ModuleEntryPointList is None:\r
-                        self._ModuleEntryPointList = []\r
-                    self._ModuleEntryPointList.append(Value)\r
-                elif Name == "DPX_SOURCE":\r
-                    File = PathClass(NormPath(Value), self._ModuleDir, Arch=self._Arch)\r
-                    # check the file validation\r
-                    ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)\r
-                    if ErrorCode != 0:\r
-                        EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,\r
-                                        File=self.MetaFile, Line=LineNo)\r
-                    if self.Sources is None:\r
-                        self._Sources = []\r
-                    self._Sources.append(File)\r
-                else:\r
-                    ToolList = self._NMAKE_FLAG_PATTERN_.findall(Name)\r
-                    if len(ToolList) == 0 or len(ToolList) != 1:\r
-                        pass\r
-#                        EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,\r
-#                                       File=self.MetaFile, Line=LineNo)\r
-                    else:\r
-                        if self._BuildOptions is None:\r
-                            self._BuildOptions = OrderedDict()\r
-\r
-                        if ToolList[0] in self._TOOL_CODE_:\r
-                            Tool = self._TOOL_CODE_[ToolList[0]]\r
-                        else:\r
-                            Tool = ToolList[0]\r
-                        ToolChain = "*_*_*_%s_FLAGS" % Tool\r
-                        ToolChainFamily = 'MSFT'  # Edk.x only support MSFT tool chain\r
-                        # ignore not replaced macros in value\r
-                        ValueList = GetSplitList(' ' + Value, '/D')\r
-                        Dummy = ValueList[0]\r
-                        for Index in range(1, len(ValueList)):\r
-                            if ValueList[Index][-1] == '=' or ValueList[Index] == '':\r
-                                continue\r
-                            Dummy = Dummy + ' /D ' + ValueList[Index]\r
-                        Value = Dummy.strip()\r
-                        if (ToolChainFamily, ToolChain) not in self._BuildOptions:\r
-                            self._BuildOptions[ToolChainFamily, ToolChain] = Value\r
-                        else:\r
-                            OptionString = self._BuildOptions[ToolChainFamily, ToolChain]\r
-                            self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Value\r
-        # set _Header to non-None in order to avoid database re-querying\r
-        self._Header_ = 'DUMMY'\r
-\r
-    ## Retrieve file version\r
-    def _GetInfVersion(self):\r
-        if self._AutoGenVersion is None:\r
+        if not self._ModuleType:\r
+            EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,\r
+                            "MODULE_TYPE is not given", File=self.MetaFile)\r
+        if self._ModuleType not in SUP_MODULE_LIST:\r
             RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
             for Record in RecordList:\r
-                if Record[1] == TAB_INF_DEFINES_INF_VERSION:\r
-                    if '.' in Record[2]:\r
-                        ValueList = Record[2].split('.')\r
-                        Major = '%04o' % int(ValueList[0], 0)\r
-                        Minor = '%04o' % int(ValueList[1], 0)\r
-                        self._AutoGenVersion = int('0x' + Major + Minor, 0)\r
-                    else:\r
-                        self._AutoGenVersion = int(Record[2], 0)\r
+                Name = Record[1]\r
+                if Name == "MODULE_TYPE":\r
+                    LineNo = Record[6]\r
                     break\r
-            if self._AutoGenVersion is None:\r
-                self._AutoGenVersion = 0x00010000\r
-        return self._AutoGenVersion\r
+            EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
+                            "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self._ModuleType, ' '.join(l for l in SUP_MODULE_LIST)),\r
+                            File=self.MetaFile, Line=LineNo)\r
+        if (self._Specification is None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (int(self._Specification['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):\r
+            if self._ModuleType == SUP_MODULE_SMM_CORE:\r
+                EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.MetaFile)\r
+        if (self._Specification is None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (int(self._Specification['PI_SPECIFICATION_VERSION'], 16) < 0x00010032):\r
+            if self._ModuleType == SUP_MODULE_MM_CORE_STANDALONE:\r
+                EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "MM_CORE_STANDALONE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x00010032", File=self.MetaFile)\r
+            if self._ModuleType == SUP_MODULE_MM_STANDALONE:\r
+                EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "MM_STANDALONE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x00010032", File=self.MetaFile)\r
+        if 'PCI_DEVICE_ID' in self._Defs and 'PCI_VENDOR_ID' in self._Defs \\r
+           and 'PCI_CLASS_CODE' in self._Defs and 'PCI_REVISION' in self._Defs:\r
+            self._BuildType = 'UEFI_OPTIONROM'\r
+            if 'PCI_COMPRESS' in self._Defs:\r
+                if self._Defs['PCI_COMPRESS'] not in ('TRUE', 'FALSE'):\r
+                    EdkLogger.error("build", FORMAT_INVALID, "Expected TRUE/FALSE for PCI_COMPRESS: %s" % self.MetaFile)\r
+\r
+        elif 'UEFI_HII_RESOURCE_SECTION' in self._Defs \\r
+           and self._Defs['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':\r
+            self._BuildType = 'UEFI_HII'\r
+        else:\r
+            self._BuildType = self._ModuleType.upper()\r
+\r
+        if self._DxsFile:\r
+            File = PathClass(NormPath(self._DxsFile), self._ModuleDir, Arch=self._Arch)\r
+            # check the file validation\r
+            ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)\r
+            if ErrorCode != 0:\r
+                EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,\r
+                                File=self.MetaFile, Line=LineNo)\r
+            if not self._DependencyFileList:\r
+                self._DependencyFileList = []\r
+            self._DependencyFileList.append(File)\r
+\r
+    ## Retrieve file version\r
+    @cached_property\r
+    def AutoGenVersion(self):\r
+        RetVal = 0x00010000\r
+        RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
+        for Record in RecordList:\r
+            if Record[1] == TAB_INF_DEFINES_INF_VERSION:\r
+                if '.' in Record[2]:\r
+                    ValueList = Record[2].split('.')\r
+                    Major = '%04o' % int(ValueList[0], 0)\r
+                    Minor = '%04o' % int(ValueList[1], 0)\r
+                    RetVal = int('0x' + Major + Minor, 0)\r
+                else:\r
+                    RetVal = int(Record[2], 0)\r
+                break\r
+        return RetVal\r
 \r
     ## Retrieve BASE_NAME\r
-    def _GetBaseName(self):\r
+    @cached_property\r
+    def BaseName(self):\r
         if self._BaseName is None:\r
-            if self._Header_ is None:\r
-                self._GetHeaderInfo()\r
+            self._GetHeaderInfo()\r
             if self._BaseName is None:\r
                 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BASE_NAME name", File=self.MetaFile)\r
         return self._BaseName\r
 \r
     ## Retrieve DxsFile\r
-    def _GetDxsFile(self):\r
+    @cached_property\r
+    def DxsFile(self):\r
         if self._DxsFile is None:\r
-            if self._Header_ is None:\r
-                self._GetHeaderInfo()\r
+            self._GetHeaderInfo()\r
             if self._DxsFile is None:\r
                 self._DxsFile = ''\r
         return self._DxsFile\r
 \r
     ## Retrieve MODULE_TYPE\r
-    def _GetModuleType(self):\r
+    @cached_property\r
+    def ModuleType(self):\r
         if self._ModuleType is None:\r
-            if self._Header_ is None:\r
-                self._GetHeaderInfo()\r
+            self._GetHeaderInfo()\r
             if self._ModuleType is None:\r
                 self._ModuleType = SUP_MODULE_BASE\r
             if self._ModuleType not in SUP_MODULE_LIST:\r
@@ -447,410 +360,362 @@ class InfBuildData(ModuleBuildClassObject):
         return self._ModuleType\r
 \r
     ## Retrieve COMPONENT_TYPE\r
-    def _GetComponentType(self):\r
+    @cached_property\r
+    def ComponentType(self):\r
         if self._ComponentType is None:\r
-            if self._Header_ is None:\r
-                self._GetHeaderInfo()\r
+            self._GetHeaderInfo()\r
             if self._ComponentType is None:\r
                 self._ComponentType = SUP_MODULE_USER_DEFINED\r
         return self._ComponentType\r
 \r
     ## Retrieve "BUILD_TYPE"\r
-    def _GetBuildType(self):\r
+    @cached_property\r
+    def BuildType(self):\r
         if self._BuildType is None:\r
-            if self._Header_ is None:\r
-                self._GetHeaderInfo()\r
+            self._GetHeaderInfo()\r
             if not self._BuildType:\r
                 self._BuildType = SUP_MODULE_BASE\r
         return self._BuildType\r
 \r
     ## Retrieve file guid\r
-    def _GetFileGuid(self):\r
+    @cached_property\r
+    def Guid(self):\r
         if self._Guid is None:\r
-            if self._Header_ is None:\r
-                self._GetHeaderInfo()\r
+            self._GetHeaderInfo()\r
             if self._Guid is None:\r
                 self._Guid = '00000000-0000-0000-0000-000000000000'\r
         return self._Guid\r
 \r
     ## Retrieve module version\r
-    def _GetVersion(self):\r
+    @cached_property\r
+    def Version(self):\r
         if self._Version is None:\r
-            if self._Header_ is None:\r
-                self._GetHeaderInfo()\r
+            self._GetHeaderInfo()\r
             if self._Version is None:\r
                 self._Version = '0.0'\r
         return self._Version\r
 \r
     ## Retrieve PCD_IS_DRIVER\r
-    def _GetPcdIsDriver(self):\r
+    @cached_property\r
+    def PcdIsDriver(self):\r
         if self._PcdIsDriver is None:\r
-            if self._Header_ is None:\r
-                self._GetHeaderInfo()\r
+            self._GetHeaderInfo()\r
             if self._PcdIsDriver is None:\r
                 self._PcdIsDriver = ''\r
         return self._PcdIsDriver\r
 \r
     ## Retrieve SHADOW\r
-    def _GetShadow(self):\r
+    @cached_property\r
+    def Shadow(self):\r
         if self._Shadow is None:\r
-            if self._Header_ is None:\r
-                self._GetHeaderInfo()\r
-            if self._Shadow is not None and self._Shadow.upper() == 'TRUE':\r
+            self._GetHeaderInfo()\r
+            if self._Shadow and self._Shadow.upper() == 'TRUE':\r
                 self._Shadow = True\r
             else:\r
                 self._Shadow = False\r
         return self._Shadow\r
 \r
     ## Retrieve CUSTOM_MAKEFILE\r
-    def _GetMakefile(self):\r
+    @cached_property\r
+    def CustomMakefile(self):\r
         if self._CustomMakefile is None:\r
-            if self._Header_ is None:\r
-                self._GetHeaderInfo()\r
+            self._GetHeaderInfo()\r
             if self._CustomMakefile is None:\r
                 self._CustomMakefile = {}\r
         return self._CustomMakefile\r
 \r
     ## Retrieve EFI_SPECIFICATION_VERSION\r
-    def _GetSpec(self):\r
+    @cached_property\r
+    def Specification(self):\r
         if self._Specification is None:\r
-            if self._Header_ is None:\r
-                self._GetHeaderInfo()\r
+            self._GetHeaderInfo()\r
             if self._Specification is None:\r
                 self._Specification = {}\r
         return self._Specification\r
 \r
     ## Retrieve LIBRARY_CLASS\r
-    def _GetLibraryClass(self):\r
+    @cached_property\r
+    def LibraryClass(self):\r
         if self._LibraryClass is None:\r
-            if self._Header_ is None:\r
-                self._GetHeaderInfo()\r
+            self._GetHeaderInfo()\r
             if self._LibraryClass is None:\r
                 self._LibraryClass = []\r
         return self._LibraryClass\r
 \r
     ## Retrieve ENTRY_POINT\r
-    def _GetEntryPoint(self):\r
+    @cached_property\r
+    def ModuleEntryPointList(self):\r
         if self._ModuleEntryPointList is None:\r
-            if self._Header_ is None:\r
-                self._GetHeaderInfo()\r
+            self._GetHeaderInfo()\r
             if self._ModuleEntryPointList is None:\r
                 self._ModuleEntryPointList = []\r
         return self._ModuleEntryPointList\r
 \r
     ## Retrieve UNLOAD_IMAGE\r
-    def _GetUnloadImage(self):\r
+    @cached_property\r
+    def ModuleUnloadImageList(self):\r
         if self._ModuleUnloadImageList is None:\r
-            if self._Header_ is None:\r
-                self._GetHeaderInfo()\r
+            self._GetHeaderInfo()\r
             if self._ModuleUnloadImageList is None:\r
                 self._ModuleUnloadImageList = []\r
         return self._ModuleUnloadImageList\r
 \r
     ## Retrieve CONSTRUCTOR\r
-    def _GetConstructor(self):\r
+    @cached_property\r
+    def ConstructorList(self):\r
         if self._ConstructorList is None:\r
-            if self._Header_ is None:\r
-                self._GetHeaderInfo()\r
+            self._GetHeaderInfo()\r
             if self._ConstructorList is None:\r
                 self._ConstructorList = []\r
         return self._ConstructorList\r
 \r
     ## Retrieve DESTRUCTOR\r
-    def _GetDestructor(self):\r
+    @cached_property\r
+    def DestructorList(self):\r
         if self._DestructorList is None:\r
-            if self._Header_ is None:\r
-                self._GetHeaderInfo()\r
+            self._GetHeaderInfo()\r
             if self._DestructorList is None:\r
                 self._DestructorList = []\r
         return self._DestructorList\r
 \r
     ## Retrieve definies other than above ones\r
-    def _GetDefines(self):\r
-        if len(self._Defs) == 0 and self._Header_ is None:\r
-            self._GetHeaderInfo()\r
+    @cached_property\r
+    def Defines(self):\r
+        self._GetHeaderInfo()\r
         return self._Defs\r
 \r
     ## Retrieve binary files\r
+    @cached_class_function\r
     def _GetBinaries(self):\r
-        if self._Binaries is None:\r
-            self._Binaries = []\r
-            RecordList = self._RawData[MODEL_EFI_BINARY_FILE, self._Arch, self._Platform]\r
-            Macros = self._Macros\r
-            Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
-            Macros['PROCESSOR'] = self._Arch\r
-            for Record in RecordList:\r
-                FileType = Record[0]\r
-                LineNo = Record[-1]\r
-                Target = TAB_COMMON\r
-                FeatureFlag = []\r
-                if Record[2]:\r
-                    TokenList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)\r
-                    if TokenList:\r
-                        Target = TokenList[0]\r
-                    if len(TokenList) > 1:\r
-                        FeatureFlag = Record[1:]\r
-\r
-                File = PathClass(NormPath(Record[1], Macros), self._ModuleDir, '', FileType, True, self._Arch, '', Target)\r
-                # check the file validation\r
-                ErrorCode, ErrorInfo = File.Validate()\r
-                if ErrorCode != 0:\r
-                    EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
-                self._Binaries.append(File)\r
-        return self._Binaries\r
+        RetVal = []\r
+        RecordList = self._RawData[MODEL_EFI_BINARY_FILE, self._Arch, self._Platform]\r
+        Macros = self._Macros\r
+        Macros['PROCESSOR'] = self._Arch\r
+        for Record in RecordList:\r
+            FileType = Record[0]\r
+            LineNo = Record[-1]\r
+            Target = TAB_COMMON\r
+            FeatureFlag = []\r
+            if Record[2]:\r
+                TokenList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)\r
+                if TokenList:\r
+                    Target = TokenList[0]\r
+                if len(TokenList) > 1:\r
+                    FeatureFlag = Record[1:]\r
+\r
+            File = PathClass(NormPath(Record[1], Macros), self._ModuleDir, '', FileType, True, self._Arch, '', Target)\r
+            # check the file validation\r
+            ErrorCode, ErrorInfo = File.Validate()\r
+            if ErrorCode != 0:\r
+                EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
+            RetVal.append(File)\r
+        return RetVal\r
 \r
     ## Retrieve binary files with error check.\r
-    def _GetBinaryFiles(self):\r
-        Binaries = self._GetBinaries()\r
-        if GlobalData.gIgnoreSource and Binaries == []:\r
-            ErrorInfo = "The INF file does not contain any Binaries to use in creating the image\n"\r
+    @cached_property\r
+    def Binaries(self):\r
+        RetVal = self._GetBinaries()\r
+        if GlobalData.gIgnoreSource and not RetVal:\r
+            ErrorInfo = "The INF file does not contain any RetVal to use in creating the image\n"\r
             EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, ExtraData=ErrorInfo, File=self.MetaFile)\r
 \r
-        return Binaries\r
-    ## Check whether it exists the binaries with current ARCH in AsBuild INF\r
-    def _IsSupportedArch(self):\r
-        if self._GetBinaries() and not self._GetSourceFiles():\r
-            return True\r
-        else:\r
-            return False\r
+        return RetVal\r
+\r
     ## Retrieve source files\r
-    def _GetSourceFiles(self):\r
+    @cached_property\r
+    def Sources(self):\r
+        self._GetHeaderInfo()\r
         # Ignore all source files in a binary build mode\r
         if GlobalData.gIgnoreSource:\r
-            self._Sources = []\r
-            return self._Sources\r
+            return []\r
 \r
-        if self._Sources is None:\r
-            self._Sources = []\r
-            RecordList = self._RawData[MODEL_EFI_SOURCE_FILE, self._Arch, self._Platform]\r
-            Macros = self._Macros\r
-            for Record in RecordList:\r
-                LineNo = Record[-1]\r
-                ToolChainFamily = Record[1]\r
-                TagName = Record[2]\r
-                ToolCode = Record[3]\r
-                FeatureFlag = Record[4]\r
-                if self.AutoGenVersion < 0x00010005:\r
-                    Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
-                    Macros['PROCESSOR'] = self._Arch\r
-                    SourceFile = NormPath(Record[0], Macros)\r
-                    if SourceFile[0] == os.path.sep:\r
-                        SourceFile = mws.join(GlobalData.gWorkspace, SourceFile[1:])\r
-                    # old module source files (Edk)\r
-                    File = PathClass(SourceFile, self._ModuleDir, self._SourceOverridePath,\r
-                                     '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)\r
-                    # check the file validation\r
-                    ErrorCode, ErrorInfo = File.Validate(CaseSensitive=False)\r
-                    if ErrorCode != 0:\r
-                        if File.Ext.lower() == '.h':\r
-                            EdkLogger.warn('build', 'Include file not found', ExtraData=ErrorInfo,\r
-                                           File=self.MetaFile, Line=LineNo)\r
-                            continue\r
-                        else:\r
-                            EdkLogger.error('build', ErrorCode, ExtraData=File, File=self.MetaFile, Line=LineNo)\r
-                else:\r
-                    File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, '',\r
-                                     '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)\r
-                    # check the file validation\r
-                    ErrorCode, ErrorInfo = File.Validate()\r
-                    if ErrorCode != 0:\r
-                        EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
-\r
-                self._Sources.append(File)\r
-        return self._Sources\r
+        RetVal = []\r
+        RecordList = self._RawData[MODEL_EFI_SOURCE_FILE, self._Arch, self._Platform]\r
+        Macros = self._Macros\r
+        for Record in RecordList:\r
+            LineNo = Record[-1]\r
+            ToolChainFamily = Record[1]\r
+            TagName = Record[2]\r
+            ToolCode = Record[3]\r
+\r
+            File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, '',\r
+                             '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)\r
+            # check the file validation\r
+            ErrorCode, ErrorInfo = File.Validate()\r
+            if ErrorCode != 0:\r
+                EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
+\r
+            RetVal.append(File)\r
+        # add any previously found dependency files to the source list\r
+        if self._DependencyFileList:\r
+            RetVal.extend(self._DependencyFileList)\r
+        return RetVal\r
 \r
     ## Retrieve library classes employed by this module\r
-    def _GetLibraryClassUses(self):\r
-        if self._LibraryClasses is None:\r
-            self._LibraryClasses = OrderedDict()\r
-            RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, self._Platform]\r
-            for Record in RecordList:\r
-                Lib = Record[0]\r
-                Instance = Record[1]\r
-                if Instance:\r
-                    Instance = NormPath(Instance, self._Macros)\r
-                self._LibraryClasses[Lib] = Instance\r
-        return self._LibraryClasses\r
+    @cached_property\r
+    def LibraryClasses(self):\r
+        RetVal = OrderedDict()\r
+        RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, self._Platform]\r
+        for Record in RecordList:\r
+            Lib = Record[0]\r
+            Instance = Record[1]\r
+            if Instance:\r
+                Instance = NormPath(Instance, self._Macros)\r
+                RetVal[Lib] = Instance\r
+            else:\r
+                RetVal[Lib] = None\r
+        return RetVal\r
 \r
     ## Retrieve library names (for Edk.x style of modules)\r
-    def _GetLibraryNames(self):\r
-        if self._Libraries is None:\r
-            self._Libraries = []\r
-            RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch, self._Platform]\r
-            for Record in RecordList:\r
-                LibraryName = ReplaceMacro(Record[0], self._Macros, False)\r
-                # in case of name with '.lib' extension, which is unusual in Edk.x inf\r
-                LibraryName = os.path.splitext(LibraryName)[0]\r
-                if LibraryName not in self._Libraries:\r
-                    self._Libraries.append(LibraryName)\r
-        return self._Libraries\r
-\r
-    def _GetProtocolComments(self):\r
-        self._GetProtocols()\r
+    @cached_property\r
+    def Libraries(self):\r
+        RetVal = []\r
+        RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch, self._Platform]\r
+        for Record in RecordList:\r
+            LibraryName = ReplaceMacro(Record[0], self._Macros, False)\r
+            # in case of name with '.lib' extension, which is unusual in Edk.x inf\r
+            LibraryName = os.path.splitext(LibraryName)[0]\r
+            if LibraryName not in RetVal:\r
+                RetVal.append(LibraryName)\r
+        return RetVal\r
+\r
+    @cached_property\r
+    def ProtocolComments(self):\r
+        self.Protocols\r
         return self._ProtocolComments\r
+\r
     ## Retrieve protocols consumed/produced by this module\r
-    def _GetProtocols(self):\r
-        if self._Protocols is None:\r
-            self._Protocols = OrderedDict()\r
-            self._ProtocolComments = OrderedDict()\r
-            RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform]\r
-            for Record in RecordList:\r
-                CName = Record[0]\r
-                Value = ProtocolValue(CName, self.Packages, self.MetaFile.Path)\r
-                if Value is None:\r
-                    PackageList = "\n\t".join(str(P) for P in self.Packages)\r
-                    EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
-                                    "Value of Protocol [%s] is not found under [Protocols] section in" % CName,\r
-                                    ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
-                self._Protocols[CName] = Value\r
-                CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
-                Comments = []\r
-                for CmtRec in CommentRecords:\r
-                    Comments.append(CmtRec[0])\r
-                self._ProtocolComments[CName] = Comments\r
-        return self._Protocols\r
-\r
-    def _GetPpiComments(self):\r
-        self._GetPpis()\r
+    @cached_property\r
+    def Protocols(self):\r
+        RetVal = OrderedDict()\r
+        self._ProtocolComments = OrderedDict()\r
+        RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform]\r
+        for Record in RecordList:\r
+            CName = Record[0]\r
+            Value = _ProtocolValue(CName, self.Packages, self.MetaFile.Path)\r
+            if Value is None:\r
+                PackageList = "\n\t".join(str(P) for P in self.Packages)\r
+                EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
+                                "Value of Protocol [%s] is not found under [Protocols] section in" % CName,\r
+                                ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
+            RetVal[CName] = Value\r
+            CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
+            self._ProtocolComments[CName] = [a[0] for a in CommentRecords]\r
+        return RetVal\r
+\r
+    @cached_property\r
+    def PpiComments(self):\r
+        self.Ppis\r
         return self._PpiComments\r
+\r
     ## Retrieve PPIs consumed/produced by this module\r
-    def _GetPpis(self):\r
-        if self._Ppis is None:\r
-            self._Ppis = OrderedDict()\r
-            self._PpiComments = OrderedDict()\r
-            RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform]\r
-            for Record in RecordList:\r
-                CName = Record[0]\r
-                Value = PpiValue(CName, self.Packages, self.MetaFile.Path)\r
-                if Value is None:\r
-                    PackageList = "\n\t".join(str(P) for P in self.Packages)\r
-                    EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
-                                    "Value of PPI [%s] is not found under [Ppis] section in " % CName,\r
-                                    ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
-                self._Ppis[CName] = Value\r
-                CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
-                Comments = []\r
-                for CmtRec in CommentRecords:\r
-                    Comments.append(CmtRec[0])\r
-                self._PpiComments[CName] = Comments\r
-        return self._Ppis\r
-\r
-    def _GetGuidComments(self):\r
-        self._GetGuids()\r
+    @cached_property\r
+    def Ppis(self):\r
+        RetVal = OrderedDict()\r
+        self._PpiComments = OrderedDict()\r
+        RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform]\r
+        for Record in RecordList:\r
+            CName = Record[0]\r
+            Value = _PpiValue(CName, self.Packages, self.MetaFile.Path)\r
+            if Value is None:\r
+                PackageList = "\n\t".join(str(P) for P in self.Packages)\r
+                EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
+                                "Value of PPI [%s] is not found under [Ppis] section in " % CName,\r
+                                ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
+            RetVal[CName] = Value\r
+            CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
+            self._PpiComments[CName] = [a[0] for a in CommentRecords]\r
+        return RetVal\r
+\r
+    @cached_property\r
+    def GuidComments(self):\r
+        self.Guids\r
         return self._GuidComments\r
+\r
     ## Retrieve GUIDs consumed/produced by this module\r
-    def _GetGuids(self):\r
-        if self._Guids is None:\r
-            self._Guids = OrderedDict()\r
-            self._GuidComments = OrderedDict()\r
-            RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform]\r
-            for Record in RecordList:\r
-                CName = Record[0]\r
-                Value = GuidValue(CName, self.Packages, self.MetaFile.Path)\r
-                if Value is None:\r
-                    PackageList = "\n\t".join(str(P) for P in self.Packages)\r
-                    EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
-                                    "Value of Guid [%s] is not found under [Guids] section in" % CName,\r
-                                    ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
-                self._Guids[CName] = Value\r
-                CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
-                Comments = []\r
-                for CmtRec in CommentRecords:\r
-                    Comments.append(CmtRec[0])\r
-                self._GuidComments[CName] = Comments\r
-        return self._Guids\r
+    @cached_property\r
+    def Guids(self):\r
+        RetVal = OrderedDict()\r
+        self._GuidComments = OrderedDict()\r
+        RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform]\r
+        for Record in RecordList:\r
+            CName = Record[0]\r
+            Value = GuidValue(CName, self.Packages, self.MetaFile.Path)\r
+            if Value is None:\r
+                PackageList = "\n\t".join(str(P) for P in self.Packages)\r
+                EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
+                                "Value of Guid [%s] is not found under [Guids] section in" % CName,\r
+                                ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
+            RetVal[CName] = Value\r
+            CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
+            self._GuidComments[CName] = [a[0] for a in CommentRecords]\r
+        return RetVal\r
 \r
     ## Retrieve include paths necessary for this module (for Edk.x style of modules)\r
-    def _GetIncludes(self):\r
-        if self._Includes is None:\r
-            self._Includes = []\r
-            if self._SourceOverridePath:\r
-                self._Includes.append(self._SourceOverridePath)\r
-\r
-            Macros = self._Macros\r
-            Macros['PROCESSOR'] = GlobalData.gEdkGlobal.get('PROCESSOR', self._Arch)\r
-            RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch, self._Platform]\r
-            for Record in RecordList:\r
-                if Record[0].find('EDK_SOURCE') > -1:\r
-                    Macros['EDK_SOURCE'] = GlobalData.gEcpSource\r
-                    File = NormPath(Record[0], self._Macros)\r
-                    if File[0] == '.':\r
-                        File = os.path.join(self._ModuleDir, File)\r
-                    else:\r
-                        File = os.path.join(GlobalData.gWorkspace, File)\r
-                    File = RealPath(os.path.normpath(File))\r
-                    if File:\r
-                        self._Includes.append(File)\r
-\r
-                    # TRICK: let compiler to choose correct header file\r
-                    Macros['EDK_SOURCE'] = GlobalData.gEdkSource\r
-                    File = NormPath(Record[0], self._Macros)\r
-                    if File[0] == '.':\r
-                        File = os.path.join(self._ModuleDir, File)\r
-                    else:\r
-                        File = os.path.join(GlobalData.gWorkspace, File)\r
-                    File = RealPath(os.path.normpath(File))\r
-                    if File:\r
-                        self._Includes.append(File)\r
-                else:\r
-                    File = NormPath(Record[0], Macros)\r
-                    if File[0] == '.':\r
-                        File = os.path.join(self._ModuleDir, File)\r
-                    else:\r
-                        File = mws.join(GlobalData.gWorkspace, File)\r
-                    File = RealPath(os.path.normpath(File))\r
-                    if File:\r
-                        self._Includes.append(File)\r
-                    if not File and Record[0].find('EFI_SOURCE') > -1:\r
-                        # tricky to regard WorkSpace as EFI_SOURCE\r
-                        Macros['EFI_SOURCE'] = GlobalData.gWorkspace\r
-                        File = NormPath(Record[0], Macros)\r
-                        if File[0] == '.':\r
-                            File = os.path.join(self._ModuleDir, File)\r
-                        else:\r
-                            File = os.path.join(GlobalData.gWorkspace, File)\r
-                        File = RealPath(os.path.normpath(File))\r
-                        if File:\r
-                            self._Includes.append(File)\r
-        return self._Includes\r
+    @cached_property\r
+    def Includes(self):\r
+        RetVal = []\r
+        Macros = self._Macros\r
+        Macros['PROCESSOR'] = GlobalData.gEdkGlobal.get('PROCESSOR', self._Arch)\r
+        RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch, self._Platform]\r
+        for Record in RecordList:\r
+            File = NormPath(Record[0], Macros)\r
+            if File[0] == '.':\r
+                File = os.path.join(self._ModuleDir, File)\r
+            else:\r
+                File = mws.join(GlobalData.gWorkspace, File)\r
+            File = RealPath(os.path.normpath(File))\r
+            if File:\r
+                RetVal.append(File)\r
+        return RetVal\r
 \r
     ## Retrieve packages this module depends on\r
-    def _GetPackages(self):\r
-        if self._Packages is None:\r
-            self._Packages = []\r
-            RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch, self._Platform]\r
-            Macros = self._Macros\r
-            Macros['EDK_SOURCE'] = GlobalData.gEcpSource\r
-            for Record in RecordList:\r
-                File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
+    @cached_property\r
+    def Packages(self):\r
+        RetVal = []\r
+        RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch, self._Platform]\r
+        Macros = self._Macros\r
+        for Record in RecordList:\r
+            File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
+            # check the file validation\r
+            ErrorCode, ErrorInfo = File.Validate('.dec')\r
+            if ErrorCode != 0:\r
                 LineNo = Record[-1]\r
-                # check the file validation\r
-                ErrorCode, ErrorInfo = File.Validate('.dec')\r
-                if ErrorCode != 0:\r
-                    EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
-                # parse this package now. we need it to get protocol/ppi/guid value\r
-                Package = self._Bdb[File, self._Arch, self._Target, self._Toolchain]\r
-                self._Packages.append(Package)\r
-        return self._Packages\r
+                EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
+            # parse this package now. we need it to get protocol/ppi/guid value\r
+            RetVal.append(self._Bdb[File, self._Arch, self._Target, self._Toolchain])\r
+        return RetVal\r
 \r
     ## Retrieve PCD comments\r
-    def _GetPcdComments(self):\r
-        self._GetPcds()\r
+    @cached_property\r
+    def PcdComments(self):\r
+        self.Pcds\r
         return self._PcdComments\r
+\r
     ## Retrieve PCDs used in this module\r
-    def _GetPcds(self):\r
-        if self._Pcds is None:\r
-            self._Pcds = OrderedDict()\r
-            self._PcdComments = OrderedDict()\r
-            self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
-            self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
-            self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
-            self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC))\r
-            self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))\r
-        return self._Pcds\r
+    @cached_property\r
+    def Pcds(self):\r
+        self._PcdComments = OrderedDict()\r
+        RetVal = OrderedDict()\r
+        RetVal.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
+        RetVal.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
+        RetVal.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
+        RetVal.update(self._GetPcd(MODEL_PCD_DYNAMIC))\r
+        RetVal.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))\r
+        return RetVal\r
+\r
+    @cached_property\r
+    def PcdsName(self):\r
+        PcdsName = set()\r
+        for Type in (MODEL_PCD_FIXED_AT_BUILD,MODEL_PCD_PATCHABLE_IN_MODULE,MODEL_PCD_FEATURE_FLAG,MODEL_PCD_DYNAMIC,MODEL_PCD_DYNAMIC_EX):\r
+            RecordList = self._RawData[Type, self._Arch, self._Platform]\r
+            for TokenSpaceGuid, PcdCName, _, _, _, _, _ in RecordList:\r
+                PcdsName.add((PcdCName, TokenSpaceGuid))\r
+        return PcdsName\r
 \r
     ## Retrieve build options specific to this module\r
-    def _GetBuildOptions(self):\r
+    @cached_property\r
+    def BuildOptions(self):\r
         if self._BuildOptions is None:\r
             self._BuildOptions = OrderedDict()\r
             RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, self._Platform]\r
@@ -867,87 +732,99 @@ class InfBuildData(ModuleBuildClassObject):
         return self._BuildOptions\r
 \r
     ## Retrieve dependency expression\r
-    def _GetDepex(self):\r
-        if self._Depex is None:\r
-            self._Depex = tdict(False, 2)\r
-            RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]\r
-\r
-            # If the module has only Binaries and no Sources, then ignore [Depex]\r
-            if self.Sources is None or self.Sources == []:\r
-                if self.Binaries is not None and self.Binaries != []:\r
-                    return self._Depex\r
-\r
-            # PEIM and DXE drivers must have a valid [Depex] section\r
-            if len(self.LibraryClass) == 0 and len(RecordList) == 0:\r
-                if self.ModuleType == SUP_MODULE_DXE_DRIVER or self.ModuleType == SUP_MODULE_PEIM or self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER or \\r
-                    self.ModuleType == SUP_MODULE_DXE_SAL_DRIVER or self.ModuleType == SUP_MODULE_DXE_RUNTIME_DRIVER:\r
-                    EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \\r
-                                    % self.ModuleType, File=self.MetaFile)\r
-\r
-            if len(RecordList) != 0 and self.ModuleType == SUP_MODULE_USER_DEFINED:\r
-                for Record in RecordList:\r
-                    if Record[4] not in [SUP_MODULE_PEIM, SUP_MODULE_DXE_DRIVER, SUP_MODULE_DXE_SMM_DRIVER]:\r
-                        EdkLogger.error('build', FORMAT_INVALID,\r
-                                        "'%s' module must specify the type of [Depex] section" % self.ModuleType,\r
-                                        File=self.MetaFile)\r
-\r
-            Depex = OrderedDict()\r
+    @cached_property\r
+    def Depex(self):\r
+        RetVal = tdict(False, 2)\r
+\r
+        # If the module has only Binaries and no Sources, then ignore [Depex]\r
+        if not self.Sources and self.Binaries:\r
+            return RetVal\r
+\r
+        RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]\r
+        # PEIM and DXE drivers must have a valid [Depex] section\r
+        if len(self.LibraryClass) == 0 and len(RecordList) == 0:\r
+            if self.ModuleType == SUP_MODULE_DXE_DRIVER or self.ModuleType == SUP_MODULE_PEIM or self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER or \\r
+                self.ModuleType == SUP_MODULE_DXE_SAL_DRIVER or self.ModuleType == SUP_MODULE_DXE_RUNTIME_DRIVER:\r
+                EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \\r
+                                % self.ModuleType, File=self.MetaFile)\r
+\r
+        if len(RecordList) != 0 and self.ModuleType == SUP_MODULE_USER_DEFINED:\r
             for Record in RecordList:\r
-                DepexStr = ReplaceMacro(Record[0], self._Macros, False)\r
-                Arch = Record[3]\r
-                ModuleType = Record[4]\r
-                TokenList = DepexStr.split()\r
-                if (Arch, ModuleType) not in Depex:\r
-                    Depex[Arch, ModuleType] = []\r
-                DepexList = Depex[Arch, ModuleType]\r
-                for Token in TokenList:\r
-                    if Token in DEPEX_SUPPORTED_OPCODE_SET:\r
-                        DepexList.append(Token)\r
-                    elif Token.endswith(".inf"):  # module file name\r
-                        ModuleFile = os.path.normpath(Token)\r
-                        Module = self.BuildDatabase[ModuleFile]\r
-                        if Module is None:\r
-                            EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "Module is not found in active platform",\r
-                                            ExtraData=Token, File=self.MetaFile, Line=Record[-1])\r
-                        DepexList.append(Module.Guid)\r
+                if Record[4] not in [SUP_MODULE_PEIM, SUP_MODULE_DXE_DRIVER, SUP_MODULE_DXE_SMM_DRIVER]:\r
+                    EdkLogger.error('build', FORMAT_INVALID,\r
+                                    "'%s' module must specify the type of [Depex] section" % self.ModuleType,\r
+                                    File=self.MetaFile)\r
+\r
+        TemporaryDictionary = OrderedDict()\r
+        for Record in RecordList:\r
+            DepexStr = ReplaceMacro(Record[0], self._Macros, False)\r
+            Arch = Record[3]\r
+            ModuleType = Record[4]\r
+            TokenList = DepexStr.split()\r
+            if (Arch, ModuleType) not in TemporaryDictionary:\r
+                TemporaryDictionary[Arch, ModuleType] = []\r
+            DepexList = TemporaryDictionary[Arch, ModuleType]\r
+            for Token in TokenList:\r
+                if Token in DEPEX_SUPPORTED_OPCODE_SET:\r
+                    DepexList.append(Token)\r
+                elif Token.endswith(".inf"):  # module file name\r
+                    ModuleFile = os.path.normpath(Token)\r
+                    Module = self.BuildDatabase[ModuleFile]\r
+                    if Module is None:\r
+                        EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "Module is not found in active platform",\r
+                                        ExtraData=Token, File=self.MetaFile, Line=Record[-1])\r
+                    DepexList.append(Module.Guid)\r
+                else:\r
+                    # it use the Fixed PCD format\r
+                    if '.' in Token:\r
+                        if tuple(Token.split('.')[::-1]) not in self.Pcds:\r
+                            EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "PCD [{}] used in [Depex] section should be listed in module PCD section".format(Token), File=self.MetaFile, Line=Record[-1])\r
+                        else:\r
+                            if self.Pcds[tuple(Token.split('.')[::-1])].DatumType != TAB_VOID:\r
+                                EdkLogger.error('build', FORMAT_INVALID, "PCD [{}] used in [Depex] section should be VOID* datum type".format(Token), File=self.MetaFile, Line=Record[-1])\r
+                        Value = Token\r
                     else:\r
                         # get the GUID value now\r
-                        Value = ProtocolValue(Token, self.Packages, self.MetaFile.Path)\r
+                        Value = _ProtocolValue(Token, self.Packages, self.MetaFile.Path)\r
                         if Value is None:\r
-                            Value = PpiValue(Token, self.Packages, self.MetaFile.Path)\r
+                            Value = _PpiValue(Token, self.Packages, self.MetaFile.Path)\r
                             if Value is None:\r
                                 Value = GuidValue(Token, self.Packages, self.MetaFile.Path)\r
-                        if Value is None:\r
-                            PackageList = "\n\t".join(str(P) for P in self.Packages)\r
-                            EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
-                                            "Value of [%s] is not found in" % Token,\r
-                                            ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
-                        DepexList.append(Value)\r
-            for Arch, ModuleType in Depex:\r
-                self._Depex[Arch, ModuleType] = Depex[Arch, ModuleType]\r
-        return self._Depex\r
-\r
-    ## Retrieve depedency expression\r
-    def _GetDepexExpression(self):\r
-        if self._DepexExpression is None:\r
-            self._DepexExpression = tdict(False, 2)\r
-            RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]\r
-            DepexExpression = OrderedDict()\r
-            for Record in RecordList:\r
-                DepexStr = ReplaceMacro(Record[0], self._Macros, False)\r
-                Arch = Record[3]\r
-                ModuleType = Record[4]\r
-                TokenList = DepexStr.split()\r
-                if (Arch, ModuleType) not in DepexExpression:\r
-                    DepexExpression[Arch, ModuleType] = ''\r
-                for Token in TokenList:\r
-                    DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType] + Token.strip() + ' '\r
-            for Arch, ModuleType in DepexExpression:\r
-                self._DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType]\r
-        return self._DepexExpression\r
 \r
+                    if Value is None:\r
+                        PackageList = "\n\t".join(str(P) for P in self.Packages)\r
+                        EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
+                                        "Value of [%s] is not found in" % Token,\r
+                                        ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
+                    DepexList.append(Value)\r
+        for Arch, ModuleType in TemporaryDictionary:\r
+            RetVal[Arch, ModuleType] = TemporaryDictionary[Arch, ModuleType]\r
+        return RetVal\r
+\r
+    ## Retrieve dependency expression\r
+    @cached_property\r
+    def DepexExpression(self):\r
+        RetVal = tdict(False, 2)\r
+        RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]\r
+        TemporaryDictionary = OrderedDict()\r
+        for Record in RecordList:\r
+            DepexStr = ReplaceMacro(Record[0], self._Macros, False)\r
+            Arch = Record[3]\r
+            ModuleType = Record[4]\r
+            TokenList = DepexStr.split()\r
+            if (Arch, ModuleType) not in TemporaryDictionary:\r
+                TemporaryDictionary[Arch, ModuleType] = ''\r
+            for Token in TokenList:\r
+                TemporaryDictionary[Arch, ModuleType] = TemporaryDictionary[Arch, ModuleType] + Token.strip() + ' '\r
+        for Arch, ModuleType in TemporaryDictionary:\r
+            RetVal[Arch, ModuleType] = TemporaryDictionary[Arch, ModuleType]\r
+        return RetVal\r
+\r
+    @cached_class_function\r
     def GetGuidsUsedByPcd(self):\r
+        self.Pcds\r
         return self._GuidsUsedByPcd\r
+\r
     ## Retrieve PCD for given type\r
     def _GetPcd(self, Type):\r
         Pcds = OrderedDict()\r
@@ -1121,7 +998,7 @@ class InfBuildData(ModuleBuildClassObject):
                     else:\r
                         try:\r
                             Pcd.DefaultValue = ValueExpressionEx(Pcd.DefaultValue, Pcd.DatumType, _GuidDict)(True)\r
-                        except BadExpression, Value:\r
+                        except BadExpression as Value:\r
                             EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %(TokenSpaceGuid, PcdRealName, Pcd.DefaultValue, Value),\r
                                             File=self.MetaFile, Line=LineNo)\r
                     break\r
@@ -1138,55 +1015,8 @@ class InfBuildData(ModuleBuildClassObject):
         return Pcds\r
 \r
     ## check whether current module is binary module\r
-    def _IsBinaryModule(self):\r
-        if self.Binaries and not self.Sources:\r
-            return True\r
-        elif GlobalData.gIgnoreSource:\r
+    @property\r
+    def IsBinaryModule(self):\r
+        if (self.Binaries and not self.Sources) or GlobalData.gIgnoreSource:\r
             return True\r
-        else:\r
-            return False\r
-\r
-    _Macros = property(_GetMacros)\r
-    Arch = property(_GetArch, _SetArch)\r
-    Platform = property(_GetPlatform, _SetPlatform)\r
-\r
-    HeaderComments = property(_GetHeaderComments)\r
-    TailComments = property(_GetTailComments)\r
-    AutoGenVersion          = property(_GetInfVersion)\r
-    BaseName                = property(_GetBaseName)\r
-    ModuleType              = property(_GetModuleType)\r
-    ComponentType           = property(_GetComponentType)\r
-    BuildType               = property(_GetBuildType)\r
-    Guid                    = property(_GetFileGuid)\r
-    Version                 = property(_GetVersion)\r
-    PcdIsDriver             = property(_GetPcdIsDriver)\r
-    Shadow                  = property(_GetShadow)\r
-    CustomMakefile          = property(_GetMakefile)\r
-    Specification           = property(_GetSpec)\r
-    LibraryClass            = property(_GetLibraryClass)\r
-    ModuleEntryPointList    = property(_GetEntryPoint)\r
-    ModuleUnloadImageList   = property(_GetUnloadImage)\r
-    ConstructorList         = property(_GetConstructor)\r
-    DestructorList          = property(_GetDestructor)\r
-    Defines                 = property(_GetDefines)\r
-    DxsFile                 = property(_GetDxsFile)\r
-\r
-    Binaries                = property(_GetBinaryFiles)\r
-    Sources                 = property(_GetSourceFiles)\r
-    LibraryClasses          = property(_GetLibraryClassUses)\r
-    Libraries               = property(_GetLibraryNames)\r
-    Protocols               = property(_GetProtocols)\r
-    ProtocolComments        = property(_GetProtocolComments)\r
-    Ppis                    = property(_GetPpis)\r
-    PpiComments             = property(_GetPpiComments)\r
-    Guids                   = property(_GetGuids)\r
-    GuidComments            = property(_GetGuidComments)\r
-    Includes                = property(_GetIncludes)\r
-    Packages                = property(_GetPackages)\r
-    Pcds                    = property(_GetPcds)\r
-    PcdComments             = property(_GetPcdComments)\r
-    BuildOptions            = property(_GetBuildOptions)\r
-    Depex                   = property(_GetDepex)\r
-    DepexExpression         = property(_GetDepexExpression)\r
-    IsBinaryModule          = property(_IsBinaryModule)\r
-    IsSupportedArch         = property(_IsSupportedArch)\r
+        return False\r