]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/UPT/GenMetaFile/GenInfFile.py
BaseTools/GenFds: enhance INF built arch filter
[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).replace('\r\n', '\n')
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 + '\r\n'
234 Content += '\r\n'
235
236 Content += FormatUniEntry('#string ' + DT.TAB_INF_ABSTRACT, ModuleObject.GetAbstract(), ContainerFile) + '\r\n'
237
238 Content += FormatUniEntry('#string ' + DT.TAB_INF_DESCRIPTION, ModuleObject.GetDescription(), ContainerFile) \
239 + '\r\n'
240
241 BinaryAbstractString = FormatUniEntry('#string ' + DT.TAB_INF_BINARY_ABSTRACT, BinaryAbstract, ContainerFile)
242 if BinaryAbstractString:
243 Content += BinaryAbstractString + '\r\n'
244
245 BinaryDescriptionString = FormatUniEntry('#string ' + DT.TAB_INF_BINARY_DESCRIPTION, BinaryDescription, \
246 ContainerFile)
247 if BinaryDescriptionString:
248 Content += BinaryDescriptionString + '\r\n'
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 LeftOffset = 31
265 Content = ''
266 NewSectionDict = {}
267
268 for UserExtension in ModuleObject.GetUserExtensionList():
269 DefinesDict = UserExtension.GetDefinesDict()
270 if not DefinesDict:
271 continue
272 for Statement in DefinesDict:
273 if Statement.split(DT.TAB_EQUAL_SPLIT) > 1:
274 Statement = (u'%s ' % Statement.split(DT.TAB_EQUAL_SPLIT, 1)[0]).ljust(LeftOffset) \
275 + u'= %s' % Statement.split(DT.TAB_EQUAL_SPLIT, 1)[1].lstrip()
276 SortedArch = DT.TAB_ARCH_COMMON
277 if Statement.strip().startswith(DT.TAB_INF_DEFINES_CUSTOM_MAKEFILE):
278 pos = Statement.find(DT.TAB_VALUE_SPLIT)
279 if pos == -1:
280 pos = Statement.find(DT.TAB_EQUAL_SPLIT)
281 Makefile = ConvertPath(Statement[pos + 1:].strip())
282 Statement = Statement[:pos + 1] + ' ' + Makefile
283 if SortedArch in NewSectionDict:
284 NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement]
285 else:
286 NewSectionDict[SortedArch] = [Statement]
287 SpecialStatementList = []
288
289 # TAB_INF_DEFINES_INF_VERSION
290 Statement = (u'%s ' % DT.TAB_INF_DEFINES_INF_VERSION).ljust(LeftOffset) + u'= %s' % '0x00010017'
291 SpecialStatementList.append(Statement)
292
293 # BaseName
294 BaseName = ModuleObject.GetBaseName()
295 if BaseName.startswith('.') or BaseName.startswith('-'):
296 BaseName = '_' + BaseName
297 Statement = (u'%s ' % DT.TAB_INF_DEFINES_BASE_NAME).ljust(LeftOffset) + u'= %s' % BaseName
298 SpecialStatementList.append(Statement)
299
300 # TAB_INF_DEFINES_FILE_GUID
301 Statement = (u'%s ' % DT.TAB_INF_DEFINES_FILE_GUID).ljust(LeftOffset) + u'= %s' % ModuleObject.GetGuid()
302 SpecialStatementList.append(Statement)
303
304 # TAB_INF_DEFINES_VERSION_STRING
305 Statement = (u'%s ' % DT.TAB_INF_DEFINES_VERSION_STRING).ljust(LeftOffset) + u'= %s' % ModuleObject.GetVersion()
306 SpecialStatementList.append(Statement)
307
308 # TAB_INF_DEFINES_VERSION_STRING
309 if ModuleObject.UNIFlag:
310 Statement = (u'%s ' % DT.TAB_INF_DEFINES_MODULE_UNI_FILE).ljust(LeftOffset) + \
311 u'= %s' % ModuleObject.GetBaseName() + '.uni'
312 SpecialStatementList.append(Statement)
313
314 # TAB_INF_DEFINES_MODULE_TYPE
315 if ModuleObject.GetModuleType():
316 Statement = (u'%s ' % DT.TAB_INF_DEFINES_MODULE_TYPE).ljust(LeftOffset) + u'= %s' % ModuleObject.GetModuleType()
317 SpecialStatementList.append(Statement)
318
319 # TAB_INF_DEFINES_PCD_IS_DRIVER
320 if ModuleObject.GetPcdIsDriver():
321 Statement = (u'%s ' % DT.TAB_INF_DEFINES_PCD_IS_DRIVER).ljust(LeftOffset) + \
322 u'= %s' % ModuleObject.GetPcdIsDriver()
323 SpecialStatementList.append(Statement)
324
325 # TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION
326 if ModuleObject.GetUefiSpecificationVersion():
327 Statement = (u'%s ' % DT.TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION).ljust(LeftOffset) + \
328 u'= %s' % ModuleObject.GetUefiSpecificationVersion()
329 SpecialStatementList.append(Statement)
330
331 # TAB_INF_DEFINES_PI_SPECIFICATION_VERSION
332 if ModuleObject.GetPiSpecificationVersion():
333 Statement = (u'%s ' % DT.TAB_INF_DEFINES_PI_SPECIFICATION_VERSION).ljust(LeftOffset) + \
334 u'= %s' % ModuleObject.GetPiSpecificationVersion()
335 SpecialStatementList.append(Statement)
336
337 # LibraryClass
338 for LibraryClass in ModuleObject.GetLibraryClassList():
339 if LibraryClass.GetUsage() == DT.USAGE_ITEM_PRODUCES or \
340 LibraryClass.GetUsage() == DT.USAGE_ITEM_SOMETIMES_PRODUCES:
341 Statement = (u'%s ' % DT.TAB_INF_DEFINES_LIBRARY_CLASS).ljust(LeftOffset) + \
342 u'= %s' % LibraryClass.GetLibraryClass()
343 if LibraryClass.GetSupModuleList():
344 Statement += '|' + DT.TAB_SPACE_SPLIT.join(l for l in LibraryClass.GetSupModuleList())
345 SpecialStatementList.append(Statement)
346
347 # Spec Item
348 for SpecItem in ModuleObject.GetSpecList():
349 Spec, Version = SpecItem
350 Spec = ConvertSpec(Spec)
351 Statement = '%s %s = %s' % (DT.TAB_INF_DEFINES_SPEC, Spec, Version)
352 SpecialStatementList.append(Statement)
353
354 # Extern
355 ExternList = []
356 for Extern in ModuleObject.GetExternList():
357 ArchList = Extern.GetSupArchList()
358 EntryPoint = Extern.GetEntryPoint()
359 UnloadImage = Extern.GetUnloadImage()
360 Constructor = Extern.GetConstructor()
361 Destructor = Extern.GetDestructor()
362 HelpStringList = Extern.GetHelpTextList()
363 FFE = Extern.GetFeatureFlag()
364 ExternList.append([ArchList, EntryPoint, UnloadImage, Constructor, Destructor, FFE, HelpStringList])
365 #
366 # Add VALID_ARCHITECTURES information
367 #
368 ValidArchStatement = None
369 if ModuleObject.SupArchList:
370 ValidArchStatement = '\n' + '# ' + '\n'
371 ValidArchStatement += '# The following information is for reference only and not required by the build tools.\n'
372 ValidArchStatement += '# ' + '\n'
373 ValidArchStatement += '# VALID_ARCHITECTURES = %s' % (' '.join(ModuleObject.SupArchList)) + '\n'
374 ValidArchStatement += '# '
375 if DT.TAB_ARCH_COMMON not in NewSectionDict:
376 NewSectionDict[DT.TAB_ARCH_COMMON] = []
377 NewSectionDict[DT.TAB_ARCH_COMMON] = NewSectionDict[DT.TAB_ARCH_COMMON] + SpecialStatementList
378 GenMetaFileMisc.AddExternToDefineSec(NewSectionDict, DT.TAB_ARCH_COMMON, ExternList)
379 if ValidArchStatement is not None:
380 NewSectionDict[DT.TAB_ARCH_COMMON] = NewSectionDict[DT.TAB_ARCH_COMMON] + [ValidArchStatement]
381 Content += GenSection('Defines', NewSectionDict)
382 return Content
383
384 def GenLibraryClasses(ModuleObject):
385 #
386 # generate [LibraryClasses] section
387 #
388 Content = ''
389 NewSectionDict = {}
390 if not GlobalData.gIS_BINARY_INF:
391 for LibraryClass in ModuleObject.GetLibraryClassList():
392 if LibraryClass.GetUsage() == DT.USAGE_ITEM_PRODUCES:
393 continue
394 #
395 # Generate generic comment
396 #
397 HelpTextList = LibraryClass.GetHelpTextList()
398 HelpStr = _GetHelpStr(HelpTextList)
399 CommentStr = GenGenericCommentF(HelpStr)
400 Statement = CommentStr
401 Name = LibraryClass.GetLibraryClass()
402 FFE = LibraryClass.GetFeatureFlag()
403 Statement += Name
404 if FFE:
405 Statement += '|' + FFE
406 ModuleList = LibraryClass.GetSupModuleList()
407 ArchList = LibraryClass.GetSupArchList()
408 for Index in xrange(0, len(ArchList)):
409 ArchList[Index] = ConvertArchForInstall(ArchList[Index])
410 ArchList.sort()
411 SortedArch = ' '.join(ArchList)
412 KeyList = []
413 if not ModuleList or IsAllModuleList(ModuleList):
414 KeyList = [SortedArch]
415 else:
416 ModuleString = DT.TAB_VALUE_SPLIT.join(l for l in ModuleList)
417 if not ArchList:
418 SortedArch = DT.TAB_ARCH_COMMON
419 KeyList = [SortedArch + '.' + ModuleString]
420 else:
421 KeyList = [Arch + '.' + ModuleString for Arch in ArchList]
422 for Key in KeyList:
423 if Key in NewSectionDict:
424 NewSectionDict[Key] = NewSectionDict[Key] + [Statement]
425 else:
426 NewSectionDict[Key] = [Statement]
427 Content += GenSection('LibraryClasses', NewSectionDict)
428 else:
429 LibraryClassDict = {}
430 for BinaryFile in ModuleObject.GetBinaryFileList():
431 if not BinaryFile.AsBuiltList:
432 continue
433 for LibraryItem in BinaryFile.AsBuiltList[0].LibraryInstancesList:
434 Statement = '# Guid: ' + LibraryItem.Guid + ' Version: ' + LibraryItem.Version
435
436 if len(BinaryFile.SupArchList) == 0:
437 if LibraryClassDict.has_key('COMMON') and Statement not in LibraryClassDict['COMMON']:
438 LibraryClassDict['COMMON'].append(Statement)
439 else:
440 LibraryClassDict['COMMON'] = ['## @LIB_INSTANCES']
441 LibraryClassDict['COMMON'].append(Statement)
442 else:
443 for Arch in BinaryFile.SupArchList:
444 if LibraryClassDict.has_key(Arch):
445 if Statement not in LibraryClassDict[Arch]:
446 LibraryClassDict[Arch].append(Statement)
447 else:
448 continue
449 else:
450 LibraryClassDict[Arch] = ['## @LIB_INSTANCES']
451 LibraryClassDict[Arch].append(Statement)
452 Content += GenSection('LibraryClasses', LibraryClassDict)
453
454 return Content
455
456 def GenPackages(ModuleObject):
457 Content = ''
458 #
459 # generate [Packages] section
460 #
461 NewSectionDict = Sdict()
462 WorkspaceDir = GlobalData.gWORKSPACE
463 for PackageDependency in ModuleObject.GetPackageDependencyList():
464 #
465 # Generate generic comment
466 #
467 CommentStr = ''
468 HelpText = PackageDependency.GetHelpText()
469 if HelpText:
470 HelpStr = HelpText.GetString()
471 CommentStr = GenGenericCommentF(HelpStr)
472 Statement = CommentStr
473 Guid = PackageDependency.GetGuid()
474 Version = PackageDependency.GetVersion()
475 FFE = PackageDependency.GetFeatureFlag()
476 Path = ''
477 #
478 # find package path/name
479 #
480 for PkgInfo in GlobalData.gWSPKG_LIST:
481 if Guid == PkgInfo[1]:
482 if (not Version) or (Version == PkgInfo[2]):
483 Path = PkgInfo[3]
484 break
485 #
486 # get relative path
487 #
488 RelaPath = GetRelativePath(Path, WorkspaceDir)
489 Statement += RelaPath.replace('\\', '/')
490 if FFE:
491 Statement += '|' + FFE
492 ArchList = PackageDependency.GetSupArchList()
493 ArchList.sort()
494 SortedArch = ' '.join(ArchList)
495 if SortedArch in NewSectionDict:
496 NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement]
497 else:
498 NewSectionDict[SortedArch] = [Statement]
499 Content += GenSection('Packages', NewSectionDict)
500 return Content
501
502 def GenSources(ModuleObject):
503 #
504 # generate [Sources] section
505 #
506 Content = ''
507 NewSectionDict = {}
508 for Source in ModuleObject.GetSourceFileList():
509 SourceFile = Source.GetSourceFile()
510 Family = Source.GetFamily()
511 FeatureFlag = Source.GetFeatureFlag()
512 SupArchList = Source.GetSupArchList()
513 SupArchList.sort()
514 SortedArch = ' '.join(SupArchList)
515 Statement = GenSourceStatement(ConvertPath(SourceFile), Family, FeatureFlag)
516 if SortedArch in NewSectionDict:
517 NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement]
518 else:
519 NewSectionDict[SortedArch] = [Statement]
520 Content += GenSection('Sources', NewSectionDict)
521
522 return Content
523
524 def GenDepex(ModuleObject):
525 #
526 # generate [Depex] section
527 #
528 NewSectionDict = Sdict()
529 Content = ''
530 for Depex in ModuleObject.GetPeiDepex() + ModuleObject.GetDxeDepex() + ModuleObject.GetSmmDepex():
531 HelpTextList = Depex.GetHelpTextList()
532 HelpStr = _GetHelpStr(HelpTextList)
533 CommentStr = GenGenericCommentF(HelpStr)
534 SupArchList = Depex.GetSupArchList()
535 SupModList = Depex.GetModuleType()
536 Expression = Depex.GetDepex()
537 Statement = CommentStr + Expression
538 SupArchList.sort()
539 KeyList = []
540 if not SupArchList:
541 SupArchList.append(DT.TAB_ARCH_COMMON.lower())
542 if not SupModList:
543 KeyList = SupArchList
544 else:
545 for ModuleType in SupModList:
546 for Arch in SupArchList:
547 KeyList.append(ConvertArchForInstall(Arch) + '.' + ModuleType)
548 for Key in KeyList:
549 if Key in NewSectionDict:
550 NewSectionDict[Key] = NewSectionDict[Key] + [Statement]
551 else:
552 NewSectionDict[Key] = [Statement]
553 Content += GenSection('Depex', NewSectionDict, False)
554
555 return Content
556 ## GenUserExtensions
557 #
558 # GenUserExtensions
559 #
560 def GenUserExtensions(ModuleObject):
561 NewSectionDict = {}
562 for UserExtension in ModuleObject.GetUserExtensionList():
563 if UserExtension.GetUserID() == DT.TAB_BINARY_HEADER_USERID and \
564 UserExtension.GetIdentifier() == DT.TAB_BINARY_HEADER_IDENTIFIER:
565 continue
566 if UserExtension.GetIdentifier() == 'Depex':
567 continue
568 Statement = UserExtension.GetStatement()
569 if not Statement:
570 continue
571 ArchList = UserExtension.GetSupArchList()
572 for Index in xrange(0, len(ArchList)):
573 ArchList[Index] = ConvertArchForInstall(ArchList[Index])
574 ArchList.sort()
575 KeyList = []
576 CommonPreFix = ''
577 if UserExtension.GetUserID():
578 CommonPreFix = UserExtension.GetUserID()
579 if CommonPreFix.find('.') > -1:
580 CommonPreFix = '"' + CommonPreFix + '"'
581 if UserExtension.GetIdentifier():
582 CommonPreFix += '.' + '"' + UserExtension.GetIdentifier() + '"'
583 if ArchList:
584 KeyList = [CommonPreFix + '.' + Arch for Arch in ArchList]
585 else:
586 KeyList = [CommonPreFix]
587 for Key in KeyList:
588 if Key in NewSectionDict:
589 NewSectionDict[Key] = NewSectionDict[Key] + [Statement]
590 else:
591 NewSectionDict[Key] = [Statement]
592 Content = GenSection('UserExtensions', NewSectionDict, False)
593
594 return Content
595
596 # GenSourceStatement
597 #
598 # @param SourceFile: string of source file path/name
599 # @param Family: string of source file family field
600 # @param FeatureFlag: string of source file FeatureFlag field
601 # @param TagName: string of source file TagName field
602 # @param ToolCode: string of source file ToolCode field
603 # @param HelpStr: string of source file HelpStr field
604 #
605 # @retval Statement: The generated statement for source
606 #
607 def GenSourceStatement(SourceFile, Family, FeatureFlag, TagName=None,
608 ToolCode=None, HelpStr=None):
609 Statement = ''
610 if HelpStr:
611 Statement += GenGenericCommentF(HelpStr)
612 #
613 # format of SourceFile|Family|TagName|ToolCode|FeatureFlag
614 #
615 Statement += SourceFile
616 if TagName == None:
617 TagName = ''
618 if ToolCode == None:
619 ToolCode = ''
620 if HelpStr == None:
621 HelpStr = ''
622 if FeatureFlag:
623 Statement += '|' + Family + '|' + TagName + '|' + ToolCode + '|' + FeatureFlag
624 elif ToolCode:
625 Statement += '|' + Family + '|' + TagName + '|' + ToolCode
626 elif TagName:
627 Statement += '|' + Family + '|' + TagName
628 elif Family:
629 Statement += '|' + Family
630 return Statement
631
632 # GenBinaryStatement
633 #
634 # @param Key: (FileName, FileType, FFE, SortedArch)
635 # @param Value: (Target, Family, TagName, Comment)
636 #
637 #
638 def GenBinaryStatement(Key, Value, SubTypeGuidValue=None):
639 (FileName, FileType, FFE, SortedArch) = Key
640 if SortedArch:
641 pass
642 if Value:
643 (Target, Family, TagName, Comment) = Value
644 else:
645 Target = ''
646 Family = ''
647 TagName = ''
648 Comment = ''
649 if Comment:
650 Statement = GenGenericCommentF(Comment)
651 else:
652 Statement = ''
653 if FileType == 'SUBTYPE_GUID' and SubTypeGuidValue:
654 Statement += FileType + '|' + SubTypeGuidValue + '|' + FileName
655 else:
656 Statement += FileType + '|' + FileName
657 if FileType in DT.BINARY_FILE_TYPE_UI_LIST + DT.BINARY_FILE_TYPE_VER_LIST:
658 if FFE:
659 Statement += '|' + Target + '|' + FFE
660 elif Target:
661 Statement += '|' + Target
662 else:
663 if FFE:
664 Statement += '|' + Target + '|' + Family + '|' + TagName + '|' + FFE
665 elif TagName:
666 Statement += '|' + Target + '|' + Family + '|' + TagName
667 elif Family:
668 Statement += '|' + Target + '|' + Family
669 elif Target:
670 Statement += '|' + Target
671 return Statement
672 ## GenGuidSections
673 #
674 # @param GuidObjList: List of GuidObject
675 # @retVal Content: The generated section contents
676 #
677 def GenGuidSections(GuidObjList):
678 #
679 # generate [Guids] section
680 #
681 Content = ''
682 GuidDict = Sdict()
683 for Guid in GuidObjList:
684 HelpTextList = Guid.GetHelpTextList()
685 HelpStr = _GetHelpStr(HelpTextList)
686 CName = Guid.GetCName()
687 FFE = Guid.GetFeatureFlag()
688 Statement = CName
689 if FFE:
690 Statement += '|' + FFE
691 Usage = Guid.GetUsage()
692 GuidType = Guid.GetGuidTypeList()[0]
693 VariableName = Guid.GetVariableName()
694 #
695 # Differentiate the generic comment and usage comment as multiple generic comment need to be put at first
696 #
697 if Usage == DT.ITEM_UNDEFINED and GuidType == DT.ITEM_UNDEFINED:
698 # generate list of generic comment
699 Comment = GenGenericCommentF(HelpStr)
700 else:
701 # generate list of other comment
702 Comment = HelpStr.replace('\n', ' ')
703 Comment = Comment.strip()
704 if Comment:
705 Comment = ' # ' + Comment
706 else:
707 Comment = ''
708 if Usage != DT.ITEM_UNDEFINED and GuidType == DT.ITEM_UNDEFINED:
709 Comment = '## ' + Usage + Comment
710 elif GuidType == 'Variable':
711 Comment = '## ' + Usage + ' ## ' + GuidType + ':' + VariableName + Comment
712 else:
713 Comment = '## ' + Usage + ' ## ' + GuidType + Comment
714
715 if Comment:
716 Comment += '\n'
717 #
718 # merge duplicate items
719 #
720 ArchList = Guid.GetSupArchList()
721 ArchList.sort()
722 SortedArch = ' '.join(ArchList)
723 if (Statement, SortedArch) in GuidDict:
724 PreviousComment = GuidDict[Statement, SortedArch]
725 Comment = PreviousComment + Comment
726 GuidDict[Statement, SortedArch] = Comment
727 NewSectionDict = GenMetaFileMisc.TransferDict(GuidDict, 'INF_GUID')
728 #
729 # generate the section contents
730 #
731 if NewSectionDict:
732 Content = GenSection('Guids', NewSectionDict)
733
734 return Content
735
736 ## GenProtocolPPiSections
737 #
738 # @param ObjList: List of ProtocolObject or Ppi Object
739 # @retVal Content: The generated section contents
740 #
741 def GenProtocolPPiSections(ObjList, IsProtocol):
742 Content = ''
743 Dict = Sdict()
744 for Object in ObjList:
745 HelpTextList = Object.GetHelpTextList()
746 HelpStr = _GetHelpStr(HelpTextList)
747 CName = Object.GetCName()
748 FFE = Object.GetFeatureFlag()
749 Statement = CName
750 if FFE:
751 Statement += '|' + FFE
752 Usage = Object.GetUsage()
753 Notify = Object.GetNotify()
754 #
755 # Differentiate the generic comment and usage comment as consecutive generic comment need to be put together
756 #
757 if Usage == DT.ITEM_UNDEFINED and Notify == '':
758 # generate list of generic comment
759 Comment = GenGenericCommentF(HelpStr)
760 else:
761 # generate list of other comment
762 Comment = HelpStr.replace('\n', ' ')
763 Comment = Comment.strip()
764 if Comment:
765 Comment = ' # ' + Comment
766 else:
767 Comment = ''
768 if Usage == DT.ITEM_UNDEFINED and not Comment and Notify == '':
769 Comment = ''
770 else:
771 if Notify:
772 Comment = '## ' + Usage + ' ## ' + 'NOTIFY' + Comment
773 else:
774 Comment = '## ' + Usage + Comment
775 if Comment:
776 Comment += '\n'
777 #
778 # merge duplicate items
779 #
780 ArchList = Object.GetSupArchList()
781 ArchList.sort()
782 SortedArch = ' '.join(ArchList)
783 if (Statement, SortedArch) in Dict:
784 PreviousComment = Dict[Statement, SortedArch]
785 Comment = PreviousComment + Comment
786 Dict[Statement, SortedArch] = Comment
787 NewSectionDict = GenMetaFileMisc.TransferDict(Dict, 'INF_PPI_PROTOCOL')
788 #
789 # generate the section contents
790 #
791 if NewSectionDict:
792 if IsProtocol:
793 Content = GenSection('Protocols', NewSectionDict)
794 else:
795 Content = GenSection('Ppis', NewSectionDict)
796
797 return Content
798
799 ## GenPcdSections
800 #
801 #
802 def GenPcdSections(ModuleObject):
803 Content = ''
804 if not GlobalData.gIS_BINARY_INF:
805 #
806 # for each Pcd Itemtype, maintain a dict so the same type will be grouped
807 # together
808 #
809 ItemTypeDict = {}
810 for Pcd in ModuleObject.GetPcdList():
811 HelpTextList = Pcd.GetHelpTextList()
812 HelpStr = _GetHelpStr(HelpTextList)
813 Statement = ''
814 CName = Pcd.GetCName()
815 TokenSpaceGuidCName = Pcd.GetTokenSpaceGuidCName()
816 DefaultValue = Pcd.GetDefaultValue()
817 ItemType = Pcd.GetItemType()
818 if ItemType in ItemTypeDict:
819 Dict = ItemTypeDict[ItemType]
820 else:
821 Dict = Sdict()
822 ItemTypeDict[ItemType] = Dict
823 FFE = Pcd.GetFeatureFlag()
824 Statement += TokenSpaceGuidCName + '.' + CName
825 if DefaultValue:
826 Statement += '|' + DefaultValue
827 if FFE:
828 Statement += '|' + FFE
829 elif FFE:
830 Statement += '||' + FFE
831 #
832 # Generate comment
833 #
834 Usage = Pcd.GetValidUsage()
835 # if FeatureFlag Pcd, then assume all Usage is CONSUMES
836 if ItemType == DT.TAB_INF_FEATURE_PCD:
837 Usage = DT.USAGE_ITEM_CONSUMES
838 if Usage == DT.ITEM_UNDEFINED:
839 # generate list of generic comment
840 Comment = GenGenericCommentF(HelpStr)
841 else:
842 # generate list of other comment
843 Comment = HelpStr.replace('\n', ' ')
844 Comment = Comment.strip()
845 if Comment:
846 Comment = ' # ' + Comment
847 else:
848 Comment = ''
849 Comment = '## ' + Usage + Comment
850 if Comment:
851 Comment += '\n'
852 #
853 # Merge duplicate entries
854 #
855 ArchList = Pcd.GetSupArchList()
856 ArchList.sort()
857 SortedArch = ' '.join(ArchList)
858 if (Statement, SortedArch) in Dict:
859 PreviousComment = Dict[Statement, SortedArch]
860 Comment = PreviousComment + Comment
861 Dict[Statement, SortedArch] = Comment
862 for ItemType in ItemTypeDict:
863 # First we need to transfer the Dict to use SortedArch as key
864 Dict = ItemTypeDict[ItemType]
865 NewSectionDict = GenMetaFileMisc.TransferDict(Dict, 'INF_PCD')
866 if NewSectionDict:
867 Content += GenSection(ItemType, NewSectionDict)
868 #
869 # For AsBuild INF files
870 #
871 else:
872 Content += GenAsBuiltPacthPcdSections(ModuleObject)
873 Content += GenAsBuiltPcdExSections(ModuleObject)
874
875 return Content
876
877 ## GenPcdSections
878 #
879 #
880 def GenAsBuiltPacthPcdSections(ModuleObject):
881 PatchPcdDict = {}
882 for BinaryFile in ModuleObject.GetBinaryFileList():
883 if not BinaryFile.AsBuiltList:
884 continue
885 for PatchPcd in BinaryFile.AsBuiltList[0].PatchPcdList:
886 TokenSpaceName = ''
887 PcdCName = PatchPcd.CName
888 PcdValue = PatchPcd.DefaultValue
889 PcdOffset = PatchPcd.Offset
890 TokenSpaceGuidValue = PatchPcd.TokenSpaceGuidValue
891 Token = PatchPcd.Token
892 HelpTextList = PatchPcd.HelpTextList
893 HelpString = ''
894 for HelpStringItem in HelpTextList:
895 for HelpLine in GetSplitValueList(HelpStringItem.String, '\n'):
896 HelpString += '## ' + HelpLine + '\n'
897 TokenSpaceName, PcdCName = GenMetaFileMisc.ObtainPcdName(ModuleObject.PackageDependencyList,
898 TokenSpaceGuidValue,
899 Token)
900 if TokenSpaceName == '' or PcdCName == '':
901 Logger.Error("Upt",
902 ToolError.RESOURCE_NOT_AVAILABLE,
903 ST.ERR_INSTALL_FILE_DEC_FILE_ERROR % (TokenSpaceGuidValue, Token),
904 File=ModuleObject.GetFullPath())
905 Statement = HelpString + TokenSpaceName + '.' + PcdCName + ' | ' + PcdValue + ' | ' + \
906 PcdOffset + DT.TAB_SPACE_SPLIT
907 #
908 # Use binary file's Arch to be Pcd's Arch
909 #
910 ArchList = []
911 FileNameObjList = BinaryFile.GetFileNameList()
912 if FileNameObjList:
913 ArchList = FileNameObjList[0].GetSupArchList()
914 if len(ArchList) == 0:
915 if PatchPcdDict.has_key(DT.TAB_ARCH_COMMON):
916 if Statement not in PatchPcdDict[DT.TAB_ARCH_COMMON]:
917 PatchPcdDict[DT.TAB_ARCH_COMMON].append(Statement)
918 else:
919 PatchPcdDict[DT.TAB_ARCH_COMMON] = [Statement]
920 else:
921 for Arch in ArchList:
922 if PatchPcdDict.has_key(Arch):
923 if Statement not in PatchPcdDict[Arch]:
924 PatchPcdDict[Arch].append(Statement)
925 else:
926 PatchPcdDict[Arch] = [Statement]
927 return GenSection(DT.TAB_INF_PATCH_PCD, PatchPcdDict)
928 ## GenPcdSections
929 #
930 #
931 def GenAsBuiltPcdExSections(ModuleObject):
932 PcdExDict = {}
933 for BinaryFile in ModuleObject.GetBinaryFileList():
934 if not BinaryFile.AsBuiltList:
935 continue
936 for PcdExItem in BinaryFile.AsBuiltList[0].PcdExValueList:
937 TokenSpaceName = ''
938 PcdCName = PcdExItem.CName
939 TokenSpaceGuidValue = PcdExItem.TokenSpaceGuidValue
940 Token = PcdExItem.Token
941 HelpTextList = PcdExItem.HelpTextList
942 HelpString = ''
943 for HelpStringItem in HelpTextList:
944 for HelpLine in GetSplitValueList(HelpStringItem.String, '\n'):
945 HelpString += '## ' + HelpLine + '\n'
946 TokenSpaceName, PcdCName = GenMetaFileMisc.ObtainPcdName(ModuleObject.PackageDependencyList,
947 TokenSpaceGuidValue, Token)
948 if TokenSpaceName == '' or PcdCName == '':
949 Logger.Error("Upt",
950 ToolError.RESOURCE_NOT_AVAILABLE,
951 ST.ERR_INSTALL_FILE_DEC_FILE_ERROR % (TokenSpaceGuidValue, Token),
952 File=ModuleObject.GetFullPath())
953
954 Statement = HelpString + TokenSpaceName + DT.TAB_SPLIT + PcdCName + DT.TAB_SPACE_SPLIT
955
956 #
957 # Use binary file's Arch to be Pcd's Arch
958 #
959 ArchList = []
960 FileNameObjList = BinaryFile.GetFileNameList()
961 if FileNameObjList:
962 ArchList = FileNameObjList[0].GetSupArchList()
963
964 if len(ArchList) == 0:
965 if PcdExDict.has_key('COMMON'):
966 PcdExDict['COMMON'].append(Statement)
967 else:
968 PcdExDict['COMMON'] = [Statement]
969 else:
970 for Arch in ArchList:
971 if PcdExDict.has_key(Arch):
972 if Statement not in PcdExDict[Arch]:
973 PcdExDict[Arch].append(Statement)
974 else:
975 PcdExDict[Arch] = [Statement]
976 return GenSection('PcdEx', PcdExDict)
977
978 ## GenSpecialSections
979 # generate special sections for Event/BootMode/Hob
980 #
981 def GenSpecialSections(ObjectList, SectionName):
982 #
983 # generate section
984 #
985 Content = ''
986 NewSectionDict = {}
987 for Obj in ObjectList:
988 #
989 # Generate comment
990 #
991 CommentStr = ''
992 HelpTextList = Obj.GetHelpTextList()
993 HelpStr = _GetHelpStr(HelpTextList)
994 CommentStr = GenGenericCommentF(HelpStr)
995 if SectionName == 'Hob':
996 Type = Obj.GetHobType()
997 elif SectionName == 'Event':
998 Type = Obj.GetEventType()
999 elif SectionName == 'BootMode':
1000 Type = Obj.GetSupportedBootModes()
1001 else:
1002 assert(SectionName)
1003 Usage = Obj.GetUsage()
1004 Statement = ' ' + Type + ' ## ' + Usage
1005 if CommentStr in ['#\n', '#\n#\n']:
1006 CommentStr = '#\n#\n#\n'
1007 #
1008 # the first head comment line should start with '##\n', if it starts with '#\n', then add one '#'
1009 # else add '##\n' to meet the format defined in INF spec
1010 #
1011 if CommentStr.startswith('#\n'):
1012 CommentStr = '#' + CommentStr
1013 elif CommentStr:
1014 CommentStr = '##\n' + CommentStr
1015 if CommentStr and not CommentStr.endswith('\n#\n'):
1016 CommentStr = CommentStr + '#\n'
1017 NewStateMent = CommentStr + Statement
1018 SupArch = Obj.GetSupArchList()
1019 SupArch.sort()
1020 SortedArch = ' '.join(SupArch)
1021 if SortedArch in NewSectionDict:
1022 NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [NewStateMent]
1023 else:
1024 NewSectionDict[SortedArch] = [NewStateMent]
1025 SectionContent = GenSection(SectionName, NewSectionDict)
1026 SectionContent = SectionContent.strip()
1027 if SectionContent:
1028 Content = '# ' + ('\n' + '# ').join(GetSplitValueList(SectionContent, '\n'))
1029 Content = Content.lstrip()
1030 #
1031 # add a return to differentiate it between other possible sections
1032 #
1033 if Content:
1034 Content += '\n'
1035 return Content
1036 ## GenBuildOptions
1037 #
1038 #
1039 def GenBuildOptions(ModuleObject):
1040 Content = ''
1041 if not ModuleObject.BinaryModule:
1042 #
1043 # generate [BuildOptions] section
1044 #
1045 NewSectionDict = {}
1046 for UserExtension in ModuleObject.GetUserExtensionList():
1047 BuildOptionDict = UserExtension.GetBuildOptionDict()
1048 if not BuildOptionDict:
1049 continue
1050 for Arch in BuildOptionDict:
1051 if Arch in NewSectionDict:
1052 NewSectionDict[Arch] = NewSectionDict[Arch] + [BuildOptionDict[Arch]]
1053 else:
1054 NewSectionDict[Arch] = [BuildOptionDict[Arch]]
1055 Content = GenSection('BuildOptions', NewSectionDict)
1056 else:
1057 BuildOptionDict = {}
1058 for BinaryFile in ModuleObject.GetBinaryFileList():
1059 if not BinaryFile.AsBuiltList:
1060 continue
1061 for BuilOptionItem in BinaryFile.AsBuiltList[0].BinaryBuildFlagList:
1062 Statement = '#' + BuilOptionItem.AsBuiltOptionFlags
1063 if len(BinaryFile.SupArchList) == 0:
1064 if BuildOptionDict.has_key('COMMON'):
1065 if Statement not in BuildOptionDict['COMMON']:
1066 BuildOptionDict['COMMON'].append(Statement)
1067 else:
1068 BuildOptionDict['COMMON'] = ['## @AsBuilt']
1069 BuildOptionDict['COMMON'].append(Statement)
1070 else:
1071 for Arch in BinaryFile.SupArchList:
1072 if BuildOptionDict.has_key(Arch):
1073 if Statement not in BuildOptionDict[Arch]:
1074 BuildOptionDict[Arch].append(Statement)
1075 else:
1076 BuildOptionDict[Arch] = ['## @AsBuilt']
1077 BuildOptionDict[Arch].append(Statement)
1078 Content = GenSection('BuildOptions', BuildOptionDict)
1079
1080 return Content
1081 ## GenBinaries
1082 #
1083 #
1084 def GenBinaries(ModuleObject):
1085 NewSectionDict = {}
1086 BinariesDict = []
1087 for UserExtension in ModuleObject.GetUserExtensionList():
1088 BinariesDict = UserExtension.GetBinariesDict()
1089 if BinariesDict:
1090 break
1091 for BinaryFile in ModuleObject.GetBinaryFileList():
1092 FileNameObjList = BinaryFile.GetFileNameList()
1093 for FileNameObj in FileNameObjList:
1094 FileName = ConvertPath(FileNameObj.GetFilename())
1095 FileType = FileNameObj.GetFileType()
1096 FFE = FileNameObj.GetFeatureFlag()
1097 ArchList = FileNameObj.GetSupArchList()
1098 ArchList.sort()
1099 SortedArch = ' '.join(ArchList)
1100 Key = (FileName, FileType, FFE, SortedArch)
1101 if Key in BinariesDict:
1102 ValueList = BinariesDict[Key]
1103 for ValueItem in ValueList:
1104 Statement = GenBinaryStatement(Key, ValueItem)
1105 if SortedArch in NewSectionDict:
1106 NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement]
1107 else:
1108 NewSectionDict[SortedArch] = [Statement]
1109 #
1110 # as we already generated statement for this DictKey here set the Valuelist to be empty
1111 # to avoid generate duplicate entries as the DictKey may have multiple entries
1112 #
1113 BinariesDict[Key] = []
1114 else:
1115 if FileType == 'SUBTYPE_GUID' and FileNameObj.GetGuidValue():
1116 Statement = GenBinaryStatement(Key, None, FileNameObj.GetGuidValue())
1117 else:
1118 Statement = GenBinaryStatement(Key, None)
1119 if SortedArch in NewSectionDict:
1120 NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement]
1121 else:
1122 NewSectionDict[SortedArch] = [Statement]
1123 Content = GenSection('Binaries', NewSectionDict)
1124
1125 return Content