]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/AutoGen/AutoGen.py
UefiCpuPkg/CpuCommonFeaturesLib: Add check for input parameter.
[mirror_edk2.git] / BaseTools / Source / Python / AutoGen / AutoGen.py
index 0664101008a8c83f68a7a1e1e9fe57aa82bdc939..6bbfc8774fedf0c27fd98d434d5d44f7c3b19731 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # Generate AutoGen.h, AutoGen.c and *.depex files\r
 #\r
-# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
@@ -42,6 +42,7 @@ from GenPcdDb import CreatePcdDatabaseCode
 from Workspace.MetaFileCommentParser import UsageList\r
 from Common.MultipleWorkspace import MultipleWorkspace as mws\r
 import InfSectionParser\r
+import datetime\r
 \r
 ## Regular expression for splitting Dependency Expression string into tokens\r
 gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)")\r
@@ -61,7 +62,10 @@ gMakeTypeMap = {"MSFT":"nmake", "GCC":"gmake"}
 \r
 \r
 ## Build rule configuration file\r
-gDefaultBuildRuleFile = 'Conf/build_rule.txt'\r
+gDefaultBuildRuleFile = 'build_rule.txt'\r
+\r
+## Tools definition configuration file\r
+gDefaultToolsDefFile = 'tools_def.txt'\r
 \r
 ## Build rule default version\r
 AutoGenReqBuildRuleVerNum = "0.1"\r
@@ -72,7 +76,8 @@ gAutoGenHeaderFileName = "AutoGen.h"
 gAutoGenStringFileName = "%(module_name)sStrDefs.h"\r
 gAutoGenStringFormFileName = "%(module_name)sStrDefs.hpk"\r
 gAutoGenDepexFileName = "%(module_name)s.depex"\r
-\r
+gAutoGenImageDefFileName = "%(module_name)sImgDefs.h"\r
+gAutoGenIdfFileName = "%(module_name)sIdf.hpk"\r
 gInfSpecVersion = "0x00010017"\r
 \r
 #\r
@@ -138,6 +143,8 @@ ${END}
 \r
 ${depexsection_item}\r
 \r
+${userextension_tianocore_item}\r
+\r
 ${tail_comments}\r
 \r
 [BuildOptions.${module_arch}]\r
@@ -329,6 +336,43 @@ class WorkspaceAutoGen(AutoGen):
                 if fvname.upper() not in self.FdfProfile.FvDict:\r
                     EdkLogger.error("build", OPTION_VALUE_INVALID,\r
                                     "No such an FV in FDF file: %s" % fvname)\r
+\r
+            # In DSC file may use FILE_GUID to override the module, then in the Platform.Modules use FILE_GUIDmodule.inf as key,\r
+            # but the path (self.MetaFile.Path) is the real path\r
+            for key in self.FdfProfile.InfDict:\r
+                if key == 'ArchTBD':\r
+                    Platform_cache = {}\r
+                    MetaFile_cache = {}\r
+                    for Arch in self.ArchList:\r
+                        Platform_cache[Arch] = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]\r
+                        MetaFile_cache[Arch] = []\r
+                        for Pkey in Platform_cache[Arch].Modules.keys():\r
+                            MetaFile_cache[Arch].append(Platform_cache[Arch].Modules[Pkey].MetaFile)\r
+                    for Inf in self.FdfProfile.InfDict[key]:\r
+                        ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch)\r
+                        for Arch in self.ArchList:\r
+                            if ModuleFile in MetaFile_cache[Arch]:\r
+                                break\r
+                        else:\r
+                            ModuleData = self.BuildDatabase[ModuleFile, Arch, Target, Toolchain]\r
+                            if not ModuleData.IsBinaryModule:\r
+                                EdkLogger.error('build', PARSER_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % ModuleFile)\r
+\r
+                else:\r
+                    for Arch in self.ArchList:\r
+                        if Arch == key:\r
+                            Platform = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]\r
+                            MetaFileList = []\r
+                            for Pkey in Platform.Modules.keys():\r
+                                MetaFileList.append(Platform.Modules[Pkey].MetaFile)\r
+                            for Inf in self.FdfProfile.InfDict[key]:\r
+                                ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch)\r
+                                if ModuleFile in MetaFileList:\r
+                                    continue\r
+                                ModuleData = self.BuildDatabase[ModuleFile, Arch, Target, Toolchain]\r
+                                if not ModuleData.IsBinaryModule:\r
+                                    EdkLogger.error('build', PARSER_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % ModuleFile)\r
+\r
         else:\r
             PcdSet = {}\r
             ModuleList = []\r
