]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/UPT/GenMetaFile/GenInfFile.py
BaseTools: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / BaseTools / Source / Python / UPT / GenMetaFile / GenInfFile.py
1 ## @file GenInfFile.py
2 #
3 # This file contained the logical of transfer package object to INF files.
4 #
5 # Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
6 #
7 # SPDX-License-Identifier: BSD-2-Clause-Patent
8 #
9 '''
10 GenInf
11 '''
12 import os
13 import stat
14 import codecs
15 from hashlib import md5
16 from Core.FileHook import __FileHookOpen__
17 from Library.StringUtils import GetSplitValueList
18 from Library.Parsing import GenSection
19 from Library.Parsing import GetWorkspacePackage
20 from Library.Parsing import ConvertArchForInstall
21 from Library.Misc import SaveFileOnChange
22 from Library.Misc import IsAllModuleList
23 from Library.Misc import Sdict
24 from Library.Misc import ConvertPath
25 from Library.Misc import ConvertSpec
26 from Library.Misc import GetRelativePath
27 from Library.Misc import GetLocalValue
28 from Library.CommentGenerating import GenHeaderCommentSection
29 from Library.CommentGenerating import GenGenericCommentF
30 from Library.CommentGenerating import _GetHelpStr
31 from Library import GlobalData
32 from Logger import StringTable as ST
33 from Logger import ToolError
34 import Logger.Log as Logger
35 from Library import DataType as DT
36 from GenMetaFile import GenMetaFileMisc
37 from Library.UniClassObject import FormatUniEntry
38 from Library.StringUtils import GetUniFileName
39
40
41 ## Transfer Module Object to Inf files
42 #
43 # Transfer all contents of a standard Module Object to an Inf file
44 # @param ModuleObject: A Module Object
45 #
46 def ModuleToInf(ModuleObject, PackageObject=None, DistHeader=None):
47 if not GlobalData.gWSPKG_LIST:
48 GlobalData.gWSPKG_LIST = GetWorkspacePackage()
49 #
50 # Init global information for the file
51 #
52 ContainerFile = ModuleObject.GetFullPath()
53
54 Content = ''
55 #
56 # Generate file header, If any Abstract, Description, Copyright or License XML elements are missing,
57 # should 1) use the Abstract, Description, Copyright or License from the PackageSurfaceArea.Header elements
58 # that the module belongs to, or 2) if this is a stand-alone module that is not included in a PackageSurfaceArea,
59 # use the abstract, description, copyright or license from the DistributionPackage.Header elements.
60 #
61 ModuleAbstract = GetLocalValue(ModuleObject.GetAbstract())
62 if not ModuleAbstract and PackageObject:
63 ModuleAbstract = GetLocalValue(PackageObject.GetAbstract())
64 if not ModuleAbstract and DistHeader:
65 ModuleAbstract = GetLocalValue(DistHeader.GetAbstract())
66 ModuleDescription = GetLocalValue(ModuleObject.GetDescription())
67 if not ModuleDescription and PackageObject:
68 ModuleDescription = GetLocalValue(PackageObject.GetDescription())
69 if not ModuleDescription and DistHeader:
70 ModuleDescription = GetLocalValue(DistHeader.GetDescription())
71 ModuleCopyright = ''
72 for (Lang, Copyright) in ModuleObject.GetCopyright():
73 if Lang:
74 pass
75 ModuleCopyright = Copyright
76 if not ModuleCopyright and PackageObject:
77 for (Lang, Copyright) in PackageObject.GetCopyright():
78 if Lang:
79 pass
80 ModuleCopyright = Copyright
81 if not ModuleCopyright and DistHeader:
82 for (Lang, Copyright) in DistHeader.GetCopyright():
83 if Lang:
84 pass
85 ModuleCopyright = Copyright
86 ModuleLicense = ''
87 for (Lang, License) in ModuleObject.GetLicense():
88 if Lang:
89 pass
90 ModuleLicense = License
91 if not ModuleLicense and PackageObject:
92 for (Lang, License) in PackageObject.GetLicense():
93 if Lang:
94 pass
95 ModuleLicense = License
96 if not ModuleLicense and DistHeader:
97 for (Lang, License) in DistHeader.GetLicense():
98 if Lang:
99 pass
100 ModuleLicense = License
101
102 #
103 # Generate header comment section of INF file
104 #
105 Content += GenHeaderCommentSection(ModuleAbstract,
106 ModuleDescription,
107 ModuleCopyright,
108 ModuleLicense).replace('\r\n', '\n')
109
110 #
111 # Generate Binary Header
112 #
113 for UserExtension in ModuleObject.GetUserExtensionList():
114 if UserExtension.GetUserID() == DT.TAB_BINARY_HEADER_USERID \
115 and UserExtension.GetIdentifier() == DT.TAB_BINARY_HEADER_IDENTIFIER:
116 ModuleBinaryAbstract = GetLocalValue(UserExtension.GetBinaryAbstract())
117 ModuleBinaryDescription = GetLocalValue(UserExtension.GetBinaryDescription())
118 ModuleBinaryCopyright = ''
119 ModuleBinaryLicense = ''
120 for (Lang, Copyright) in UserExtension.GetBinaryCopyright():
121 ModuleBinaryCopyright = Copyright
122 for (Lang, License) in UserExtension.GetBinaryLicense():
123 ModuleBinaryLicense = License
124 if ModuleBinaryAbstract and ModuleBinaryDescription and \
125 ModuleBinaryCopyright and ModuleBinaryLicense:
126 Content += GenHeaderCommentSection(ModuleBinaryAbstract,
127 ModuleBinaryDescription,
128 ModuleBinaryCopyright,
129 ModuleBinaryLicense,
130 True)
131
132 #
133 # Generate MODULE_UNI_FILE for module
134 #
135 FileHeader = GenHeaderCommentSection(ModuleAbstract, ModuleDescription, ModuleCopyright, ModuleLicense, False, \
136 DT.TAB_COMMENT_EDK1_SPLIT)
137 ModuleUniFile = GenModuleUNIEncodeFile(ModuleObject, FileHeader)
138 if ModuleUniFile:
139 ModuleObject.SetModuleUniFile(os.path.basename(ModuleUniFile))
140
141 #
142 # Judge whether the INF file is an AsBuild INF.
143 #
144 if ModuleObject.BinaryModule:
145 GlobalData.gIS_BINARY_INF = True
146 else:
147 GlobalData.gIS_BINARY_INF = False
148 #
149 # for each section, maintain a dict, sorted arch will be its key,
150 # statement list will be its data
151 # { 'Arch1 Arch2 Arch3': [statement1, statement2],
152 # 'Arch1' : [statement1, statement3]
153 # }
154 #
155 # Gen section contents
156 #
157 Content += GenDefines(ModuleObject)
158 Content += GenBuildOptions(ModuleObject)
159 Content += GenLibraryClasses(ModuleObject)
160 Content += GenPackages(ModuleObject)
161 Content += GenPcdSections(ModuleObject)
162 Content += GenSources(ModuleObject)
163 Content += GenProtocolPPiSections(ModuleObject.GetProtocolList(), True)
164 Content += GenProtocolPPiSections(ModuleObject.GetPpiList(), False)
165 Content += GenGuidSections(ModuleObject.GetGuidList())
166 Content += GenBinaries(ModuleObject)
167 Content += GenDepex(ModuleObject)
168 __UserExtensionsContent = GenUserExtensions(ModuleObject)
169 Content += __UserExtensionsContent
170 if ModuleObject.GetEventList() or ModuleObject.GetBootModeList() or ModuleObject.GetHobList():
171 Content += '\n'
172 #
173 # generate [Event], [BootMode], [Hob] section
174 #
175 Content += GenSpecialSections(ModuleObject.GetEventList(), 'Event', __UserExtensionsContent)
176 Content += GenSpecialSections(ModuleObject.GetBootModeList(), 'BootMode', __UserExtensionsContent)
177 Content += GenSpecialSections(ModuleObject.GetHobList(), 'Hob', __UserExtensionsContent)
178 SaveFileOnChange(ContainerFile, Content, False)
179 if DistHeader.ReadOnly:
180 os.chmod(ContainerFile, stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH)
181 else:
182 os.chmod(ContainerFile, stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH|stat.S_IWUSR|stat.S_IWGRP|stat.S_IWOTH)
183 return ContainerFile
184
185 ## GenModuleUNIEncodeFile
186 # GenModuleUNIEncodeFile, default is a UCS-2LE encode file
187 #
188 def GenModuleUNIEncodeFile(ModuleObject, UniFileHeader='', Encoding=DT.TAB_ENCODING_UTF16LE):
189 GenUNIFlag = False
190 OnlyLANGUAGE_EN_X = True
191 BinaryAbstract = []
192 BinaryDescription = []
193 #
194 # If more than one language code is used for any element that would be present in the MODULE_UNI_FILE,
195 # then the MODULE_UNI_FILE must be created.
196 #
197 for (Key, Value) in ModuleObject.GetAbstract() + ModuleObject.GetDescription():
198 if Key == DT.TAB_LANGUAGE_EN_X:
199 GenUNIFlag = True
200 else:
201 OnlyLANGUAGE_EN_X = False
202
203 for UserExtension in ModuleObject.GetUserExtensionList():
204 if UserExtension.GetUserID() == DT.TAB_BINARY_HEADER_USERID \
205 and UserExtension.GetIdentifier() == DT.TAB_BINARY_HEADER_IDENTIFIER:
206 for (Key, Value) in UserExtension.GetBinaryAbstract():
207 if Key == DT.TAB_LANGUAGE_EN_X:
208 GenUNIFlag = True
209 else:
210 OnlyLANGUAGE_EN_X = False
211 BinaryAbstract.append((Key, Value))
212 for (Key, Value) in UserExtension.GetBinaryDescription():
213 if Key == DT.TAB_LANGUAGE_EN_X:
214 GenUNIFlag = True
215 else:
216 OnlyLANGUAGE_EN_X = False
217 BinaryDescription.append((Key, Value))
218
219
220 if not GenUNIFlag:
221 return
222 elif OnlyLANGUAGE_EN_X:
223 return
224 else:
225 ModuleObject.UNIFlag = True
226 ContainerFile = GetUniFileName(os.path.dirname(ModuleObject.GetFullPath()), ModuleObject.GetBaseName())
227
228 if not os.path.exists(os.path.dirname(ModuleObject.GetFullPath())):
229 os.makedirs(os.path.dirname(ModuleObject.GetFullPath()))
230
231 Content = UniFileHeader + '\r\n'
232 Content += '\r\n'
233
234 Content += FormatUniEntry('#string ' + DT.TAB_INF_ABSTRACT, ModuleObject.GetAbstract(), ContainerFile) + '\r\n'
235
236 Content += FormatUniEntry('#string ' + DT.TAB_INF_DESCRIPTION, ModuleObject.GetDescription(), ContainerFile) \
237 + '\r\n'
238
239 BinaryAbstractString = FormatUniEntry('#string ' + DT.TAB_INF_BINARY_ABSTRACT, BinaryAbstract, ContainerFile)
240 if BinaryAbstractString:
241 Content += BinaryAbstractString + '\r\n'
242
243 BinaryDescriptionString = FormatUniEntry('#string ' + DT.TAB_INF_BINARY_DESCRIPTION, BinaryDescription, \
244 ContainerFile)
245 if BinaryDescriptionString:
246 Content += BinaryDescriptionString + '\r\n'
247
248 if not os.path.exists(ContainerFile):
249 File = codecs.open(ContainerFile, 'wb', Encoding)
250 File.write(u'\uFEFF' + Content)
251 File.stream.close()
252 Md5Signature = md5(__FileHookOpen__(str(ContainerFile), 'rb').read())
253 Md5Sum = Md5Signature.hexdigest()
254 if (ContainerFile, Md5Sum) not in ModuleObject.FileList:
255 ModuleObject.FileList.append((ContainerFile, Md5Sum))
256
257 return ContainerFile
258 def GenDefines(ModuleObject):
259 #
260 # generate [Defines] section
261 #
262 LeftOffset = 31
263 Content = ''
264 NewSectionDict = {}
265
266 for UserExtension in ModuleObject.GetUserExtensionList():
267 DefinesDict = UserExtension.GetDefinesDict()
268 if not DefinesDict:
269 continue
270 for Statement in DefinesDict:
271 if len(Statement.split(DT.TAB_EQUAL_SPLIT)) > 1:
272 Statement = (u'%s ' % Statement.split(DT.TAB_EQUAL_SPLIT, 1)[0]).ljust(LeftOffset) \
273 + u'= %s' % Statement.split(DT.TAB_EQUAL_SPLIT, 1)[1].lstrip()
274 SortedArch = DT.TAB_ARCH_COMMON
275 if Statement.strip().startswith(DT.TAB_INF_DEFINES_CUSTOM_MAKEFILE):
276 pos = Statement.find(DT.TAB_VALUE_SPLIT)
277 if pos == -1:
278 pos = Statement.find(DT.TAB_EQUAL_SPLIT)
279 Makefile = ConvertPath(Statement[pos + 1:].strip())
280 Statement = Statement[:pos + 1] + ' ' + Makefile
281 if SortedArch in NewSectionDict:
282 NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement]
283 else:
284 NewSectionDict[SortedArch] = [Statement]
285 SpecialStatementList = []
286
287 # TAB_INF_DEFINES_INF_VERSION
288 Statement = (u'%s ' % DT.TAB_INF_DEFINES_INF_VERSION).ljust(LeftOffset) + u'= %s' % '0x00010017'
289 SpecialStatementList.append(Statement)
290
291 # BaseName
292 BaseName = ModuleObject.GetBaseName()
293 if BaseName.startswith('.') or BaseName.startswith('-'):
294 BaseName = '_' + BaseName
295 Statement = (u'%s ' % DT.TAB_INF_DEFINES_BASE_NAME).ljust(LeftOffset) + u'= %s' % BaseName
296 SpecialStatementList.append(Statement)
297
298 # TAB_INF_DEFINES_FILE_GUID
299 Statement = (u'%s ' % DT.TAB_INF_DEFINES_FILE_GUID).ljust(LeftOffset) + u'= %s' % ModuleObject.GetGuid()
300 SpecialStatementList.append(Statement)
301
302 # TAB_INF_DEFINES_VERSION_STRING
303 Statement = (u'%s ' % DT.TAB_INF_DEFINES_VERSION_STRING).ljust(LeftOffset) + u'= %s' % ModuleObject.GetVersion()
304 SpecialStatementList.append(Statement)
305
306 # TAB_INF_DEFINES_VERSION_STRING
307 if ModuleObject.UNIFlag:
308 Statement = (u'%s ' % DT.TAB_INF_DEFINES_MODULE_UNI_FILE).ljust(LeftOffset) + \
309 u'= %s' % ModuleObject.GetModuleUniFile()
310 SpecialStatementList.append(Statement)
311
312 # TAB_INF_DEFINES_MODULE_TYPE
313 if ModuleObject.GetModuleType():
314 Statement = (u'%s ' % DT.TAB_INF_DEFINES_MODULE_TYPE).ljust(LeftOffset) + u'= %s' % ModuleObject.GetModuleType()
315 SpecialStatementList.append(Statement)
316
317 # TAB_INF_DEFINES_PCD_IS_DRIVER
318 if ModuleObject.GetPcdIsDriver():
319 Statement = (u'%s ' % DT.TAB_INF_DEFINES_PCD_IS_DRIVER).ljust(LeftOffset) + \
320 u'= %s' % ModuleObject.GetPcdIsDriver()
321 SpecialStatementList.append(Statement)
322
323 # TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION
324 if ModuleObject.GetUefiSpecificationVersion():
325 Statement = (u'%s ' % DT.TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION).ljust(LeftOffset) + \
326 u'= %s' % ModuleObject.GetUefiSpecificationVersion()
327 SpecialStatementList.append(Statement)
328
329 # TAB_INF_DEFINES_PI_SPECIFICATION_VERSION
330 if ModuleObject.GetPiSpecificationVersion():
331 Statement = (u'%s ' % DT.TAB_INF_DEFINES_PI_SPECIFICATION_VERSION).ljust(LeftOffset) + \
332 u'= %s' % ModuleObject.GetPiSpecificationVersion()
333 SpecialStatementList.append(Statement)
334
335 # LibraryClass
336 for LibraryClass in ModuleObject.GetLibraryClassList():
337 if LibraryClass.GetUsage() == DT.USAGE_ITEM_PRODUCES or \
338 LibraryClass.GetUsage() == DT.USAGE_ITEM_SOMETIMES_PRODUCES:
339 Statement = (u'%s ' % DT.TAB_INF_DEFINES_LIBRARY_CLASS).ljust(LeftOffset) + \
340 u'= %s' % LibraryClass.GetLibraryClass()
341 if LibraryClass.GetSupModuleList():
342 Statement += '|' + DT.TAB_SPACE_SPLIT.join(l for l in LibraryClass.GetSupModuleList())
343 SpecialStatementList.append(Statement)
344
345 # Spec Item
346 for SpecItem in ModuleObject.GetSpecList():
347 Spec, Version = SpecItem
348 Spec = ConvertSpec(Spec)
349 Statement = '%s %s = %s' % (DT.TAB_INF_DEFINES_SPEC, Spec, Version)
350 SpecialStatementList.append(Statement)
351
352 # Extern
353 ExternList = []
354 for Extern in ModuleObject.GetExternList():
355 ArchList = Extern.GetSupArchList()
356 EntryPoint = Extern.GetEntryPoint()
357 UnloadImage = Extern.GetUnloadImage()
358 Constructor = Extern.GetConstructor()
359 Destructor = Extern.GetDestructor()
360 HelpStringList = Extern.GetHelpTextList()
361 FFE = Extern.GetFeatureFlag()
362 ExternList.append([ArchList, EntryPoint, UnloadImage, Constructor, Destructor, FFE, HelpStringList])
363 #
364 # Add VALID_ARCHITECTURES information
365 #
366 ValidArchStatement = None
367 if ModuleObject.SupArchList:
368 ValidArchStatement = '\n' + '# ' + '\n'
369 ValidArchStatement += '# The following information is for reference only and not required by the build tools.\n'
370 ValidArchStatement += '# ' + '\n'
371 ValidArchStatement += '# VALID_ARCHITECTURES = %s' % (' '.join(ModuleObject.SupArchList)) + '\n'
372 ValidArchStatement += '# '
373 if DT.TAB_ARCH_COMMON not in NewSectionDict:
374 NewSectionDict[DT.TAB_ARCH_COMMON] = []
375 NewSectionDict[DT.TAB_ARCH_COMMON] = NewSectionDict[DT.TAB_ARCH_COMMON] + SpecialStatementList
376 GenMetaFileMisc.AddExternToDefineSec(NewSectionDict, DT.TAB_ARCH_COMMON, ExternList)
377 if ValidArchStatement is not None:
378 NewSectionDict[DT.TAB_ARCH_COMMON] = NewSectionDict[DT.TAB_ARCH_COMMON] + [ValidArchStatement]
379 Content += GenSection('Defines', NewSectionDict)
380 return Content
381
382 def GenLibraryClasses(ModuleObject):
383 #
384 # generate [LibraryClasses] section
385 #
386 Content = ''
387 NewSectionDict = {}
388 if not GlobalData.gIS_BINARY_INF:
389 for LibraryClass in ModuleObject.GetLibraryClassList():
390 if LibraryClass.GetUsage() == DT.USAGE_ITEM_PRODUCES:
391 continue
392 #
393 # Generate generic comment
394 #
395 HelpTextList = LibraryClass.GetHelpTextList()
396 HelpStr = _GetHelpStr(HelpTextList)
397 CommentStr = GenGenericCommentF(HelpStr)
398 Statement = CommentStr
399 Name = LibraryClass.GetLibraryClass()
400 FFE = LibraryClass.GetFeatureFlag()
401 Statement += Name
402 if FFE:
403 Statement += '|' + FFE
404 ModuleList = LibraryClass.GetSupModuleList()
405 ArchList = LibraryClass.GetSupArchList()
406 for Index in range(0, len(ArchList)):
407 ArchList[Index] = ConvertArchForInstall(ArchList[Index])
408 ArchList.sort()
409 SortedArch = ' '.join(ArchList)
410 KeyList = []
411 if not ModuleList or IsAllModuleList(ModuleList):
412 KeyList = [SortedArch]
413 else:
414 ModuleString = DT.TAB_VALUE_SPLIT.join(l for l in ModuleList)
415 if not ArchList:
416 SortedArch = DT.TAB_ARCH_COMMON
417 KeyList = [SortedArch + '.' + ModuleString]
418 else:
419 KeyList = [Arch + '.' + ModuleString for Arch in ArchList]
420 for Key in KeyList:
421 if Key in NewSectionDict:
422 NewSectionDict[Key] = NewSectionDict[Key] + [Statement]
423 else:
424 NewSectionDict[Key] = [Statement]
425 Content += GenSection('LibraryClasses', NewSectionDict)
426 else:
427 LibraryClassDict = {}
428 for BinaryFile in ModuleObject.GetBinaryFileList():
429 if not BinaryFile.AsBuiltList:
430 continue
431 for LibraryItem in BinaryFile.AsBuiltList[0].LibraryInstancesList:
432 Statement = '# Guid: ' + LibraryItem.Guid + ' Version: ' + LibraryItem.Version
433
434 if len(BinaryFile.SupArchList) == 0:
435 if 'COMMON' in LibraryClassDict and Statement not in LibraryClassDict['COMMON']:
436 LibraryClassDict['COMMON'].append(Statement)
437 else:
438 LibraryClassDict['COMMON'] = ['## @LIB_INSTANCES']
439 LibraryClassDict['COMMON'].append(Statement)
440 else:
441 for Arch in BinaryFile.SupArchList:
442 if Arch in LibraryClassDict:
443 if Statement not in LibraryClassDict[Arch]:
444 LibraryClassDict[Arch].append(Statement)
445 else:
446 continue
447 else:
448 LibraryClassDict[Arch] = ['## @LIB_INSTANCES']
449 LibraryClassDict[Arch].append(Statement)
450 Content += GenSection('LibraryClasses', LibraryClassDict)
451
452 return Content
453
454 def GenPackages(ModuleObject):
455 Content = ''
456 #
457 # generate [Packages] section
458 #
459 NewSectionDict = Sdict()
460 WorkspaceDir = GlobalData.gWORKSPACE
461 for PackageDependency in ModuleObject.GetPackageDependencyList():
462 #
463 # Generate generic comment
464 #
465 CommentStr = ''
466 HelpText = PackageDependency.GetHelpText()
467 if HelpText:
468 HelpStr = HelpText.GetString()
469 CommentStr = GenGenericCommentF(HelpStr)
470 Statement = CommentStr
471 Guid = PackageDependency.GetGuid()
472 Version = PackageDependency.GetVersion()
473 FFE = PackageDependency.GetFeatureFlag()
474 Path = ''
475 #
476 # find package path/name
477 #
478 for PkgInfo in GlobalData.gWSPKG_LIST:
479 if Guid == PkgInfo[1]:
480 if (not Version) or (Version == PkgInfo[2]):
481 Path = PkgInfo[3]
482 break
483 #
484 # get relative path
485 #
486 RelaPath = GetRelativePath(Path, WorkspaceDir)
487 Statement += RelaPath.replace('\\', '/')
488 if FFE:
489 Statement += '|' + FFE
490 ArchList = sorted(PackageDependency.GetSupArchList())
491 SortedArch = ' '.join(ArchList)
492 if SortedArch in NewSectionDict:
493 NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement]
494 else:
495 NewSectionDict[SortedArch] = [Statement]
496 Content += GenSection('Packages', NewSectionDict)
497 return Content
498
499 def GenSources(ModuleObject):
500 #
501 # generate [Sources] section
502 #
503 Content = ''
504 NewSectionDict = {}
505 for Source in ModuleObject.GetSourceFileList():
506 SourceFile = Source.GetSourceFile()
507 Family = Source.GetFamily()
508 FeatureFlag = Source.GetFeatureFlag()
509 SupArchList = sorted(Source.GetSupArchList())
510 SortedArch = ' '.join(SupArchList)
511 Statement = GenSourceStatement(ConvertPath(SourceFile), Family, FeatureFlag)
512 if SortedArch in NewSectionDict:
513 NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement]
514 else:
515 NewSectionDict[SortedArch] = [Statement]
516 Content += GenSection('Sources', NewSectionDict)
517
518 return Content
519
520 def GenDepex(ModuleObject):
521 #
522 # generate [Depex] section
523 #
524 NewSectionDict = Sdict()
525 Content = ''
526 for Depex in ModuleObject.GetPeiDepex() + ModuleObject.GetDxeDepex() + ModuleObject.GetSmmDepex():
527 HelpTextList = Depex.GetHelpTextList()
528 HelpStr = _GetHelpStr(HelpTextList)
529 CommentStr = GenGenericCommentF(HelpStr)
530 SupArchList = Depex.GetSupArchList()
531 SupModList = Depex.GetModuleType()
532 Expression = Depex.GetDepex()
533 Statement = CommentStr + Expression
534 SupArchList.sort()
535 KeyList = []
536 if not SupArchList:
537 SupArchList.append(DT.TAB_ARCH_COMMON.lower())
538 if not SupModList:
539 KeyList = SupArchList
540 else:
541 for ModuleType in SupModList:
542 for Arch in SupArchList:
543 KeyList.append(ConvertArchForInstall(Arch) + '.' + ModuleType)
544 for Key in KeyList:
545 if Key in NewSectionDict:
546 NewSectionDict[Key] = NewSectionDict[Key] + [Statement]
547 else:
548 NewSectionDict[Key] = [Statement]
549 Content += GenSection('Depex', NewSectionDict, False)
550
551 return Content
552 ## GenUserExtensions
553 #
554 # GenUserExtensions
555 #
556 def GenUserExtensions(ModuleObject):
557 NewSectionDict = {}
558 for UserExtension in ModuleObject.GetUserExtensionList():
559 if UserExtension.GetUserID() == DT.TAB_BINARY_HEADER_USERID and \
560 UserExtension.GetIdentifier() == DT.TAB_BINARY_HEADER_IDENTIFIER:
561 continue
562 if UserExtension.GetIdentifier() == 'Depex':
563 continue
564 Statement = UserExtension.GetStatement()
565 # Comment the code to support user extension without any statement just the section header in []
566 # if not Statement:
567 # continue
568 ArchList = UserExtension.GetSupArchList()
569 for Index in range(0, len(ArchList)):
570 ArchList[Index] = ConvertArchForInstall(ArchList[Index])
571 ArchList.sort()
572 KeyList = []
573 CommonPreFix = ''
574 if UserExtension.GetUserID():
575 CommonPreFix = UserExtension.GetUserID()
576 if CommonPreFix.find('.') > -1:
577 CommonPreFix = '"' + CommonPreFix + '"'
578 if UserExtension.GetIdentifier():
579 CommonPreFix += '.' + '"' + UserExtension.GetIdentifier() + '"'
580 if ArchList:
581 KeyList = [CommonPreFix + '.' + Arch for Arch in ArchList]
582 else:
583 KeyList = [CommonPreFix]
584 for Key in KeyList:
585 if Key in NewSectionDict:
586 NewSectionDict[Key] = NewSectionDict[Key] + [Statement]
587 else:
588 NewSectionDict[Key] = [Statement]
589 Content = GenSection('UserExtensions', NewSectionDict, False)
590
591 return Content
592
593 # GenSourceStatement
594 #
595 # @param SourceFile: string of source file path/name
596 # @param Family: string of source file family field
597 # @param FeatureFlag: string of source file FeatureFlag field
598 # @param TagName: string of source file TagName field
599 # @param ToolCode: string of source file ToolCode field
600 # @param HelpStr: string of source file HelpStr field
601 #
602 # @retval Statement: The generated statement for source
603 #
604 def GenSourceStatement(SourceFile, Family, FeatureFlag, TagName=None,
605 ToolCode=None, HelpStr=None):
606 Statement = ''
607 if HelpStr:
608 Statement += GenGenericCommentF(HelpStr)
609 #
610 # format of SourceFile|Family|TagName|ToolCode|FeatureFlag
611 #
612 Statement += SourceFile
613 if TagName is None:
614 TagName = ''
615 if ToolCode is None:
616 ToolCode = ''
617 if HelpStr is None:
618 HelpStr = ''
619 if FeatureFlag:
620 Statement += '|' + Family + '|' + TagName + '|' + ToolCode + '|' + FeatureFlag
621 elif ToolCode:
622 Statement += '|' + Family + '|' + TagName + '|' + ToolCode
623 elif TagName:
624 Statement += '|' + Family + '|' + TagName
625 elif Family:
626 Statement += '|' + Family
627 return Statement
628
629 # GenBinaryStatement
630 #
631 # @param Key: (FileName, FileType, FFE, SortedArch)
632 # @param Value: (Target, Family, TagName, Comment)
633 #
634 #
635 def GenBinaryStatement(Key, Value, SubTypeGuidValue=None):
636 (FileName, FileType, FFE, SortedArch) = Key
637 if SortedArch:
638 pass
639 if Value:
640 (Target, Family, TagName, Comment) = Value
641 else:
642 Target = ''
643 Family = ''
644 TagName = ''
645 Comment = ''
646 if Comment:
647 Statement = GenGenericCommentF(Comment)
648 else:
649 Statement = ''
650 if FileType == 'SUBTYPE_GUID' and SubTypeGuidValue:
651 Statement += FileType + '|' + SubTypeGuidValue + '|' + FileName
652 else:
653 Statement += FileType + '|' + FileName
654 if FileType in DT.BINARY_FILE_TYPE_UI_LIST + DT.BINARY_FILE_TYPE_VER_LIST:
655 if FFE:
656 Statement += '|' + Target + '|' + FFE
657 elif Target:
658 Statement += '|' + Target
659 else:
660 if FFE:
661 Statement += '|' + Target + '|' + Family + '|' + TagName + '|' + FFE
662 elif TagName:
663 Statement += '|' + Target + '|' + Family + '|' + TagName
664 elif Family:
665 Statement += '|' + Target + '|' + Family
666 elif Target:
667 Statement += '|' + Target
668 return Statement
669 ## GenGuidSections
670 #
671 # @param GuidObjList: List of GuidObject
672 # @retVal Content: The generated section contents
673 #
674 def GenGuidSections(GuidObjList):
675 #
676 # generate [Guids] section
677 #
678 Content = ''
679 GuidDict = Sdict()
680 for Guid in GuidObjList:
681 HelpTextList = Guid.GetHelpTextList()
682 HelpStr = _GetHelpStr(HelpTextList)
683 CName = Guid.GetCName()
684 FFE = Guid.GetFeatureFlag()
685 Statement = CName
686 if FFE:
687 Statement += '|' + FFE
688 Usage = Guid.GetUsage()
689 GuidType = Guid.GetGuidTypeList()[0]
690 VariableName = Guid.GetVariableName()
691 #
692 # Differentiate the generic comment and usage comment as multiple generic comment need to be put at first
693 #
694 if Usage == DT.ITEM_UNDEFINED and GuidType == DT.ITEM_UNDEFINED:
695 # generate list of generic comment
696 Comment = GenGenericCommentF(HelpStr)
697 else:
698 # generate list of other comment
699 Comment = HelpStr.replace('\n', ' ')
700 Comment = Comment.strip()
701 if Comment:
702 Comment = ' # ' + Comment
703 else:
704 Comment = ''
705 if Usage != DT.ITEM_UNDEFINED and GuidType == DT.ITEM_UNDEFINED:
706 Comment = '## ' + Usage + Comment
707 elif GuidType == 'Variable':
708 Comment = '## ' + Usage + ' ## ' + GuidType + ':' + VariableName + Comment
709 else:
710 Comment = '## ' + Usage + ' ## ' + GuidType + Comment
711
712 if Comment:
713 Comment += '\n'
714 #
715 # merge duplicate items
716 #
717 ArchList = sorted(Guid.GetSupArchList())
718 SortedArch = ' '.join(ArchList)
719 if (Statement, SortedArch) in GuidDict:
720 PreviousComment = GuidDict[Statement, SortedArch]
721 Comment = PreviousComment + Comment
722 GuidDict[Statement, SortedArch] = Comment
723 NewSectionDict = GenMetaFileMisc.TransferDict(GuidDict, 'INF_GUID')
724 #
725 # generate the section contents
726 #
727 if NewSectionDict:
728 Content = GenSection('Guids', NewSectionDict)
729
730 return Content
731
732 ## GenProtocolPPiSections
733 #
734 # @param ObjList: List of ProtocolObject or Ppi Object
735 # @retVal Content: The generated section contents
736 #
737 def GenProtocolPPiSections(ObjList, IsProtocol):
738 Content = ''
739 Dict = Sdict()
740 for Object in ObjList:
741 HelpTextList = Object.GetHelpTextList()
742 HelpStr = _GetHelpStr(HelpTextList)
743 CName = Object.GetCName()
744 FFE = Object.GetFeatureFlag()
745 Statement = CName
746 if FFE:
747 Statement += '|' + FFE
748 Usage = Object.GetUsage()
749 Notify = Object.GetNotify()
750 #
751 # Differentiate the generic comment and usage comment as consecutive generic comment need to be put together
752 #
753 if Usage == DT.ITEM_UNDEFINED and Notify == '':
754 # generate list of generic comment
755 Comment = GenGenericCommentF(HelpStr)
756 else:
757 # generate list of other comment
758 Comment = HelpStr.replace('\n', ' ')
759 Comment = Comment.strip()
760 if Comment:
761 Comment = ' # ' + Comment
762 else:
763 Comment = ''
764 if Usage == DT.ITEM_UNDEFINED and not Comment and Notify == '':
765 Comment = ''
766 else:
767 if Notify:
768 Comment = '## ' + Usage + ' ## ' + 'NOTIFY' + Comment
769 else:
770 Comment = '## ' + Usage + Comment
771 if Comment:
772 Comment += '\n'
773 #
774 # merge duplicate items
775 #
776 ArchList = sorted(Object.GetSupArchList())
777 SortedArch = ' '.join(ArchList)
778 if (Statement, SortedArch) in Dict:
779 PreviousComment = Dict[Statement, SortedArch]
780 Comment = PreviousComment + Comment
781 Dict[Statement, SortedArch] = Comment
782 NewSectionDict = GenMetaFileMisc.TransferDict(Dict, 'INF_PPI_PROTOCOL')
783 #
784 # generate the section contents
785 #
786 if NewSectionDict:
787 if IsProtocol:
788 Content = GenSection('Protocols', NewSectionDict)
789 else:
790 Content = GenSection('Ppis', NewSectionDict)
791
792 return Content
793
794 ## GenPcdSections
795 #
796 #
797 def GenPcdSections(ModuleObject):
798 Content = ''
799 if not GlobalData.gIS_BINARY_INF:
800 #
801 # for each Pcd Itemtype, maintain a dict so the same type will be grouped
802 # together
803 #
804 ItemTypeDict = {}
805 for Pcd in ModuleObject.GetPcdList():
806 HelpTextList = Pcd.GetHelpTextList()
807 HelpStr = _GetHelpStr(HelpTextList)
808 Statement = ''
809 CName = Pcd.GetCName()
810 TokenSpaceGuidCName = Pcd.GetTokenSpaceGuidCName()
811 DefaultValue = Pcd.GetDefaultValue()
812 ItemType = Pcd.GetItemType()
813 if ItemType in ItemTypeDict:
814 Dict = ItemTypeDict[ItemType]
815 else:
816 Dict = Sdict()
817 ItemTypeDict[ItemType] = Dict
818 FFE = Pcd.GetFeatureFlag()
819 Statement += TokenSpaceGuidCName + '.' + CName
820 if DefaultValue:
821 Statement += '|' + DefaultValue
822 if FFE:
823 Statement += '|' + FFE
824 elif FFE:
825 Statement += '||' + FFE
826 #
827 # Generate comment
828 #
829 Usage = Pcd.GetValidUsage()
830 # if FeatureFlag Pcd, then assume all Usage is CONSUMES
831 if ItemType == DT.TAB_INF_FEATURE_PCD:
832 Usage = DT.USAGE_ITEM_CONSUMES
833 if Usage == DT.ITEM_UNDEFINED:
834 # generate list of generic comment
835 Comment = GenGenericCommentF(HelpStr)
836 else:
837 # generate list of other comment
838 Comment = HelpStr.replace('\n', ' ')
839 Comment = Comment.strip()
840 if Comment:
841 Comment = ' # ' + Comment
842 else:
843 Comment = ''
844 Comment = '## ' + Usage + Comment
845 if Comment:
846 Comment += '\n'
847 #
848 # Merge duplicate entries
849 #
850 ArchList = sorted(Pcd.GetSupArchList())
851 SortedArch = ' '.join(ArchList)
852 if (Statement, SortedArch) in Dict:
853 PreviousComment = Dict[Statement, SortedArch]
854 Comment = PreviousComment + Comment
855 Dict[Statement, SortedArch] = Comment
856 for ItemType in ItemTypeDict:
857 # First we need to transfer the Dict to use SortedArch as key
858 Dict = ItemTypeDict[ItemType]
859 NewSectionDict = GenMetaFileMisc.TransferDict(Dict, 'INF_PCD')
860 if NewSectionDict:
861 Content += GenSection(ItemType, NewSectionDict)
862 #
863 # For AsBuild INF files
864 #
865 else:
866 Content += GenAsBuiltPacthPcdSections(ModuleObject)
867 Content += GenAsBuiltPcdExSections(ModuleObject)
868
869 return Content
870
871 ## GenPcdSections
872 #
873 #
874 def GenAsBuiltPacthPcdSections(ModuleObject):
875 PatchPcdDict = {}
876 for BinaryFile in ModuleObject.GetBinaryFileList():
877 if not BinaryFile.AsBuiltList:
878 continue
879 for PatchPcd in BinaryFile.AsBuiltList[0].PatchPcdList:
880 TokenSpaceName = ''
881 PcdCName = PatchPcd.CName
882 PcdValue = PatchPcd.DefaultValue
883 PcdOffset = PatchPcd.Offset
884 TokenSpaceGuidValue = PatchPcd.TokenSpaceGuidValue
885 Token = PatchPcd.Token
886 HelpTextList = PatchPcd.HelpTextList
887 HelpString = ''
888 for HelpStringItem in HelpTextList:
889 for HelpLine in GetSplitValueList(HelpStringItem.String, '\n'):
890 HelpString += '## ' + HelpLine + '\n'
891 TokenSpaceName, PcdCName = GenMetaFileMisc.ObtainPcdName(ModuleObject.PackageDependencyList,
892 TokenSpaceGuidValue,
893 Token)
894 if TokenSpaceName == '' or PcdCName == '':
895 Logger.Error("Upt",
896 ToolError.RESOURCE_NOT_AVAILABLE,
897 ST.ERR_INSTALL_FILE_DEC_FILE_ERROR % (TokenSpaceGuidValue, Token),
898 File=ModuleObject.GetFullPath())
899 Statement = HelpString + TokenSpaceName + '.' + PcdCName + ' | ' + PcdValue + ' | ' + \
900 PcdOffset + DT.TAB_SPACE_SPLIT
901 #
902 # Use binary file's Arch to be Pcd's Arch
903 #
904 ArchList = []
905 FileNameObjList = BinaryFile.GetFileNameList()
906 if FileNameObjList:
907 ArchList = FileNameObjList[0].GetSupArchList()
908 if len(ArchList) == 0:
909 if DT.TAB_ARCH_COMMON in PatchPcdDict:
910 if Statement not in PatchPcdDict[DT.TAB_ARCH_COMMON]:
911 PatchPcdDict[DT.TAB_ARCH_COMMON].append(Statement)
912 else:
913 PatchPcdDict[DT.TAB_ARCH_COMMON] = [Statement]
914 else:
915 for Arch in ArchList:
916 if Arch in PatchPcdDict:
917 if Statement not in PatchPcdDict[Arch]:
918 PatchPcdDict[Arch].append(Statement)
919 else:
920 PatchPcdDict[Arch] = [Statement]
921 return GenSection(DT.TAB_INF_PATCH_PCD, PatchPcdDict)
922 ## GenPcdSections
923 #
924 #
925 def GenAsBuiltPcdExSections(ModuleObject):
926 PcdExDict = {}
927 for BinaryFile in ModuleObject.GetBinaryFileList():
928 if not BinaryFile.AsBuiltList:
929 continue
930 for PcdExItem in BinaryFile.AsBuiltList[0].PcdExValueList:
931 TokenSpaceName = ''
932 PcdCName = PcdExItem.CName
933 TokenSpaceGuidValue = PcdExItem.TokenSpaceGuidValue
934 Token = PcdExItem.Token
935 HelpTextList = PcdExItem.HelpTextList
936 HelpString = ''
937 for HelpStringItem in HelpTextList:
938 for HelpLine in GetSplitValueList(HelpStringItem.String, '\n'):
939 HelpString += '## ' + HelpLine + '\n'
940 TokenSpaceName, PcdCName = GenMetaFileMisc.ObtainPcdName(ModuleObject.PackageDependencyList,
941 TokenSpaceGuidValue, Token)
942 if TokenSpaceName == '' or PcdCName == '':
943 Logger.Error("Upt",
944 ToolError.RESOURCE_NOT_AVAILABLE,
945 ST.ERR_INSTALL_FILE_DEC_FILE_ERROR % (TokenSpaceGuidValue, Token),
946 File=ModuleObject.GetFullPath())
947
948 Statement = HelpString + TokenSpaceName + DT.TAB_SPLIT + PcdCName + DT.TAB_SPACE_SPLIT
949
950 #
951 # Use binary file's Arch to be Pcd's Arch
952 #
953 ArchList = []
954 FileNameObjList = BinaryFile.GetFileNameList()
955 if FileNameObjList:
956 ArchList = FileNameObjList[0].GetSupArchList()
957
958 if len(ArchList) == 0:
959 if 'COMMON' in PcdExDict:
960 PcdExDict['COMMON'].append(Statement)
961 else:
962 PcdExDict['COMMON'] = [Statement]
963 else:
964 for Arch in ArchList:
965 if Arch in PcdExDict:
966 if Statement not in PcdExDict[Arch]:
967 PcdExDict[Arch].append(Statement)
968 else:
969 PcdExDict[Arch] = [Statement]
970 return GenSection('PcdEx', PcdExDict)
971
972 ## GenSpecialSections
973 # generate special sections for Event/BootMode/Hob
974 #
975 def GenSpecialSections(ObjectList, SectionName, UserExtensionsContent=''):
976 #
977 # generate section
978 #
979 Content = ''
980 NewSectionDict = {}
981 for Obj in ObjectList:
982 #
983 # Generate comment
984 #
985 CommentStr = ''
986 HelpTextList = Obj.GetHelpTextList()
987 HelpStr = _GetHelpStr(HelpTextList)
988 CommentStr = GenGenericCommentF(HelpStr)
989 if SectionName == 'Hob':
990 Type = Obj.GetHobType()
991 elif SectionName == 'Event':
992 Type = Obj.GetEventType()
993 elif SectionName == 'BootMode':
994 Type = Obj.GetSupportedBootModes()
995 else:
996 assert(SectionName)
997 Usage = Obj.GetUsage()
998
999 # If the content already in UserExtensionsContent then ignore
1000 if '[%s]' % SectionName in UserExtensionsContent and Type in UserExtensionsContent:
1001 return ''
1002
1003 Statement = ' ' + Type + ' ## ' + Usage
1004 if CommentStr in ['#\n', '#\n#\n']:
1005 CommentStr = '#\n#\n#\n'
1006 #
1007 # the first head comment line should start with '##\n', if it starts with '#\n', then add one '#'
1008 # else add '##\n' to meet the format defined in INF spec
1009 #
1010 if CommentStr.startswith('#\n'):
1011 CommentStr = '#' + CommentStr
1012 elif CommentStr:
1013 CommentStr = '##\n' + CommentStr
1014 if CommentStr and not CommentStr.endswith('\n#\n'):
1015 CommentStr = CommentStr + '#\n'
1016 NewStateMent = CommentStr + Statement
1017 SupArch = sorted(Obj.GetSupArchList())
1018 SortedArch = ' '.join(SupArch)
1019 if SortedArch in NewSectionDict:
1020 NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [NewStateMent]
1021 else:
1022 NewSectionDict[SortedArch] = [NewStateMent]
1023 SectionContent = GenSection(SectionName, NewSectionDict)
1024 SectionContent = SectionContent.strip()
1025 if SectionContent:
1026 Content = '# ' + ('\n' + '# ').join(GetSplitValueList(SectionContent, '\n'))
1027 Content = Content.lstrip()
1028 #
1029 # add a return to differentiate it between other possible sections
1030 #
1031 if Content:
1032 Content += '\n'
1033 return Content
1034 ## GenBuildOptions
1035 #
1036 #
1037 def GenBuildOptions(ModuleObject):
1038 Content = ''
1039 if not ModuleObject.BinaryModule:
1040 #
1041 # generate [BuildOptions] section
1042 #
1043 NewSectionDict = {}
1044 for UserExtension in ModuleObject.GetUserExtensionList():
1045 BuildOptionDict = UserExtension.GetBuildOptionDict()
1046 if not BuildOptionDict:
1047 continue
1048 for Arch in BuildOptionDict:
1049 if Arch in NewSectionDict:
1050 NewSectionDict[Arch] = NewSectionDict[Arch] + [BuildOptionDict[Arch]]
1051 else:
1052 NewSectionDict[Arch] = [BuildOptionDict[Arch]]
1053 Content = GenSection('BuildOptions', NewSectionDict)
1054 else:
1055 BuildOptionDict = {}
1056 for BinaryFile in ModuleObject.GetBinaryFileList():
1057 if not BinaryFile.AsBuiltList:
1058 continue
1059 for BuilOptionItem in BinaryFile.AsBuiltList[0].BinaryBuildFlagList:
1060 Statement = '#' + BuilOptionItem.AsBuiltOptionFlags
1061 if len(BinaryFile.SupArchList) == 0:
1062 if 'COMMON' in BuildOptionDict:
1063 if Statement not in BuildOptionDict['COMMON']:
1064 BuildOptionDict['COMMON'].append(Statement)
1065 else:
1066 BuildOptionDict['COMMON'] = ['## @AsBuilt']
1067 BuildOptionDict['COMMON'].append(Statement)
1068 else:
1069 for Arch in BinaryFile.SupArchList:
1070 if Arch in BuildOptionDict:
1071 if Statement not in BuildOptionDict[Arch]:
1072 BuildOptionDict[Arch].append(Statement)
1073 else:
1074 BuildOptionDict[Arch] = ['## @AsBuilt']
1075 BuildOptionDict[Arch].append(Statement)
1076 Content = GenSection('BuildOptions', BuildOptionDict)
1077
1078 return Content
1079 ## GenBinaries
1080 #
1081 #
1082 def GenBinaries(ModuleObject):
1083 NewSectionDict = {}
1084 BinariesDict = []
1085 for UserExtension in ModuleObject.GetUserExtensionList():
1086 BinariesDict = UserExtension.GetBinariesDict()
1087 if BinariesDict:
1088 break
1089 for BinaryFile in ModuleObject.GetBinaryFileList():
1090 FileNameObjList = BinaryFile.GetFileNameList()
1091 for FileNameObj in FileNameObjList:
1092 FileName = ConvertPath(FileNameObj.GetFilename())
1093 FileType = FileNameObj.GetFileType()
1094 FFE = FileNameObj.GetFeatureFlag()
1095 ArchList = sorted(FileNameObj.GetSupArchList())
1096 SortedArch = ' '.join(ArchList)
1097 Key = (FileName, FileType, FFE, SortedArch)
1098 if Key in BinariesDict:
1099 ValueList = BinariesDict[Key]
1100 for ValueItem in ValueList:
1101 Statement = GenBinaryStatement(Key, ValueItem)
1102 if SortedArch in NewSectionDict:
1103 NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement]
1104 else:
1105 NewSectionDict[SortedArch] = [Statement]
1106 #
1107 # as we already generated statement for this DictKey here set the Valuelist to be empty
1108 # to avoid generate duplicate entries as the DictKey may have multiple entries
1109 #
1110 BinariesDict[Key] = []
1111 else:
1112 if FileType == 'SUBTYPE_GUID' and FileNameObj.GetGuidValue():
1113 Statement = GenBinaryStatement(Key, None, FileNameObj.GetGuidValue())
1114 else:
1115 Statement = GenBinaryStatement(Key, None)
1116 if SortedArch in NewSectionDict:
1117 NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement]
1118 else:
1119 NewSectionDict[SortedArch] = [Statement]
1120 Content = GenSection('Binaries', NewSectionDict)
1121
1122 return Content