]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/UPT/GenMetaFile/GenInfFile.py
BaseTools/UPT: Fix UNI file name issue
[mirror_edk2.git] / BaseTools / Source / Python / UPT / GenMetaFile / GenInfFile.py
index 78bb6ea4f1807eef20b80f3086f3b430ae9ee855..d7eaf3ea1d12d1bd210110970114c923d58b51ef 100644 (file)
@@ -2,7 +2,7 @@
 #\r
 # This file contained the logical of transfer package object to INF files.\r
 #\r
-# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2011 - 2017, Intel Corporation. All rights reserved.<BR>\r
 #\r
 # This program and the accompanying materials are licensed and made available \r
 # under the terms and conditions of the BSD License which accompanies this \r
 '''\r
 GenInf\r
 '''\r
-from os import getenv\r
+import os\r
+import stat\r
+import codecs\r
+import md5\r
+from Core.FileHook import __FileHookOpen__\r
 from Library.String import GetSplitValueList\r
 from Library.Parsing import GenSection\r
 from Library.Parsing import GetWorkspacePackage\r
-from Library.Parsing import ConvertArchForInstall                     \r
+from Library.Parsing import ConvertArchForInstall\r
 from Library.Misc import SaveFileOnChange\r
 from Library.Misc import IsAllModuleList\r
 from Library.Misc import Sdict\r
 from Library.Misc import ConvertPath\r
 from Library.Misc import ConvertSpec\r
+from Library.Misc import GetRelativePath\r
+from Library.Misc import GetLocalValue\r
 from Library.CommentGenerating import GenHeaderCommentSection\r
 from Library.CommentGenerating import GenGenericCommentF\r
 from Library.CommentGenerating import _GetHelpStr\r
@@ -34,29 +40,110 @@ from Logger import ToolError
 import Logger.Log as Logger\r
 from Library import DataType as DT\r
 from GenMetaFile import GenMetaFileMisc\r
+from Library.UniClassObject import FormatUniEntry\r
+from Library.String import GetUniFileName\r
+\r
 \r
 ## Transfer Module Object to Inf files\r
 #\r
 # Transfer all contents of a standard Module Object to an Inf file \r
 # @param ModuleObject: A Module Object  \r
 #\r
-def ModuleToInf(ModuleObject):\r
-    if not GlobalData.gWSPKG_LIST:  \r
+def ModuleToInf(ModuleObject, PackageObject=None, DistHeader=None):\r
+    if not GlobalData.gWSPKG_LIST:\r
         GlobalData.gWSPKG_LIST = GetWorkspacePackage()\r
-    \r
     #\r
     # Init global information for the file\r
     #\r
     ContainerFile = ModuleObject.GetFullPath()\r
+\r
     Content = ''\r
     #\r
-    # generate header comment section\r
+    # Generate file header, If any Abstract, Description, Copyright or License XML elements are missing, \r
+    # should 1) use the Abstract, Description, Copyright or License from the PackageSurfaceArea.Header elements \r
+    # that the module belongs to, or 2) if this is a stand-alone module that is not included in a PackageSurfaceArea, \r
+    # use the abstract, description, copyright or license from the DistributionPackage.Header elements.\r
+    #\r
+    ModuleAbstract = GetLocalValue(ModuleObject.GetAbstract())\r
+    if not ModuleAbstract and PackageObject:\r
+        ModuleAbstract = GetLocalValue(PackageObject.GetAbstract())\r
+    if not ModuleAbstract and DistHeader:\r
+        ModuleAbstract = GetLocalValue(DistHeader.GetAbstract())\r
+    ModuleDescription = GetLocalValue(ModuleObject.GetDescription())\r
+    if not ModuleDescription and PackageObject:\r
+        ModuleDescription = GetLocalValue(PackageObject.GetDescription())\r
+    if not ModuleDescription and DistHeader:\r
+        ModuleDescription = GetLocalValue(DistHeader.GetDescription())\r
+    ModuleCopyright = ''\r
+    for (Lang, Copyright) in ModuleObject.GetCopyright():\r
+        if Lang:\r
+            pass\r
+        ModuleCopyright = Copyright\r
+    if not ModuleCopyright and PackageObject:\r
+        for (Lang, Copyright) in PackageObject.GetCopyright():\r
+            if Lang:\r
+                pass\r
+            ModuleCopyright = Copyright\r
+    if not ModuleCopyright and DistHeader:\r
+        for (Lang, Copyright) in DistHeader.GetCopyright():\r
+            if Lang:\r
+                pass\r
+            ModuleCopyright = Copyright\r
+    ModuleLicense = ''\r
+    for (Lang, License) in ModuleObject.GetLicense():\r
+        if Lang:\r
+            pass\r
+        ModuleLicense = License\r
+    if not ModuleLicense and PackageObject:\r
+        for (Lang, License) in PackageObject.GetLicense():\r
+            if Lang:\r
+                pass\r
+            ModuleLicense = License\r
+    if not ModuleLicense and DistHeader:\r
+        for (Lang, License) in DistHeader.GetLicense():\r
+            if Lang:\r
+                pass\r
+            ModuleLicense = License\r
+\r
+    #\r
+    # Generate header comment section of INF file\r
     #        \r
-    Content += GenHeaderCommentSection(ModuleObject.GetAbstract(), \r
-                                       ModuleObject.GetDescription(), \r
-                                       ModuleObject.GetCopyright(), \r
-                                       ModuleObject.GetLicense())\r
-    \r
+    Content += GenHeaderCommentSection(ModuleAbstract,\r
+                                       ModuleDescription,\r
+                                       ModuleCopyright,\r
+                                       ModuleLicense).replace('\r\n', '\n')\r
+\r
+    #\r
+    # Generate Binary Header \r
+    # \r
+    for UserExtension in ModuleObject.GetUserExtensionList():\r
+        if UserExtension.GetUserID() == DT.TAB_BINARY_HEADER_USERID \\r
+        and UserExtension.GetIdentifier() == DT.TAB_BINARY_HEADER_IDENTIFIER:\r
+            ModuleBinaryAbstract = GetLocalValue(UserExtension.GetBinaryAbstract())\r
+            ModuleBinaryDescription = GetLocalValue(UserExtension.GetBinaryDescription())\r
+            ModuleBinaryCopyright = ''\r
+            ModuleBinaryLicense = ''\r
+            for (Lang, Copyright) in UserExtension.GetBinaryCopyright():\r
+                ModuleBinaryCopyright = Copyright\r
+            for (Lang, License) in UserExtension.GetBinaryLicense():\r
+                ModuleBinaryLicense = License\r
+            if ModuleBinaryAbstract and ModuleBinaryDescription and \\r
+            ModuleBinaryCopyright and ModuleBinaryLicense:\r
+                Content += GenHeaderCommentSection(ModuleBinaryAbstract,\r
+                                           ModuleBinaryDescription,\r
+                                           ModuleBinaryCopyright,\r
+                                           ModuleBinaryLicense,\r
+                                           True)\r
+\r
+    #\r
+    # Generate MODULE_UNI_FILE for module\r
+    #\r
+    FileHeader = GenHeaderCommentSection(ModuleAbstract, ModuleDescription, ModuleCopyright, ModuleLicense, False, \\r
+                                         DT.TAB_COMMENT_EDK1_SPLIT)\r
+    ModuleUniFile = GenModuleUNIEncodeFile(ModuleObject, FileHeader)\r
+    if ModuleUniFile:\r
+        ModuleObject.SetModuleUniFile(os.path.basename(ModuleUniFile))\r
+\r
     #\r
     # Judge whether the INF file is an AsBuild INF.\r
     #\r