@@ -374,7 +418,7 @@ class WorkspaceAutoGen(AutoGen):
                             if HasTokenSpace:\r
                                 if (PcdItem.TokenCName, PcdItem.TokenSpaceGuidCName) == (TokenCName, TokenSpaceGuidCName):\r
                                     PcdDatumType = PcdItem.DatumType\r
-                                    NewValue = self._BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)\r
+                                    NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)\r
                                     FoundFlag = True\r
                             else:\r
                                 if PcdItem.TokenCName == TokenCName:\r
@@ -383,7 +427,7 @@ class WorkspaceAutoGen(AutoGen):
                                             TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)\r
                                             PcdDatumType = PcdItem.DatumType\r
                                             TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName\r
-                                            NewValue = self._BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)\r
+                                            NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)\r
                                             FoundFlag = True\r
                                         else:\r
                                             EdkLogger.error(\r
@@ -462,6 +506,22 @@ class WorkspaceAutoGen(AutoGen):
                                 SourcePcdDict['FixedAtBuild'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r
                 else:\r
                     pass\r
+            #\r
+            # A PCD can only use one type for all source modules\r
+            #\r
+            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
+                            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
+                            )\r
+                    else:\r
+                        pass\r
 \r
             #\r
             # intersection the BinaryPCD for Mixed PCD\r
@@ -602,33 +662,111 @@ class WorkspaceAutoGen(AutoGen):
         self._MakeFileDir = None\r
         self._BuildCommand = None\r
 \r
+        #\r
+        # Create BuildOptions Macro & PCD metafile, also add the Active Platform and FDF file.\r
+        #\r
+        content = 'gCommandLineDefines: '\r
+        content += str(GlobalData.gCommandLineDefines)\r
+        content += os.linesep\r
+        content += 'BuildOptionPcd: '\r
+        content += str(GlobalData.BuildOptionPcd)\r
+        content += os.linesep\r
+        content += 'Active Platform: '\r
+        content += str(self.Platform)\r
+        content += os.linesep\r
+        if self.FdfFile:\r
+            content += 'Flash Image Definition: '\r
+            content += str(self.FdfFile)\r
+        SaveFileOnChange(os.path.join(self.BuildDir, 'BuildOptions'), content, False)\r
+\r
+        #\r
+        # Create PcdToken Number file for Dynamic/DynamicEx Pcd.\r
+        #\r
+        PcdTokenNumber = 'PcdTokenNumber: '\r
+        if Pa.PcdTokenNumber:\r
+            if Pa.DynamicPcdList:\r
+                for Pcd in Pa.DynamicPcdList:\r
+                    PcdTokenNumber += os.linesep\r
+                    PcdTokenNumber += str((Pcd.TokenCName, Pcd.TokenSpaceGuidCName))\r
+                    PcdTokenNumber += ' : '\r
+                    PcdTokenNumber += str(Pa.PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName])\r
+        SaveFileOnChange(os.path.join(self.BuildDir, 'PcdTokenNumber'), PcdTokenNumber, False)\r
+\r
+        #\r
+        # Get set of workspace metafiles\r
+        #\r
+        AllWorkSpaceMetaFiles = self._GetMetaFiles(Target, Toolchain, Arch)\r
+\r
+        #\r
+        # Retrieve latest modified time of all metafiles\r
+        #\r
+        SrcTimeStamp = 0\r
+        for f in AllWorkSpaceMetaFiles:\r
+            if os.stat(f)[8] > SrcTimeStamp:\r
+                SrcTimeStamp = os.stat(f)[8]\r
+        self._SrcTimeStamp = SrcTimeStamp\r
+\r
+        #\r
+        # Write metafile list to build directory\r
+        #\r
+        AutoGenFilePath = os.path.join(self.BuildDir, 'AutoGen')\r
+        if os.path.exists (AutoGenFilePath):\r
+            os.remove(AutoGenFilePath)\r
+        if not os.path.exists(self.BuildDir):\r
+            os.makedirs(self.BuildDir)\r
+        with open(os.path.join(self.BuildDir, 'AutoGen'), 'w+') as file:\r
+            for f in AllWorkSpaceMetaFiles:\r
+                print >> file, f\r
         return True\r
 \r
