3 # This file contained the logical of transfer package object to INF files.
5 # Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
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
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.
21 from hashlib
import md5
22 from Core
.FileHook
import __FileHookOpen__
23 from Library
.StringUtils
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
.StringUtils
import GetUniFileName
47 ## Transfer Module Object to Inf files
49 # Transfer all contents of a standard Module Object to an Inf file
50 # @param ModuleObject: A Module Object
52 def ModuleToInf(ModuleObject
, PackageObject
=None, DistHeader
=None):
53 if not GlobalData
.gWSPKG_LIST
:
54 GlobalData
.gWSPKG_LIST
= GetWorkspacePackage()
56 # Init global information for the file
58 ContainerFile
= ModuleObject
.GetFullPath()
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.
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())
78 for (Lang
, Copyright
) in ModuleObject
.GetCopyright():
81 ModuleCopyright
= Copyright
82 if not ModuleCopyright
and PackageObject
:
83 for (Lang
, Copyright
) in PackageObject
.GetCopyright():
86 ModuleCopyright
= Copyright
87 if not ModuleCopyright
and DistHeader
:
88 for (Lang
, Copyright
) in DistHeader
.GetCopyright():
91 ModuleCopyright
= Copyright
93 for (Lang
, License
) in ModuleObject
.GetLicense():
96 ModuleLicense
= License
97 if not ModuleLicense
and PackageObject
:
98 for (Lang
, License
) in PackageObject
.GetLicense():
101 ModuleLicense
= License
102 if not ModuleLicense
and DistHeader
:
103 for (Lang
, License
) in DistHeader
.GetLicense():
106 ModuleLicense
= License
109 # Generate header comment section of INF file
111 Content
+= GenHeaderCommentSection(ModuleAbstract
,
114 ModuleLicense
).replace('\r\n', '\n')
117 # Generate Binary Header
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
,
139 # Generate MODULE_UNI_FILE for module
141 FileHeader
= GenHeaderCommentSection(ModuleAbstract
, ModuleDescription
, ModuleCopyright
, ModuleLicense
, False, \
142 DT
.TAB_COMMENT_EDK1_SPLIT
)
143 ModuleUniFile
= GenModuleUNIEncodeFile(ModuleObject
, FileHeader
)
145 ModuleObject
.SetModuleUniFile(os
.path
.basename(ModuleUniFile
))
148 # Judge whether the INF file is an AsBuild INF.
150 if ModuleObject
.BinaryModule
:
151 GlobalData
.gIS_BINARY_INF
= True
153 GlobalData
.gIS_BINARY_INF
= False
155 # for each section, maintain a dict, sorted arch will be its key,
156 # statement list will be its data
157 # { 'Arch1 Arch2 Arch3': [statement1, statement2],
158 # 'Arch1' : [statement1, statement3]
161 # Gen section contents
163 Content
+= GenDefines(ModuleObject
)
164 Content
+= GenBuildOptions(ModuleObject
)
165 Content
+= GenLibraryClasses(ModuleObject
)
166 Content
+= GenPackages(ModuleObject
)
167 Content
+= GenPcdSections(ModuleObject
)
168 Content
+= GenSources(ModuleObject
)
169 Content
+= GenProtocolPPiSections(ModuleObject
.GetProtocolList(), True)
170 Content
+= GenProtocolPPiSections(ModuleObject
.GetPpiList(), False)
171 Content
+= GenGuidSections(ModuleObject
.GetGuidList())
172 Content
+= GenBinaries(ModuleObject
)
173 Content
+= GenDepex(ModuleObject
)
174 __UserExtensionsContent
= GenUserExtensions(ModuleObject
)
175 Content
+= __UserExtensionsContent
176 if ModuleObject
.GetEventList() or ModuleObject
.GetBootModeList() or ModuleObject
.GetHobList():
179 # generate [Event], [BootMode], [Hob] section
181 Content
+= GenSpecialSections(ModuleObject
.GetEventList(), 'Event', __UserExtensionsContent
)
182 Content
+= GenSpecialSections(ModuleObject
.GetBootModeList(), 'BootMode', __UserExtensionsContent
)
183 Content
+= GenSpecialSections(ModuleObject
.GetHobList(), 'Hob', __UserExtensionsContent
)
184 SaveFileOnChange(ContainerFile
, Content
, False)
185 if DistHeader
.ReadOnly
:
186 os
.chmod(ContainerFile
, stat
.S_IRUSR|stat
.S_IRGRP|stat
.S_IROTH
)
188 os
.chmod(ContainerFile
, stat
.S_IRUSR|stat
.S_IRGRP|stat
.S_IROTH|stat
.S_IWUSR|stat
.S_IWGRP|stat
.S_IWOTH
)
191 ## GenModuleUNIEncodeFile
192 # GenModuleUNIEncodeFile, default is a UCS-2LE encode file
194 def GenModuleUNIEncodeFile(ModuleObject
, UniFileHeader
='', Encoding
=DT
.TAB_ENCODING_UTF16LE
):
196 OnlyLANGUAGE_EN_X
= True
198 BinaryDescription
= []
200 # If more than one language code is used for any element that would be present in the MODULE_UNI_FILE,
201 # then the MODULE_UNI_FILE must be created.
203 for (Key
, Value
) in ModuleObject
.GetAbstract() + ModuleObject
.GetDescription():
204 if Key
== DT
.TAB_LANGUAGE_EN_X
:
207 OnlyLANGUAGE_EN_X
= False
209 for UserExtension
in ModuleObject
.GetUserExtensionList():
210 if UserExtension
.GetUserID() == DT
.TAB_BINARY_HEADER_USERID \
211 and UserExtension
.GetIdentifier() == DT
.TAB_BINARY_HEADER_IDENTIFIER
:
212 for (Key
, Value
) in UserExtension
.GetBinaryAbstract():
213 if Key
== DT
.TAB_LANGUAGE_EN_X
:
216 OnlyLANGUAGE_EN_X
= False
217 BinaryAbstract
.append((Key
, Value
))
218 for (Key
, Value
) in UserExtension
.GetBinaryDescription():
219 if Key
== DT
.TAB_LANGUAGE_EN_X
:
222 OnlyLANGUAGE_EN_X
= False
223 BinaryDescription
.append((Key
, Value
))
228 elif OnlyLANGUAGE_EN_X
:
231 ModuleObject
.UNIFlag
= True
232 ContainerFile
= GetUniFileName(os
.path
.dirname(ModuleObject
.GetFullPath()), ModuleObject
.GetBaseName())
234 if not os
.path
.exists(os
.path
.dirname(ModuleObject
.GetFullPath())):
235 os
.makedirs(os
.path
.dirname(ModuleObject
.GetFullPath()))
237 Content
= UniFileHeader
+ '\r\n'
240 Content
+= FormatUniEntry('#string ' + DT
.TAB_INF_ABSTRACT
, ModuleObject
.GetAbstract(), ContainerFile
) + '\r\n'
242 Content
+= FormatUniEntry('#string ' + DT
.TAB_INF_DESCRIPTION
, ModuleObject
.GetDescription(), ContainerFile
) \
245 BinaryAbstractString
= FormatUniEntry('#string ' + DT
.TAB_INF_BINARY_ABSTRACT
, BinaryAbstract
, ContainerFile
)
246 if BinaryAbstractString
:
247 Content
+= BinaryAbstractString
+ '\r\n'
249 BinaryDescriptionString
= FormatUniEntry('#string ' + DT
.TAB_INF_BINARY_DESCRIPTION
, BinaryDescription
, \
251 if BinaryDescriptionString
:
252 Content
+= BinaryDescriptionString
+ '\r\n'
254 if not os
.path
.exists(ContainerFile
):
255 File
= codecs
.open(ContainerFile
, 'wb', Encoding
)
256 File
.write(u
'\uFEFF' + Content
)
258 Md5Signature
= md5(__FileHookOpen__(str(ContainerFile
), 'rb').read())
259 Md5Sum
= Md5Signature
.hexdigest()
260 if (ContainerFile
, Md5Sum
) not in ModuleObject
.FileList
:
261 ModuleObject
.FileList
.append((ContainerFile
, Md5Sum
))
264 def GenDefines(ModuleObject
):
266 # generate [Defines] section
272 for UserExtension
in ModuleObject
.GetUserExtensionList():
273 DefinesDict
= UserExtension
.GetDefinesDict()
276 for Statement
in DefinesDict
:
277 if len(Statement
.split(DT
.TAB_EQUAL_SPLIT
)) > 1:
278 Statement
= (u
'%s ' % Statement
.split(DT
.TAB_EQUAL_SPLIT
, 1)[0]).ljust(LeftOffset
) \
279 + u
'= %s' % Statement
.split(DT
.TAB_EQUAL_SPLIT
, 1)[1].lstrip()
280 SortedArch
= DT
.TAB_ARCH_COMMON
281 if Statement
.strip().startswith(DT
.TAB_INF_DEFINES_CUSTOM_MAKEFILE
):
282 pos
= Statement
.find(DT
.TAB_VALUE_SPLIT
)
284 pos
= Statement
.find(DT
.TAB_EQUAL_SPLIT
)
285 Makefile
= ConvertPath(Statement
[pos
+ 1:].strip())
286 Statement
= Statement
[:pos
+ 1] + ' ' + Makefile
287 if SortedArch
in NewSectionDict
:
288 NewSectionDict
[SortedArch
] = NewSectionDict
[SortedArch
] + [Statement
]
290 NewSectionDict
[SortedArch
] = [Statement
]
291 SpecialStatementList
= []
293 # TAB_INF_DEFINES_INF_VERSION
294 Statement
= (u
'%s ' % DT
.TAB_INF_DEFINES_INF_VERSION
).ljust(LeftOffset
) + u
'= %s' % '0x00010017'
295 SpecialStatementList
.append(Statement
)
298 BaseName
= ModuleObject
.GetBaseName()
299 if BaseName
.startswith('.') or BaseName
.startswith('-'):
300 BaseName
= '_' + BaseName
301 Statement
= (u
'%s ' % DT
.TAB_INF_DEFINES_BASE_NAME
).ljust(LeftOffset
) + u
'= %s' % BaseName
302 SpecialStatementList
.append(Statement
)
304 # TAB_INF_DEFINES_FILE_GUID
305 Statement
= (u
'%s ' % DT
.TAB_INF_DEFINES_FILE_GUID
).ljust(LeftOffset
) + u
'= %s' % ModuleObject
.GetGuid()
306 SpecialStatementList
.append(Statement
)
308 # TAB_INF_DEFINES_VERSION_STRING
309 Statement
= (u
'%s ' % DT
.TAB_INF_DEFINES_VERSION_STRING
).ljust(LeftOffset
) + u
'= %s' % ModuleObject
.GetVersion()
310 SpecialStatementList
.append(Statement
)
312 # TAB_INF_DEFINES_VERSION_STRING
313 if ModuleObject
.UNIFlag
:
314 Statement
= (u
'%s ' % DT
.TAB_INF_DEFINES_MODULE_UNI_FILE
).ljust(LeftOffset
) + \
315 u
'= %s' % ModuleObject
.GetModuleUniFile()
316 SpecialStatementList
.append(Statement
)
318 # TAB_INF_DEFINES_MODULE_TYPE
319 if ModuleObject
.GetModuleType():
320 Statement
= (u
'%s ' % DT
.TAB_INF_DEFINES_MODULE_TYPE
).ljust(LeftOffset
) + u
'= %s' % ModuleObject
.GetModuleType()
321 SpecialStatementList
.append(Statement
)
323 # TAB_INF_DEFINES_PCD_IS_DRIVER
324 if ModuleObject
.GetPcdIsDriver():
325 Statement
= (u
'%s ' % DT
.TAB_INF_DEFINES_PCD_IS_DRIVER
).ljust(LeftOffset
) + \
326 u
'= %s' % ModuleObject
.GetPcdIsDriver()
327 SpecialStatementList
.append(Statement
)
329 # TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION
330 if ModuleObject
.GetUefiSpecificationVersion():
331 Statement
= (u
'%s ' % DT
.TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION
).ljust(LeftOffset
) + \
332 u
'= %s' % ModuleObject
.GetUefiSpecificationVersion()
333 SpecialStatementList
.append(Statement
)
335 # TAB_INF_DEFINES_PI_SPECIFICATION_VERSION
336 if ModuleObject
.GetPiSpecificationVersion():
337 Statement
= (u
'%s ' % DT
.TAB_INF_DEFINES_PI_SPECIFICATION_VERSION
).ljust(LeftOffset
) + \
338 u
'= %s' % ModuleObject
.GetPiSpecificationVersion()
339 SpecialStatementList
.append(Statement
)
342 for LibraryClass
in ModuleObject
.GetLibraryClassList():
343 if LibraryClass
.GetUsage() == DT
.USAGE_ITEM_PRODUCES
or \
344 LibraryClass
.GetUsage() == DT
.USAGE_ITEM_SOMETIMES_PRODUCES
:
345 Statement
= (u
'%s ' % DT
.TAB_INF_DEFINES_LIBRARY_CLASS
).ljust(LeftOffset
) + \
346 u
'= %s' % LibraryClass
.GetLibraryClass()
347 if LibraryClass
.GetSupModuleList():
348 Statement
+= '|' + DT
.TAB_SPACE_SPLIT
.join(l
for l
in LibraryClass
.GetSupModuleList())
349 SpecialStatementList
.append(Statement
)
352 for SpecItem
in ModuleObject
.GetSpecList():
353 Spec
, Version
= SpecItem
354 Spec
= ConvertSpec(Spec
)
355 Statement
= '%s %s = %s' % (DT
.TAB_INF_DEFINES_SPEC
, Spec
, Version
)
356 SpecialStatementList
.append(Statement
)
360 for Extern
in ModuleObject
.GetExternList():
361 ArchList
= Extern
.GetSupArchList()
362 EntryPoint
= Extern
.GetEntryPoint()
363 UnloadImage
= Extern
.GetUnloadImage()
364 Constructor
= Extern
.GetConstructor()
365 Destructor
= Extern
.GetDestructor()
366 HelpStringList
= Extern
.GetHelpTextList()
367 FFE
= Extern
.GetFeatureFlag()
368 ExternList
.append([ArchList
, EntryPoint
, UnloadImage
, Constructor
, Destructor
, FFE
, HelpStringList
])
370 # Add VALID_ARCHITECTURES information
372 ValidArchStatement
= None
373 if ModuleObject
.SupArchList
:
374 ValidArchStatement
= '\n' + '# ' + '\n'
375 ValidArchStatement
+= '# The following information is for reference only and not required by the build tools.\n'
376 ValidArchStatement
+= '# ' + '\n'
377 ValidArchStatement
+= '# VALID_ARCHITECTURES = %s' % (' '.join(ModuleObject
.SupArchList
)) + '\n'
378 ValidArchStatement
+= '# '
379 if DT
.TAB_ARCH_COMMON
not in NewSectionDict
:
380 NewSectionDict
[DT
.TAB_ARCH_COMMON
] = []
381 NewSectionDict
[DT
.TAB_ARCH_COMMON
] = NewSectionDict
[DT
.TAB_ARCH_COMMON
] + SpecialStatementList
382 GenMetaFileMisc
.AddExternToDefineSec(NewSectionDict
, DT
.TAB_ARCH_COMMON
, ExternList
)
383 if ValidArchStatement
is not None:
384 NewSectionDict
[DT
.TAB_ARCH_COMMON
] = NewSectionDict
[DT
.TAB_ARCH_COMMON
] + [ValidArchStatement
]
385 Content
+= GenSection('Defines', NewSectionDict
)
388 def GenLibraryClasses(ModuleObject
):
390 # generate [LibraryClasses] section
394 if not GlobalData
.gIS_BINARY_INF
:
395 for LibraryClass
in ModuleObject
.GetLibraryClassList():
396 if LibraryClass
.GetUsage() == DT
.USAGE_ITEM_PRODUCES
:
399 # Generate generic comment
401 HelpTextList
= LibraryClass
.GetHelpTextList()
402 HelpStr
= _GetHelpStr(HelpTextList
)
403 CommentStr
= GenGenericCommentF(HelpStr
)
404 Statement
= CommentStr
405 Name
= LibraryClass
.GetLibraryClass()
406 FFE
= LibraryClass
.GetFeatureFlag()
409 Statement
+= '|' + FFE
410 ModuleList
= LibraryClass
.GetSupModuleList()
411 ArchList
= LibraryClass
.GetSupArchList()
412 for Index
in range(0, len(ArchList
)):
413 ArchList
[Index
] = ConvertArchForInstall(ArchList
[Index
])
415 SortedArch
= ' '.join(ArchList
)
417 if not ModuleList
or IsAllModuleList(ModuleList
):
418 KeyList
= [SortedArch
]
420 ModuleString
= DT
.TAB_VALUE_SPLIT
.join(l
for l
in ModuleList
)
422 SortedArch
= DT
.TAB_ARCH_COMMON
423 KeyList
= [SortedArch
+ '.' + ModuleString
]
425 KeyList
= [Arch
+ '.' + ModuleString
for Arch
in ArchList
]
427 if Key
in NewSectionDict
:
428 NewSectionDict
[Key
] = NewSectionDict
[Key
] + [Statement
]
430 NewSectionDict
[Key
] = [Statement
]
431 Content
+= GenSection('LibraryClasses', NewSectionDict
)
433 LibraryClassDict
= {}
434 for BinaryFile
in ModuleObject
.GetBinaryFileList():
435 if not BinaryFile
.AsBuiltList
:
437 for LibraryItem
in BinaryFile
.AsBuiltList
[0].LibraryInstancesList
:
438 Statement
= '# Guid: ' + LibraryItem
.Guid
+ ' Version: ' + LibraryItem
.Version
440 if len(BinaryFile
.SupArchList
) == 0:
441 if 'COMMON' in LibraryClassDict
and Statement
not in LibraryClassDict
['COMMON']:
442 LibraryClassDict
['COMMON'].append(Statement
)
444 LibraryClassDict
['COMMON'] = ['## @LIB_INSTANCES']
445 LibraryClassDict
['COMMON'].append(Statement
)
447 for Arch
in BinaryFile
.SupArchList
:
448 if Arch
in LibraryClassDict
:
449 if Statement
not in LibraryClassDict
[Arch
]:
450 LibraryClassDict
[Arch
].append(Statement
)
454 LibraryClassDict
[Arch
] = ['## @LIB_INSTANCES']
455 LibraryClassDict
[Arch
].append(Statement
)
456 Content
+= GenSection('LibraryClasses', LibraryClassDict
)
460 def GenPackages(ModuleObject
):
463 # generate [Packages] section
465 NewSectionDict
= Sdict()
466 WorkspaceDir
= GlobalData
.gWORKSPACE
467 for PackageDependency
in ModuleObject
.GetPackageDependencyList():
469 # Generate generic comment
472 HelpText
= PackageDependency
.GetHelpText()
474 HelpStr
= HelpText
.GetString()
475 CommentStr
= GenGenericCommentF(HelpStr
)
476 Statement
= CommentStr
477 Guid
= PackageDependency
.GetGuid()
478 Version
= PackageDependency
.GetVersion()
479 FFE
= PackageDependency
.GetFeatureFlag()
482 # find package path/name
484 for PkgInfo
in GlobalData
.gWSPKG_LIST
:
485 if Guid
== PkgInfo
[1]:
486 if (not Version
) or (Version
== PkgInfo
[2]):
492 RelaPath
= GetRelativePath(Path
, WorkspaceDir
)
493 Statement
+= RelaPath
.replace('\\', '/')
495 Statement
+= '|' + FFE
496 ArchList
= sorted(PackageDependency
.GetSupArchList())
497 SortedArch
= ' '.join(ArchList
)
498 if SortedArch
in NewSectionDict
:
499 NewSectionDict
[SortedArch
] = NewSectionDict
[SortedArch
] + [Statement
]
501 NewSectionDict
[SortedArch
] = [Statement
]
502 Content
+= GenSection('Packages', NewSectionDict
)
505 def GenSources(ModuleObject
):
507 # generate [Sources] section
511 for Source
in ModuleObject
.GetSourceFileList():
512 SourceFile
= Source
.GetSourceFile()
513 Family
= Source
.GetFamily()
514 FeatureFlag
= Source
.GetFeatureFlag()
515 SupArchList
= sorted(Source
.GetSupArchList())
516 SortedArch
= ' '.join(SupArchList
)
517 Statement
= GenSourceStatement(ConvertPath(SourceFile
), Family
, FeatureFlag
)
518 if SortedArch
in NewSectionDict
:
519 NewSectionDict
[SortedArch
] = NewSectionDict
[SortedArch
] + [Statement
]
521 NewSectionDict
[SortedArch
] = [Statement
]
522 Content
+= GenSection('Sources', NewSectionDict
)
526 def GenDepex(ModuleObject
):
528 # generate [Depex] section
530 NewSectionDict
= Sdict()
532 for Depex
in ModuleObject
.GetPeiDepex() + ModuleObject
.GetDxeDepex() + ModuleObject
.GetSmmDepex():
533 HelpTextList
= Depex
.GetHelpTextList()
534 HelpStr
= _GetHelpStr(HelpTextList
)
535 CommentStr
= GenGenericCommentF(HelpStr
)
536 SupArchList
= Depex
.GetSupArchList()
537 SupModList
= Depex
.GetModuleType()
538 Expression
= Depex
.GetDepex()
539 Statement
= CommentStr
+ Expression
543 SupArchList
.append(DT
.TAB_ARCH_COMMON
.lower())
545 KeyList
= SupArchList
547 for ModuleType
in SupModList
:
548 for Arch
in SupArchList
:
549 KeyList
.append(ConvertArchForInstall(Arch
) + '.' + ModuleType
)
551 if Key
in NewSectionDict
:
552 NewSectionDict
[Key
] = NewSectionDict
[Key
] + [Statement
]
554 NewSectionDict
[Key
] = [Statement
]
555 Content
+= GenSection('Depex', NewSectionDict
, False)
562 def GenUserExtensions(ModuleObject
):
564 for UserExtension
in ModuleObject
.GetUserExtensionList():
565 if UserExtension
.GetUserID() == DT
.TAB_BINARY_HEADER_USERID
and \
566 UserExtension
.GetIdentifier() == DT
.TAB_BINARY_HEADER_IDENTIFIER
:
568 if UserExtension
.GetIdentifier() == 'Depex':
570 Statement
= UserExtension
.GetStatement()
571 # Comment the code to support user extension without any statement just the section header in []
574 ArchList
= UserExtension
.GetSupArchList()
575 for Index
in range(0, len(ArchList
)):
576 ArchList
[Index
] = ConvertArchForInstall(ArchList
[Index
])
580 if UserExtension
.GetUserID():
581 CommonPreFix
= UserExtension
.GetUserID()
582 if CommonPreFix
.find('.') > -1:
583 CommonPreFix
= '"' + CommonPreFix
+ '"'
584 if UserExtension
.GetIdentifier():
585 CommonPreFix
+= '.' + '"' + UserExtension
.GetIdentifier() + '"'
587 KeyList
= [CommonPreFix
+ '.' + Arch
for Arch
in ArchList
]
589 KeyList
= [CommonPreFix
]
591 if Key
in NewSectionDict
:
592 NewSectionDict
[Key
] = NewSectionDict
[Key
] + [Statement
]
594 NewSectionDict
[Key
] = [Statement
]
595 Content
= GenSection('UserExtensions', NewSectionDict
, False)
601 # @param SourceFile: string of source file path/name
602 # @param Family: string of source file family field
603 # @param FeatureFlag: string of source file FeatureFlag field
604 # @param TagName: string of source file TagName field
605 # @param ToolCode: string of source file ToolCode field
606 # @param HelpStr: string of source file HelpStr field
608 # @retval Statement: The generated statement for source
610 def GenSourceStatement(SourceFile
, Family
, FeatureFlag
, TagName
=None,
611 ToolCode
=None, HelpStr
=None):
614 Statement
+= GenGenericCommentF(HelpStr
)
616 # format of SourceFile|Family|TagName|ToolCode|FeatureFlag
618 Statement
+= SourceFile
626 Statement
+= '|' + Family
+ '|' + TagName
+ '|' + ToolCode
+ '|' + FeatureFlag
628 Statement
+= '|' + Family
+ '|' + TagName
+ '|' + ToolCode
630 Statement
+= '|' + Family
+ '|' + TagName
632 Statement
+= '|' + Family
637 # @param Key: (FileName, FileType, FFE, SortedArch)
638 # @param Value: (Target, Family, TagName, Comment)
641 def GenBinaryStatement(Key
, Value
, SubTypeGuidValue
=None):
642 (FileName
, FileType
, FFE
, SortedArch
) = Key
646 (Target
, Family
, TagName
, Comment
) = Value
653 Statement
= GenGenericCommentF(Comment
)
656 if FileType
== 'SUBTYPE_GUID' and SubTypeGuidValue
:
657 Statement
+= FileType
+ '|' + SubTypeGuidValue
+ '|' + FileName
659 Statement
+= FileType
+ '|' + FileName
660 if FileType
in DT
.BINARY_FILE_TYPE_UI_LIST
+ DT
.BINARY_FILE_TYPE_VER_LIST
:
662 Statement
+= '|' + Target
+ '|' + FFE
664 Statement
+= '|' + Target
667 Statement
+= '|' + Target
+ '|' + Family
+ '|' + TagName
+ '|' + FFE
669 Statement
+= '|' + Target
+ '|' + Family
+ '|' + TagName
671 Statement
+= '|' + Target
+ '|' + Family
673 Statement
+= '|' + Target
677 # @param GuidObjList: List of GuidObject
678 # @retVal Content: The generated section contents
680 def GenGuidSections(GuidObjList
):
682 # generate [Guids] section
686 for Guid
in GuidObjList
:
687 HelpTextList
= Guid
.GetHelpTextList()
688 HelpStr
= _GetHelpStr(HelpTextList
)
689 CName
= Guid
.GetCName()
690 FFE
= Guid
.GetFeatureFlag()
693 Statement
+= '|' + FFE
694 Usage
= Guid
.GetUsage()
695 GuidType
= Guid
.GetGuidTypeList()[0]
696 VariableName
= Guid
.GetVariableName()
698 # Differentiate the generic comment and usage comment as multiple generic comment need to be put at first
700 if Usage
== DT
.ITEM_UNDEFINED
and GuidType
== DT
.ITEM_UNDEFINED
:
701 # generate list of generic comment
702 Comment
= GenGenericCommentF(HelpStr
)
704 # generate list of other comment
705 Comment
= HelpStr
.replace('\n', ' ')
706 Comment
= Comment
.strip()
708 Comment
= ' # ' + Comment
711 if Usage
!= DT
.ITEM_UNDEFINED
and GuidType
== DT
.ITEM_UNDEFINED
:
712 Comment
= '## ' + Usage
+ Comment
713 elif GuidType
== 'Variable':
714 Comment
= '## ' + Usage
+ ' ## ' + GuidType
+ ':' + VariableName
+ Comment
716 Comment
= '## ' + Usage
+ ' ## ' + GuidType
+ Comment
721 # merge duplicate items
723 ArchList
= sorted(Guid
.GetSupArchList())
724 SortedArch
= ' '.join(ArchList
)
725 if (Statement
, SortedArch
) in GuidDict
:
726 PreviousComment
= GuidDict
[Statement
, SortedArch
]
727 Comment
= PreviousComment
+ Comment
728 GuidDict
[Statement
, SortedArch
] = Comment
729 NewSectionDict
= GenMetaFileMisc
.TransferDict(GuidDict
, 'INF_GUID')
731 # generate the section contents
734 Content
= GenSection('Guids', NewSectionDict
)
738 ## GenProtocolPPiSections
740 # @param ObjList: List of ProtocolObject or Ppi Object
741 # @retVal Content: The generated section contents
743 def GenProtocolPPiSections(ObjList
, IsProtocol
):
746 for Object
in ObjList
:
747 HelpTextList
= Object
.GetHelpTextList()
748 HelpStr
= _GetHelpStr(HelpTextList
)
749 CName
= Object
.GetCName()
750 FFE
= Object
.GetFeatureFlag()
753 Statement
+= '|' + FFE
754 Usage
= Object
.GetUsage()
755 Notify
= Object
.GetNotify()
757 # Differentiate the generic comment and usage comment as consecutive generic comment need to be put together
759 if Usage
== DT
.ITEM_UNDEFINED
and Notify
== '':
760 # generate list of generic comment
761 Comment
= GenGenericCommentF(HelpStr
)
763 # generate list of other comment
764 Comment
= HelpStr
.replace('\n', ' ')
765 Comment
= Comment
.strip()
767 Comment
= ' # ' + Comment
770 if Usage
== DT
.ITEM_UNDEFINED
and not Comment
and Notify
== '':
774 Comment
= '## ' + Usage
+ ' ## ' + 'NOTIFY' + Comment
776 Comment
= '## ' + Usage
+ Comment
780 # merge duplicate items
782 ArchList
= sorted(Object
.GetSupArchList())
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')
790 # generate the section contents
794 Content
= GenSection('Protocols', NewSectionDict
)
796 Content
= GenSection('Ppis', NewSectionDict
)
803 def GenPcdSections(ModuleObject
):
805 if not GlobalData
.gIS_BINARY_INF
:
807 # for each Pcd Itemtype, maintain a dict so the same type will be grouped
811 for Pcd
in ModuleObject
.GetPcdList():
812 HelpTextList
= Pcd
.GetHelpTextList()
813 HelpStr
= _GetHelpStr(HelpTextList
)
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
]
823 ItemTypeDict
[ItemType
] = Dict
824 FFE
= Pcd
.GetFeatureFlag()
825 Statement
+= TokenSpaceGuidCName
+ '.' + CName
827 Statement
+= '|' + DefaultValue
829 Statement
+= '|' + FFE
831 Statement
+= '||' + FFE
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
)
843 # generate list of other comment
844 Comment
= HelpStr
.replace('\n', ' ')
845 Comment
= Comment
.strip()
847 Comment
= ' # ' + Comment
850 Comment
= '## ' + Usage
+ Comment
854 # Merge duplicate entries
856 ArchList
= sorted(Pcd
.GetSupArchList())
857 SortedArch
= ' '.join(ArchList
)
858 if (Statement
, SortedArch
) in Dict
:
859 PreviousComment
= Dict
[Statement
, SortedArch
]
860 Comment
= PreviousComment
+ Comment
861 Dict
[Statement
, SortedArch
] = Comment
862 for ItemType
in ItemTypeDict
:
863 # First we need to transfer the Dict to use SortedArch as key
864 Dict
= ItemTypeDict
[ItemType
]
865 NewSectionDict
= GenMetaFileMisc
.TransferDict(Dict
, 'INF_PCD')
867 Content
+= GenSection(ItemType
, NewSectionDict
)
869 # For AsBuild INF files
872 Content
+= GenAsBuiltPacthPcdSections(ModuleObject
)
873 Content
+= GenAsBuiltPcdExSections(ModuleObject
)
880 def GenAsBuiltPacthPcdSections(ModuleObject
):
882 for BinaryFile
in ModuleObject
.GetBinaryFileList():
883 if not BinaryFile
.AsBuiltList
:
885 for PatchPcd
in BinaryFile
.AsBuiltList
[0].PatchPcdList
:
887 PcdCName
= PatchPcd
.CName
888 PcdValue
= PatchPcd
.DefaultValue
889 PcdOffset
= PatchPcd
.Offset
890 TokenSpaceGuidValue
= PatchPcd
.TokenSpaceGuidValue
891 Token
= PatchPcd
.Token
892 HelpTextList
= PatchPcd
.HelpTextList
894 for HelpStringItem
in HelpTextList
:
895 for HelpLine
in GetSplitValueList(HelpStringItem
.String
, '\n'):
896 HelpString
+= '## ' + HelpLine
+ '\n'
897 TokenSpaceName
, PcdCName
= GenMetaFileMisc
.ObtainPcdName(ModuleObject
.PackageDependencyList
,
900 if TokenSpaceName
== '' or PcdCName
== '':
902 ToolError
.RESOURCE_NOT_AVAILABLE
,
903 ST
.ERR_INSTALL_FILE_DEC_FILE_ERROR
% (TokenSpaceGuidValue
, Token
),
904 File
=ModuleObject
.GetFullPath())
905 Statement
= HelpString
+ TokenSpaceName
+ '.' + PcdCName
+ ' | ' + PcdValue
+ ' | ' + \
906 PcdOffset
+ DT
.TAB_SPACE_SPLIT
908 # Use binary file's Arch to be Pcd's Arch
911 FileNameObjList
= BinaryFile
.GetFileNameList()
913 ArchList
= FileNameObjList
[0].GetSupArchList()
914 if len(ArchList
) == 0:
915 if DT
.TAB_ARCH_COMMON
in PatchPcdDict
:
916 if Statement
not in PatchPcdDict
[DT
.TAB_ARCH_COMMON
]:
917 PatchPcdDict
[DT
.TAB_ARCH_COMMON
].append(Statement
)
919 PatchPcdDict
[DT
.TAB_ARCH_COMMON
] = [Statement
]
921 for Arch
in ArchList
:
922 if Arch
in PatchPcdDict
:
923 if Statement
not in PatchPcdDict
[Arch
]:
924 PatchPcdDict
[Arch
].append(Statement
)
926 PatchPcdDict
[Arch
] = [Statement
]
927 return GenSection(DT
.TAB_INF_PATCH_PCD
, PatchPcdDict
)
931 def GenAsBuiltPcdExSections(ModuleObject
):
933 for BinaryFile
in ModuleObject
.GetBinaryFileList():
934 if not BinaryFile
.AsBuiltList
:
936 for PcdExItem
in BinaryFile
.AsBuiltList
[0].PcdExValueList
:
938 PcdCName
= PcdExItem
.CName
939 TokenSpaceGuidValue
= PcdExItem
.TokenSpaceGuidValue
940 Token
= PcdExItem
.Token
941 HelpTextList
= PcdExItem
.HelpTextList
943 for HelpStringItem
in HelpTextList
:
944 for HelpLine
in GetSplitValueList(HelpStringItem
.String
, '\n'):
945 HelpString
+= '## ' + HelpLine
+ '\n'
946 TokenSpaceName
, PcdCName
= GenMetaFileMisc
.ObtainPcdName(ModuleObject
.PackageDependencyList
,
947 TokenSpaceGuidValue
, Token
)
948 if TokenSpaceName
== '' or PcdCName
== '':
950 ToolError
.RESOURCE_NOT_AVAILABLE
,
951 ST
.ERR_INSTALL_FILE_DEC_FILE_ERROR
% (TokenSpaceGuidValue
, Token
),
952 File
=ModuleObject
.GetFullPath())
954 Statement
= HelpString
+ TokenSpaceName
+ DT
.TAB_SPLIT
+ PcdCName
+ DT
.TAB_SPACE_SPLIT
957 # Use binary file's Arch to be Pcd's Arch
960 FileNameObjList
= BinaryFile
.GetFileNameList()
962 ArchList
= FileNameObjList
[0].GetSupArchList()
964 if len(ArchList
) == 0:
965 if 'COMMON' in PcdExDict
:
966 PcdExDict
['COMMON'].append(Statement
)
968 PcdExDict
['COMMON'] = [Statement
]
970 for Arch
in ArchList
:
971 if Arch
in PcdExDict
:
972 if Statement
not in PcdExDict
[Arch
]:
973 PcdExDict
[Arch
].append(Statement
)
975 PcdExDict
[Arch
] = [Statement
]
976 return GenSection('PcdEx', PcdExDict
)
978 ## GenSpecialSections
979 # generate special sections for Event/BootMode/Hob
981 def GenSpecialSections(ObjectList
, SectionName
, UserExtensionsContent
=''):
987 for Obj
in ObjectList
:
992 HelpTextList
= Obj
.GetHelpTextList()
993 HelpStr
= _GetHelpStr(HelpTextList
)
994 CommentStr
= GenGenericCommentF(HelpStr
)
995 if SectionName
== 'Hob':
996 Type
= Obj
.GetHobType()
997 elif SectionName
== 'Event':
998 Type
= Obj
.GetEventType()
999 elif SectionName
== 'BootMode':
1000 Type
= Obj
.GetSupportedBootModes()
1003 Usage
= Obj
.GetUsage()
1005 # If the content already in UserExtensionsContent then ignore
1006 if '[%s]' % SectionName
in UserExtensionsContent
and Type
in UserExtensionsContent
:
1009 Statement
= ' ' + Type
+ ' ## ' + Usage
1010 if CommentStr
in ['#\n', '#\n#\n']:
1011 CommentStr
= '#\n#\n#\n'
1013 # the first head comment line should start with '##\n', if it starts with '#\n', then add one '#'
1014 # else add '##\n' to meet the format defined in INF spec
1016 if CommentStr
.startswith('#\n'):
1017 CommentStr
= '#' + CommentStr
1019 CommentStr
= '##\n' + CommentStr
1020 if CommentStr
and not CommentStr
.endswith('\n#\n'):
1021 CommentStr
= CommentStr
+ '#\n'
1022 NewStateMent
= CommentStr
+ Statement
1023 SupArch
= sorted(Obj
.GetSupArchList())
1024 SortedArch
= ' '.join(SupArch
)
1025 if SortedArch
in NewSectionDict
:
1026 NewSectionDict
[SortedArch
] = NewSectionDict
[SortedArch
] + [NewStateMent
]
1028 NewSectionDict
[SortedArch
] = [NewStateMent
]
1029 SectionContent
= GenSection(SectionName
, NewSectionDict
)
1030 SectionContent
= SectionContent
.strip()
1032 Content
= '# ' + ('\n' + '# ').join(GetSplitValueList(SectionContent
, '\n'))
1033 Content
= Content
.lstrip()
1035 # add a return to differentiate it between other possible sections
1043 def GenBuildOptions(ModuleObject
):
1045 if not ModuleObject
.BinaryModule
:
1047 # generate [BuildOptions] section
1050 for UserExtension
in ModuleObject
.GetUserExtensionList():
1051 BuildOptionDict
= UserExtension
.GetBuildOptionDict()
1052 if not BuildOptionDict
:
1054 for Arch
in BuildOptionDict
:
1055 if Arch
in NewSectionDict
:
1056 NewSectionDict
[Arch
] = NewSectionDict
[Arch
] + [BuildOptionDict
[Arch
]]
1058 NewSectionDict
[Arch
] = [BuildOptionDict
[Arch
]]
1059 Content
= GenSection('BuildOptions', NewSectionDict
)
1061 BuildOptionDict
= {}
1062 for BinaryFile
in ModuleObject
.GetBinaryFileList():
1063 if not BinaryFile
.AsBuiltList
:
1065 for BuilOptionItem
in BinaryFile
.AsBuiltList
[0].BinaryBuildFlagList
:
1066 Statement
= '#' + BuilOptionItem
.AsBuiltOptionFlags
1067 if len(BinaryFile
.SupArchList
) == 0:
1068 if 'COMMON' in BuildOptionDict
:
1069 if Statement
not in BuildOptionDict
['COMMON']:
1070 BuildOptionDict
['COMMON'].append(Statement
)
1072 BuildOptionDict
['COMMON'] = ['## @AsBuilt']
1073 BuildOptionDict
['COMMON'].append(Statement
)
1075 for Arch
in BinaryFile
.SupArchList
:
1076 if Arch
in BuildOptionDict
:
1077 if Statement
not in BuildOptionDict
[Arch
]:
1078 BuildOptionDict
[Arch
].append(Statement
)
1080 BuildOptionDict
[Arch
] = ['## @AsBuilt']
1081 BuildOptionDict
[Arch
].append(Statement
)
1082 Content
= GenSection('BuildOptions', BuildOptionDict
)
1088 def GenBinaries(ModuleObject
):
1091 for UserExtension
in ModuleObject
.GetUserExtensionList():
1092 BinariesDict
= UserExtension
.GetBinariesDict()
1095 for BinaryFile
in ModuleObject
.GetBinaryFileList():
1096 FileNameObjList
= BinaryFile
.GetFileNameList()
1097 for FileNameObj
in FileNameObjList
:
1098 FileName
= ConvertPath(FileNameObj
.GetFilename())
1099 FileType
= FileNameObj
.GetFileType()
1100 FFE
= FileNameObj
.GetFeatureFlag()
1101 ArchList
= sorted(FileNameObj
.GetSupArchList())
1102 SortedArch
= ' '.join(ArchList
)
1103 Key
= (FileName
, FileType
, FFE
, SortedArch
)
1104 if Key
in BinariesDict
:
1105 ValueList
= BinariesDict
[Key
]
1106 for ValueItem
in ValueList
:
1107 Statement
= GenBinaryStatement(Key
, ValueItem
)
1108 if SortedArch
in NewSectionDict
:
1109 NewSectionDict
[SortedArch
] = NewSectionDict
[SortedArch
] + [Statement
]
1111 NewSectionDict
[SortedArch
] = [Statement
]
1113 # as we already generated statement for this DictKey here set the Valuelist to be empty
1114 # to avoid generate duplicate entries as the DictKey may have multiple entries
1116 BinariesDict
[Key
] = []
1118 if FileType
== 'SUBTYPE_GUID' and FileNameObj
.GetGuidValue():
1119 Statement
= GenBinaryStatement(Key
, None, FileNameObj
.GetGuidValue())
1121 Statement
= GenBinaryStatement(Key
, None)
1122 if SortedArch
in NewSectionDict
:
1123 NewSectionDict
[SortedArch
] = NewSectionDict
[SortedArch
] + [Statement
]
1125 NewSectionDict
[SortedArch
] = [Statement
]
1126 Content
= GenSection('Binaries', NewSectionDict
)