@@ -64,15 +151,12 @@ def ModuleToInf(ModuleObject):
         GlobalData.gIS_BINARY_INF = True\r
     else:\r
         GlobalData.gIS_BINARY_INF = False\r
-    \r
     #\r
     # for each section, maintain a dict, sorted arch will be its key, \r
     # statement list will be its data\r
     # { 'Arch1 Arch2 Arch3': [statement1, statement2],\r
     #   'Arch1' : [statement1, statement3] \r
     #  }\r
-    #\r
-    \r
     #\r
     # Gen section contents\r
     #\r
@@ -82,37 +166,117 @@ def ModuleToInf(ModuleObject):
     Content += GenPackages(ModuleObject)\r
     Content += GenPcdSections(ModuleObject)\r
     Content += GenSources(ModuleObject)\r
-    Content += GenProtocolPPiSections(ModuleObject.GetProtocolList(), True) \r
-    Content += GenProtocolPPiSections(ModuleObject.GetPpiList(), False) \r
-    Content += GenGuidSections(ModuleObject.GetGuidList())    \r
+    Content += GenProtocolPPiSections(ModuleObject.GetProtocolList(), True)\r
+    Content += GenProtocolPPiSections(ModuleObject.GetPpiList(), False)\r
+    Content += GenGuidSections(ModuleObject.GetGuidList())\r
     Content += GenBinaries(ModuleObject)\r
     Content += GenDepex(ModuleObject)\r
-    Content += GenUserExtensions(ModuleObject)        \r
-\r
+    __UserExtensionsContent = GenUserExtensions(ModuleObject)\r
+    Content += __UserExtensionsContent\r
     if ModuleObject.GetEventList() or ModuleObject.GetBootModeList() or ModuleObject.GetHobList():\r
-        Content += '\n\n'\r
+        Content += '\n'\r
     #\r
     # generate [Event], [BootMode], [Hob] section\r
     #\r
-    Content += GenSpecialSections(ModuleObject.GetEventList(), 'Event')    \r
-    Content += GenSpecialSections(ModuleObject.GetBootModeList(), 'BootMode')\r
-    Content += GenSpecialSections(ModuleObject.GetHobList(), 'Hob')\r
-\r
+    Content += GenSpecialSections(ModuleObject.GetEventList(), 'Event', __UserExtensionsContent)\r
+    Content += GenSpecialSections(ModuleObject.GetBootModeList(), 'BootMode', __UserExtensionsContent)\r
+    Content += GenSpecialSections(ModuleObject.GetHobList(), 'Hob', __UserExtensionsContent)\r
     SaveFileOnChange(ContainerFile, Content, False)\r
+    if DistHeader.ReadOnly:\r
+        os.chmod(ContainerFile, stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH)\r
+    else:\r
+        os.chmod(ContainerFile, stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH|stat.S_IWUSR|stat.S_IWGRP|stat.S_IWOTH)\r
     return ContainerFile\r
 \r
+## GenModuleUNIEncodeFile\r
+# GenModuleUNIEncodeFile, default is a UCS-2LE encode file\r
+#\r
+def GenModuleUNIEncodeFile(ModuleObject, UniFileHeader='', Encoding=DT.TAB_ENCODING_UTF16LE):\r
+    GenUNIFlag = False\r
+    OnlyLANGUAGE_EN_X = True\r
+    BinaryAbstract = []\r
+    BinaryDescription = []\r
+    #\r
+    # If more than one language code is used for any element that would be present in the MODULE_UNI_FILE, \r
+    # then the MODULE_UNI_FILE must be created.\r
+    #\r
+    for (Key, Value) in ModuleObject.GetAbstract() + ModuleObject.GetDescription():\r
+        if Key == DT.TAB_LANGUAGE_EN_X:\r
+            GenUNIFlag = True\r
+        else:\r
+            OnlyLANGUAGE_EN_X = False\r
+\r
+    for UserExtension in ModuleObject.GetUserExtensionList():\r
+        if UserExtension.GetUserID() == DT.TAB_BINARY_HEADER_USERID \\r
+        and UserExtension.GetIdentifier() == DT.TAB_BINARY_HEADER_IDENTIFIER:\r
+            for (Key, Value) in UserExtension.GetBinaryAbstract():\r
+                if Key == DT.TAB_LANGUAGE_EN_X:\r
+                    GenUNIFlag = True\r
+                else:\r
+                    OnlyLANGUAGE_EN_X = False\r
+                BinaryAbstract.append((Key, Value))\r
+            for (Key, Value) in UserExtension.GetBinaryDescription():\r
+                if Key == DT.TAB_LANGUAGE_EN_X:\r
+                    GenUNIFlag = True\r
+                else:\r
+                    OnlyLANGUAGE_EN_X = False\r
+                BinaryDescription.append((Key, Value))\r
+\r
+\r
+    if not GenUNIFlag:\r
+        return\r
+    elif OnlyLANGUAGE_EN_X:\r
+        return\r
+    else:\r
+        ModuleObject.UNIFlag = True\r
+    ContainerFile = GetUniFileName(os.path.dirname(ModuleObject.GetFullPath()), ModuleObject.GetBaseName())\r
+\r
+    if not os.path.exists(os.path.dirname(ModuleObject.GetFullPath())):\r
+        os.makedirs(os.path.dirname(ModuleObject.GetFullPath()))\r
+\r
+    Content = UniFileHeader + '\r\n'\r
+    Content += '\r\n'\r
+\r
+    Content += FormatUniEntry('#string ' + DT.TAB_INF_ABSTRACT, ModuleObject.GetAbstract(), ContainerFile) + '\r\n'\r
+\r
+    Content += FormatUniEntry('#string ' + DT.TAB_INF_DESCRIPTION, ModuleObject.GetDescription(), ContainerFile) \\r
+            + '\r\n'\r
+\r
+    BinaryAbstractString = FormatUniEntry('#string ' + DT.TAB_INF_BINARY_ABSTRACT, BinaryAbstract, ContainerFile)\r
+    if BinaryAbstractString:\r
+        Content += BinaryAbstractString + '\r\n'\r
+\r
+    BinaryDescriptionString = FormatUniEntry('#string ' + DT.TAB_INF_BINARY_DESCRIPTION, BinaryDescription, \\r
+                                             ContainerFile)\r
+    if BinaryDescriptionString:\r
+        Content += BinaryDescriptionString + '\r\n'\r
+\r
+    if not os.path.exists(ContainerFile):\r
+        File = codecs.open(ContainerFile, 'wb', Encoding)\r
+        File.write(u'\uFEFF' + Content)\r
+        File.stream.close()\r
+    Md5Sigature = md5.new(__FileHookOpen__(str(ContainerFile), 'rb').read())\r
+    Md5Sum = Md5Sigature.hexdigest()\r
+    if (ContainerFile, Md5Sum) not in ModuleObject.FileList:\r
+        ModuleObject.FileList.append((ContainerFile, Md5Sum))\r
+\r
+    return ContainerFile\r
 def GenDefines(ModuleObject):\r
     #\r
     # generate [Defines] section\r
     #\r