-    def _BuildOptionPcdValueFormat(self, TokenSpaceGuidCName, TokenCName, PcdDatumType, Value):\r
-        if PcdDatumType == 'VOID*':\r
-            if Value.startswith('L'):\r
-                if not Value[1]:\r
-                    EdkLogger.error('build', OPTION_VALUE_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"')\r
-                Value = Value[0] + '"' + Value[1:] + '"'\r
-            elif Value.startswith('B'):\r
-                if not Value[1]:\r
-                    EdkLogger.error('build', OPTION_VALUE_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"')\r
-                Value = Value[1:]\r
-            else:\r
-                if not Value[0]:\r
-                    EdkLogger.error('build', OPTION_VALUE_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"')\r
-                Value = '"' + Value + '"'\r
-\r
-        IsValid, Cause = CheckPcdDatum(PcdDatumType, Value)\r
-        if not IsValid:\r
-            EdkLogger.error('build', FORMAT_INVALID, Cause, ExtraData="%s.%s" % (TokenSpaceGuidCName, TokenCName))\r
-        if PcdDatumType == 'BOOLEAN':\r
-            Value = Value.upper()\r
-            if Value == 'TRUE' or Value == '1':\r
-                Value = '1'\r
-            elif Value == 'FALSE' or Value == '0':\r
-                Value = '0'\r
-        return  Value\r
+\r
+    def _GetMetaFiles(self, Target, Toolchain, Arch):\r
+        AllWorkSpaceMetaFiles = set()\r
+        #\r
+        # add fdf\r
+        #\r
+        if self.FdfFile:\r
+            AllWorkSpaceMetaFiles.add (self.FdfFile.Path)\r
+            if self.FdfFile:\r
+                FdfFiles = GlobalData.gFdfParser.GetAllIncludedFile()\r
+                for f in FdfFiles:\r
+                    AllWorkSpaceMetaFiles.add (f.FileName)\r
+        #\r
+        # add dsc\r
+        #\r
+        AllWorkSpaceMetaFiles.add(self.MetaFile.Path)\r
+\r
+        #\r
+        # add build_rule.txt & tools_def.txt\r
+        #\r
+        AllWorkSpaceMetaFiles.add(os.path.join(GlobalData.gConfDirectory, gDefaultBuildRuleFile))\r
+        AllWorkSpaceMetaFiles.add(os.path.join(GlobalData.gConfDirectory, gDefaultToolsDefFile))\r
+\r
+        # add BuildOption metafile\r
+        #\r
+        AllWorkSpaceMetaFiles.add(os.path.join(self.BuildDir, 'BuildOptions'))\r
+\r
+        # add PcdToken Number file for Dynamic/DynamicEx Pcd\r
+        #\r
+        AllWorkSpaceMetaFiles.add(os.path.join(self.BuildDir, 'PcdTokenNumber'))\r
+\r
+        for Arch in self.ArchList:\r
+            Platform = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]\r
+            PGen = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch)\r
+\r
+            #\r
+            # add dec\r
+            #\r
+            for Package in PGen.PackageList:\r
+                AllWorkSpaceMetaFiles.add(Package.MetaFile.Path)\r
+\r
+            #\r
+            # add included dsc\r
+            #\r
+            for filePath in Platform._RawData.IncludedFiles:\r
+                AllWorkSpaceMetaFiles.add(filePath.Path)\r
+\r
+        return AllWorkSpaceMetaFiles\r
 \r
     ## _CheckDuplicateInFV() method\r
     #\r
@@ -1680,7 +1818,10 @@ class PlatformAutoGen(AutoGen):
                         if self.BuildOption[Tool][Attr].startswith('='):\r
                             Value = self.BuildOption[Tool][Attr][1:]\r
                         else:\r
-                            Value += " " + self.BuildOption[Tool][Attr]\r
+                            if Attr != 'PATH':\r
+                                Value += " " + self.BuildOption[Tool][Attr]\r
+                            else:\r
+                                Value = self.BuildOption[Tool][Attr]\r
 \r
                     if Attr == "PATH":\r
                         # Don't put MAKE definition in the file\r
@@ -1914,6 +2055,10 @@ class PlatformAutoGen(AutoGen):
     #   @retval library_list    List of library instances sorted\r
     #\r
     def ApplyLibraryInstance(self, Module):\r
+        # Cover the case that the binary INF file is list in the FDF file but not DSC file, return empty list directly\r
+        if str(Module) not in self.Platform.Modules:\r
+            return []\r
+\r
         ModuleType = Module.ModuleType\r
 \r
         # for overridding library instances with module specific setting\r
@@ -2174,7 +2319,7 @@ class PlatformAutoGen(AutoGen):
             for SkuId in PcdInModule.SkuInfoList:\r
                 Sku = PcdInModule.SkuInfoList[SkuId]\r
                 if Sku.VariableGuid == '': continue\r
-                Sku.VariableGuidValue = GuidValue(Sku.VariableGuid, self.PackageList)\r
+                Sku.VariableGuidValue = GuidValue(Sku.VariableGuid, self.PackageList, self.MetaFile.Path)\r
                 if Sku.VariableGuidValue == None:\r
                     PackageList = "\n\t".join([str(P) for P in self.PackageList])\r
                     EdkLogger.error(\r
@@ -2190,8 +2335,18 @@ class PlatformAutoGen(AutoGen):
         if Module in self.Platform.Modules:\r
             PlatformModule = self.Platform.Modules[str(Module)]\r
             for Key  in PlatformModule.Pcds:\r
+                Flag = False\r
                 if Key in Pcds:\r
-                    self._OverridePcd(Pcds[Key], PlatformModule.Pcds[Key], Module)\r
+                    ToPcd = Pcds[Key]\r
+                    Flag = True\r
+                elif Key in GlobalData.MixedPcd:\r
+                    for PcdItem in GlobalData.MixedPcd[Key]:\r
+                        if PcdItem in Pcds:\r
+                            ToPcd = Pcds[PcdItem]\r
+                            Flag = True\r
+                            break\r
+                if Flag:\r
+                    self._OverridePcd(ToPcd, PlatformModule.Pcds[Key], Module)\r
         return Pcds.values()\r
 \r
     ## Resolve library names to library modules\r
@@ -2339,8 +2494,11 @@ class PlatformAutoGen(AutoGen):
                         if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or Options[Key].startswith('='):\r
                             BuildOptions[Tool][Attr] = Options[Key]\r
                         else:\r
-                            # append options for the same tool\r
-                            BuildOptions[Tool][Attr] += " " + Options[Key]\r
+                            # append options for the same tool except PATH\r
+                            if Attr != 'PATH':\r
+                                BuildOptions[Tool][Attr] += " " + Options[Key]\r
+                            else:\r
+                                BuildOptions[Tool][Attr] = Options[Key]\r
         # Build Option Family has been checked, which need't to be checked again for family.\r
         if FamilyMatch or FamilyIsNull:\r
             return BuildOptions\r
@@ -2371,8 +2529,11 @@ class PlatformAutoGen(AutoGen):
                         if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or Options[Key].startswith('='):\r
                             BuildOptions[Tool][Attr] = Options[Key]\r
                         else:\r
-                            # append options for the same tool\r
-                            BuildOptions[Tool][Attr] += " " + Options[Key]\r
+                            # append options for the same tool except PATH\r
+                            if Attr != 'PATH':\r
+                                BuildOptions[Tool][Attr] += " " + Options[Key]\r
+                            else:\r
+                                BuildOptions[Tool][Attr] = Options[Key]\r
         return BuildOptions\r
 \r
     ## Append build options in platform to a module\r
@@ -2431,7 +2592,10 @@ class PlatformAutoGen(AutoGen):
                         BuildOptions[Tool][Attr] = ToolPath\r
                     else:\r
                         Value = mws.handleWsMacro(Value)\r
-                        BuildOptions[Tool][Attr] += " " + Value\r
+                        if Attr != 'PATH':\r
+                            BuildOptions[Tool][Attr] += " " + Value\r
+                        else:\r
+                            BuildOptions[Tool][Attr] = Value\r
         if Module.AutoGenVersion < 0x00010005 and self.Workspace.UniFlag != None:\r
             #\r
             # Override UNI flag only for EDK module.\r
@@ -2478,6 +2642,10 @@ class PlatformAutoGen(AutoGen):
 # to the [depex] section in module's inf file.\r
 #\r
 class ModuleAutoGen(AutoGen):\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
@@ -2527,6 +2695,7 @@ class ModuleAutoGen(AutoGen):
 \r
         self.BuildDatabase = self.Workspace.BuildDatabase\r
         self.BuildRuleOrder = None\r
+        self.BuildTime      = 0\r
 \r
         self._Module          = None\r
         self._Name            = None\r
@@ -2549,6 +2718,8 @@ class ModuleAutoGen(AutoGen):
         self._IncludePathLength = 0\r
         self._AutoGenFileList = None\r
         self._UnicodeFileList = None\r
+        self._VfrFileList = None\r
+        self._IdfFileList = None\r
         self._SourceFileList  = None\r
         self._ObjectFileList  = None\r
         self._BinaryFileList  = None\r
@@ -2576,6 +2747,11 @@ class ModuleAutoGen(AutoGen):
         self._FinalBuildTargetList    = None\r
         self._FileTypes               = None\r
         self._BuildRules              = None\r
+\r
+        self._TimeStampPath           = None\r
+\r
+        self.AutoGenDepSet = set()\r
+\r
         \r
         ## The Modules referenced to this Library\r
         #  Only Library has this attribute\r
@@ -2595,10 +2771,7 @@ class ModuleAutoGen(AutoGen):
         if self._FixedAtBuildPcds:\r
             return self._FixedAtBuildPcds\r
         for Pcd in self.ModulePcdList:\r
-            if self.IsLibrary:\r
-                if not (Pcd.Pending == False and Pcd.Type == "FixedAtBuild"):\r
-                    continue\r
-            elif Pcd.Type != "FixedAtBuild":\r
+            if Pcd.Type != "FixedAtBuild":\r
                 continue\r
             if Pcd not in self._FixedAtBuildPcds:\r
                 self._FixedAtBuildPcds.append(Pcd)\r
@@ -2928,6 +3101,30 @@ class ModuleAutoGen(AutoGen):
                 self._DepexExpressionList[ModuleType] = DepexExpressionList\r
         return self._DepexExpressionList\r
 \r
+    # Get the tiano core user extension, it is contain dependent library.\r
+    # @retval: a list contain tiano core userextension.\r
+    #\r
+    def _GetTianoCoreUserExtensionList(self):\r
+        TianoCoreUserExtentionList = []\r
+        for M in [self.Module] + self.DependentLibraryList:\r
+            Filename = M.MetaFile.Path\r
+            InfObj = InfSectionParser.InfSectionParser(Filename)\r
+            TianoCoreUserExtenList = InfObj.GetUserExtensionTianoCore()\r
+            for TianoCoreUserExtent in TianoCoreUserExtenList:\r
+                for Section in TianoCoreUserExtent.keys():\r
+                    ItemList = Section.split(TAB_SPLIT)\r
+                    Arch = self.Arch\r
+                    if len(ItemList) == 4:\r
+                        Arch = ItemList[3]\r
+                    if Arch.upper() == TAB_ARCH_COMMON or Arch.upper() == self.Arch.upper():\r
+                        TianoCoreList = []\r
+                        TianoCoreList.extend([TAB_SECTION_START + Section + TAB_SECTION_END])\r
+                        TianoCoreList.extend(TianoCoreUserExtent[Section][:])\r
+                        TianoCoreList.append('\n')\r
+                        TianoCoreUserExtentionList.append(TianoCoreList)\r
+\r
+        return TianoCoreUserExtentionList\r
+\r
     ## Return the list of specification version required for the module\r
     #\r
     #   @retval     list    The list of specification defined in module file\r
@@ -3073,6 +3270,24 @@ class ModuleAutoGen(AutoGen):
                 self._UnicodeFileList = []\r
         return self._UnicodeFileList\r
 \r
+    ## Return the list of vfr files\r
+    def _GetVfrFileList(self):\r
+        if self._VfrFileList == None:\r
+            if TAB_VFR_FILE in self.FileTypes:\r
+                self._VfrFileList = self.FileTypes[TAB_VFR_FILE]\r
+            else:\r
+                self._VfrFileList = []\r
+        return self._VfrFileList\r
+\r
+    ## Return the list of Image Definition files\r
+    def _GetIdfFileList(self):\r
+        if self._IdfFileList == None:\r
+            if TAB_IMAGE_FILE in self.FileTypes:\r
+                self._IdfFileList = self.FileTypes[TAB_IMAGE_FILE]\r
+            else:\r
+                self._IdfFileList = []\r
+        return self._IdfFileList\r
+\r
     ## Return a list of files which can be built from binary\r
     #\r
     #  "Build" binary files are just to copy them to build directory.\r
@@ -3235,15 +3450,19 @@ class ModuleAutoGen(AutoGen):
     #\r
     def _GetAutoGenFileList(self):\r
         UniStringAutoGenC = True\r
+        IdfStringAutoGenC = True\r
         UniStringBinBuffer = StringIO()\r
+        IdfGenBinBuffer = StringIO()\r
         if self.BuildType == 'UEFI_HII':\r
             UniStringAutoGenC = False\r
+            IdfStringAutoGenC = False\r
         if self._AutoGenFileList == None:\r
             self._AutoGenFileList = {}\r
             AutoGenC = TemplateString()\r
             AutoGenH = TemplateString()\r
             StringH = TemplateString()\r
-            GenC.CreateCode(self, AutoGenC, AutoGenH, StringH, UniStringAutoGenC, UniStringBinBuffer)\r
+            StringIdf = TemplateString()\r
+            GenC.CreateCode(self, AutoGenC, AutoGenH, StringH, UniStringAutoGenC, UniStringBinBuffer, StringIdf, IdfStringAutoGenC, IdfGenBinBuffer)\r
             #\r
             # AutoGen.c is generated if there are library classes in inf, or there are object files\r
             #\r
@@ -3267,6 +3486,17 @@ class ModuleAutoGen(AutoGen):
                 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)\r
             if UniStringBinBuffer != 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
+                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
+                IdfGenBinBuffer.close()\r
         return self._AutoGenFileList\r
 \r
     ## Return the list of library modules explicitly or implicityly used by this module\r
@@ -3395,7 +3625,11 @@ class ModuleAutoGen(AutoGen):
                 PackageDir = mws.join(self.WorkspaceDir, Package.MetaFile.Dir)\r
                 if PackageDir not in self._IncludePathList:\r
                     self._IncludePathList.append(PackageDir)\r
-                for Inc in Package.Includes:\r
+                IncludesList = Package.Includes\r
+                if Package._PrivateIncludes:\r
+                    if not self.MetaFile.Path.startswith(PackageDir):\r
+                        IncludesList = list(set(Package.Includes).difference(set(Package._PrivateIncludes)))\r
+                for Inc in IncludesList:\r
                     if Inc not in self._IncludePathList:\r
                         self._IncludePathList.append(str(Inc))\r
         return self._IncludePathList\r
@@ -3462,7 +3696,7 @@ class ModuleAutoGen(AutoGen):
             for SkuName in Pcd.SkuInfoList:\r
                 SkuInfo = Pcd.SkuInfoList[SkuName]\r
                 Name = ConvertStringToByteArray(SkuInfo.VariableName)\r
-                Value = GuidValue(SkuInfo.VariableGuid, self.PlatformInfo.PackageList)\r
+                Value = GuidValue(SkuInfo.VariableGuid, self.PlatformInfo.PackageList, self.MetaFile.Path)\r
                 if not Value:\r
                     continue\r
                 Guid = GuidStructureStringToGuidString(Value)\r
@@ -3569,13 +3803,13 @@ class ModuleAutoGen(AutoGen):
         # Find all DynamicEx and PatchableInModule PCDs used by this module and dependent libraries\r
         # Also find all packages that the DynamicEx PCDs depend on\r
         Pcds = []\r
-        PatchablePcds = {}\r
+        PatchablePcds = []\r
         Packages = []\r
         PcdCheckList = []\r
         PcdTokenSpaceList = []\r
         for Pcd in self.ModulePcdList + self.LibraryPcdList:\r
             if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:\r
-                PatchablePcds[Pcd.TokenCName] = Pcd\r
+                PatchablePcds += [Pcd]\r
                 PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'PatchableInModule'))\r
             elif Pcd.Type in GenC.gDynamicExPcd:\r
                 if Pcd not in Pcds:\r
