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