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''' 16GenInf 17''' 18import os 19import stat 20import codecs 21import md5 22from Core.FileHook import __FileHookOpen__ 23from Library.String import GetSplitValueList 24from Library.Parsing import GenSection 25from Library.Parsing import GetWorkspacePackage 26from Library.Parsing import ConvertArchForInstall 27from Library.Misc import SaveFileOnChange 28from Library.Misc import IsAllModuleList 29from Library.Misc import Sdict 30from Library.Misc import ConvertPath 31from Library.Misc import ConvertSpec 32from Library.Misc import GetRelativePath 33from Library.Misc import GetLocalValue 34from Library.CommentGenerating import GenHeaderCommentSection 35from Library.CommentGenerating import GenGenericCommentF 36from Library.CommentGenerating import _GetHelpStr 37from Library import GlobalData 38from Logger import StringTable as ST 39from Logger import ToolError 40import Logger.Log as Logger 41from Library import DataType as DT 42from GenMetaFile import GenMetaFileMisc 43from 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# 51def 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# 190def 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 260def 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 384def 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 456def 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 502def 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 524def 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# 560def 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# 607def 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# 638def 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# 677def 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# 741def 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# 802def 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# 880def 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# 931def 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# 981def 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# 1039def 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# 1084def 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 1126