-    Content = ''          \r
-    NewSectionDict = {}     \r
+    LeftOffset = 31\r
+    Content = ''\r
+    NewSectionDict = {}\r
+\r
     for UserExtension in ModuleObject.GetUserExtensionList():\r
         DefinesDict = UserExtension.GetDefinesDict()\r
         if not DefinesDict:\r
             continue\r
-        \r
         for Statement in DefinesDict:\r
+            if Statement.split(DT.TAB_EQUAL_SPLIT) > 1:\r
+                Statement = (u'%s ' % Statement.split(DT.TAB_EQUAL_SPLIT, 1)[0]).ljust(LeftOffset) \\r
+                             + u'= %s' % Statement.split(DT.TAB_EQUAL_SPLIT, 1)[1].lstrip()\r
             SortedArch = DT.TAB_ARCH_COMMON\r
             if Statement.strip().startswith(DT.TAB_INF_DEFINES_CUSTOM_MAKEFILE):\r
                 pos = Statement.find(DT.TAB_VALUE_SPLIT)\r
@@ -123,52 +287,75 @@ def GenDefines(ModuleObject):
             if SortedArch in NewSectionDict:\r
                 NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement]\r
             else:\r
-                NewSectionDict[SortedArch] = [Statement]        \r
-\r
+                NewSectionDict[SortedArch] = [Statement]\r
     SpecialStatementList = []\r
-    \r
-    #\r
-    # Add INF_VERSION statement firstly\r
-    #\r
-    Statement = 'INF_VERSION = 0x00010017'\r
+\r
+    # TAB_INF_DEFINES_INF_VERSION\r
+    Statement = (u'%s ' % DT.TAB_INF_DEFINES_INF_VERSION).ljust(LeftOffset) + u'= %s' % '0x00010017'\r
     SpecialStatementList.append(Statement)\r
 \r
+    # BaseName\r
     BaseName = ModuleObject.GetBaseName()\r
     if BaseName.startswith('.') or BaseName.startswith('-'):\r
         BaseName = '_' + BaseName\r
-    Statement = '%s = %s' % (DT.TAB_INF_DEFINES_BASE_NAME, BaseName)\r
-    SpecialStatementList.append(Statement)\r
-    Statement = '%s = %s' % (DT.TAB_INF_DEFINES_FILE_GUID, ModuleObject.GetGuid())\r
+    Statement = (u'%s ' % DT.TAB_INF_DEFINES_BASE_NAME).ljust(LeftOffset) + u'= %s' % BaseName\r
     SpecialStatementList.append(Statement)\r
-    Statement = '%s = %s' % (DT.TAB_INF_DEFINES_VERSION_STRING, ModuleObject.GetVersion())\r
+    \r
+    # TAB_INF_DEFINES_FILE_GUID\r
+    Statement = (u'%s ' % DT.TAB_INF_DEFINES_FILE_GUID).ljust(LeftOffset) + u'= %s' % ModuleObject.GetGuid()\r
     SpecialStatementList.append(Statement)\r
     \r
+    # TAB_INF_DEFINES_VERSION_STRING\r
+    Statement = (u'%s ' % DT.TAB_INF_DEFINES_VERSION_STRING).ljust(LeftOffset) + u'= %s' % ModuleObject.GetVersion()\r
+    SpecialStatementList.append(Statement)\r
+\r
+    # TAB_INF_DEFINES_VERSION_STRING\r
+    if ModuleObject.UNIFlag:\r
+        Statement = (u'%s ' % DT.TAB_INF_DEFINES_MODULE_UNI_FILE).ljust(LeftOffset) + \\r
+                    u'= %s' % ModuleObject.GetModuleUniFile()\r
+        SpecialStatementList.append(Statement)\r
+\r
+    # TAB_INF_DEFINES_MODULE_TYPE\r
     if ModuleObject.GetModuleType():\r
-        Statement = '%s = %s' % (DT.TAB_INF_DEFINES_MODULE_TYPE, ModuleObject.GetModuleType())\r
+        Statement = (u'%s ' % DT.TAB_INF_DEFINES_MODULE_TYPE).ljust(LeftOffset) + u'= %s' % ModuleObject.GetModuleType()\r
         SpecialStatementList.append(Statement)\r
+\r
+    # TAB_INF_DEFINES_PCD_IS_DRIVER\r
     if ModuleObject.GetPcdIsDriver():\r
-        Statement = '%s = %s' % (DT.TAB_INF_DEFINES_PCD_IS_DRIVER, ModuleObject.GetPcdIsDriver())\r
+        Statement = (u'%s ' % DT.TAB_INF_DEFINES_PCD_IS_DRIVER).ljust(LeftOffset) + \\r
+                    u'= %s' % ModuleObject.GetPcdIsDriver()\r
         SpecialStatementList.append(Statement)\r
+\r
+    # TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION\r
     if ModuleObject.GetUefiSpecificationVersion():\r
-        Statement = '%s = %s' % (DT.TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION, \\r
-                                 ModuleObject.GetUefiSpecificationVersion())\r
+        Statement = (u'%s ' % DT.TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION).ljust(LeftOffset) + \\r
+                    u'= %s' % ModuleObject.GetUefiSpecificationVersion()\r
         SpecialStatementList.append(Statement)\r
+\r
+    # TAB_INF_DEFINES_PI_SPECIFICATION_VERSION\r
     if ModuleObject.GetPiSpecificationVersion():\r
-        Statement = '%s = %s' % (DT.TAB_INF_DEFINES_PI_SPECIFICATION_VERSION, ModuleObject.GetPiSpecificationVersion())\r
-        SpecialStatementList.append(Statement)        \r
+        Statement = (u'%s ' % DT.TAB_INF_DEFINES_PI_SPECIFICATION_VERSION).ljust(LeftOffset) + \\r
+                    u'= %s' % ModuleObject.GetPiSpecificationVersion()\r
+        SpecialStatementList.append(Statement)\r
+\r
+    # LibraryClass\r
     for LibraryClass in ModuleObject.GetLibraryClassList():\r
         if LibraryClass.GetUsage() == DT.USAGE_ITEM_PRODUCES or \\r
            LibraryClass.GetUsage() == DT.USAGE_ITEM_SOMETIMES_PRODUCES:\r
-            Statement = '%s = %s' % (DT.TAB_INF_DEFINES_LIBRARY_CLASS, LibraryClass.GetLibraryClass())\r
+            Statement = (u'%s ' % DT.TAB_INF_DEFINES_LIBRARY_CLASS).ljust(LeftOffset) + \\r
+                        u'= %s' % LibraryClass.GetLibraryClass()\r
             if LibraryClass.GetSupModuleList():\r
                 Statement += '|' + DT.TAB_SPACE_SPLIT.join(l for l in LibraryClass.GetSupModuleList())\r
             SpecialStatementList.append(Statement)\r
+\r
+    # Spec Item\r
     for SpecItem in ModuleObject.GetSpecList():\r
         Spec, Version = SpecItem\r
         Spec = ConvertSpec(Spec)\r
         Statement = '%s %s = %s' % (DT.TAB_INF_DEFINES_SPEC, Spec, Version)\r
         SpecialStatementList.append(Statement)\r
-        \r
+\r
+    # Extern\r
     ExternList = []\r
     for Extern in ModuleObject.GetExternList():\r
         ArchList = Extern.GetSupArchList()\r