@@ -3658,6 +3892,11 @@ class ModuleAutoGen(AutoGen):
           'libraryclasses_item'               : []\r
         }\r
 \r
+        if 'MODULE_UNI_FILE' in MDefs:\r
+            UNIFile = os.path.join(self.MetaFile.Dir, MDefs['MODULE_UNI_FILE'])\r
+            if os.path.isfile(UNIFile):\r
+                shutil.copy2(UNIFile, self.OutputDir)\r
+\r
         if self.AutoGenVersion > int(gInfSpecVersion, 0):\r
             AsBuiltInfDict['module_inf_version'] = '0x%08x' % self.AutoGenVersion\r
         else:\r
@@ -3728,16 +3967,25 @@ class ModuleAutoGen(AutoGen):
                             os.path.join(self.OutputDir, self.Name + '.efi')\r
                         )\r
         if PatchList:\r
-            for PatchPcd in PatchList:\r
-                if PatchPcd[0] in PatchablePcds:\r
-                    key = PatchPcd[0]\r
-                elif PatchPcd[0] + '_PatchableInModule' in PatchablePcds:\r
-                    key = PatchPcd[0] + '_PatchableInModule'\r
+            for Pcd in PatchablePcds:\r
+                TokenCName = Pcd.TokenCName\r
+                for PcdItem in GlobalData.MixedPcd:\r
+                    if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:\r
+                        TokenCName = PcdItem[0]\r
+                        break\r
+                for PatchPcd in PatchList:\r
+                    if TokenCName == PatchPcd[0]:\r
+                        break\r
                 else:\r
                     continue\r
