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