@@ -179,27 +366,23 @@ def GenDefines(ModuleObject):
         HelpStringList = Extern.GetHelpTextList()\r
         FFE = Extern.GetFeatureFlag()\r
         ExternList.append([ArchList, EntryPoint, UnloadImage, Constructor, Destructor, FFE, HelpStringList])\r
-    \r
     #\r
     # Add VALID_ARCHITECTURES information\r
     #\r
     ValidArchStatement = None\r
     if ModuleObject.SupArchList:\r
-        ValidArchStatement = '# ' + '\n'\r
+        ValidArchStatement = '\n' + '# ' + '\n'\r
         ValidArchStatement += '# The following information is for reference only and not required by the build tools.\n'\r
         ValidArchStatement += '# ' + '\n'\r
         ValidArchStatement += '# VALID_ARCHITECTURES = %s' % (' '.join(ModuleObject.SupArchList)) + '\n'\r
-        ValidArchStatement += '# ' + '\n'\r
-        \r
+        ValidArchStatement += '# '\r
     if DT.TAB_ARCH_COMMON not in NewSectionDict:\r
         NewSectionDict[DT.TAB_ARCH_COMMON] = []\r
     NewSectionDict[DT.TAB_ARCH_COMMON] = NewSectionDict[DT.TAB_ARCH_COMMON] + SpecialStatementList\r
     GenMetaFileMisc.AddExternToDefineSec(NewSectionDict, DT.TAB_ARCH_COMMON, ExternList)\r
     if ValidArchStatement is not None:\r
         NewSectionDict[DT.TAB_ARCH_COMMON] = NewSectionDict[DT.TAB_ARCH_COMMON] + [ValidArchStatement]\r
-        \r
     Content += GenSection('Defines', NewSectionDict)\r
-    \r
     return Content\r
 \r
 def GenLibraryClasses(ModuleObject):\r
@@ -223,17 +406,16 @@ def GenLibraryClasses(ModuleObject):
             FFE = LibraryClass.GetFeatureFlag()\r
             Statement += Name\r
             if FFE:\r
-                Statement += '|' + FFE \r
+                Statement += '|' + FFE\r
             ModuleList = LibraryClass.GetSupModuleList()\r
             ArchList = LibraryClass.GetSupArchList()\r
             for Index in xrange(0, len(ArchList)):\r
                 ArchList[Index] = ConvertArchForInstall(ArchList[Index])\r
             ArchList.sort()\r
             SortedArch = ' '.join(ArchList)\r
-            \r
             KeyList = []\r
             if not ModuleList or IsAllModuleList(ModuleList):\r
-                KeyList = [SortedArch]        \r
+                KeyList = [SortedArch]\r
             else:\r
                 ModuleString = DT.TAB_VALUE_SPLIT.join(l for l in ModuleList)\r
                 if not ArchList:\r
@@ -241,7 +423,6 @@ def GenLibraryClasses(ModuleObject):
                     KeyList = [SortedArch + '.' + ModuleString]\r
                 else:\r
                     KeyList = [Arch + '.' + ModuleString for Arch in ArchList]\r
-                                \r
             for Key in KeyList:\r
                 if Key in NewSectionDict:\r
                     NewSectionDict[Key] = NewSectionDict[Key] + [Statement]\r
@@ -254,9 +435,10 @@ def GenLibraryClasses(ModuleObject):
             if not BinaryFile.AsBuiltList:\r
                 continue\r
             for LibraryItem in BinaryFile.AsBuiltList[0].LibraryInstancesList:\r
-                Statement = '# Guid: ' +  LibraryItem.Guid + ' Version: ' + LibraryItem.Version\r
+                Statement = '# Guid: ' + LibraryItem.Guid + ' Version: ' + LibraryItem.Version\r
+\r
                 if len(BinaryFile.SupArchList) == 0:\r
-                    if LibraryClassDict.has_key('COMMON'):\r
+                    if LibraryClassDict.has_key('COMMON') and Statement not in LibraryClassDict['COMMON']:\r
                         LibraryClassDict['COMMON'].append(Statement)\r
                     else:\r
                         LibraryClassDict['COMMON'] = ['## @LIB_INSTANCES']\r
@@ -264,13 +446,15 @@ def GenLibraryClasses(ModuleObject):
                 else:\r
                     for Arch in BinaryFile.SupArchList:\r
                         if LibraryClassDict.has_key(Arch):\r
-                            LibraryClassDict[Arch].append(Statement)\r
+                            if Statement not in LibraryClassDict[Arch]:\r
+                                LibraryClassDict[Arch].append(Statement)\r
+                            else:\r
+                                continue\r
                         else:\r
                             LibraryClassDict[Arch] = ['## @LIB_INSTANCES']\r
                             LibraryClassDict[Arch].append(Statement)\r
-                    \r
         Content += GenSection('LibraryClasses', LibraryClassDict)\r
-    \r
+\r
     return Content\r
 \r
 def GenPackages(ModuleObject):\r
@@ -279,7 +463,7 @@ def GenPackages(ModuleObject):
     # generate [Packages] section\r
     #\r
     NewSectionDict = Sdict()\r
-    WorkspaceDir = getenv('WORKSPACE')\r
+    WorkspaceDir = GlobalData.gWORKSPACE\r
     for PackageDependency in ModuleObject.GetPackageDependencyList():\r
         #\r
         # Generate generic comment\r
@@ -288,11 +472,12 @@ def GenPackages(ModuleObject):
         HelpText = PackageDependency.GetHelpText()\r
         if HelpText:\r
             HelpStr = HelpText.GetString()\r
-            CommentStr = GenGenericCommentF(HelpStr)   \r
+            CommentStr = GenGenericCommentF(HelpStr)\r
         Statement = CommentStr\r
         Guid = PackageDependency.GetGuid()\r
         Version = PackageDependency.GetVersion()\r
         FFE = PackageDependency.GetFeatureFlag()\r
+        Path = ''\r
         #\r
         # find package path/name\r
         # \r
@@ -304,20 +489,18 @@ def GenPackages(ModuleObject):
         #\r
         # get relative path\r
         #\r
-        RelaPath = Path[Path.upper().find(WorkspaceDir.upper()) + len(WorkspaceDir) + 1:]\r
+        RelaPath = GetRelativePath(Path, WorkspaceDir)\r
         Statement += RelaPath.replace('\\', '/')\r
         if FFE:\r
-            Statement += '|' + FFE        \r
+            Statement += '|' + FFE\r
         ArchList = PackageDependency.GetSupArchList()\r
         ArchList.sort()\r
         SortedArch = ' '.join(ArchList)\r
         if SortedArch in NewSectionDict:\r
             NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement]\r
         else:\r
-            NewSectionDict[SortedArch] = [Statement]            \r
-\r
+            NewSectionDict[SortedArch] = [Statement]\r
     Content += GenSection('Packages', NewSectionDict)\r
-    \r
     return Content\r
 \r
 def GenSources(ModuleObject):\r
@@ -326,23 +509,20 @@ def GenSources(ModuleObject):
     #\r
     Content = ''\r
     NewSectionDict = {}\r
-    \r
-    for Source in ModuleObject.GetSourceFileList():    \r
+    for Source in ModuleObject.GetSourceFileList():\r
         SourceFile = Source.GetSourceFile()\r
         Family = Source.GetFamily()\r
         FeatureFlag = Source.GetFeatureFlag()\r
         SupArchList = Source.GetSupArchList()\r
         SupArchList.sort()\r