-                Pcd = PatchablePcds[key]\r
-                TokenCName = PatchPcd[0]\r
                 PcdValue = ''\r
+                if Pcd.DatumType == 'BOOLEAN':\r
+                    BoolValue = Pcd.DefaultValue.upper()\r
+                    if BoolValue == 'TRUE':\r
+                        Pcd.DefaultValue = '1'\r
+                    elif BoolValue == 'FALSE':\r
+                        Pcd.DefaultValue = '0'\r
+\r
                 if Pcd.DatumType != 'VOID*':\r
                     HexFormat = '0x%02x'\r
                     if Pcd.DatumType == 'UINT16':\r
@@ -3848,6 +4096,16 @@ class ModuleAutoGen(AutoGen):
         for Library in self.LibraryAutoGenList:\r
             AsBuiltInfDict['libraryclasses_item'] += [Library.MetaFile.File.replace('\\', '/')]\r
         \r
+        # Generated UserExtensions TianoCore section.\r
+        # All tianocore user extensions are copied.\r
+        UserExtStr = ''\r
+        for TianoCore in self._GetTianoCoreUserExtensionList():\r
+            UserExtStr += '\n'.join(TianoCore)\r
+            ExtensionFile = os.path.join(self.MetaFile.Dir, TianoCore[1])\r
+            if os.path.isfile(ExtensionFile):\r
+                shutil.copy2(ExtensionFile, self.OutputDir)\r
+        AsBuiltInfDict['userextension_tianocore_item'] = UserExtStr\r
+\r
         # Generated depex expression section in comments.\r
         AsBuiltInfDict['depexsection_item'] = ''\r
         DepexExpresion = self._GetDepexExpresionString()\r
