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