-        SortedArch = ' '.join(SupArchList)    \r
-\r
+        SortedArch = ' '.join(SupArchList)\r
         Statement = GenSourceStatement(ConvertPath(SourceFile), Family, FeatureFlag)\r
         if SortedArch in NewSectionDict:\r
             NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement]\r
         else:\r
             NewSectionDict[SortedArch] = [Statement]\r
-\r
     Content += GenSection('Sources', NewSectionDict)\r
-    \r
+\r
     return Content\r
 \r
 def GenDepex(ModuleObject):\r
@@ -359,7 +539,6 @@ def GenDepex(ModuleObject):
         SupModList = Depex.GetModuleType()\r
         Expression = Depex.GetDepex()\r
         Statement = CommentStr + Expression\r
-        \r
         SupArchList.sort()\r
         KeyList = []\r
         if not SupArchList:\r
@@ -370,17 +549,14 @@ def GenDepex(ModuleObject):
             for ModuleType in SupModList:\r
                 for Arch in SupArchList:\r
                     KeyList.append(ConvertArchForInstall(Arch) + '.' + ModuleType)\r
-                            \r
         for Key in KeyList:\r
             if Key in NewSectionDict:\r
                 NewSectionDict[Key] = NewSectionDict[Key] + [Statement]\r
             else:\r
                 NewSectionDict[Key] = [Statement]\r
-        \r
     Content += GenSection('Depex', NewSectionDict, False)\r
     \r
     return Content\r
-\r
 ## GenUserExtensions\r
 #\r
 # GenUserExtensions\r
@@ -388,17 +564,19 @@ def GenDepex(ModuleObject):
 def GenUserExtensions(ModuleObject):\r
     NewSectionDict = {}\r
     for UserExtension in ModuleObject.GetUserExtensionList():\r
+        if UserExtension.GetUserID() == DT.TAB_BINARY_HEADER_USERID and \\r
+            UserExtension.GetIdentifier() == DT.TAB_BINARY_HEADER_IDENTIFIER:\r
+            continue\r
         if UserExtension.GetIdentifier() == 'Depex':\r
             continue\r
         Statement = UserExtension.GetStatement()\r
-        if not Statement:\r
-            continue\r
-        \r
+# Comment the code to support user extension without any statement just the section header in []\r
+#         if not Statement:\r
+#             continue\r
         ArchList = UserExtension.GetSupArchList()\r
         for Index in xrange(0, len(ArchList)):\r
             ArchList[Index] = ConvertArchForInstall(ArchList[Index])\r
         ArchList.sort()\r
-                \r
         KeyList = []\r
         CommonPreFix = ''\r
         if UserExtension.GetUserID():\r
@@ -410,17 +588,16 @@ def GenUserExtensions(ModuleObject):
             if ArchList:\r
                 KeyList = [CommonPreFix + '.' + Arch for Arch in ArchList]\r
             else:\r
-                KeyList = [CommonPreFix]    \r
-        \r
+                KeyList = [CommonPreFix]\r
         for Key in KeyList:\r
             if Key in NewSectionDict:\r
                 NewSectionDict[Key] = NewSectionDict[Key] + [Statement]\r
             else:\r
                 NewSectionDict[Key] = [Statement]\r
     Content = GenSection('UserExtensions', NewSectionDict, False)\r
-    \r
+\r
     return Content\r
-    \r
+\r
 # GenSourceStatement\r
 #\r
 #  @param SourceFile: string of source file path/name\r
@@ -432,23 +609,21 @@ def GenUserExtensions(ModuleObject):
 #\r
 #  @retval Statement: The generated statement for source\r
 #\r