@@ -3873,6 +4131,8 @@ class ModuleAutoGen(AutoGen):
 \r
         if self.IsMakeFileCreated:\r
             return\r
+        if self.CanSkip():\r
+            return\r
 \r
         if not self.IsLibrary and CreateLibraryMakeFile:\r
             for LibraryAutoGen in self.LibraryAutoGenList:\r
@@ -3889,6 +4149,7 @@ class ModuleAutoGen(AutoGen):
             EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of makefile for module %s [%s]" %\r
                             (self.Name, self.Arch))\r
 \r
+        self.CreateTimeStamp(Makefile)\r
         self.IsMakeFileCreated = True\r
 \r
     def CopyBinaryFiles(self):\r
@@ -3904,6 +4165,8 @@ class ModuleAutoGen(AutoGen):
     def CreateCodeFile(self, CreateLibraryCodeFile=True):\r
         if self.IsCodeFileCreated:\r
             return\r
+        if self.CanSkip():\r
+            return\r
 \r
         # Need to generate PcdDatabase even PcdDriver is binarymodule\r
         if self.IsBinaryModule and self.PcdIsDriver != '':\r
@@ -3983,6 +4246,55 @@ class ModuleAutoGen(AutoGen):
                         self._ApplyBuildRule(Lib.Target, TAB_UNKNOWN_FILE)\r
         return self._LibraryAutoGenList\r
 \r
