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