-def GenSourceStatement(SourceFile, Family, FeatureFlag, TagName=None, \r
+def GenSourceStatement(SourceFile, Family, FeatureFlag, TagName=None,\r
                        ToolCode=None, HelpStr=None):\r
     Statement = ''\r
     if HelpStr:\r
-        Statement += GenGenericCommentF(HelpStr)   \r
+        Statement += GenGenericCommentF(HelpStr)\r
     #\r
     # format of SourceFile|Family|TagName|ToolCode|FeatureFlag\r
     #\r
     Statement += SourceFile\r
-    \r
     if TagName == None:\r
         TagName = ''\r
     if ToolCode == None:\r
         ToolCode = ''\r
     if HelpStr == None:\r
         HelpStr = ''\r
-    \r
     if FeatureFlag:\r
         Statement += '|' + Family + '|' + TagName + '|' + ToolCode + '|' + FeatureFlag\r
     elif ToolCode:\r
@@ -457,7 +632,6 @@ def GenSourceStatement(SourceFile, Family, FeatureFlag, TagName=None,
         Statement += '|' + Family + '|' + TagName\r
     elif Family:\r
         Statement += '|' + Family\r
-    \r
     return Statement\r
 \r
 # GenBinaryStatement\r
@@ -466,7 +640,7 @@ def GenSourceStatement(SourceFile, Family, FeatureFlag, TagName=None,
 #  @param Value:     (Target, Family, TagName, Comment)\r
 #\r
 #\r
-def GenBinaryStatement(Key, Value):\r
+def GenBinaryStatement(Key, Value, SubTypeGuidValue=None):\r
     (FileName, FileType, FFE, SortedArch) = Key\r
     if SortedArch:\r
         pass\r
@@ -477,14 +651,14 @@ def GenBinaryStatement(Key, Value):
         Family = ''\r
         TagName = ''\r
         Comment = ''\r
-    \r
     if Comment:\r
         Statement = GenGenericCommentF(Comment)\r
     else:\r
         Statement = ''\r
-    \r
-    Statement += FileType + '|' + FileName\r
-\r
+    if FileType == 'SUBTYPE_GUID' and SubTypeGuidValue:\r
+        Statement += FileType + '|' + SubTypeGuidValue + '|' + FileName\r
+    else:\r
+        Statement += FileType + '|' + FileName\r
     if FileType in DT.BINARY_FILE_TYPE_UI_LIST + DT.BINARY_FILE_TYPE_VER_LIST:\r
         if FFE:\r
             Statement += '|' + Target + '|' + FFE\r
@@ -499,9 +673,7 @@ def GenBinaryStatement(Key, Value):
             Statement += '|' + Target + '|' + Family\r
         elif Target:\r
             Statement += '|' + Target\r
-\r
     return Statement\r
-\r
 ## GenGuidSections\r
 # \r
 #  @param GuidObjList: List of GuidObject\r
@@ -511,26 +683,21 @@ def GenGuidSections(GuidObjList):
     #\r
     # generate [Guids] section\r
     #\r
-    Content = '' \r
+    Content = ''\r
     GuidDict = Sdict()\r
-\r
     for Guid in GuidObjList:\r
         HelpTextList = Guid.GetHelpTextList()\r
         HelpStr = _GetHelpStr(HelpTextList)\r
-\r
         CName = Guid.GetCName()\r
         FFE = Guid.GetFeatureFlag()\r
         Statement = CName\r
         if FFE:\r
             Statement += '|' + FFE\r
-        \r
         Usage = Guid.GetUsage()\r
         GuidType = Guid.GetGuidTypeList()[0]\r
         VariableName = Guid.GetVariableName()\r
-        \r
         #\r
-        # we need to differentiate the generic comment and usage comment\r
-        # as multiple generic comment need to be put at first\r
+        # Differentiate the generic comment and usage comment as multiple generic comment need to be put at first\r
         #\r
         if Usage == DT.ITEM_UNDEFINED and GuidType == DT.ITEM_UNDEFINED:\r
             # generate list of generic comment\r
@@ -543,17 +710,15 @@ def GenGuidSections(GuidObjList):
                 Comment = ' # ' + Comment\r
             else:\r
                 Comment = ''\r
-            \r
             if Usage != DT.ITEM_UNDEFINED and GuidType == DT.ITEM_UNDEFINED:\r
                 Comment = '## ' + Usage + Comment\r
             elif GuidType == 'Variable':\r
                 Comment = '## ' + Usage + ' ## ' + GuidType + ':' + VariableName + Comment\r
             else:\r
                 Comment = '## ' + Usage + ' ## ' + GuidType + Comment\r
-            \r
+\r
             if Comment:\r
                 Comment += '\n'\r
-        \r
         #\r
         # merge duplicate items\r
         #\r
@@ -562,18 +727,15 @@ def GenGuidSections(GuidObjList):
         SortedArch = ' '.join(ArchList)\r
         if (Statement, SortedArch) in GuidDict:\r
             PreviousComment = GuidDict[Statement, SortedArch]\r
-            Comment = PreviousComment +  Comment     \r
+            Comment = PreviousComment + Comment\r
         GuidDict[Statement, SortedArch] = Comment\r
-\r
-    \r
-    NewSectionDict = GenMetaFileMisc.TransferDict(GuidDict) \r
-\r
+    NewSectionDict = GenMetaFileMisc.TransferDict(GuidDict, 'INF_GUID')\r
     #\r
     # generate the section contents\r
     #\r
     if NewSectionDict:\r
         Content = GenSection('Guids', NewSectionDict)\r
-    \r
+\r
     return Content\r
 \r
 ## GenProtocolPPiSections\r
@@ -587,19 +749,15 @@ def GenProtocolPPiSections(ObjList, IsProtocol):
     for Object in ObjList:\r
         HelpTextList = Object.GetHelpTextList()\r
         HelpStr = _GetHelpStr(HelpTextList)\r
-\r
         CName = Object.GetCName()\r
         FFE = Object.GetFeatureFlag()\r
         Statement = CName\r
         if FFE:\r
             Statement += '|' + FFE\r
-        \r
         Usage = Object.GetUsage()\r
         Notify = Object.GetNotify()\r
-        \r
         #\r
-        # we need to differentiate the generic comment and usage comment\r
-        # as consecutive generic comment need to be put together\r
+        # Differentiate the generic comment and usage comment as consecutive generic comment need to be put together\r
         #\r
         if Usage == DT.ITEM_UNDEFINED and Notify == '':\r
             # generate list of generic comment\r
@@ -612,7 +770,6 @@ def GenProtocolPPiSections(ObjList, IsProtocol):
                 Comment = ' # ' + Comment\r
             else:\r
                 Comment = ''\r
-            \r
             if Usage == DT.ITEM_UNDEFINED and not Comment and Notify == '':\r
                 Comment = ''\r
             else:\r
@@ -620,10 +777,8 @@ def GenProtocolPPiSections(ObjList, IsProtocol):
                     Comment = '## ' + Usage + ' ## ' + 'NOTIFY' + Comment\r
                 else:\r
                     Comment = '## ' + Usage + Comment\r
-           \r
             if Comment:\r
                 Comment += '\n'\r
-        \r
         #\r
         # merge duplicate items\r
         #\r
@@ -634,9 +789,7 @@ def GenProtocolPPiSections(ObjList, IsProtocol):
             PreviousComment = Dict[Statement, SortedArch]\r
             Comment = PreviousComment + Comment\r
         Dict[Statement, SortedArch] = Comment\r
-    \r
-    NewSectionDict = GenMetaFileMisc.TransferDict(Dict)         \r
-\r
+    NewSectionDict = GenMetaFileMisc.TransferDict(Dict, 'INF_PPI_PROTOCOL')\r
     #\r
     # generate the section contents\r
     #\r
@@ -645,7 +798,7 @@ def GenProtocolPPiSections(ObjList, IsProtocol):
             Content = GenSection('Protocols', NewSectionDict)\r
         else:\r
             Content = GenSection('Ppis', NewSectionDict)\r
-    \r
+\r
     return Content\r
 \r
 ## GenPcdSections\r
@@ -662,7 +815,6 @@ def GenPcdSections(ModuleObject):
         for Pcd in ModuleObject.GetPcdList():\r
             HelpTextList = Pcd.GetHelpTextList()\r
             HelpStr = _GetHelpStr(HelpTextList)\r
-    \r
             Statement = ''\r
             CName = Pcd.GetCName()\r
             TokenSpaceGuidCName = Pcd.GetTokenSpaceGuidCName()\r
@@ -673,7 +825,6 @@ def GenPcdSections(ModuleObject):
             else:\r
                 Dict = Sdict()\r
                 ItemTypeDict[ItemType] = Dict\r
-                \r
             FFE = Pcd.GetFeatureFlag()\r
             Statement += TokenSpaceGuidCName + '.' + CName\r
             if DefaultValue:\r
@@ -682,18 +833,14 @@ def GenPcdSections(ModuleObject):
                     Statement += '|' + FFE\r
             elif FFE:\r
                 Statement += '||' + FFE\r
-    \r
             #\r
             # Generate comment\r
             #\r
             Usage = Pcd.GetValidUsage()\r
-            \r
-            #\r
             # if FeatureFlag Pcd, then assume all Usage is CONSUMES\r
-            #\r
             if ItemType == DT.TAB_INF_FEATURE_PCD:\r
                 Usage = DT.USAGE_ITEM_CONSUMES\r
-            if Usage == DT.ITEM_UNDEFINED or (ItemType == DT.TAB_INF_FEATURE_PCD):\r
+            if Usage == DT.ITEM_UNDEFINED:\r
                 # generate list of generic comment\r
                 Comment = GenGenericCommentF(HelpStr)\r
             else:\r
@@ -704,12 +851,9 @@ def GenPcdSections(ModuleObject):
                     Comment = ' # ' + Comment\r
                 else:\r
                     Comment = ''\r
-    \r
                 Comment = '## ' + Usage + Comment\r
-               \r
                 if Comment:\r
                     Comment += '\n'\r
-        \r
             #\r
             # Merge duplicate entries\r
             #\r
@@ -719,15 +863,11 @@ def GenPcdSections(ModuleObject):
             if (Statement, SortedArch) in Dict:\r
                 PreviousComment = Dict[Statement, SortedArch]\r
                 Comment = PreviousComment + Comment\r
-            Dict[Statement, SortedArch] = Comment             \r
-                 \r
+            Dict[Statement, SortedArch] = Comment\r
         for ItemType in ItemTypeDict:\r
-            #\r
             # First we need to transfer the Dict to use SortedArch as key\r
-            #\r
             Dict = ItemTypeDict[ItemType]\r
-            NewSectionDict = GenMetaFileMisc.TransferDict(Dict)   \r
-            \r
+            NewSectionDict = GenMetaFileMisc.TransferDict(Dict, 'INF_PCD')\r
             if NewSectionDict:\r
                 Content += GenSection(ItemType, NewSectionDict)\r
     #\r
@@ -736,7 +876,7 @@ def GenPcdSections(ModuleObject):
     else:\r
         Content += GenAsBuiltPacthPcdSections(ModuleObject)\r
         Content += GenAsBuiltPcdExSections(ModuleObject)\r
-    \r
+\r
     return Content\r
 \r
 ## GenPcdSections\r
@@ -746,8 +886,8 @@ def GenAsBuiltPacthPcdSections(ModuleObject):
     PatchPcdDict = {}\r
     for BinaryFile in ModuleObject.GetBinaryFileList():\r
         if not BinaryFile.AsBuiltList:\r
-            continue            \r
-        for PatchPcd in BinaryFile.AsBuiltList[0].PatchPcdList:      \r
+            continue\r
+        for PatchPcd in BinaryFile.AsBuiltList[0].PatchPcdList:\r
             TokenSpaceName = ''\r
             PcdCName = PatchPcd.CName\r
             PcdValue = PatchPcd.DefaultValue\r
@@ -758,31 +898,38 @@ def GenAsBuiltPacthPcdSections(ModuleObject):
             HelpString = ''\r
             for HelpStringItem in HelpTextList:\r
                 for HelpLine in GetSplitValueList(HelpStringItem.String, '\n'):\r
-                    HelpString += '# ' + HelpLine + '\n'\r
-                    \r
-            TokenSpaceName, PcdCName = GenMetaFileMisc.ObtainPcdName(ModuleObject.PackageDependencyList, \r
-                                                                     TokenSpaceGuidValue, \r
+                    HelpString += '## ' + HelpLine + '\n'\r
+            TokenSpaceName, PcdCName = GenMetaFileMisc.ObtainPcdName(ModuleObject.PackageDependencyList,\r
+                                                                     TokenSpaceGuidValue,\r
                                                                      Token)\r
-            if TokenSpaceName == '' or PcdCName == '':    \r
-                Logger.Error("Upt", \r
+            if TokenSpaceName == '' or PcdCName == '':\r
+                Logger.Error("Upt",\r
                              ToolError.RESOURCE_NOT_AVAILABLE,\r
-                             ST.ERR_INSTALL_FILE_DEC_FILE_ERROR%(TokenSpaceGuidValue, Token), \r
-                             File=ModuleObject.GetFullPath())                 \r
-            Statement = HelpString[:-3] + TokenSpaceName + '.' + PcdCName + ' | ' + PcdValue + ' | ' + PcdOffset\r
-            \r
-            if len(BinaryFile.SupArchList) == 0:\r
-                if PatchPcdDict.has_key('COMMON'):\r
-                    PatchPcdDict['COMMON'].append(Statement)\r
+                             ST.ERR_INSTALL_FILE_DEC_FILE_ERROR % (TokenSpaceGuidValue, Token),\r
+                             File=ModuleObject.GetFullPath())\r
+            Statement = HelpString + TokenSpaceName + '.' + PcdCName + ' | ' + PcdValue + ' | ' + \\r
+                         PcdOffset + DT.TAB_SPACE_SPLIT\r
+            #\r
+            # Use binary file's Arch to be Pcd's Arch \r
+            #\r
+            ArchList = []\r
+            FileNameObjList = BinaryFile.GetFileNameList()\r
+            if FileNameObjList:\r
+                ArchList = FileNameObjList[0].GetSupArchList()\r
+            if len(ArchList) == 0:\r
+                if PatchPcdDict.has_key(DT.TAB_ARCH_COMMON):\r
+                    if Statement not in PatchPcdDict[DT.TAB_ARCH_COMMON]:\r
+                        PatchPcdDict[DT.TAB_ARCH_COMMON].append(Statement)\r
                 else:\r
-                    PatchPcdDict['COMMON'] = [Statement]\r
+                    PatchPcdDict[DT.TAB_ARCH_COMMON] = [Statement]\r
             else:\r
-                for Arch in BinaryFile.SupArchList:\r
+                for Arch in ArchList:\r
                     if PatchPcdDict.has_key(Arch):\r
-                        PatchPcdDict[Arch].append(Statement)\r
+                        if Statement not in PatchPcdDict[Arch]:\r
+                            PatchPcdDict[Arch].append(Statement)\r
                     else:\r
                         PatchPcdDict[Arch] = [Statement]\r
-    return GenSection('PatchPcd', PatchPcdDict)\r
-\r
+    return GenSection(DT.TAB_INF_PATCH_PCD, PatchPcdDict)\r
 ## GenPcdSections\r
 #\r
 #\r
@@ -790,46 +937,53 @@ def GenAsBuiltPcdExSections(ModuleObject):
     PcdExDict = {}\r
     for BinaryFile in ModuleObject.GetBinaryFileList():\r
         if not BinaryFile.AsBuiltList:\r
-            continue   \r
+            continue\r
         for PcdExItem in BinaryFile.AsBuiltList[0].PcdExValueList:\r
             TokenSpaceName = ''\r
             PcdCName = PcdExItem.CName\r
-            PcdValue = PcdExItem.DefaultValue\r
             TokenSpaceGuidValue = PcdExItem.TokenSpaceGuidValue\r
             Token = PcdExItem.Token\r
             HelpTextList = PcdExItem.HelpTextList\r
             HelpString = ''\r
             for HelpStringItem in HelpTextList:\r
                 for HelpLine in GetSplitValueList(HelpStringItem.String, '\n'):\r
-                    HelpString += '# ' + HelpLine + '\n'            \r
-            TokenSpaceName, PcdCName = GenMetaFileMisc.ObtainPcdName(ModuleObject.PackageDependencyList, \r
+                    HelpString += '## ' + HelpLine + '\n'\r
+            TokenSpaceName, PcdCName = GenMetaFileMisc.ObtainPcdName(ModuleObject.PackageDependencyList,\r
                                                                      TokenSpaceGuidValue, Token)\r
-            \r
-            if TokenSpaceName == '' or PcdCName == '':    \r
+            if TokenSpaceName == '' or PcdCName == '':\r
                 Logger.Error("Upt",\r
                              ToolError.RESOURCE_NOT_AVAILABLE,\r
-                             ST.ERR_INSTALL_FILE_DEC_FILE_ERROR%(TokenSpaceGuidValue, Token), \r
-                             File=ModuleObject.GetFullPath()) \r
-                                      \r
-            Statement = HelpString[:-3] + TokenSpaceName + '.' + PcdCName + ' | ' + PcdValue\r
-            \r
-            if len(BinaryFile.SupArchList) == 0:\r
+                             ST.ERR_INSTALL_FILE_DEC_FILE_ERROR % (TokenSpaceGuidValue, Token),\r
+                             File=ModuleObject.GetFullPath())\r
+\r
+            Statement = HelpString + TokenSpaceName + DT.TAB_SPLIT + PcdCName + DT.TAB_SPACE_SPLIT\r
+\r
+            #\r
+            # Use binary file's Arch to be Pcd's Arch \r
+            #\r
+            ArchList = []\r
+            FileNameObjList = BinaryFile.GetFileNameList()\r
+            if FileNameObjList:\r
+                ArchList = FileNameObjList[0].GetSupArchList()\r
+\r
+            if len(ArchList) == 0:\r
                 if PcdExDict.has_key('COMMON'):\r
                     PcdExDict['COMMON'].append(Statement)\r
                 else:\r
                     PcdExDict['COMMON'] = [Statement]\r
             else:\r
-                for Arch in BinaryFile.SupArchList:\r
+                for Arch in ArchList:\r
                     if PcdExDict.has_key(Arch):\r
-                        PcdExDict[Arch].append(Statement)\r
+                        if Statement not in PcdExDict[Arch]:\r
+                            PcdExDict[Arch].append(Statement)\r
                     else:\r
                         PcdExDict[Arch] = [Statement]\r
     return GenSection('PcdEx', PcdExDict)\r
-               \r
+\r
 ## GenSpecialSections\r
 #  generate special sections for Event/BootMode/Hob\r
 #\r
-def GenSpecialSections(ObjectList, SectionName):\r
+def GenSpecialSections(ObjectList, SectionName, UserExtensionsContent=''):\r
     #\r
     # generate section\r
     #\r
@@ -843,7 +997,6 @@ def GenSpecialSections(ObjectList, SectionName):
         HelpTextList = Obj.GetHelpTextList()\r
         HelpStr = _GetHelpStr(HelpTextList)\r
         CommentStr = GenGenericCommentF(HelpStr)\r
-        \r
         if SectionName == 'Hob':\r
             Type = Obj.GetHobType()\r
         elif SectionName == 'Event':\r
@@ -852,25 +1005,25 @@ def GenSpecialSections(ObjectList, SectionName):
             Type = Obj.GetSupportedBootModes()\r
         else:\r
             assert(SectionName)\r
-        \r
         Usage = Obj.GetUsage()\r
+\r
+        # If the content already in UserExtensionsContent then ignore\r
+        if '[%s]' % SectionName in UserExtensionsContent and Type in UserExtensionsContent:\r
+            return ''\r
+\r
         Statement = ' ' + Type + ' ## ' + Usage\r
-        \r
         if CommentStr in ['#\n', '#\n#\n']:\r
             CommentStr = '#\n#\n#\n'\r
         #\r
-        # the first head comment line should start with '##\n', \r
-        # if it starts with '#\n', then add one '#'\r
+        # the first head comment line should start with '##\n', if it starts with '#\n', then add one '#'\r
         # else add '##\n' to meet the format defined in INF spec\r
         #\r
         if CommentStr.startswith('#\n'):\r
             CommentStr = '#' + CommentStr\r
         elif CommentStr:\r
             CommentStr = '##\n' + CommentStr\r
-\r
         if CommentStr and not CommentStr.endswith('\n#\n'):\r
-            CommentStr = CommentStr + '#\n' \r
-        \r
+            CommentStr = CommentStr + '#\n'\r
         NewStateMent = CommentStr + Statement\r
         SupArch = Obj.GetSupArchList()\r
         SupArch.sort()\r
@@ -879,20 +1032,17 @@ def GenSpecialSections(ObjectList, SectionName):
             NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [NewStateMent]\r
         else:\r
             NewSectionDict[SortedArch] = [NewStateMent]\r
-    \r
     SectionContent = GenSection(SectionName, NewSectionDict)\r
     SectionContent = SectionContent.strip()\r
     if SectionContent:\r
         Content = '# ' + ('\n' + '# ').join(GetSplitValueList(SectionContent, '\n'))\r
         Content = Content.lstrip()\r
     #\r
-    # add two empty line after the generated section content to differentiate \r
-    # it between other possible sections\r
-    #\r
-    if Content: \r
-        Content += '\n#\n#\n'\r
+    # add a return to differentiate it between other possible sections\r
+    # \r
+    if Content:\r
+        Content += '\n'\r
     return Content\r
-\r
 ## GenBuildOptions\r
 #\r
 #\r
@@ -912,7 +1062,6 @@ def GenBuildOptions(ModuleObject):
                     NewSectionDict[Arch] = NewSectionDict[Arch] + [BuildOptionDict[Arch]]\r
                 else:\r
                     NewSectionDict[Arch] = [BuildOptionDict[Arch]]\r
-    \r
         Content = GenSection('BuildOptions', NewSectionDict)\r
     else:\r
         BuildOptionDict = {}\r
@@ -920,7 +1069,7 @@ def GenBuildOptions(ModuleObject):
             if not BinaryFile.AsBuiltList:\r
                 continue\r
             for BuilOptionItem in BinaryFile.AsBuiltList[0].BinaryBuildFlagList:\r
-                Statement = '#' +  BuilOptionItem.AsBuiltOptionFlags\r
+                Statement = '#' + BuilOptionItem.AsBuiltOptionFlags\r
                 if len(BinaryFile.SupArchList) == 0:\r
                     if BuildOptionDict.has_key('COMMON'):\r
                         if Statement not in BuildOptionDict['COMMON']:\r
@@ -936,11 +1085,9 @@ def GenBuildOptions(ModuleObject):
                         else:\r
                             BuildOptionDict[Arch] = ['## @AsBuilt']\r
                             BuildOptionDict[Arch].append(Statement)\r
-                    \r
         Content = GenSection('BuildOptions', BuildOptionDict)\r
-    \r
-    return Content\r
 \r
+    return Content\r
 ## GenBinaries\r
 #\r
 #\r
@@ -951,7 +1098,6 @@ def GenBinaries(ModuleObject):
         BinariesDict = UserExtension.GetBinariesDict()\r
         if BinariesDict:\r
             break\r
-        \r
     for BinaryFile in ModuleObject.GetBinaryFileList():\r
         FileNameObjList = BinaryFile.GetFileNameList()\r
         for FileNameObj in FileNameObjList:\r
@@ -960,10 +1106,8 @@ def GenBinaries(ModuleObject):
             FFE = FileNameObj.GetFeatureFlag()\r
             ArchList = FileNameObj.GetSupArchList()\r
             ArchList.sort()\r
-            SortedArch = ' '.join(ArchList)      \r
-            \r
+            SortedArch = ' '.join(ArchList)\r
             Key = (FileName, FileType, FFE, SortedArch)\r
-\r
             if Key in BinariesDict:\r
                 ValueList = BinariesDict[Key]\r
                 for ValueItem in ValueList:\r
@@ -973,16 +1117,19 @@ def GenBinaries(ModuleObject):
                     else:\r
                         NewSectionDict[SortedArch] = [Statement]\r
                 #\r
-                # as we already generated statement for this DictKey\r
-                # here set the Valuelist to be empty to avoid generate duplicate entries \r
-                # as the DictKey may have multiple entries\r
+                # as we already generated statement for this DictKey here set the Valuelist to be empty \r
+                # to avoid generate duplicate entries as the DictKey may have multiple entries\r
                 #\r
                 BinariesDict[Key] = []\r
             else:\r
-                Statement = GenBinaryStatement(Key, None)\r
+                if FileType == 'SUBTYPE_GUID' and FileNameObj.GetGuidValue():\r
+                    Statement = GenBinaryStatement(Key, None, FileNameObj.GetGuidValue())\r
+                else:\r
+                    Statement = GenBinaryStatement(Key, None)\r
                 if SortedArch in NewSectionDict:\r
                     NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement]\r
                 else:\r
-                    NewSectionDict[SortedArch] = [Statement]               \r
\r
-    return GenSection('Binaries', NewSectionDict)
\ No newline at end of file
+                    NewSectionDict[SortedArch] = [Statement]\r
+    Content = GenSection('Binaries', NewSectionDict)\r
+\r
+    return Content\r