+    ## Decide whether we can skip the ModuleAutoGen process\r
+    #  If any source file is newer than the modeule than we cannot skip\r
+    #\r
+    def CanSkip(self):\r
+        if not os.path.exists(self.GetTimeStampPath()):\r
+            return False\r
+        #last creation time of the module\r
+        DstTimeStamp = os.stat(self.GetTimeStampPath())[8]\r
+\r
+        SrcTimeStamp = self.Workspace._SrcTimeStamp\r
+        if SrcTimeStamp > DstTimeStamp:\r
+            return False\r
+\r
+        with open(self.GetTimeStampPath(),'r') as f:\r
+            for source in f:\r
+                source = source.rstrip('\n')\r
+                if not os.path.exists(source):\r
+                    return False\r
+                if source not in ModuleAutoGen.TimeDict :\r
+                    ModuleAutoGen.TimeDict[source] = os.stat(source)[8]\r
+                if ModuleAutoGen.TimeDict[source] > DstTimeStamp:\r
+                    return False\r
+        return True\r
+\r
+    def GetTimeStampPath(self):\r
+        if self._TimeStampPath == None:\r
+            self._TimeStampPath = os.path.join(self.MakeFileDir, 'AutoGenTimeStamp')\r
+        return self._TimeStampPath\r
+    def CreateTimeStamp(self, Makefile):\r
+\r
+        FileSet = set()\r
+\r
+        FileSet.add (self.MetaFile.Path)\r
+\r
+        for SourceFile in self.Module.Sources:\r
+            FileSet.add (SourceFile.Path)\r
+\r
+        for Lib in self.DependentLibraryList:\r
+            FileSet.add (Lib.MetaFile.Path)\r
+\r
+        for f in self.AutoGenDepSet:\r
+            FileSet.add (f.Path)\r
+\r
+        if os.path.exists (self.GetTimeStampPath()):\r
+            os.remove (self.GetTimeStampPath())\r
+        with open(self.GetTimeStampPath(), 'w+') as file:\r
+            for f in FileSet:\r
+                print >> file, f\r
+\r
     Module          = property(_GetModule)\r
     Name            = property(_GetBaseName)\r
     Guid            = property(_GetGuid)\r
@@ -4007,6 +4319,7 @@ class ModuleAutoGen(AutoGen):
     IncludePathLength = property(_GetIncludePathLength)\r
     AutoGenFileList = property(_GetAutoGenFileList)\r
     UnicodeFileList = property(_GetUnicodeFileList)\r
+    VfrFileList     = property(_GetVfrFileList)\r
     SourceFileList  = property(_GetSourceFileList)\r
     BinaryFileList  = property(_GetBinaryFiles) # FileType : [File List]\r
     Targets         = property(_GetTargets)\r
@@ -4014,6 +4327,7 @@ class ModuleAutoGen(AutoGen):
     CodaTargetList  = property(_GetFinalTargetList)\r
     FileTypes       = property(_GetFileTypes)\r
     BuildRules      = property(_GetBuildRules)\r
+    IdfFileList     = property(_GetIdfFileList)\r
 \r
     DependentPackageList    = property(_GetDependentPackageList)\r
     DependentLibraryList    = property(_GetLibraryList)\r