Home | History | Annotate | Download | only in GenMetaFile
      1 ## @file GenInfFile.py

      2 #

      3 # This file contained the logical of transfer package object to INF files.

      4 #

      5 # Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>

      6 #

      7 # This program and the accompanying materials are licensed and made available 

      8 # under the terms and conditions of the BSD License which accompanies this 

      9 # distribution. The full text of the license may be found at 

     10 # http://opensource.org/licenses/bsd-license.php

     11 #

     12 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

     13 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

     14 #

     15 '''
     16 GenInf
     17 '''
     18 import os
     19 import stat
     20 import codecs
     21 import md5
     22 from Core.FileHook import __FileHookOpen__
     23 from Library.String import GetSplitValueList
     24 from Library.Parsing import GenSection
     25 from Library.Parsing import GetWorkspacePackage
     26 from Library.Parsing import ConvertArchForInstall
     27 from Library.Misc import SaveFileOnChange
     28 from Library.Misc import IsAllModuleList
     29 from Library.Misc import Sdict
     30 from Library.Misc import ConvertPath
     31 from Library.Misc import ConvertSpec
     32 from Library.Misc import GetRelativePath
     33 from Library.Misc import GetLocalValue
     34 from Library.CommentGenerating import GenHeaderCommentSection
     35 from Library.CommentGenerating import GenGenericCommentF
     36 from Library.CommentGenerating import _GetHelpStr
     37 from Library import GlobalData
     38 from Logger import StringTable as ST
     39 from Logger import ToolError
     40 import Logger.Log as Logger
     41 from Library import DataType as DT
     42 from GenMetaFile import GenMetaFileMisc
     43 from Library.UniClassObject import FormatUniEntry
     44 from Library.String import GetUniFileName
     45 
     46 
     47 ## Transfer Module Object to Inf files

     48 #

     49 # Transfer all contents of a standard Module Object to an Inf file 

     50 # @param ModuleObject: A Module Object  

     51 #

     52 def ModuleToInf(ModuleObject, PackageObject=None, DistHeader=None):
     53     if not GlobalData.gWSPKG_LIST:
     54         GlobalData.gWSPKG_LIST = GetWorkspacePackage()
     55     #

     56     # Init global information for the file

     57     #

     58     ContainerFile = ModuleObject.GetFullPath()
     59 
     60     Content = ''
     61     #

     62     # Generate file header, If any Abstract, Description, Copyright or License XML elements are missing, 

     63     # should 1) use the Abstract, Description, Copyright or License from the PackageSurfaceArea.Header elements 

     64     # that the module belongs to, or 2) if this is a stand-alone module that is not included in a PackageSurfaceArea, 

     65     # use the abstract, description, copyright or license from the DistributionPackage.Header elements.

     66     #

     67     ModuleAbstract = GetLocalValue(ModuleObject.GetAbstract())
     68     if not ModuleAbstract and PackageObject:
     69         ModuleAbstract = GetLocalValue(PackageObject.GetAbstract())
     70     if not ModuleAbstract and DistHeader:
     71         ModuleAbstract = GetLocalValue(DistHeader.GetAbstract())
     72     ModuleDescription = GetLocalValue(ModuleObject.GetDescription())
     73     if not ModuleDescription and PackageObject:
     74         ModuleDescription = GetLocalValue(PackageObject.GetDescription())
     75     if not ModuleDescription and DistHeader:
     76         ModuleDescription = GetLocalValue(DistHeader.GetDescription())
     77     ModuleCopyright = ''
     78     for (Lang, Copyright) in ModuleObject.GetCopyright():
     79         if Lang:
     80             pass
     81         ModuleCopyright = Copyright
     82     if not ModuleCopyright and PackageObject:
     83         for (Lang, Copyright) in PackageObject.GetCopyright():
     84             if Lang:
     85                 pass
     86             ModuleCopyright = Copyright
     87     if not ModuleCopyright and DistHeader:
     88         for (Lang, Copyright) in DistHeader.GetCopyright():
     89             if Lang:
     90                 pass
     91             ModuleCopyright = Copyright
     92     ModuleLicense = ''
     93     for (Lang, License) in ModuleObject.GetLicense():
     94         if Lang:
     95             pass
     96         ModuleLicense = License
     97     if not ModuleLicense and PackageObject:
     98         for (Lang, License) in PackageObject.GetLicense():
     99             if Lang:
    100                 pass
    101             ModuleLicense = License
    102     if not ModuleLicense and DistHeader:
    103         for (Lang, License) in DistHeader.GetLicense():
    104             if Lang:
    105                 pass
    106             ModuleLicense = License
    107 
    108     #

    109     # Generate header comment section of INF file

    110     #        

    111     Content += GenHeaderCommentSection(ModuleAbstract,
    112                                        ModuleDescription,
    113                                        ModuleCopyright,
    114                                        ModuleLicense).replace('\r\n', '\n')
    115 
    116     #

    117     # Generate Binary Header 

    118     # 

    119     for UserExtension in ModuleObject.GetUserExtensionList():
    120         if UserExtension.GetUserID() == DT.TAB_BINARY_HEADER_USERID \
    121         and UserExtension.GetIdentifier() == DT.TAB_BINARY_HEADER_IDENTIFIER:
    122             ModuleBinaryAbstract = GetLocalValue(UserExtension.GetBinaryAbstract())
    123             ModuleBinaryDescription = GetLocalValue(UserExtension.GetBinaryDescription())
    124             ModuleBinaryCopyright = ''
    125             ModuleBinaryLicense = ''
    126             for (Lang, Copyright) in UserExtension.GetBinaryCopyright():
    127                 ModuleBinaryCopyright = Copyright
    128             for (Lang, License) in UserExtension.GetBinaryLicense():
    129                 ModuleBinaryLicense = License
    130             if ModuleBinaryAbstract and ModuleBinaryDescription and \
    131             ModuleBinaryCopyright and ModuleBinaryLicense:
    132                 Content += GenHeaderCommentSection(ModuleBinaryAbstract,
    133                                            ModuleBinaryDescription,
    134                                            ModuleBinaryCopyright,
    135                                            ModuleBinaryLicense,
    136                                            True)
    137 
    138     #

    139     # Generate MODULE_UNI_FILE for module

    140     #

    141     FileHeader = GenHeaderCommentSection(ModuleAbstract, ModuleDescription, ModuleCopyright, ModuleLicense, False, \
    142                                          DT.TAB_COMMENT_EDK1_SPLIT)
    143     GenModuleUNIEncodeFile(ModuleObject, FileHeader)
    144 
    145     #

    146     # Judge whether the INF file is an AsBuild INF.

    147     #

    148     if ModuleObject.BinaryModule:
    149         GlobalData.gIS_BINARY_INF = True
    150     else:
    151         GlobalData.gIS_BINARY_INF = False
    152     #

    153     # for each section, maintain a dict, sorted arch will be its key, 

    154     # statement list will be its data

    155     # { 'Arch1 Arch2 Arch3': [statement1, statement2],

    156     #   'Arch1' : [statement1, statement3] 

    157     #  }

    158     #

    159     # Gen section contents

    160     #

    161     Content += GenDefines(ModuleObject)
    162     Content += GenBuildOptions(ModuleObject)
    163     Content += GenLibraryClasses(ModuleObject)
    164     Content += GenPackages(ModuleObject)
    165     Content += GenPcdSections(ModuleObject)
    166     Content += GenSources(ModuleObject)
    167     Content += GenProtocolPPiSections(ModuleObject.GetProtocolList(), True)
    168     Content += GenProtocolPPiSections(ModuleObject.GetPpiList(), False)
    169     Content += GenGuidSections(ModuleObject.GetGuidList())
    170     Content += GenBinaries(ModuleObject)
    171     Content += GenDepex(ModuleObject)
    172     Content += GenUserExtensions(ModuleObject)
    173     if ModuleObject.GetEventList() or ModuleObject.GetBootModeList() or ModuleObject.GetHobList():
    174         Content += '\n'
    175     #

    176     # generate [Event], [BootMode], [Hob] section

    177     #

    178     Content += GenSpecialSections(ModuleObject.GetEventList(), 'Event')
    179     Content += GenSpecialSections(ModuleObject.GetBootModeList(), 'BootMode')
    180     Content += GenSpecialSections(ModuleObject.GetHobList(), 'Hob')
    181     SaveFileOnChange(ContainerFile, Content, False)
    182     if DistHeader.ReadOnly:
    183         os.chmod(ContainerFile, stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH)
    184     else:
    185         os.chmod(ContainerFile, stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH|stat.S_IWUSR|stat.S_IWGRP|stat.S_IWOTH)
    186     return ContainerFile
    187 
    188 ## GenModuleUNIEncodeFile

    189 # GenModuleUNIEncodeFile, default is a UCS-2LE encode file

    190 #

    191 def GenModuleUNIEncodeFile(ModuleObject, UniFileHeader='', Encoding=DT.TAB_ENCODING_UTF16LE):
    192     GenUNIFlag = False
    193     OnlyLANGUAGE_EN_X = True
    194     BinaryAbstract = []
    195     BinaryDescription = []
    196     #

    197     # If more than one language code is used for any element that would be present in the MODULE_UNI_FILE, 

    198     # then the MODULE_UNI_FILE must be created.

    199     #

    200     for (Key, Value) in ModuleObject.GetAbstract() + ModuleObject.GetDescription():
    201         if Key == DT.TAB_LANGUAGE_EN_X:
    202             GenUNIFlag = True
    203         else:
    204             OnlyLANGUAGE_EN_X = False
    205 
    206     for UserExtension in ModuleObject.GetUserExtensionList():
    207         if UserExtension.GetUserID() == DT.TAB_BINARY_HEADER_USERID \
    208         and UserExtension.GetIdentifier() == DT.TAB_BINARY_HEADER_IDENTIFIER:
    209             for (Key, Value) in UserExtension.GetBinaryAbstract():
    210                 if Key == DT.TAB_LANGUAGE_EN_X:
    211                     GenUNIFlag = True
    212                 else:
    213                     OnlyLANGUAGE_EN_X = False
    214                 BinaryAbstract.append((Key, Value))
    215             for (Key, Value) in UserExtension.GetBinaryDescription():
    216                 if Key == DT.TAB_LANGUAGE_EN_X:
    217                     GenUNIFlag = True
    218                 else:
    219                     OnlyLANGUAGE_EN_X = False
    220                 BinaryDescription.append((Key, Value))
    221 
    222 
    223     if not GenUNIFlag:
    224         return
    225     elif OnlyLANGUAGE_EN_X:
    226         return
    227     else:
    228         ModuleObject.UNIFlag = True
    229     ContainerFile = GetUniFileName(os.path.dirname(ModuleObject.GetFullPath()), ModuleObject.GetBaseName())
    230 
    231     if not os.path.exists(os.path.dirname(ModuleObject.GetFullPath())):
    232         os.makedirs(os.path.dirname(ModuleObject.GetFullPath()))
    233 
    234     Content = UniFileHeader + '\r\n'
    235     Content += '\r\n'
    236 
    237     Content += FormatUniEntry('#string ' + DT.TAB_INF_ABSTRACT, ModuleObject.GetAbstract(), ContainerFile) + '\r\n'
    238 
    239     Content += FormatUniEntry('#string ' + DT.TAB_INF_DESCRIPTION, ModuleObject.GetDescription(), ContainerFile) \
    240             + '\r\n'
    241 
    242     BinaryAbstractString = FormatUniEntry('#string ' + DT.TAB_INF_BINARY_ABSTRACT, BinaryAbstract, ContainerFile)
    243     if BinaryAbstractString:
    244         Content += BinaryAbstractString + '\r\n'
    245 
    246     BinaryDescriptionString = FormatUniEntry('#string ' + DT.TAB_INF_BINARY_DESCRIPTION, BinaryDescription, \
    247                                              ContainerFile)
    248     if BinaryDescriptionString:
    249         Content += BinaryDescriptionString + '\r\n'
    250 
    251     if not os.path.exists(ContainerFile):
    252         File = codecs.open(ContainerFile, 'wb', Encoding)
    253         File.write(u'\uFEFF' + Content)
    254         File.stream.close()
    255     Md5Sigature = md5.new(__FileHookOpen__(str(ContainerFile), 'rb').read())
    256     Md5Sum = Md5Sigature.hexdigest()
    257     if (ContainerFile, Md5Sum) not in ModuleObject.FileList:
    258         ModuleObject.FileList.append((ContainerFile, Md5Sum))
    259 
    260     return ContainerFile
    261 def GenDefines(ModuleObject):
    262     #

    263     # generate [Defines] section

    264     #

    265     LeftOffset = 31
    266     Content = ''
    267     NewSectionDict = {}
    268 
    269     for UserExtension in ModuleObject.GetUserExtensionList():
    270         DefinesDict = UserExtension.GetDefinesDict()
    271         if not DefinesDict:
    272             continue
    273         for Statement in DefinesDict:
    274             if Statement.split(DT.TAB_EQUAL_SPLIT) > 1:
    275                 Statement = (u'%s ' % Statement.split(DT.TAB_EQUAL_SPLIT, 1)[0]).ljust(LeftOffset) \
    276                              + u'= %s' % Statement.split(DT.TAB_EQUAL_SPLIT, 1)[1].lstrip()
    277             SortedArch = DT.TAB_ARCH_COMMON
    278             if Statement.strip().startswith(DT.TAB_INF_DEFINES_CUSTOM_MAKEFILE):
    279                 pos = Statement.find(DT.TAB_VALUE_SPLIT)
    280                 if pos == -1:
    281                     pos = Statement.find(DT.TAB_EQUAL_SPLIT)
    282                 Makefile = ConvertPath(Statement[pos + 1:].strip())
    283                 Statement = Statement[:pos + 1] + ' ' + Makefile
    284             if SortedArch in NewSectionDict:
    285                 NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement]
    286             else:
    287                 NewSectionDict[SortedArch] = [Statement]
    288     SpecialStatementList = []
    289 
    290     # TAB_INF_DEFINES_INF_VERSION

    291     Statement = (u'%s ' % DT.TAB_INF_DEFINES_INF_VERSION).ljust(LeftOffset) + u'= %s' % '0x00010017'
    292     SpecialStatementList.append(Statement)
    293 
    294     # BaseName

    295     BaseName = ModuleObject.GetBaseName()
    296     if BaseName.startswith('.') or BaseName.startswith('-'):
    297         BaseName = '_' + BaseName
    298     Statement = (u'%s ' % DT.TAB_INF_DEFINES_BASE_NAME).ljust(LeftOffset) + u'= %s' % BaseName
    299     SpecialStatementList.append(Statement)
    300     
    301     # TAB_INF_DEFINES_FILE_GUID

    302     Statement = (u'%s ' % DT.TAB_INF_DEFINES_FILE_GUID).ljust(LeftOffset) + u'= %s' % ModuleObject.GetGuid()
    303     SpecialStatementList.append(Statement)
    304     
    305     # TAB_INF_DEFINES_VERSION_STRING

    306     Statement = (u'%s ' % DT.TAB_INF_DEFINES_VERSION_STRING).ljust(LeftOffset) + u'= %s' % ModuleObject.GetVersion()
    307     SpecialStatementList.append(Statement)
    308 
    309     # TAB_INF_DEFINES_VERSION_STRING

    310     if ModuleObject.UNIFlag:
    311         Statement = (u'%s ' % DT.TAB_INF_DEFINES_MODULE_UNI_FILE).ljust(LeftOffset) + \
    312                     u'= %s' % ModuleObject.GetBaseName() + '.uni'
    313         SpecialStatementList.append(Statement)
    314 
    315     # TAB_INF_DEFINES_MODULE_TYPE

    316     if ModuleObject.GetModuleType():
    317         Statement = (u'%s ' % DT.TAB_INF_DEFINES_MODULE_TYPE).ljust(LeftOffset) + u'= %s' % ModuleObject.GetModuleType()
    318         SpecialStatementList.append(Statement)
    319 
    320     # TAB_INF_DEFINES_PCD_IS_DRIVER

    321     if ModuleObject.GetPcdIsDriver():
    322         Statement = (u'%s ' % DT.TAB_INF_DEFINES_PCD_IS_DRIVER).ljust(LeftOffset) + \
    323                     u'= %s' % ModuleObject.GetPcdIsDriver()
    324         SpecialStatementList.append(Statement)
    325 
    326     # TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION

    327     if ModuleObject.GetUefiSpecificationVersion():
    328         Statement = (u'%s ' % DT.TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION).ljust(LeftOffset) + \
    329                     u'= %s' % ModuleObject.GetUefiSpecificationVersion()
    330         SpecialStatementList.append(Statement)
    331 
    332     # TAB_INF_DEFINES_PI_SPECIFICATION_VERSION

    333     if ModuleObject.GetPiSpecificationVersion():
    334         Statement = (u'%s ' % DT.TAB_INF_DEFINES_PI_SPECIFICATION_VERSION).ljust(LeftOffset) + \
    335                     u'= %s' % ModuleObject.GetPiSpecificationVersion()
    336         SpecialStatementList.append(Statement)
    337 
    338     # LibraryClass

    339     for LibraryClass in ModuleObject.GetLibraryClassList():
    340         if LibraryClass.GetUsage() == DT.USAGE_ITEM_PRODUCES or \
    341            LibraryClass.GetUsage() == DT.USAGE_ITEM_SOMETIMES_PRODUCES:
    342             Statement = (u'%s ' % DT.TAB_INF_DEFINES_LIBRARY_CLASS).ljust(LeftOffset) + \
    343                         u'= %s' % LibraryClass.GetLibraryClass()
    344             if LibraryClass.GetSupModuleList():
    345                 Statement += '|' + DT.TAB_SPACE_SPLIT.join(l for l in LibraryClass.GetSupModuleList())
    346             SpecialStatementList.append(Statement)
    347 
    348     # Spec Item

    349     for SpecItem in ModuleObject.GetSpecList():
    350         Spec, Version = SpecItem
    351         Spec = ConvertSpec(Spec)
    352         Statement = '%s %s = %s' % (DT.TAB_INF_DEFINES_SPEC, Spec, Version)
    353         SpecialStatementList.append(Statement)
    354 
    355     # Extern

    356     ExternList = []
    357     for Extern in ModuleObject.GetExternList():
    358         ArchList = Extern.GetSupArchList()
    359         EntryPoint = Extern.GetEntryPoint()
    360         UnloadImage = Extern.GetUnloadImage()
    361         Constructor = Extern.GetConstructor()
    362         Destructor = Extern.GetDestructor()
    363         HelpStringList = Extern.GetHelpTextList()
    364         FFE = Extern.GetFeatureFlag()
    365         ExternList.append([ArchList, EntryPoint, UnloadImage, Constructor, Destructor, FFE, HelpStringList])
    366     #

    367     # Add VALID_ARCHITECTURES information

    368     #

    369     ValidArchStatement = None
    370     if ModuleObject.SupArchList:
    371         ValidArchStatement = '\n' + '# ' + '\n'
    372         ValidArchStatement += '# The following information is for reference only and not required by the build tools.\n'
    373         ValidArchStatement += '# ' + '\n'
    374         ValidArchStatement += '# VALID_ARCHITECTURES = %s' % (' '.join(ModuleObject.SupArchList)) + '\n'
    375         ValidArchStatement += '# '
    376     if DT.TAB_ARCH_COMMON not in NewSectionDict:
    377         NewSectionDict[DT.TAB_ARCH_COMMON] = []
    378     NewSectionDict[DT.TAB_ARCH_COMMON] = NewSectionDict[DT.TAB_ARCH_COMMON] + SpecialStatementList
    379     GenMetaFileMisc.AddExternToDefineSec(NewSectionDict, DT.TAB_ARCH_COMMON, ExternList)
    380     if ValidArchStatement is not None:
    381         NewSectionDict[DT.TAB_ARCH_COMMON] = NewSectionDict[DT.TAB_ARCH_COMMON] + [ValidArchStatement]
    382     Content += GenSection('Defines', NewSectionDict)
    383     return Content
    384 
    385 def GenLibraryClasses(ModuleObject):
    386     #

    387     # generate [LibraryClasses] section

    388     #

    389     Content = ''
    390     NewSectionDict = {}
    391     if not GlobalData.gIS_BINARY_INF:
    392         for LibraryClass in ModuleObject.GetLibraryClassList():
    393             if LibraryClass.GetUsage() == DT.USAGE_ITEM_PRODUCES:
    394                 continue
    395             #

    396             # Generate generic comment

    397             #

    398             HelpTextList = LibraryClass.GetHelpTextList()
    399             HelpStr = _GetHelpStr(HelpTextList)
    400             CommentStr = GenGenericCommentF(HelpStr)
    401             Statement = CommentStr
    402             Name = LibraryClass.GetLibraryClass()
    403             FFE = LibraryClass.GetFeatureFlag()
    404             Statement += Name
    405             if FFE:
    406                 Statement += '|' + FFE
    407             ModuleList = LibraryClass.GetSupModuleList()
    408             ArchList = LibraryClass.GetSupArchList()
    409             for Index in xrange(0, len(ArchList)):
    410                 ArchList[Index] = ConvertArchForInstall(ArchList[Index])
    411             ArchList.sort()
    412             SortedArch = ' '.join(ArchList)
    413             KeyList = []
    414             if not ModuleList or IsAllModuleList(ModuleList):
    415                 KeyList = [SortedArch]
    416             else:
    417                 ModuleString = DT.TAB_VALUE_SPLIT.join(l for l in ModuleList)
    418                 if not ArchList:
    419                     SortedArch = DT.TAB_ARCH_COMMON
    420                     KeyList = [SortedArch + '.' + ModuleString]
    421                 else:
    422                     KeyList = [Arch + '.' + ModuleString for Arch in ArchList]
    423             for Key in KeyList:
    424                 if Key in NewSectionDict:
    425                     NewSectionDict[Key] = NewSectionDict[Key] + [Statement]
    426                 else:
    427                     NewSectionDict[Key] = [Statement]
    428         Content += GenSection('LibraryClasses', NewSectionDict)
    429     else:
    430         LibraryClassDict = {}
    431         for BinaryFile in ModuleObject.GetBinaryFileList():
    432             if not BinaryFile.AsBuiltList:
    433                 continue
    434             for LibraryItem in BinaryFile.AsBuiltList[0].LibraryInstancesList:
    435                 Statement = '# Guid: ' + LibraryItem.Guid + ' Version: ' + LibraryItem.Version
    436 
    437                 if len(BinaryFile.SupArchList) == 0:
    438                     if LibraryClassDict.has_key('COMMON') and Statement not in LibraryClassDict['COMMON']:
    439                         LibraryClassDict['COMMON'].append(Statement)
    440                     else:
    441                         LibraryClassDict['COMMON'] = ['## @LIB_INSTANCES']
    442                         LibraryClassDict['COMMON'].append(Statement)
    443                 else:
    444                     for Arch in BinaryFile.SupArchList:
    445                         if LibraryClassDict.has_key(Arch):
    446                             if Statement not in LibraryClassDict[Arch]:
    447                                 LibraryClassDict[Arch].append(Statement)
    448                             else:
    449                                 continue
    450                         else:
    451                             LibraryClassDict[Arch] = ['## @LIB_INSTANCES']
    452                             LibraryClassDict[Arch].append(Statement)
    453         Content += GenSection('LibraryClasses', LibraryClassDict)
    454 
    455     return Content
    456 
    457 def GenPackages(ModuleObject):
    458     Content = ''
    459     #

    460     # generate [Packages] section

    461     #

    462     NewSectionDict = Sdict()
    463     WorkspaceDir = GlobalData.gWORKSPACE
    464     for PackageDependency in ModuleObject.GetPackageDependencyList():
    465         #

    466         # Generate generic comment

    467         #

    468         CommentStr = ''
    469         HelpText = PackageDependency.GetHelpText()
    470         if HelpText:
    471             HelpStr = HelpText.GetString()
    472             CommentStr = GenGenericCommentF(HelpStr)
    473         Statement = CommentStr
    474         Guid = PackageDependency.GetGuid()
    475         Version = PackageDependency.GetVersion()
    476         FFE = PackageDependency.GetFeatureFlag()
    477         Path = ''
    478         #

    479         # find package path/name

    480         # 

    481         for PkgInfo in GlobalData.gWSPKG_LIST:
    482             if Guid == PkgInfo[1]:
    483                 if (not Version) or (Version == PkgInfo[2]):
    484                     Path = PkgInfo[3]
    485                     break
    486         #

    487         # get relative path

    488         #

    489         RelaPath = GetRelativePath(Path, WorkspaceDir)
    490         Statement += RelaPath.replace('\\', '/')
    491         if FFE:
    492             Statement += '|' + FFE
    493         ArchList = PackageDependency.GetSupArchList()
    494         ArchList.sort()
    495         SortedArch = ' '.join(ArchList)
    496         if SortedArch in NewSectionDict:
    497             NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement]
    498         else:
    499             NewSectionDict[SortedArch] = [Statement]
    500     Content += GenSection('Packages', NewSectionDict)
    501     return Content
    502 
    503 def GenSources(ModuleObject):
    504     #
    505     # generate [Sources] section
    506     #
    507     Content = ''
    508     NewSectionDict = {}
    509     for Source in ModuleObject.GetSourceFileList():
    510         SourceFile = Source.GetSourceFile()
    511         Family = Source.GetFamily()
    512         FeatureFlag = Source.GetFeatureFlag()
    513         SupArchList = Source.GetSupArchList()
    514         SupArchList.sort()
    515         SortedArch = ' '.join(SupArchList)
    516         Statement = GenSourceStatement(ConvertPath(SourceFile), Family, FeatureFlag)
    517         if SortedArch in NewSectionDict:
    518             NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement]
    519         else:
    520             NewSectionDict[SortedArch] = [Statement]
    521     Content += GenSection('Sources', NewSectionDict)
    522 
    523     return Content
    524 
    525 def GenDepex(ModuleObject):
    526     #
    527     # generate [Depex] section
    528     #
    529     NewSectionDict = Sdict()
    530     Content = ''
    531     for Depex in ModuleObject.GetPeiDepex() + ModuleObject.GetDxeDepex() + ModuleObject.GetSmmDepex():
    532         HelpTextList = Depex.GetHelpTextList()
    533         HelpStr = _GetHelpStr(HelpTextList)
    534         CommentStr = GenGenericCommentF(HelpStr)
    535         SupArchList = Depex.GetSupArchList()
    536         SupModList = Depex.GetModuleType()
    537         Expression = Depex.GetDepex()
    538         Statement = CommentStr + Expression
    539         SupArchList.sort()
    540         KeyList = []
    541         if not SupArchList:
    542             SupArchList.append(DT.TAB_ARCH_COMMON.lower())
    543         if not SupModList:
    544             KeyList = SupArchList
    545         else:
    546             for ModuleType in SupModList:
    547                 for Arch in SupArchList:
    548                     KeyList.append(ConvertArchForInstall(Arch) + '.' + ModuleType)
    549         for Key in KeyList:
    550             if Key in NewSectionDict:
    551                 NewSectionDict[Key] = NewSectionDict[Key] + [Statement]
    552             else:
    553                 NewSectionDict[Key] = [Statement]
    554     Content += GenSection('Depex', NewSectionDict, False)
    555     
    556     return Content
    557 ## GenUserExtensions
    558 #
    559 # GenUserExtensions
    560 #
    561 def GenUserExtensions(ModuleObject):
    562     NewSectionDict = {}
    563     for UserExtension in ModuleObject.GetUserExtensionList():
    564         if UserExtension.GetUserID() == DT.TAB_BINARY_HEADER_USERID and \
    565             UserExtension.GetIdentifier() == DT.TAB_BINARY_HEADER_IDENTIFIER:
    566             continue
    567         if UserExtension.GetIdentifier() == 'Depex':
    568             continue
    569         Statement = UserExtension.GetStatement()
    570         if not Statement:
    571             continue
    572         ArchList = UserExtension.GetSupArchList()
    573         for Index in xrange(0, len(ArchList)):
    574             ArchList[Index] = ConvertArchForInstall(ArchList[Index])
    575         ArchList.sort()
    576         KeyList = []
    577         CommonPreFix = ''
    578         if UserExtension.GetUserID():
    579             CommonPreFix = UserExtension.GetUserID()
    580             if CommonPreFix.find('.') > -1:
    581                 CommonPreFix = '"' + CommonPreFix + '"'
    582             if UserExtension.GetIdentifier():
    583                 CommonPreFix += '.' + '"' + UserExtension.GetIdentifier() + '"'
    584             if ArchList:
    585                 KeyList = [CommonPreFix + '.' + Arch for Arch in ArchList]
    586             else:
    587                 KeyList = [CommonPreFix]
    588         for Key in KeyList:
    589             if Key in NewSectionDict:
    590                 NewSectionDict[Key] = NewSectionDict[Key] + [Statement]
    591             else:
    592                 NewSectionDict[Key] = [Statement]
    593     Content = GenSection('UserExtensions', NewSectionDict, False)
    594 
    595     return Content
    596 
    597 # GenSourceStatement
    598 #
    599 #  @param SourceFile: string of source file path/name
    600 #  @param Family:     string of source file family field
    601 #  @param FeatureFlag:  string of source file FeatureFlag field
    602 #  @param TagName:  string of source file TagName field
    603 #  @param ToolCode:  string of source file ToolCode field
    604 #  @param HelpStr:  string of source file HelpStr field
    605 #
    606 #  @retval Statement: The generated statement for source
    607 #
    608 def GenSourceStatement(SourceFile, Family, FeatureFlag, TagName=None,
    609                        ToolCode=None, HelpStr=None):
    610     Statement = ''
    611     if HelpStr:
    612         Statement += GenGenericCommentF(HelpStr)
    613     #
    614     # format of SourceFile|Family|TagName|ToolCode|FeatureFlag
    615     #
    616     Statement += SourceFile
    617     if TagName == None:
    618         TagName = ''
    619     if ToolCode == None:
    620         ToolCode = ''
    621     if HelpStr == None:
    622         HelpStr = ''
    623     if FeatureFlag:
    624         Statement += '|' + Family + '|' + TagName + '|' + ToolCode + '|' + FeatureFlag
    625     elif ToolCode:
    626         Statement += '|' + Family + '|' + TagName + '|' + ToolCode
    627     elif TagName:
    628         Statement += '|' + Family + '|' + TagName
    629     elif Family:
    630         Statement += '|' + Family
    631     return Statement
    632 
    633 # GenBinaryStatement
    634 #
    635 #  @param Key:       (FileName, FileType, FFE, SortedArch)
    636 #  @param Value:     (Target, Family, TagName, Comment)
    637 #
    638 #
    639 def GenBinaryStatement(Key, Value, SubTypeGuidValue=None):
    640     (FileName, FileType, FFE, SortedArch) = Key
    641     if SortedArch:
    642         pass
    643     if Value:
    644         (Target, Family, TagName, Comment) = Value
    645     else:
    646         Target = ''
    647         Family = ''
    648         TagName = ''
    649         Comment = ''
    650     if Comment:
    651         Statement = GenGenericCommentF(Comment)
    652     else:
    653         Statement = ''
    654     if FileType == 'SUBTYPE_GUID' and SubTypeGuidValue:
    655         Statement += FileType + '|' + SubTypeGuidValue + '|' + FileName
    656     else:
    657         Statement += FileType + '|' + FileName
    658     if FileType in DT.BINARY_FILE_TYPE_UI_LIST + DT.BINARY_FILE_TYPE_VER_LIST:
    659         if FFE:
    660             Statement += '|' + Target + '|' + FFE
    661         elif Target:
    662             Statement += '|' + Target
    663     else:
    664         if FFE:
    665             Statement += '|' + Target + '|' + Family + '|' + TagName + '|' + FFE
    666         elif TagName:
    667             Statement += '|' + Target + '|' + Family + '|' + TagName
    668         elif Family:
    669             Statement += '|' + Target + '|' + Family
    670         elif Target:
    671             Statement += '|' + Target
    672     return Statement
    673 ## GenGuidSections
    674 # 
    675 #  @param GuidObjList: List of GuidObject
    676 #  @retVal Content: The generated section contents
    677 #
    678 def GenGuidSections(GuidObjList):
    679     #
    680     # generate [Guids] section
    681     #
    682     Content = ''
    683     GuidDict = Sdict()
    684     for Guid in GuidObjList:
    685         HelpTextList = Guid.GetHelpTextList()
    686         HelpStr = _GetHelpStr(HelpTextList)
    687         CName = Guid.GetCName()
    688         FFE = Guid.GetFeatureFlag()
    689         Statement = CName
    690         if FFE:
    691             Statement += '|' + FFE
    692         Usage = Guid.GetUsage()
    693         GuidType = Guid.GetGuidTypeList()[0]
    694         VariableName = Guid.GetVariableName()
    695         #
    696         # Differentiate the generic comment and usage comment as multiple generic comment need to be put at first
    697         #
    698         if Usage == DT.ITEM_UNDEFINED and GuidType == DT.ITEM_UNDEFINED:
    699             # generate list of generic comment
    700             Comment = GenGenericCommentF(HelpStr)
    701         else:
    702             # generate list of other comment
    703             Comment = HelpStr.replace('\n', ' ')
    704             Comment = Comment.strip()
    705             if Comment:
    706                 Comment = ' # ' + Comment

    707             else:
    708                 Comment = ''
    709             if Usage != DT.ITEM_UNDEFINED and GuidType == DT.ITEM_UNDEFINED:
    710                 Comment = '## ' + Usage + Comment
    711             elif GuidType == 'Variable':
    712                 Comment = '## ' + Usage + ' ## ' + GuidType + ':' + VariableName + Comment
    713             else:
    714                 Comment = '## ' + Usage + ' ## ' + GuidType + Comment
    715 
    716             if Comment:
    717                 Comment += '\n'
    718         #

    719         # merge duplicate items

    720         #

    721         ArchList = Guid.GetSupArchList()
    722         ArchList.sort()
    723         SortedArch = ' '.join(ArchList)
    724         if (Statement, SortedArch) in GuidDict:
    725             PreviousComment = GuidDict[Statement, SortedArch]
    726             Comment = PreviousComment + Comment
    727         GuidDict[Statement, SortedArch] = Comment
    728     NewSectionDict = GenMetaFileMisc.TransferDict(GuidDict, 'INF_GUID')
    729     #

    730     # generate the section contents

    731     #

    732     if NewSectionDict:
    733         Content = GenSection('Guids', NewSectionDict)
    734 
    735     return Content
    736 
    737 ## GenProtocolPPiSections

    738 # 

    739 #  @param ObjList: List of ProtocolObject or Ppi Object

    740 #  @retVal Content: The generated section contents

    741 #

    742 def GenProtocolPPiSections(ObjList, IsProtocol):
    743     Content = ''
    744     Dict = Sdict()
    745     for Object in ObjList:
    746         HelpTextList = Object.GetHelpTextList()
    747         HelpStr = _GetHelpStr(HelpTextList)
    748         CName = Object.GetCName()
    749         FFE = Object.GetFeatureFlag()
    750         Statement = CName
    751         if FFE:
    752             Statement += '|' + FFE
    753         Usage = Object.GetUsage()
    754         Notify = Object.GetNotify()
    755         #

    756         # Differentiate the generic comment and usage comment as consecutive generic comment need to be put together

    757         #

    758         if Usage == DT.ITEM_UNDEFINED and Notify == '':
    759             # generate list of generic comment

    760             Comment = GenGenericCommentF(HelpStr)
    761         else:
    762             # generate list of other comment

    763             Comment = HelpStr.replace('\n', ' ')
    764             Comment = Comment.strip()
    765             if Comment:
    766                 Comment = ' # ' + Comment
    767             else:
    768                 Comment = ''
    769             if Usage == DT.ITEM_UNDEFINED and not Comment and Notify == '':
    770                 Comment = ''
    771             else:
    772                 if Notify:
    773                     Comment = '## ' + Usage + ' ## ' + 'NOTIFY' + Comment
    774                 else:
    775                     Comment = '## ' + Usage + Comment
    776             if Comment:
    777                 Comment += '\n'
    778         #

    779         # merge duplicate items

    780         #

    781         ArchList = Object.GetSupArchList()
    782         ArchList.sort()
    783         SortedArch = ' '.join(ArchList)
    784         if (Statement, SortedArch) in Dict:
    785             PreviousComment = Dict[Statement, SortedArch]
    786             Comment = PreviousComment + Comment
    787         Dict[Statement, SortedArch] = Comment
    788     NewSectionDict = GenMetaFileMisc.TransferDict(Dict, 'INF_PPI_PROTOCOL')
    789     #

    790     # generate the section contents

    791     #

    792     if NewSectionDict:
    793         if IsProtocol:
    794             Content = GenSection('Protocols', NewSectionDict)
    795         else:
    796             Content = GenSection('Ppis', NewSectionDict)
    797 
    798     return Content
    799 
    800 ## GenPcdSections

    801 #

    802 #

    803 def GenPcdSections(ModuleObject):
    804     Content = ''
    805     if not GlobalData.gIS_BINARY_INF:
    806         #

    807         # for each Pcd Itemtype, maintain a dict so the same type will be grouped 

    808         # together

    809         #

    810         ItemTypeDict = {}
    811         for Pcd in ModuleObject.GetPcdList():
    812             HelpTextList = Pcd.GetHelpTextList()
    813             HelpStr = _GetHelpStr(HelpTextList)
    814             Statement = ''
    815             CName = Pcd.GetCName()
    816             TokenSpaceGuidCName = Pcd.GetTokenSpaceGuidCName()
    817             DefaultValue = Pcd.GetDefaultValue()
    818             ItemType = Pcd.GetItemType()
    819             if ItemType in ItemTypeDict:
    820                 Dict = ItemTypeDict[ItemType]
    821             else:
    822                 Dict = Sdict()
    823                 ItemTypeDict[ItemType] = Dict
    824             FFE = Pcd.GetFeatureFlag()
    825             Statement += TokenSpaceGuidCName + '.' + CName
    826             if DefaultValue:
    827                 Statement += '|' + DefaultValue
    828                 if FFE:
    829                     Statement += '|' + FFE
    830             elif FFE:
    831                 Statement += '||' + FFE
    832             #

    833             # Generate comment

    834             #

    835             Usage = Pcd.GetValidUsage()
    836             # if FeatureFlag Pcd, then assume all Usage is CONSUMES

    837             if ItemType == DT.TAB_INF_FEATURE_PCD:
    838                 Usage = DT.USAGE_ITEM_CONSUMES
    839             if Usage == DT.ITEM_UNDEFINED:
    840                 # generate list of generic comment

    841                 Comment = GenGenericCommentF(HelpStr)
    842             else:
    843                 # generate list of other comment

    844                 Comment = HelpStr.replace('\n', ' ')
    845                 Comment = Comment.strip()
    846                 if Comment:
    847                     Comment = ' # ' + Comment
    848                 else:
    849                     Comment = ''
    850                 Comment = '## ' + Usage + Comment
    851                 if Comment:
    852                     Comment += '\n'
    853             #

    854             # Merge duplicate entries

    855             #

    856             ArchList = Pcd.GetSupArchList()
    857             ArchList.sort()
    858             SortedArch = ' '.join(ArchList)
    859             if (Statement, SortedArch) in Dict:
    860                 PreviousComment = Dict[Statement, SortedArch]
    861                 Comment = PreviousComment + Comment
    862             Dict[Statement, SortedArch] = Comment
    863         for ItemType in ItemTypeDict:
    864             # First we need to transfer the Dict to use SortedArch as key

    865             Dict = ItemTypeDict[ItemType]
    866             NewSectionDict = GenMetaFileMisc.TransferDict(Dict, 'INF_PCD')
    867             if NewSectionDict:
    868                 Content += GenSection(ItemType, NewSectionDict)
    869     #

    870     # For AsBuild INF files   

    871     #

    872     else:
    873         Content += GenAsBuiltPacthPcdSections(ModuleObject)
    874         Content += GenAsBuiltPcdExSections(ModuleObject)
    875 
    876     return Content
    877 
    878 ## GenPcdSections

    879 #

    880 #

    881 def GenAsBuiltPacthPcdSections(ModuleObject):
    882     PatchPcdDict = {}
    883     for BinaryFile in ModuleObject.GetBinaryFileList():
    884         if not BinaryFile.AsBuiltList:
    885             continue
    886         for PatchPcd in BinaryFile.AsBuiltList[0].PatchPcdList:
    887             TokenSpaceName = ''
    888             PcdCName = PatchPcd.CName
    889             PcdValue = PatchPcd.DefaultValue
    890             PcdOffset = PatchPcd.Offset
    891             TokenSpaceGuidValue = PatchPcd.TokenSpaceGuidValue
    892             Token = PatchPcd.Token
    893             HelpTextList = PatchPcd.HelpTextList
    894             HelpString = ''
    895             for HelpStringItem in HelpTextList:
    896                 for HelpLine in GetSplitValueList(HelpStringItem.String, '\n'):
    897                     HelpString += '## ' + HelpLine + '\n'
    898             TokenSpaceName, PcdCName = GenMetaFileMisc.ObtainPcdName(ModuleObject.PackageDependencyList,
    899                                                                      TokenSpaceGuidValue,
    900                                                                      Token)
    901             if TokenSpaceName == '' or PcdCName == '':
    902                 Logger.Error("Upt",
    903                              ToolError.RESOURCE_NOT_AVAILABLE,
    904                              ST.ERR_INSTALL_FILE_DEC_FILE_ERROR % (TokenSpaceGuidValue, Token),
    905                              File=ModuleObject.GetFullPath())
    906             Statement = HelpString + TokenSpaceName + '.' + PcdCName + ' | ' + PcdValue + ' | ' + \
    907                          PcdOffset + DT.TAB_SPACE_SPLIT
    908             #

    909             # Use binary file's Arch to be Pcd's Arch 

    910             #

    911             ArchList = []
    912             FileNameObjList = BinaryFile.GetFileNameList()
    913             if FileNameObjList:
    914                 ArchList = FileNameObjList[0].GetSupArchList()
    915             if len(ArchList) == 0:
    916                 if PatchPcdDict.has_key(DT.TAB_ARCH_COMMON):
    917                     if Statement not in PatchPcdDict[DT.TAB_ARCH_COMMON]:
    918                         PatchPcdDict[DT.TAB_ARCH_COMMON].append(Statement)
    919                 else:
    920                     PatchPcdDict[DT.TAB_ARCH_COMMON] = [Statement]
    921             else:
    922                 for Arch in ArchList:
    923                     if PatchPcdDict.has_key(Arch):
    924                         if Statement not in PatchPcdDict[Arch]:
    925                             PatchPcdDict[Arch].append(Statement)
    926                     else:
    927                         PatchPcdDict[Arch] = [Statement]
    928     return GenSection(DT.TAB_INF_PATCH_PCD, PatchPcdDict)
    929 ## GenPcdSections

    930 #

    931 #

    932 def GenAsBuiltPcdExSections(ModuleObject):
    933     PcdExDict = {}
    934     for BinaryFile in ModuleObject.GetBinaryFileList():
    935         if not BinaryFile.AsBuiltList:
    936             continue
    937         for PcdExItem in BinaryFile.AsBuiltList[0].PcdExValueList:
    938             TokenSpaceName = ''
    939             PcdCName = PcdExItem.CName
    940             TokenSpaceGuidValue = PcdExItem.TokenSpaceGuidValue
    941             Token = PcdExItem.Token
    942             HelpTextList = PcdExItem.HelpTextList
    943             HelpString = ''
    944             for HelpStringItem in HelpTextList:
    945                 for HelpLine in GetSplitValueList(HelpStringItem.String, '\n'):
    946                     HelpString += '## ' + HelpLine + '\n'
    947             TokenSpaceName, PcdCName = GenMetaFileMisc.ObtainPcdName(ModuleObject.PackageDependencyList,
    948                                                                      TokenSpaceGuidValue, Token)
    949             if TokenSpaceName == '' or PcdCName == '':
    950                 Logger.Error("Upt",
    951                              ToolError.RESOURCE_NOT_AVAILABLE,
    952                              ST.ERR_INSTALL_FILE_DEC_FILE_ERROR % (TokenSpaceGuidValue, Token),
    953                              File=ModuleObject.GetFullPath())
    954 
    955             Statement = HelpString + TokenSpaceName + DT.TAB_SPLIT + PcdCName + DT.TAB_SPACE_SPLIT
    956 
    957             #

    958             # Use binary file's Arch to be Pcd's Arch 

    959             #

    960             ArchList = []
    961             FileNameObjList = BinaryFile.GetFileNameList()
    962             if FileNameObjList:
    963                 ArchList = FileNameObjList[0].GetSupArchList()
    964 
    965             if len(ArchList) == 0:
    966                 if PcdExDict.has_key('COMMON'):
    967                     PcdExDict['COMMON'].append(Statement)
    968                 else:
    969                     PcdExDict['COMMON'] = [Statement]
    970             else:
    971                 for Arch in ArchList:
    972                     if PcdExDict.has_key(Arch):
    973                         if Statement not in PcdExDict[Arch]:
    974                             PcdExDict[Arch].append(Statement)
    975                     else:
    976                         PcdExDict[Arch] = [Statement]
    977     return GenSection('PcdEx', PcdExDict)
    978 
    979 ## GenSpecialSections

    980 #  generate special sections for Event/BootMode/Hob

    981 #

    982 def GenSpecialSections(ObjectList, SectionName):
    983     #

    984     # generate section

    985     #

    986     Content = ''
    987     NewSectionDict = {}
    988     for Obj in ObjectList:
    989         #

    990         # Generate comment

    991         #

    992         CommentStr = ''
    993         HelpTextList = Obj.GetHelpTextList()
    994         HelpStr = _GetHelpStr(HelpTextList)
    995         CommentStr = GenGenericCommentF(HelpStr)
    996         if SectionName == 'Hob':
    997             Type = Obj.GetHobType()
    998         elif SectionName == 'Event':
    999             Type = Obj.GetEventType()
   1000         elif SectionName == 'BootMode':
   1001             Type = Obj.GetSupportedBootModes()
   1002         else:
   1003             assert(SectionName)
   1004         Usage = Obj.GetUsage()
   1005         Statement = ' ' + Type + ' ## ' + Usage
   1006         if CommentStr in ['#\n', '#\n#\n']:
   1007             CommentStr = '#\n#\n#\n'
   1008         #

   1009         # the first head comment line should start with '##\n', if it starts with '#\n', then add one '#'

   1010         # else add '##\n' to meet the format defined in INF spec

   1011         #

   1012         if CommentStr.startswith('#\n'):
   1013             CommentStr = '#' + CommentStr
   1014         elif CommentStr:
   1015             CommentStr = '##\n' + CommentStr
   1016         if CommentStr and not CommentStr.endswith('\n#\n'):
   1017             CommentStr = CommentStr + '#\n'
   1018         NewStateMent = CommentStr + Statement
   1019         SupArch = Obj.GetSupArchList()
   1020         SupArch.sort()
   1021         SortedArch = ' '.join(SupArch)
   1022         if SortedArch in NewSectionDict:
   1023             NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [NewStateMent]
   1024         else:
   1025             NewSectionDict[SortedArch] = [NewStateMent]
   1026     SectionContent = GenSection(SectionName, NewSectionDict)
   1027     SectionContent = SectionContent.strip()
   1028     if SectionContent:
   1029         Content = '# ' + ('\n' + '# ').join(GetSplitValueList(SectionContent, '\n'))
   1030         Content = Content.lstrip()
   1031     #

   1032     # add a return to differentiate it between other possible sections

   1033     # 

   1034     if Content:
   1035         Content += '\n'
   1036     return Content
   1037 ## GenBuildOptions

   1038 #

   1039 #

   1040 def GenBuildOptions(ModuleObject):
   1041     Content = ''
   1042     if not ModuleObject.BinaryModule:
   1043         #

   1044         # generate [BuildOptions] section

   1045         #

   1046         NewSectionDict = {}
   1047         for UserExtension in ModuleObject.GetUserExtensionList():
   1048             BuildOptionDict = UserExtension.GetBuildOptionDict()
   1049             if not BuildOptionDict:
   1050                 continue
   1051             for Arch in BuildOptionDict:
   1052                 if Arch in NewSectionDict:
   1053                     NewSectionDict[Arch] = NewSectionDict[Arch] + [BuildOptionDict[Arch]]
   1054                 else:
   1055                     NewSectionDict[Arch] = [BuildOptionDict[Arch]]
   1056         Content = GenSection('BuildOptions', NewSectionDict)
   1057     else:
   1058         BuildOptionDict = {}
   1059         for BinaryFile in ModuleObject.GetBinaryFileList():
   1060             if not BinaryFile.AsBuiltList:
   1061                 continue
   1062             for BuilOptionItem in BinaryFile.AsBuiltList[0].BinaryBuildFlagList:
   1063                 Statement = '#' + BuilOptionItem.AsBuiltOptionFlags
   1064                 if len(BinaryFile.SupArchList) == 0:
   1065                     if BuildOptionDict.has_key('COMMON'):
   1066                         if Statement not in BuildOptionDict['COMMON']:
   1067                             BuildOptionDict['COMMON'].append(Statement)
   1068                     else:
   1069                         BuildOptionDict['COMMON'] = ['## @AsBuilt']
   1070                         BuildOptionDict['COMMON'].append(Statement)
   1071                 else:
   1072                     for Arch in BinaryFile.SupArchList:
   1073                         if BuildOptionDict.has_key(Arch):
   1074                             if Statement not in BuildOptionDict[Arch]:
   1075                                 BuildOptionDict[Arch].append(Statement)
   1076                         else:
   1077                             BuildOptionDict[Arch] = ['## @AsBuilt']
   1078                             BuildOptionDict[Arch].append(Statement)
   1079         Content = GenSection('BuildOptions', BuildOptionDict)
   1080 
   1081     return Content
   1082 ## GenBinaries

   1083 #

   1084 #

   1085 def GenBinaries(ModuleObject):
   1086     NewSectionDict = {}
   1087     BinariesDict = []
   1088     for UserExtension in ModuleObject.GetUserExtensionList():
   1089         BinariesDict = UserExtension.GetBinariesDict()
   1090         if BinariesDict:
   1091             break
   1092     for BinaryFile in ModuleObject.GetBinaryFileList():
   1093         FileNameObjList = BinaryFile.GetFileNameList()
   1094         for FileNameObj in FileNameObjList:
   1095             FileName = ConvertPath(FileNameObj.GetFilename())
   1096             FileType = FileNameObj.GetFileType()
   1097             FFE = FileNameObj.GetFeatureFlag()
   1098             ArchList = FileNameObj.GetSupArchList()
   1099             ArchList.sort()
   1100             SortedArch = ' '.join(ArchList)
   1101             Key = (FileName, FileType, FFE, SortedArch)
   1102             if Key in BinariesDict:
   1103                 ValueList = BinariesDict[Key]
   1104                 for ValueItem in ValueList:
   1105                     Statement = GenBinaryStatement(Key, ValueItem)
   1106                     if SortedArch in NewSectionDict:
   1107                         NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement]
   1108                     else:
   1109                         NewSectionDict[SortedArch] = [Statement]
   1110                 #

   1111                 # as we already generated statement for this DictKey here set the Valuelist to be empty 

   1112                 # to avoid generate duplicate entries as the DictKey may have multiple entries

   1113                 #

   1114                 BinariesDict[Key] = []
   1115             else:
   1116                 if FileType == 'SUBTYPE_GUID' and FileNameObj.GetGuidValue():
   1117                     Statement = GenBinaryStatement(Key, None, FileNameObj.GetGuidValue())
   1118                 else:
   1119                     Statement = GenBinaryStatement(Key, None)
   1120                 if SortedArch in NewSectionDict:
   1121                     NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement]
   1122                 else:
   1123                     NewSectionDict[SortedArch] = [Statement]
   1124     Content = GenSection('Binaries', NewSectionDict)
   1125 
   1126     return Content
   1127