## @file GenInfFile.py | |
# | |
# This file contained the logical of transfer package object to INF files. | |
# | |
# Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR> | |
# | |
# This program and the accompanying materials are licensed and made available | |
# under the terms and conditions of the BSD License which accompanies this | |
# distribution. The full text of the license may be found at | |
# http://opensource.org/licenses/bsd-license.php | |
# | |
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
# | |
''' | |
GenInf | |
''' | |
import os | |
import stat | |
import codecs | |
import md5 | |
from Core.FileHook import __FileHookOpen__ | |
from Library.String import GetSplitValueList | |
from Library.Parsing import GenSection | |
from Library.Parsing import GetWorkspacePackage | |
from Library.Parsing import ConvertArchForInstall | |
from Library.Misc import SaveFileOnChange | |
from Library.Misc import IsAllModuleList | |
from Library.Misc import Sdict | |
from Library.Misc import ConvertPath | |
from Library.Misc import ConvertSpec | |
from Library.Misc import GetRelativePath | |
from Library.Misc import GetLocalValue | |
from Library.CommentGenerating import GenHeaderCommentSection | |
from Library.CommentGenerating import GenGenericCommentF | |
from Library.CommentGenerating import _GetHelpStr | |
from Library import GlobalData | |
from Logger import StringTable as ST | |
from Logger import ToolError | |
import Logger.Log as Logger | |
from Library import DataType as DT | |
from GenMetaFile import GenMetaFileMisc | |
from Library.UniClassObject import FormatUniEntry | |
from Library.String import GetUniFileName | |
## Transfer Module Object to Inf files | |
# | |
# Transfer all contents of a standard Module Object to an Inf file | |
# @param ModuleObject: A Module Object | |
# | |
def ModuleToInf(ModuleObject, PackageObject=None, DistHeader=None): | |
if not GlobalData.gWSPKG_LIST: | |
GlobalData.gWSPKG_LIST = GetWorkspacePackage() | |
# | |
# Init global information for the file | |
# | |
ContainerFile = ModuleObject.GetFullPath() | |
Content = '' | |
# | |
# Generate file header, If any Abstract, Description, Copyright or License XML elements are missing, | |
# should 1) use the Abstract, Description, Copyright or License from the PackageSurfaceArea.Header elements | |
# that the module belongs to, or 2) if this is a stand-alone module that is not included in a PackageSurfaceArea, | |
# use the abstract, description, copyright or license from the DistributionPackage.Header elements. | |
# | |
ModuleAbstract = GetLocalValue(ModuleObject.GetAbstract()) | |
if not ModuleAbstract and PackageObject: | |
ModuleAbstract = GetLocalValue(PackageObject.GetAbstract()) | |
if not ModuleAbstract and DistHeader: | |
ModuleAbstract = GetLocalValue(DistHeader.GetAbstract()) | |
ModuleDescription = GetLocalValue(ModuleObject.GetDescription()) | |
if not ModuleDescription and PackageObject: | |
ModuleDescription = GetLocalValue(PackageObject.GetDescription()) | |
if not ModuleDescription and DistHeader: | |
ModuleDescription = GetLocalValue(DistHeader.GetDescription()) | |
ModuleCopyright = '' | |
for (Lang, Copyright) in ModuleObject.GetCopyright(): | |
if Lang: | |
pass | |
ModuleCopyright = Copyright | |
if not ModuleCopyright and PackageObject: | |
for (Lang, Copyright) in PackageObject.GetCopyright(): | |
if Lang: | |
pass | |
ModuleCopyright = Copyright | |
if not ModuleCopyright and DistHeader: | |
for (Lang, Copyright) in DistHeader.GetCopyright(): | |
if Lang: | |
pass | |
ModuleCopyright = Copyright | |
ModuleLicense = '' | |
for (Lang, License) in ModuleObject.GetLicense(): | |
if Lang: | |
pass | |
ModuleLicense = License | |
if not ModuleLicense and PackageObject: | |
for (Lang, License) in PackageObject.GetLicense(): | |
if Lang: | |
pass | |
ModuleLicense = License | |
if not ModuleLicense and DistHeader: | |
for (Lang, License) in DistHeader.GetLicense(): | |
if Lang: | |
pass | |
ModuleLicense = License | |
# | |
# Generate header comment section of INF file | |
# | |
Content += GenHeaderCommentSection(ModuleAbstract, | |
ModuleDescription, | |
ModuleCopyright, | |
ModuleLicense).replace('\r\n', '\n') | |
# | |
# Generate Binary Header | |
# | |
for UserExtension in ModuleObject.GetUserExtensionList(): | |
if UserExtension.GetUserID() == DT.TAB_BINARY_HEADER_USERID \ | |
and UserExtension.GetIdentifier() == DT.TAB_BINARY_HEADER_IDENTIFIER: | |
ModuleBinaryAbstract = GetLocalValue(UserExtension.GetBinaryAbstract()) | |
ModuleBinaryDescription = GetLocalValue(UserExtension.GetBinaryDescription()) | |
ModuleBinaryCopyright = '' | |
ModuleBinaryLicense = '' | |
for (Lang, Copyright) in UserExtension.GetBinaryCopyright(): | |
ModuleBinaryCopyright = Copyright | |
for (Lang, License) in UserExtension.GetBinaryLicense(): | |
ModuleBinaryLicense = License | |
if ModuleBinaryAbstract and ModuleBinaryDescription and \ | |
ModuleBinaryCopyright and ModuleBinaryLicense: | |
Content += GenHeaderCommentSection(ModuleBinaryAbstract, | |
ModuleBinaryDescription, | |
ModuleBinaryCopyright, | |
ModuleBinaryLicense, | |
True) | |
# | |
# Generate MODULE_UNI_FILE for module | |
# | |
FileHeader = GenHeaderCommentSection(ModuleAbstract, ModuleDescription, ModuleCopyright, ModuleLicense, False, \ | |
DT.TAB_COMMENT_EDK1_SPLIT) | |
GenModuleUNIEncodeFile(ModuleObject, FileHeader) | |
# | |
# Judge whether the INF file is an AsBuild INF. | |
# | |
if ModuleObject.BinaryModule: | |
GlobalData.gIS_BINARY_INF = True | |
else: | |
GlobalData.gIS_BINARY_INF = False | |
# | |
# for each section, maintain a dict, sorted arch will be its key, | |
# statement list will be its data | |
# { 'Arch1 Arch2 Arch3': [statement1, statement2], | |
# 'Arch1' : [statement1, statement3] | |
# } | |
# | |
# Gen section contents | |
# | |
Content += GenDefines(ModuleObject) | |
Content += GenBuildOptions(ModuleObject) | |
Content += GenLibraryClasses(ModuleObject) | |
Content += GenPackages(ModuleObject) | |
Content += GenPcdSections(ModuleObject) | |
Content += GenSources(ModuleObject) | |
Content += GenProtocolPPiSections(ModuleObject.GetProtocolList(), True) | |
Content += GenProtocolPPiSections(ModuleObject.GetPpiList(), False) | |
Content += GenGuidSections(ModuleObject.GetGuidList()) | |
Content += GenBinaries(ModuleObject) | |
Content += GenDepex(ModuleObject) | |
Content += GenUserExtensions(ModuleObject) | |
if ModuleObject.GetEventList() or ModuleObject.GetBootModeList() or ModuleObject.GetHobList(): | |
Content += '\n' | |
# | |
# generate [Event], [BootMode], [Hob] section | |
# | |
Content += GenSpecialSections(ModuleObject.GetEventList(), 'Event') | |
Content += GenSpecialSections(ModuleObject.GetBootModeList(), 'BootMode') | |
Content += GenSpecialSections(ModuleObject.GetHobList(), 'Hob') | |
SaveFileOnChange(ContainerFile, Content, False) | |
if DistHeader.ReadOnly: | |
os.chmod(ContainerFile, stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH) | |
else: | |
os.chmod(ContainerFile, stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH|stat.S_IWUSR|stat.S_IWGRP|stat.S_IWOTH) | |
return ContainerFile | |
## GenModuleUNIEncodeFile | |
# GenModuleUNIEncodeFile, default is a UCS-2LE encode file | |
# | |
def GenModuleUNIEncodeFile(ModuleObject, UniFileHeader='', Encoding=DT.TAB_ENCODING_UTF16LE): | |
GenUNIFlag = False | |
OnlyLANGUAGE_EN_X = True | |
BinaryAbstract = [] | |
BinaryDescription = [] | |
# | |
# If more than one language code is used for any element that would be present in the MODULE_UNI_FILE, | |
# then the MODULE_UNI_FILE must be created. | |
# | |
for (Key, Value) in ModuleObject.GetAbstract() + ModuleObject.GetDescription(): | |
if Key == DT.TAB_LANGUAGE_EN_X: | |
GenUNIFlag = True | |
else: | |
OnlyLANGUAGE_EN_X = False | |
for UserExtension in ModuleObject.GetUserExtensionList(): | |
if UserExtension.GetUserID() == DT.TAB_BINARY_HEADER_USERID \ | |
and UserExtension.GetIdentifier() == DT.TAB_BINARY_HEADER_IDENTIFIER: | |
for (Key, Value) in UserExtension.GetBinaryAbstract(): | |
if Key == DT.TAB_LANGUAGE_EN_X: | |
GenUNIFlag = True | |
else: | |
OnlyLANGUAGE_EN_X = False | |
BinaryAbstract.append((Key, Value)) | |
for (Key, Value) in UserExtension.GetBinaryDescription(): | |
if Key == DT.TAB_LANGUAGE_EN_X: | |
GenUNIFlag = True | |
else: | |
OnlyLANGUAGE_EN_X = False | |
BinaryDescription.append((Key, Value)) | |
if not GenUNIFlag: | |
return | |
elif OnlyLANGUAGE_EN_X: | |
return | |
else: | |
ModuleObject.UNIFlag = True | |
ContainerFile = GetUniFileName(os.path.dirname(ModuleObject.GetFullPath()), ModuleObject.GetBaseName()) | |
if not os.path.exists(os.path.dirname(ModuleObject.GetFullPath())): | |
os.makedirs(os.path.dirname(ModuleObject.GetFullPath())) | |
Content = UniFileHeader + '\r\n' | |
Content += '\r\n' | |
Content += FormatUniEntry('#string ' + DT.TAB_INF_ABSTRACT, ModuleObject.GetAbstract(), ContainerFile) + '\r\n' | |
Content += FormatUniEntry('#string ' + DT.TAB_INF_DESCRIPTION, ModuleObject.GetDescription(), ContainerFile) \ | |
+ '\r\n' | |
BinaryAbstractString = FormatUniEntry('#string ' + DT.TAB_INF_BINARY_ABSTRACT, BinaryAbstract, ContainerFile) | |
if BinaryAbstractString: | |
Content += BinaryAbstractString + '\r\n' | |
BinaryDescriptionString = FormatUniEntry('#string ' + DT.TAB_INF_BINARY_DESCRIPTION, BinaryDescription, \ | |
ContainerFile) | |
if BinaryDescriptionString: | |
Content += BinaryDescriptionString + '\r\n' | |
if not os.path.exists(ContainerFile): | |
File = codecs.open(ContainerFile, 'wb', Encoding) | |
File.write(u'\uFEFF' + Content) | |
File.stream.close() | |
Md5Sigature = md5.new(__FileHookOpen__(str(ContainerFile), 'rb').read()) | |
Md5Sum = Md5Sigature.hexdigest() | |
if (ContainerFile, Md5Sum) not in ModuleObject.FileList: | |
ModuleObject.FileList.append((ContainerFile, Md5Sum)) | |
return ContainerFile | |
def GenDefines(ModuleObject): | |
# | |
# generate [Defines] section | |
# | |
LeftOffset = 31 | |
Content = '' | |
NewSectionDict = {} | |
for UserExtension in ModuleObject.GetUserExtensionList(): | |
DefinesDict = UserExtension.GetDefinesDict() | |
if not DefinesDict: | |
continue | |
for Statement in DefinesDict: | |
if Statement.split(DT.TAB_EQUAL_SPLIT) > 1: | |
Statement = (u'%s ' % Statement.split(DT.TAB_EQUAL_SPLIT, 1)[0]).ljust(LeftOffset) \ | |
+ u'= %s' % Statement.split(DT.TAB_EQUAL_SPLIT, 1)[1].lstrip() | |
SortedArch = DT.TAB_ARCH_COMMON | |
if Statement.strip().startswith(DT.TAB_INF_DEFINES_CUSTOM_MAKEFILE): | |
pos = Statement.find(DT.TAB_VALUE_SPLIT) | |
if pos == -1: | |
pos = Statement.find(DT.TAB_EQUAL_SPLIT) | |
Makefile = ConvertPath(Statement[pos + 1:].strip()) | |
Statement = Statement[:pos + 1] + ' ' + Makefile | |
if SortedArch in NewSectionDict: | |
NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement] | |
else: | |
NewSectionDict[SortedArch] = [Statement] | |
SpecialStatementList = [] | |
# TAB_INF_DEFINES_INF_VERSION | |
Statement = (u'%s ' % DT.TAB_INF_DEFINES_INF_VERSION).ljust(LeftOffset) + u'= %s' % '0x00010017' | |
SpecialStatementList.append(Statement) | |
# BaseName | |
BaseName = ModuleObject.GetBaseName() | |
if BaseName.startswith('.') or BaseName.startswith('-'): | |
BaseName = '_' + BaseName | |
Statement = (u'%s ' % DT.TAB_INF_DEFINES_BASE_NAME).ljust(LeftOffset) + u'= %s' % BaseName | |
SpecialStatementList.append(Statement) | |
# TAB_INF_DEFINES_FILE_GUID | |
Statement = (u'%s ' % DT.TAB_INF_DEFINES_FILE_GUID).ljust(LeftOffset) + u'= %s' % ModuleObject.GetGuid() | |
SpecialStatementList.append(Statement) | |
# TAB_INF_DEFINES_VERSION_STRING | |
Statement = (u'%s ' % DT.TAB_INF_DEFINES_VERSION_STRING).ljust(LeftOffset) + u'= %s' % ModuleObject.GetVersion() | |
SpecialStatementList.append(Statement) | |
# TAB_INF_DEFINES_VERSION_STRING | |
if ModuleObject.UNIFlag: | |
Statement = (u'%s ' % DT.TAB_INF_DEFINES_MODULE_UNI_FILE).ljust(LeftOffset) + \ | |
u'= %s' % ModuleObject.GetBaseName() + '.uni' | |
SpecialStatementList.append(Statement) | |
# TAB_INF_DEFINES_MODULE_TYPE | |
if ModuleObject.GetModuleType(): | |
Statement = (u'%s ' % DT.TAB_INF_DEFINES_MODULE_TYPE).ljust(LeftOffset) + u'= %s' % ModuleObject.GetModuleType() | |
SpecialStatementList.append(Statement) | |
# TAB_INF_DEFINES_PCD_IS_DRIVER | |
if ModuleObject.GetPcdIsDriver(): | |
Statement = (u'%s ' % DT.TAB_INF_DEFINES_PCD_IS_DRIVER).ljust(LeftOffset) + \ | |
u'= %s' % ModuleObject.GetPcdIsDriver() | |
SpecialStatementList.append(Statement) | |
# TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION | |
if ModuleObject.GetUefiSpecificationVersion(): | |
Statement = (u'%s ' % DT.TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION).ljust(LeftOffset) + \ | |
u'= %s' % ModuleObject.GetUefiSpecificationVersion() | |
SpecialStatementList.append(Statement) | |
# TAB_INF_DEFINES_PI_SPECIFICATION_VERSION | |
if ModuleObject.GetPiSpecificationVersion(): | |
Statement = (u'%s ' % DT.TAB_INF_DEFINES_PI_SPECIFICATION_VERSION).ljust(LeftOffset) + \ | |
u'= %s' % ModuleObject.GetPiSpecificationVersion() | |
SpecialStatementList.append(Statement) | |
# LibraryClass | |
for LibraryClass in ModuleObject.GetLibraryClassList(): | |
if LibraryClass.GetUsage() == DT.USAGE_ITEM_PRODUCES or \ | |
LibraryClass.GetUsage() == DT.USAGE_ITEM_SOMETIMES_PRODUCES: | |
Statement = (u'%s ' % DT.TAB_INF_DEFINES_LIBRARY_CLASS).ljust(LeftOffset) + \ | |
u'= %s' % LibraryClass.GetLibraryClass() | |
if LibraryClass.GetSupModuleList(): | |
Statement += '|' + DT.TAB_SPACE_SPLIT.join(l for l in LibraryClass.GetSupModuleList()) | |
SpecialStatementList.append(Statement) | |
# Spec Item | |
for SpecItem in ModuleObject.GetSpecList(): | |
Spec, Version = SpecItem | |
Spec = ConvertSpec(Spec) | |
Statement = '%s %s = %s' % (DT.TAB_INF_DEFINES_SPEC, Spec, Version) | |
SpecialStatementList.append(Statement) | |
# Extern | |
ExternList = [] | |
for Extern in ModuleObject.GetExternList(): | |
ArchList = Extern.GetSupArchList() | |
EntryPoint = Extern.GetEntryPoint() | |
UnloadImage = Extern.GetUnloadImage() | |
Constructor = Extern.GetConstructor() | |
Destructor = Extern.GetDestructor() | |
HelpStringList = Extern.GetHelpTextList() | |
FFE = Extern.GetFeatureFlag() | |
ExternList.append([ArchList, EntryPoint, UnloadImage, Constructor, Destructor, FFE, HelpStringList]) | |
# | |
# Add VALID_ARCHITECTURES information | |
# | |
ValidArchStatement = None | |
if ModuleObject.SupArchList: | |
ValidArchStatement = '\n' + '# ' + '\n' | |
ValidArchStatement += '# The following information is for reference only and not required by the build tools.\n' | |
ValidArchStatement += '# ' + '\n' | |
ValidArchStatement += '# VALID_ARCHITECTURES = %s' % (' '.join(ModuleObject.SupArchList)) + '\n' | |
ValidArchStatement += '# ' | |
if DT.TAB_ARCH_COMMON not in NewSectionDict: | |
NewSectionDict[DT.TAB_ARCH_COMMON] = [] | |
NewSectionDict[DT.TAB_ARCH_COMMON] = NewSectionDict[DT.TAB_ARCH_COMMON] + SpecialStatementList | |
GenMetaFileMisc.AddExternToDefineSec(NewSectionDict, DT.TAB_ARCH_COMMON, ExternList) | |
if ValidArchStatement is not None: | |
NewSectionDict[DT.TAB_ARCH_COMMON] = NewSectionDict[DT.TAB_ARCH_COMMON] + [ValidArchStatement] | |
Content += GenSection('Defines', NewSectionDict) | |
return Content | |
def GenLibraryClasses(ModuleObject): | |
# | |
# generate [LibraryClasses] section | |
# | |
Content = '' | |
NewSectionDict = {} | |
if not GlobalData.gIS_BINARY_INF: | |
for LibraryClass in ModuleObject.GetLibraryClassList(): | |
if LibraryClass.GetUsage() == DT.USAGE_ITEM_PRODUCES: | |
continue | |
# | |
# Generate generic comment | |
# | |
HelpTextList = LibraryClass.GetHelpTextList() | |
HelpStr = _GetHelpStr(HelpTextList) | |
CommentStr = GenGenericCommentF(HelpStr) | |
Statement = CommentStr | |
Name = LibraryClass.GetLibraryClass() | |
FFE = LibraryClass.GetFeatureFlag() | |
Statement += Name | |
if FFE: | |
Statement += '|' + FFE | |
ModuleList = LibraryClass.GetSupModuleList() | |
ArchList = LibraryClass.GetSupArchList() | |
for Index in xrange(0, len(ArchList)): | |
ArchList[Index] = ConvertArchForInstall(ArchList[Index]) | |
ArchList.sort() | |
SortedArch = ' '.join(ArchList) | |
KeyList = [] | |
if not ModuleList or IsAllModuleList(ModuleList): | |
KeyList = [SortedArch] | |
else: | |
ModuleString = DT.TAB_VALUE_SPLIT.join(l for l in ModuleList) | |
if not ArchList: | |
SortedArch = DT.TAB_ARCH_COMMON | |
KeyList = [SortedArch + '.' + ModuleString] | |
else: | |
KeyList = [Arch + '.' + ModuleString for Arch in ArchList] | |
for Key in KeyList: | |
if Key in NewSectionDict: | |
NewSectionDict[Key] = NewSectionDict[Key] + [Statement] | |
else: | |
NewSectionDict[Key] = [Statement] | |
Content += GenSection('LibraryClasses', NewSectionDict) | |
else: | |
LibraryClassDict = {} | |
for BinaryFile in ModuleObject.GetBinaryFileList(): | |
if not BinaryFile.AsBuiltList: | |
continue | |
for LibraryItem in BinaryFile.AsBuiltList[0].LibraryInstancesList: | |
Statement = '# Guid: ' + LibraryItem.Guid + ' Version: ' + LibraryItem.Version | |
if len(BinaryFile.SupArchList) == 0: | |
if LibraryClassDict.has_key('COMMON') and Statement not in LibraryClassDict['COMMON']: | |
LibraryClassDict['COMMON'].append(Statement) | |
else: | |
LibraryClassDict['COMMON'] = ['## @LIB_INSTANCES'] | |
LibraryClassDict['COMMON'].append(Statement) | |
else: | |
for Arch in BinaryFile.SupArchList: | |
if LibraryClassDict.has_key(Arch): | |
if Statement not in LibraryClassDict[Arch]: | |
LibraryClassDict[Arch].append(Statement) | |
else: | |
continue | |
else: | |
LibraryClassDict[Arch] = ['## @LIB_INSTANCES'] | |
LibraryClassDict[Arch].append(Statement) | |
Content += GenSection('LibraryClasses', LibraryClassDict) | |
return Content | |
def GenPackages(ModuleObject): | |
Content = '' | |
# | |
# generate [Packages] section | |
# | |
NewSectionDict = Sdict() | |
WorkspaceDir = GlobalData.gWORKSPACE | |
for PackageDependency in ModuleObject.GetPackageDependencyList(): | |
# | |
# Generate generic comment | |
# | |
CommentStr = '' | |
HelpText = PackageDependency.GetHelpText() | |
if HelpText: | |
HelpStr = HelpText.GetString() | |
CommentStr = GenGenericCommentF(HelpStr) | |
Statement = CommentStr | |
Guid = PackageDependency.GetGuid() | |
Version = PackageDependency.GetVersion() | |
FFE = PackageDependency.GetFeatureFlag() | |
Path = '' | |
# | |
# find package path/name | |
# | |
for PkgInfo in GlobalData.gWSPKG_LIST: | |
if Guid == PkgInfo[1]: | |
if (not Version) or (Version == PkgInfo[2]): | |
Path = PkgInfo[3] | |
break | |
# | |
# get relative path | |
# | |
RelaPath = GetRelativePath(Path, WorkspaceDir) | |
Statement += RelaPath.replace('\\', '/') | |
if FFE: | |
Statement += '|' + FFE | |
ArchList = PackageDependency.GetSupArchList() | |
ArchList.sort() | |
SortedArch = ' '.join(ArchList) | |
if SortedArch in NewSectionDict: | |
NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement] | |
else: | |
NewSectionDict[SortedArch] = [Statement] | |
Content += GenSection('Packages', NewSectionDict) | |
return Content | |
def GenSources(ModuleObject): | |
# | |
# generate [Sources] section | |
# | |
Content = '' | |
NewSectionDict = {} | |
for Source in ModuleObject.GetSourceFileList(): | |
SourceFile = Source.GetSourceFile() | |
Family = Source.GetFamily() | |
FeatureFlag = Source.GetFeatureFlag() | |
SupArchList = Source.GetSupArchList() | |
SupArchList.sort() | |
SortedArch = ' '.join(SupArchList) | |
Statement = GenSourceStatement(ConvertPath(SourceFile), Family, FeatureFlag) | |
if SortedArch in NewSectionDict: | |
NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement] | |
else: | |
NewSectionDict[SortedArch] = [Statement] | |
Content += GenSection('Sources', NewSectionDict) | |
return Content | |
def GenDepex(ModuleObject): | |
# | |
# generate [Depex] section | |
# | |
NewSectionDict = Sdict() | |
Content = '' | |
for Depex in ModuleObject.GetPeiDepex() + ModuleObject.GetDxeDepex() + ModuleObject.GetSmmDepex(): | |
HelpTextList = Depex.GetHelpTextList() | |
HelpStr = _GetHelpStr(HelpTextList) | |
CommentStr = GenGenericCommentF(HelpStr) | |
SupArchList = Depex.GetSupArchList() | |
SupModList = Depex.GetModuleType() | |
Expression = Depex.GetDepex() | |
Statement = CommentStr + Expression | |
SupArchList.sort() | |
KeyList = [] | |
if not SupArchList: | |
SupArchList.append(DT.TAB_ARCH_COMMON.lower()) | |
if not SupModList: | |
KeyList = SupArchList | |
else: | |
for ModuleType in SupModList: | |
for Arch in SupArchList: | |
KeyList.append(ConvertArchForInstall(Arch) + '.' + ModuleType) | |
for Key in KeyList: | |
if Key in NewSectionDict: | |
NewSectionDict[Key] = NewSectionDict[Key] + [Statement] | |
else: | |
NewSectionDict[Key] = [Statement] | |
Content += GenSection('Depex', NewSectionDict, False) | |
return Content | |
## GenUserExtensions | |
# | |
# GenUserExtensions | |
# | |
def GenUserExtensions(ModuleObject): | |
NewSectionDict = {} | |
for UserExtension in ModuleObject.GetUserExtensionList(): | |
if UserExtension.GetUserID() == DT.TAB_BINARY_HEADER_USERID and \ | |
UserExtension.GetIdentifier() == DT.TAB_BINARY_HEADER_IDENTIFIER: | |
continue | |
if UserExtension.GetIdentifier() == 'Depex': | |
continue | |
Statement = UserExtension.GetStatement() | |
if not Statement: | |
continue | |
ArchList = UserExtension.GetSupArchList() | |
for Index in xrange(0, len(ArchList)): | |
ArchList[Index] = ConvertArchForInstall(ArchList[Index]) | |
ArchList.sort() | |
KeyList = [] | |
CommonPreFix = '' | |
if UserExtension.GetUserID(): | |
CommonPreFix = UserExtension.GetUserID() | |
if CommonPreFix.find('.') > -1: | |
CommonPreFix = '"' + CommonPreFix + '"' | |
if UserExtension.GetIdentifier(): | |
CommonPreFix += '.' + '"' + UserExtension.GetIdentifier() + '"' | |
if ArchList: | |
KeyList = [CommonPreFix + '.' + Arch for Arch in ArchList] | |
else: | |
KeyList = [CommonPreFix] | |
for Key in KeyList: | |
if Key in NewSectionDict: | |
NewSectionDict[Key] = NewSectionDict[Key] + [Statement] | |
else: | |
NewSectionDict[Key] = [Statement] | |
Content = GenSection('UserExtensions', NewSectionDict, False) | |
return Content | |
# GenSourceStatement | |
# | |
# @param SourceFile: string of source file path/name | |
# @param Family: string of source file family field | |
# @param FeatureFlag: string of source file FeatureFlag field | |
# @param TagName: string of source file TagName field | |
# @param ToolCode: string of source file ToolCode field | |
# @param HelpStr: string of source file HelpStr field | |
# | |
# @retval Statement: The generated statement for source | |
# | |
def GenSourceStatement(SourceFile, Family, FeatureFlag, TagName=None, | |
ToolCode=None, HelpStr=None): | |
Statement = '' | |
if HelpStr: | |
Statement += GenGenericCommentF(HelpStr) | |
# | |
# format of SourceFile|Family|TagName|ToolCode|FeatureFlag | |
# | |
Statement += SourceFile | |
if TagName == None: | |
TagName = '' | |
if ToolCode == None: | |
ToolCode = '' | |
if HelpStr == None: | |
HelpStr = '' | |
if FeatureFlag: | |
Statement += '|' + Family + '|' + TagName + '|' + ToolCode + '|' + FeatureFlag | |
elif ToolCode: | |
Statement += '|' + Family + '|' + TagName + '|' + ToolCode | |
elif TagName: | |
Statement += '|' + Family + '|' + TagName | |
elif Family: | |
Statement += '|' + Family | |
return Statement | |
# GenBinaryStatement | |
# | |
# @param Key: (FileName, FileType, FFE, SortedArch) | |
# @param Value: (Target, Family, TagName, Comment) | |
# | |
# | |
def GenBinaryStatement(Key, Value, SubTypeGuidValue=None): | |
(FileName, FileType, FFE, SortedArch) = Key | |
if SortedArch: | |
pass | |
if Value: | |
(Target, Family, TagName, Comment) = Value | |
else: | |
Target = '' | |
Family = '' | |
TagName = '' | |
Comment = '' | |
if Comment: | |
Statement = GenGenericCommentF(Comment) | |
else: | |
Statement = '' | |
if FileType == 'SUBTYPE_GUID' and SubTypeGuidValue: | |
Statement += FileType + '|' + SubTypeGuidValue + '|' + FileName | |
else: | |
Statement += FileType + '|' + FileName | |
if FileType in DT.BINARY_FILE_TYPE_UI_LIST + DT.BINARY_FILE_TYPE_VER_LIST: | |
if FFE: | |
Statement += '|' + Target + '|' + FFE | |
elif Target: | |
Statement += '|' + Target | |
else: | |
if FFE: | |
Statement += '|' + Target + '|' + Family + '|' + TagName + '|' + FFE | |
elif TagName: | |
Statement += '|' + Target + '|' + Family + '|' + TagName | |
elif Family: | |
Statement += '|' + Target + '|' + Family | |
elif Target: | |
Statement += '|' + Target | |
return Statement | |
## GenGuidSections | |
# | |
# @param GuidObjList: List of GuidObject | |
# @retVal Content: The generated section contents | |
# | |
def GenGuidSections(GuidObjList): | |
# | |
# generate [Guids] section | |
# | |
Content = '' | |
GuidDict = Sdict() | |
for Guid in GuidObjList: | |
HelpTextList = Guid.GetHelpTextList() | |
HelpStr = _GetHelpStr(HelpTextList) | |
CName = Guid.GetCName() | |
FFE = Guid.GetFeatureFlag() | |
Statement = CName | |
if FFE: | |
Statement += '|' + FFE | |
Usage = Guid.GetUsage() | |
GuidType = Guid.GetGuidTypeList()[0] | |
VariableName = Guid.GetVariableName() | |
# | |
# Differentiate the generic comment and usage comment as multiple generic comment need to be put at first | |
# | |
if Usage == DT.ITEM_UNDEFINED and GuidType == DT.ITEM_UNDEFINED: | |
# generate list of generic comment | |
Comment = GenGenericCommentF(HelpStr) | |
else: | |
# generate list of other comment | |
Comment = HelpStr.replace('\n', ' ') | |
Comment = Comment.strip() | |
if Comment: | |
Comment = ' # ' + Comment | |
else: | |
Comment = '' | |
if Usage != DT.ITEM_UNDEFINED and GuidType == DT.ITEM_UNDEFINED: | |
Comment = '## ' + Usage + Comment | |
elif GuidType == 'Variable': | |
Comment = '## ' + Usage + ' ## ' + GuidType + ':' + VariableName + Comment | |
else: | |
Comment = '## ' + Usage + ' ## ' + GuidType + Comment | |
if Comment: | |
Comment += '\n' | |
# | |
# merge duplicate items | |
# | |
ArchList = Guid.GetSupArchList() | |
ArchList.sort() | |
SortedArch = ' '.join(ArchList) | |
if (Statement, SortedArch) in GuidDict: | |
PreviousComment = GuidDict[Statement, SortedArch] | |
Comment = PreviousComment + Comment | |
GuidDict[Statement, SortedArch] = Comment | |
NewSectionDict = GenMetaFileMisc.TransferDict(GuidDict, 'INF_GUID') | |
# | |
# generate the section contents | |
# | |
if NewSectionDict: | |
Content = GenSection('Guids', NewSectionDict) | |
return Content | |
## GenProtocolPPiSections | |
# | |
# @param ObjList: List of ProtocolObject or Ppi Object | |
# @retVal Content: The generated section contents | |
# | |
def GenProtocolPPiSections(ObjList, IsProtocol): | |
Content = '' | |
Dict = Sdict() | |
for Object in ObjList: | |
HelpTextList = Object.GetHelpTextList() | |
HelpStr = _GetHelpStr(HelpTextList) | |
CName = Object.GetCName() | |
FFE = Object.GetFeatureFlag() | |
Statement = CName | |
if FFE: | |
Statement += '|' + FFE | |
Usage = Object.GetUsage() | |
Notify = Object.GetNotify() | |
# | |
# Differentiate the generic comment and usage comment as consecutive generic comment need to be put together | |
# | |
if Usage == DT.ITEM_UNDEFINED and Notify == '': | |
# generate list of generic comment | |
Comment = GenGenericCommentF(HelpStr) | |
else: | |
# generate list of other comment | |
Comment = HelpStr.replace('\n', ' ') | |
Comment = Comment.strip() | |
if Comment: | |
Comment = ' # ' + Comment | |
else: | |
Comment = '' | |
if Usage == DT.ITEM_UNDEFINED and not Comment and Notify == '': | |
Comment = '' | |
else: | |
if Notify: | |
Comment = '## ' + Usage + ' ## ' + 'NOTIFY' + Comment | |
else: | |
Comment = '## ' + Usage + Comment | |
if Comment: | |
Comment += '\n' | |
# | |
# merge duplicate items | |
# | |
ArchList = Object.GetSupArchList() | |
ArchList.sort() | |
SortedArch = ' '.join(ArchList) | |
if (Statement, SortedArch) in Dict: | |
PreviousComment = Dict[Statement, SortedArch] | |
Comment = PreviousComment + Comment | |
Dict[Statement, SortedArch] = Comment | |
NewSectionDict = GenMetaFileMisc.TransferDict(Dict, 'INF_PPI_PROTOCOL') | |
# | |
# generate the section contents | |
# | |
if NewSectionDict: | |
if IsProtocol: | |
Content = GenSection('Protocols', NewSectionDict) | |
else: | |
Content = GenSection('Ppis', NewSectionDict) | |
return Content | |
## GenPcdSections | |
# | |
# | |
def GenPcdSections(ModuleObject): | |
Content = '' | |
if not GlobalData.gIS_BINARY_INF: | |
# | |
# for each Pcd Itemtype, maintain a dict so the same type will be grouped | |
# together | |
# | |
ItemTypeDict = {} | |
for Pcd in ModuleObject.GetPcdList(): | |
HelpTextList = Pcd.GetHelpTextList() | |
HelpStr = _GetHelpStr(HelpTextList) | |
Statement = '' | |
CName = Pcd.GetCName() | |
TokenSpaceGuidCName = Pcd.GetTokenSpaceGuidCName() | |
DefaultValue = Pcd.GetDefaultValue() | |
ItemType = Pcd.GetItemType() | |
if ItemType in ItemTypeDict: | |
Dict = ItemTypeDict[ItemType] | |
else: | |
Dict = Sdict() | |
ItemTypeDict[ItemType] = Dict | |
FFE = Pcd.GetFeatureFlag() | |
Statement += TokenSpaceGuidCName + '.' + CName | |
if DefaultValue: | |
Statement += '|' + DefaultValue | |
if FFE: | |
Statement += '|' + FFE | |
elif FFE: | |
Statement += '||' + FFE | |
# | |
# Generate comment | |
# | |
Usage = Pcd.GetValidUsage() | |
# if FeatureFlag Pcd, then assume all Usage is CONSUMES | |
if ItemType == DT.TAB_INF_FEATURE_PCD: | |
Usage = DT.USAGE_ITEM_CONSUMES | |
if Usage == DT.ITEM_UNDEFINED: | |
# generate list of generic comment | |
Comment = GenGenericCommentF(HelpStr) | |
else: | |
# generate list of other comment | |
Comment = HelpStr.replace('\n', ' ') | |
Comment = Comment.strip() | |
if Comment: | |
Comment = ' # ' + Comment | |
else: | |
Comment = '' | |
Comment = '## ' + Usage + Comment | |
if Comment: | |
Comment += '\n' | |
# | |
# Merge duplicate entries | |
# | |
ArchList = Pcd.GetSupArchList() | |
ArchList.sort() | |
SortedArch = ' '.join(ArchList) | |
if (Statement, SortedArch) in Dict: | |
PreviousComment = Dict[Statement, SortedArch] | |
Comment = PreviousComment + Comment | |
Dict[Statement, SortedArch] = Comment | |
for ItemType in ItemTypeDict: | |
# First we need to transfer the Dict to use SortedArch as key | |
Dict = ItemTypeDict[ItemType] | |
NewSectionDict = GenMetaFileMisc.TransferDict(Dict, 'INF_PCD') | |
if NewSectionDict: | |
Content += GenSection(ItemType, NewSectionDict) | |
# | |
# For AsBuild INF files | |
# | |
else: | |
Content += GenAsBuiltPacthPcdSections(ModuleObject) | |
Content += GenAsBuiltPcdExSections(ModuleObject) | |
return Content | |
## GenPcdSections | |
# | |
# | |
def GenAsBuiltPacthPcdSections(ModuleObject): | |
PatchPcdDict = {} | |
for BinaryFile in ModuleObject.GetBinaryFileList(): | |
if not BinaryFile.AsBuiltList: | |
continue | |
for PatchPcd in BinaryFile.AsBuiltList[0].PatchPcdList: | |
TokenSpaceName = '' | |
PcdCName = PatchPcd.CName | |
PcdValue = PatchPcd.DefaultValue | |
PcdOffset = PatchPcd.Offset | |
TokenSpaceGuidValue = PatchPcd.TokenSpaceGuidValue | |
Token = PatchPcd.Token | |
HelpTextList = PatchPcd.HelpTextList | |
HelpString = '' | |
for HelpStringItem in HelpTextList: | |
for HelpLine in GetSplitValueList(HelpStringItem.String, '\n'): | |
HelpString += '## ' + HelpLine + '\n' | |
TokenSpaceName, PcdCName = GenMetaFileMisc.ObtainPcdName(ModuleObject.PackageDependencyList, | |
TokenSpaceGuidValue, | |
Token) | |
if TokenSpaceName == '' or PcdCName == '': | |
Logger.Error("Upt", | |
ToolError.RESOURCE_NOT_AVAILABLE, | |
ST.ERR_INSTALL_FILE_DEC_FILE_ERROR % (TokenSpaceGuidValue, Token), | |
File=ModuleObject.GetFullPath()) | |
Statement = HelpString + TokenSpaceName + '.' + PcdCName + ' | ' + PcdValue + ' | ' + \ | |
PcdOffset + DT.TAB_SPACE_SPLIT | |
# | |
# Use binary file's Arch to be Pcd's Arch | |
# | |
ArchList = [] | |
FileNameObjList = BinaryFile.GetFileNameList() | |
if FileNameObjList: | |
ArchList = FileNameObjList[0].GetSupArchList() | |
if len(ArchList) == 0: | |
if PatchPcdDict.has_key(DT.TAB_ARCH_COMMON): | |
if Statement not in PatchPcdDict[DT.TAB_ARCH_COMMON]: | |
PatchPcdDict[DT.TAB_ARCH_COMMON].append(Statement) | |
else: | |
PatchPcdDict[DT.TAB_ARCH_COMMON] = [Statement] | |
else: | |
for Arch in ArchList: | |
if PatchPcdDict.has_key(Arch): | |
if Statement not in PatchPcdDict[Arch]: | |
PatchPcdDict[Arch].append(Statement) | |
else: | |
PatchPcdDict[Arch] = [Statement] | |
return GenSection(DT.TAB_INF_PATCH_PCD, PatchPcdDict) | |
## GenPcdSections | |
# | |
# | |
def GenAsBuiltPcdExSections(ModuleObject): | |
PcdExDict = {} | |
for BinaryFile in ModuleObject.GetBinaryFileList(): | |
if not BinaryFile.AsBuiltList: | |
continue | |
for PcdExItem in BinaryFile.AsBuiltList[0].PcdExValueList: | |
TokenSpaceName = '' | |
PcdCName = PcdExItem.CName | |
TokenSpaceGuidValue = PcdExItem.TokenSpaceGuidValue | |
Token = PcdExItem.Token | |
HelpTextList = PcdExItem.HelpTextList | |
HelpString = '' | |
for HelpStringItem in HelpTextList: | |
for HelpLine in GetSplitValueList(HelpStringItem.String, '\n'): | |
HelpString += '## ' + HelpLine + '\n' | |
TokenSpaceName, PcdCName = GenMetaFileMisc.ObtainPcdName(ModuleObject.PackageDependencyList, | |
TokenSpaceGuidValue, Token) | |
if TokenSpaceName == '' or PcdCName == '': | |
Logger.Error("Upt", | |
ToolError.RESOURCE_NOT_AVAILABLE, | |
ST.ERR_INSTALL_FILE_DEC_FILE_ERROR % (TokenSpaceGuidValue, Token), | |
File=ModuleObject.GetFullPath()) | |
Statement = HelpString + TokenSpaceName + DT.TAB_SPLIT + PcdCName + DT.TAB_SPACE_SPLIT | |
# | |
# Use binary file's Arch to be Pcd's Arch | |
# | |
ArchList = [] | |
FileNameObjList = BinaryFile.GetFileNameList() | |
if FileNameObjList: | |
ArchList = FileNameObjList[0].GetSupArchList() | |
if len(ArchList) == 0: | |
if PcdExDict.has_key('COMMON'): | |
PcdExDict['COMMON'].append(Statement) | |
else: | |
PcdExDict['COMMON'] = [Statement] | |
else: | |
for Arch in ArchList: | |
if PcdExDict.has_key(Arch): | |
if Statement not in PcdExDict[Arch]: | |
PcdExDict[Arch].append(Statement) | |
else: | |
PcdExDict[Arch] = [Statement] | |
return GenSection('PcdEx', PcdExDict) | |
## GenSpecialSections | |
# generate special sections for Event/BootMode/Hob | |
# | |
def GenSpecialSections(ObjectList, SectionName): | |
# | |
# generate section | |
# | |
Content = '' | |
NewSectionDict = {} | |
for Obj in ObjectList: | |
# | |
# Generate comment | |
# | |
CommentStr = '' | |
HelpTextList = Obj.GetHelpTextList() | |
HelpStr = _GetHelpStr(HelpTextList) | |
CommentStr = GenGenericCommentF(HelpStr) | |
if SectionName == 'Hob': | |
Type = Obj.GetHobType() | |
elif SectionName == 'Event': | |
Type = Obj.GetEventType() | |
elif SectionName == 'BootMode': | |
Type = Obj.GetSupportedBootModes() | |
else: | |
assert(SectionName) | |
Usage = Obj.GetUsage() | |
Statement = ' ' + Type + ' ## ' + Usage | |
if CommentStr in ['#\n', '#\n#\n']: | |
CommentStr = '#\n#\n#\n' | |
# | |
# the first head comment line should start with '##\n', if it starts with '#\n', then add one '#' | |
# else add '##\n' to meet the format defined in INF spec | |
# | |
if CommentStr.startswith('#\n'): | |
CommentStr = '#' + CommentStr | |
elif CommentStr: | |
CommentStr = '##\n' + CommentStr | |
if CommentStr and not CommentStr.endswith('\n#\n'): | |
CommentStr = CommentStr + '#\n' | |
NewStateMent = CommentStr + Statement | |
SupArch = Obj.GetSupArchList() | |
SupArch.sort() | |
SortedArch = ' '.join(SupArch) | |
if SortedArch in NewSectionDict: | |
NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [NewStateMent] | |
else: | |
NewSectionDict[SortedArch] = [NewStateMent] | |
SectionContent = GenSection(SectionName, NewSectionDict) | |
SectionContent = SectionContent.strip() | |
if SectionContent: | |
Content = '# ' + ('\n' + '# ').join(GetSplitValueList(SectionContent, '\n')) | |
Content = Content.lstrip() | |
# | |
# add a return to differentiate it between other possible sections | |
# | |
if Content: | |
Content += '\n' | |
return Content | |
## GenBuildOptions | |
# | |
# | |
def GenBuildOptions(ModuleObject): | |
Content = '' | |
if not ModuleObject.BinaryModule: | |
# | |
# generate [BuildOptions] section | |
# | |
NewSectionDict = {} | |
for UserExtension in ModuleObject.GetUserExtensionList(): | |
BuildOptionDict = UserExtension.GetBuildOptionDict() | |
if not BuildOptionDict: | |
continue | |
for Arch in BuildOptionDict: | |
if Arch in NewSectionDict: | |
NewSectionDict[Arch] = NewSectionDict[Arch] + [BuildOptionDict[Arch]] | |
else: | |
NewSectionDict[Arch] = [BuildOptionDict[Arch]] | |
Content = GenSection('BuildOptions', NewSectionDict) | |
else: | |
BuildOptionDict = {} | |
for BinaryFile in ModuleObject.GetBinaryFileList(): | |
if not BinaryFile.AsBuiltList: | |
continue | |
for BuilOptionItem in BinaryFile.AsBuiltList[0].BinaryBuildFlagList: | |
Statement = '#' + BuilOptionItem.AsBuiltOptionFlags | |
if len(BinaryFile.SupArchList) == 0: | |
if BuildOptionDict.has_key('COMMON'): | |
if Statement not in BuildOptionDict['COMMON']: | |
BuildOptionDict['COMMON'].append(Statement) | |
else: | |
BuildOptionDict['COMMON'] = ['## @AsBuilt'] | |
BuildOptionDict['COMMON'].append(Statement) | |
else: | |
for Arch in BinaryFile.SupArchList: | |
if BuildOptionDict.has_key(Arch): | |
if Statement not in BuildOptionDict[Arch]: | |
BuildOptionDict[Arch].append(Statement) | |
else: | |
BuildOptionDict[Arch] = ['## @AsBuilt'] | |
BuildOptionDict[Arch].append(Statement) | |
Content = GenSection('BuildOptions', BuildOptionDict) | |
return Content | |
## GenBinaries | |
# | |
# | |
def GenBinaries(ModuleObject): | |
NewSectionDict = {} | |
BinariesDict = [] | |
for UserExtension in ModuleObject.GetUserExtensionList(): | |
BinariesDict = UserExtension.GetBinariesDict() | |
if BinariesDict: | |
break | |
for BinaryFile in ModuleObject.GetBinaryFileList(): | |
FileNameObjList = BinaryFile.GetFileNameList() | |
for FileNameObj in FileNameObjList: | |
FileName = ConvertPath(FileNameObj.GetFilename()) | |
FileType = FileNameObj.GetFileType() | |
FFE = FileNameObj.GetFeatureFlag() | |
ArchList = FileNameObj.GetSupArchList() | |
ArchList.sort() | |
SortedArch = ' '.join(ArchList) | |
Key = (FileName, FileType, FFE, SortedArch) | |
if Key in BinariesDict: | |
ValueList = BinariesDict[Key] | |
for ValueItem in ValueList: | |
Statement = GenBinaryStatement(Key, ValueItem) | |
if SortedArch in NewSectionDict: | |
NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement] | |
else: | |
NewSectionDict[SortedArch] = [Statement] | |
# | |
# as we already generated statement for this DictKey here set the Valuelist to be empty | |
# to avoid generate duplicate entries as the DictKey may have multiple entries | |
# | |
BinariesDict[Key] = [] | |
else: | |
if FileType == 'SUBTYPE_GUID' and FileNameObj.GetGuidValue(): | |
Statement = GenBinaryStatement(Key, None, FileNameObj.GetGuidValue()) | |
else: | |
Statement = GenBinaryStatement(Key, None) | |
if SortedArch in NewSectionDict: | |
NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement] | |
else: | |
NewSectionDict[SortedArch] = [Statement] | |
Content = GenSection('Binaries', NewSectionDict) | |
return Content |