1## @file 2# This file is used to define each component of the build database 3# 4# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR> 5# This program and the accompanying materials 6# are licensed and made available under the terms and conditions of the BSD License 7# which accompanies this distribution. The full text of the license may be found at 8# http://opensource.org/licenses/bsd-license.php 9# 10# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12# 13 14## 15# Import Modules 16# 17import Common.LongFilePathOs as os, string, copy, pdb, copy 18import EdkLogger 19import DataType 20from InfClassObject import * 21from DecClassObject import * 22from DscClassObject import * 23from String import * 24from BuildToolError import * 25from Misc import sdict 26import Database as Database 27import time as time 28 29## PcdClassObject 30# 31# This Class is used for PcdObject 32# 33# @param object: Inherited from object class 34# @param Name: Input value for Name of Pcd, default is None 35# @param Guid: Input value for Guid of Pcd, default is None 36# @param Type: Input value for Type of Pcd, default is None 37# @param DatumType: Input value for DatumType of Pcd, default is None 38# @param Value: Input value for Value of Pcd, default is None 39# @param Token: Input value for Token of Pcd, default is None 40# @param MaxDatumSize: Input value for MaxDatumSize of Pcd, default is None 41# @param SkuInfoList: Input value for SkuInfoList of Pcd, default is {} 42# @param IsOverrided: Input value for IsOverrided of Pcd, default is False 43# 44# @var TokenCName: To store value for TokenCName 45# @var TokenSpaceGuidCName: To store value for TokenSpaceGuidCName 46# @var Type: To store value for Type 47# @var DatumType: To store value for DatumType 48# @var TokenValue: To store value for TokenValue 49# @var MaxDatumSize: To store value for MaxDatumSize 50# @var SkuInfoList: To store value for SkuInfoList 51# @var IsOverrided: To store value for IsOverrided 52# @var Phase: To store value for Phase, default is "DXE" 53# 54class PcdClassObject(object): 55 def __init__(self, Name = None, Guid = None, Type = None, DatumType = None, Value = None, Token = None, MaxDatumSize = None, SkuInfoList = {}, IsOverrided = False): 56 self.TokenCName = Name 57 self.TokenSpaceGuidCName = Guid 58 self.Type = Type 59 self.DatumType = DatumType 60 self.DefaultValue = Value 61 self.TokenValue = Token 62 self.MaxDatumSize = MaxDatumSize 63 self.SkuInfoList = SkuInfoList 64 self.IsOverrided = IsOverrided 65 self.Phase = "DXE" 66 67 ## Convert the class to a string 68 # 69 # Convert each member of the class to string 70 # Organize to a signle line format string 71 # 72 # @retval Rtn Formatted String 73 # 74 def __str__(self): 75 Rtn = '\tTokenCName=' + str(self.TokenCName) + ', ' + \ 76 'TokenSpaceGuidCName=' + str(self.TokenSpaceGuidCName) + ', ' + \ 77 'Type=' + str(self.Type) + ', ' + \ 78 'DatumType=' + str(self.DatumType) + ', ' + \ 79 'DefaultValue=' + str(self.DefaultValue) + ', ' + \ 80 'TokenValue=' + str(self.TokenValue) + ', ' + \ 81 'MaxDatumSize=' + str(self.MaxDatumSize) + ', ' 82 for Item in self.SkuInfoList.values(): 83 Rtn = Rtn + 'SkuId=' + Item.SkuId + ', ' + 'SkuIdName=' + Item.SkuIdName 84 Rtn = Rtn + str(self.IsOverrided) 85 86 return Rtn 87 88 ## Override __eq__ function 89 # 90 # Check whether pcds are the same 91 # 92 # @retval False The two pcds are different 93 # @retval True The two pcds are the same 94 # 95 def __eq__(self, Other): 96 return Other != None and self.TokenCName == Other.TokenCName and self.TokenSpaceGuidCName == Other.TokenSpaceGuidCName 97 98 ## Override __hash__ function 99 # 100 # Use (TokenCName, TokenSpaceGuidCName) as key in hash table 101 # 102 # @retval truple() Key for hash table 103 # 104 def __hash__(self): 105 return hash((self.TokenCName, self.TokenSpaceGuidCName)) 106 107## LibraryClassObject 108# 109# This Class defines LibraryClassObject used in BuildDatabase 110# 111# @param object: Inherited from object class 112# @param Name: Input value for LibraryClassName, default is None 113# @param SupModList: Input value for SupModList, default is [] 114# @param Type: Input value for Type, default is None 115# 116# @var LibraryClass: To store value for LibraryClass 117# @var SupModList: To store value for SupModList 118# @var Type: To store value for Type 119# 120class LibraryClassObject(object): 121 def __init__(self, Name = None, SupModList = [], Type = None): 122 self.LibraryClass = Name 123 self.SupModList = SupModList 124 if Type != None: 125 self.SupModList = CleanString(Type).split(DataType.TAB_SPACE_SPLIT) 126 127## ModuleBuildClassObject 128# 129# This Class defines ModuleBuildClass 130# 131# @param object: Inherited from object class 132# 133# @var DescFilePath: To store value for DescFilePath 134# @var BaseName: To store value for BaseName 135# @var ModuleType: To store value for ModuleType 136# @var Guid: To store value for Guid 137# @var Version: To store value for Version 138# @var PcdIsDriver: To store value for PcdIsDriver 139# @var BinaryModule: To store value for BinaryModule 140# @var CustomMakefile: To store value for CustomMakefile 141# @var Specification: To store value for Specification 142# @var Shadow To store value for Shadow 143# @var LibraryClass: To store value for LibraryClass, it is a list structure as 144# [ LibraryClassObject, ...] 145# @var ModuleEntryPointList: To store value for ModuleEntryPointList 146# @var ModuleUnloadImageList: To store value for ModuleUnloadImageList 147# @var ConstructorList: To store value for ConstructorList 148# @var DestructorList: To store value for DestructorList 149# @var Binaries: To store value for Binaries, it is a list structure as 150# [ ModuleBinaryClassObject, ...] 151# @var Sources: To store value for Sources, it is a list structure as 152# [ ModuleSourceFilesClassObject, ... ] 153# @var LibraryClasses: To store value for LibraryClasses, it is a set structure as 154# { [LibraryClassName, ModuleType] : LibraryClassInfFile } 155# @var Protocols: To store value for Protocols, it is a list structure as 156# [ ProtocolName, ... ] 157# @var Ppis: To store value for Ppis, it is a list structure as 158# [ PpiName, ... ] 159# @var Guids: To store value for Guids, it is a list structure as 160# [ GuidName, ... ] 161# @var Includes: To store value for Includes, it is a list structure as 162# [ IncludePath, ... ] 163# @var Packages: To store value for Packages, it is a list structure as 164# [ DecFileName, ... ] 165# @var Pcds: To store value for Pcds, it is a set structure as 166# { [(PcdCName, PcdGuidCName)] : PcdClassObject} 167# @var BuildOptions: To store value for BuildOptions, it is a set structure as 168# { [BuildOptionKey] : BuildOptionValue} 169# @var Depex: To store value for Depex 170# 171class ModuleBuildClassObject(object): 172 def __init__(self): 173 self.AutoGenVersion = 0 174 self.DescFilePath = '' 175 self.BaseName = '' 176 self.ModuleType = '' 177 self.Guid = '' 178 self.Version = '' 179 self.PcdIsDriver = '' 180 self.BinaryModule = '' 181 self.Shadow = '' 182 self.CustomMakefile = {} 183 self.Specification = {} 184 self.LibraryClass = [] 185 self.ModuleEntryPointList = [] 186 self.ModuleUnloadImageList = [] 187 self.ConstructorList = [] 188 self.DestructorList = [] 189 190 self.Binaries = [] 191 self.Sources = [] 192 self.LibraryClasses = sdict() 193 self.Libraries = [] 194 self.Protocols = [] 195 self.Ppis = [] 196 self.Guids = [] 197 self.Includes = [] 198 self.Packages = [] 199 self.Pcds = {} 200 self.BuildOptions = {} 201 self.Depex = '' 202 203 ## Convert the class to a string 204 # 205 # Convert member DescFilePath of the class to a string 206 # 207 # @retval string Formatted String 208 # 209 def __str__(self): 210 return self.DescFilePath 211 212 ## Override __eq__ function 213 # 214 # Check whether ModuleBuildClassObjects are the same 215 # 216 # @retval False The two ModuleBuildClassObjects are different 217 # @retval True The two ModuleBuildClassObjects are the same 218 # 219 def __eq__(self, Other): 220 return self.DescFilePath == str(Other) 221 222 ## Override __hash__ function 223 # 224 # Use DescFilePath as key in hash table 225 # 226 # @retval string Key for hash table 227 # 228 def __hash__(self): 229 return hash(self.DescFilePath) 230 231## PackageBuildClassObject 232# 233# This Class defines PackageBuildClass 234# 235# @param object: Inherited from object class 236# 237# @var DescFilePath: To store value for DescFilePath 238# @var PackageName: To store value for PackageName 239# @var Guid: To store value for Guid 240# @var Version: To store value for Version 241# @var Protocols: To store value for Protocols, it is a set structure as 242# { [ProtocolName] : Protocol Guid, ... } 243# @var Ppis: To store value for Ppis, it is a set structure as 244# { [PpiName] : Ppi Guid, ... } 245# @var Guids: To store value for Guids, it is a set structure as 246# { [GuidName] : Guid, ... } 247# @var Includes: To store value for Includes, it is a list structure as 248# [ IncludePath, ... ] 249# @var LibraryClasses: To store value for LibraryClasses, it is a set structure as 250# { [LibraryClassName] : LibraryClassInfFile } 251# @var Pcds: To store value for Pcds, it is a set structure as 252# { [(PcdCName, PcdGuidCName)] : PcdClassObject} 253# 254class PackageBuildClassObject(object): 255 def __init__(self): 256 self.DescFilePath = '' 257 self.PackageName = '' 258 self.Guid = '' 259 self.Version = '' 260 261 self.Protocols = {} 262 self.Ppis = {} 263 self.Guids = {} 264 self.Includes = [] 265 self.LibraryClasses = {} 266 self.Pcds = {} 267 268 ## Convert the class to a string 269 # 270 # Convert member DescFilePath of the class to a string 271 # 272 # @retval string Formatted String 273 # 274 def __str__(self): 275 return self.DescFilePath 276 277 ## Override __eq__ function 278 # 279 # Check whether PackageBuildClassObjects are the same 280 # 281 # @retval False The two PackageBuildClassObjects are different 282 # @retval True The two PackageBuildClassObjects are the same 283 # 284 def __eq__(self, Other): 285 return self.DescFilePath == str(Other) 286 287 ## Override __hash__ function 288 # 289 # Use DescFilePath as key in hash table 290 # 291 # @retval string Key for hash table 292 # 293 def __hash__(self): 294 return hash(self.DescFilePath) 295 296## PlatformBuildClassObject 297# 298# This Class defines PlatformBuildClass 299# 300# @param object: Inherited from object class 301# 302# @var DescFilePath: To store value for DescFilePath 303# @var PlatformName: To store value for PlatformName 304# @var Guid: To store value for Guid 305# @var Version: To store value for Version 306# @var DscSpecification: To store value for DscSpecification 307# @var OutputDirectory: To store value for OutputDirectory 308# @var FlashDefinition: To store value for FlashDefinition 309# @var BuildNumber: To store value for BuildNumber 310# @var MakefileName: To store value for MakefileName 311# @var SkuIds: To store value for SkuIds, it is a set structure as 312# { 'SkuName' : SkuId, '!include' : includefilename, ...} 313# @var Modules: To store value for Modules, it is a list structure as 314# [ InfFileName, ... ] 315# @var Libraries: To store value for Libraries, it is a list structure as 316# [ InfFileName, ... ] 317# @var LibraryClasses: To store value for LibraryClasses, it is a set structure as 318# { (LibraryClassName, ModuleType) : LibraryClassInfFile } 319# @var Pcds: To store value for Pcds, it is a set structure as 320# { [(PcdCName, PcdGuidCName)] : PcdClassObject } 321# @var BuildOptions: To store value for BuildOptions, it is a set structure as 322# { [BuildOptionKey] : BuildOptionValue } 323# 324class PlatformBuildClassObject(object): 325 def __init__(self): 326 self.DescFilePath = '' 327 self.PlatformName = '' 328 self.Guid = '' 329 self.Version = '' 330 self.DscSpecification = '' 331 self.OutputDirectory = '' 332 self.FlashDefinition = '' 333 self.BuildNumber = '' 334 self.MakefileName = '' 335 336 self.SkuIds = {} 337 self.Modules = [] 338 self.LibraryInstances = [] 339 self.LibraryClasses = {} 340 self.Libraries = {} 341 self.Pcds = {} 342 self.BuildOptions = {} 343 344 ## Convert the class to a string 345 # 346 # Convert member DescFilePath of the class to a string 347 # 348 # @retval string Formatted String 349 # 350 def __str__(self): 351 return self.DescFilePath 352 353 ## Override __eq__ function 354 # 355 # Check whether PlatformBuildClassObjects are the same 356 # 357 # @retval False The two PlatformBuildClassObjects are different 358 # @retval True The two PlatformBuildClassObjects are the same 359 # 360 def __eq__(self, other): 361 return self.DescFilePath == str(other) 362 363 ## Override __hash__ function 364 # 365 # Use DescFilePath as key in hash table 366 # 367 # @retval string Key for hash table 368 # 369 def __hash__(self): 370 return hash(self.DescFilePath) 371 372## ItemBuild 373# 374# This Class defines Module/Platform/Package databases for build system 375# 376# @param object: Inherited from object class 377# @param Arch: Build arch 378# @param Platform: Build Platform 379# @param Package: Build Package 380# @param Module: Build Module 381# 382# @var Arch: To store value for Build Arch 383# @var PlatformDatabase: To store value for PlatformDatabase, it is a set structure as 384# { [DscFileName] : PlatformBuildClassObject, ...} 385# @var PackageDatabase: To store value for PackageDatabase, it is a set structure as 386# { [DecFileName] : PacakgeBuildClassObject, ...} 387# @var ModuleDatabase: To store value for ModuleDatabase, it is a list structure as 388# { [InfFileName] : ModuleBuildClassObject, ...} 389# 390class ItemBuild(object): 391 def __init__(self, Arch, Platform = None, Package = None, Module = None): 392 self.Arch = Arch 393 self.PlatformDatabase = {} 394 self.PackageDatabase = {} 395 self.ModuleDatabase = {} 396 397## WorkspaceBuild 398# 399# This class is used to parse active platform to init all inf/dec/dsc files 400# Generate module/package/platform databases for build 401# 402# @param object: Inherited from object class 403# @param ActivePlatform: Input value for current active platform 404# @param WorkspaceDir: Input value for current WorkspaceDir 405# 406# @var WorkspaceDir: To store value for WorkspaceDir 407# @var SupArchList: To store value for SupArchList, selection scope is in below list 408# EBC | IA32 | X64 | IPF | ARM | PPC | AARCH64 409# @var BuildTarget: To store value for WorkspaceDir, selection scope is in below list 410# RELEASE | DEBUG 411# @var SkuId: To store value for SkuId 412# @var Fdf: To store value for Fdf 413# @var FdTargetList: To store value for FdTargetList 414# @var FvTargetList: To store value for FvTargetList 415# @var TargetTxt: To store value for TargetTxt, it is a set structure as 416# TargetTxtClassObject 417# @var ToolDef: To store value for ToolDef, it is a set structure as 418# ToolDefClassObject 419# @var InfDatabase: To store value for InfDatabase, it is a set structure as 420# { [InfFileName] : InfClassObject} 421# @var DecDatabase: To store value for DecDatabase, it is a set structure as 422# { [DecFileName] : DecClassObject} 423# @var DscDatabase: To store value for DscDatabase, it is a set structure as 424# { [DscFileName] : DscClassObject} 425# @var Build: To store value for DscDatabase, it is a set structure as 426# ItemBuild 427# @var DscFileName: To store value for Active Platform 428# @var UnFoundPcdInDsc: To store values for the pcds defined in INF/DEC but not found in DSC, it is a set structure as 429# { (PcdGuid, PcdCName, Arch) : DecFileName } 430# 431class WorkspaceBuild(object): 432 def __init__(self, ActivePlatform, WorkspaceDir): 433 self.WorkspaceDir = NormPath(WorkspaceDir) 434 self.SupArchList = [] 435 self.BuildTarget = [] 436 self.SkuId = '' 437 self.Fdf = '' 438 self.FdTargetList = [] 439 self.FvTargetList = [] 440 self.TargetTxt = None 441 self.ToolDef = None 442 443 self.InfDatabase = {} 444 self.DecDatabase = {} 445 self.DscDatabase = {} 446 447 self.UnFoundPcdInDsc = {} 448 449 # 450 # Init build for all arches 451 # 452 self.Build = {} 453 for Arch in DataType.ARCH_LIST: 454 self.Build[Arch] = ItemBuild(Arch) 455 456 # 457 # Init build database 458 # 459 self.Db = Database.Database(DATABASE_PATH) 460 self.Db.InitDatabase() 461 462 # 463 # Get active platform 464 # 465 self.DscFileName = NormPath(ActivePlatform) 466 File = self.WorkspaceFile(self.DscFileName) 467 if os.path.exists(File) and os.path.isfile(File): 468 self.DscDatabase[self.DscFileName] = Dsc(File, False, True, self.WorkspaceDir, self.Db) 469 else: 470 EdkLogger.error("AutoGen", FILE_NOT_FOUND, ExtraData = File) 471 472 # 473 # Parse platform to get module 474 # 475 for DscFile in self.DscDatabase.keys(): 476 Platform = self.DscDatabase[DscFile].Platform 477 478 # 479 # Get global information 480 # 481 Tmp = set() 482 for Arch in DataType.ARCH_LIST: 483 for Item in Platform.Header[Arch].SupArchList: 484 Tmp.add(Item) 485 self.SupArchList = list(Tmp) 486 Tmp = set() 487 for Arch in DataType.ARCH_LIST: 488 for Item in Platform.Header[Arch].BuildTargets: 489 Tmp.add(Item) 490 self.BuildTarget = list(Tmp) 491 for Arch in self.SupArchList: 492 self.SkuId = Platform.Header[Arch].SkuIdName 493 self.Fdf = Platform.FlashDefinitionFile.FilePath 494 495 # 496 # Get all inf files 497 # 498 for Item in Platform.LibraryClasses.LibraryList: 499 for Arch in Item.SupArchList: 500 self.AddToInfDatabase(Item.FilePath) 501 502 for Item in Platform.Libraries.LibraryList: 503 for Arch in Item.SupArchList: 504 self.AddToInfDatabase(Item.FilePath) 505 506 for Item in Platform.Modules.ModuleList: 507 for Arch in Item.SupArchList: 508 # 509 # Add modules 510 # 511 Module = Item.FilePath 512 self.AddToInfDatabase(Module) 513 # 514 # Add library used in modules 515 # 516 for Lib in Item.LibraryClasses.LibraryList: 517 self.AddToInfDatabase(Lib.FilePath) 518 self.UpdateLibraryClassOfModule(Module, Lib.Name, Arch, Lib.FilePath) 519 520 # 521 # Parse module to get package 522 # 523 for InfFile in self.InfDatabase.keys(): 524 Module = self.InfDatabase[InfFile].Module 525 # 526 # Get all dec 527 # 528 for Item in Module.PackageDependencies: 529 for Arch in Item.SupArchList: 530 self.AddToDecDatabase(Item.FilePath) 531 # End of self.Init() 532 533 ## Generate PlatformDatabase 534 # 535 # Go through each arch to get all items in DscDatabase to PlatformDatabase 536 # 537 def GenPlatformDatabase(self, PcdsSet={}): 538 for Dsc in self.DscDatabase.keys(): 539 Platform = self.DscDatabase[Dsc].Platform 540 for Arch in self.SupArchList: 541 Pb = PlatformBuildClassObject() 542 543 # 544 # Defines 545 # 546 Pb.DescFilePath = Dsc 547 Pb.PlatformName = Platform.Header[Arch].Name 548 if Pb.PlatformName == '': 549 EdkLogger.error("AutoGen", PARSER_ERROR, "The BaseName of platform %s is not defined for arch %s" % (Dsc, Arch)) 550 Pb.Guid = Platform.Header[Arch].Guid 551 Pb.Version = Platform.Header[Arch].Version 552 Pb.DscSpecification = Platform.Header[Arch].DscSpecification 553 Pb.OutputDirectory = Platform.Header[Arch].OutputDirectory 554 Pb.FlashDefinition = Platform.FlashDefinitionFile.FilePath 555 Pb.BuildNumber = Platform.Header[Arch].BuildNumber 556 557 # 558 # SkuId 559 # 560 for Key in Platform.SkuInfos.SkuInfoList.keys(): 561 Pb.SkuIds[Key] = Platform.SkuInfos.SkuInfoList[Key] 562 563 # 564 # Module 565 # 566 for Item in Platform.Modules.ModuleList: 567 if Arch in Item.SupArchList: 568 Pb.Modules.append(Item.FilePath) 569 570 # 571 # BuildOptions 572 # 573 for Item in Platform.BuildOptions.BuildOptionList: 574 if Arch in Item.SupArchList: 575 Pb.BuildOptions[(Item.ToolChainFamily, Item.ToolChain)] = Item.Option 576 577 # 578 # LibraryClass 579 # 580 for Item in Platform.LibraryClasses.LibraryList: 581 SupModuleList = self.FindSupModuleListOfLibraryClass(Item, Platform.LibraryClasses.LibraryList, Arch) 582 if Arch in Item.SupArchList: 583 for ModuleType in SupModuleList: 584 Pb.LibraryClasses[(Item.Name, ModuleType)] = Item.FilePath 585 586 # 587 # Libraries 588 # 589 for Item in Platform.Libraries.LibraryList: 590 for ItemArch in Item.SupArchList: 591 Library = self.InfDatabase[Item.FilePath] 592 if ItemArch not in Library.Module.Header: 593 continue 594 Pb.Libraries[Library.Module.Header[ItemArch].Name] = Item.FilePath 595 596 # 597 # Pcds 598 # 599 for Item in Platform.DynamicPcdBuildDefinitions: 600 if Arch in Item.SupArchList: 601 Name = Item.CName 602 Guid = Item.TokenSpaceGuidCName 603 Type = Item.ItemType 604 DatumType = Item.DatumType 605 Value = Item.DefaultValue 606 Token = Item.Token 607 MaxDatumSize = Item.MaxDatumSize 608 SkuInfoList = Item.SkuInfoList 609 Pb.Pcds[(Name, Guid)] = PcdClassObject(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList, False) 610 611 for (Name, Guid) in PcdsSet: 612 Value = PcdsSet[Name, Guid] 613 for PcdType in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]: 614 for Dec in self.Build[Arch].PackageDatabase: 615 Pcds = self.Build[Arch].PackageDatabase[Dec].Pcds 616 if (Name, Guid, PcdType) in Pcds: 617 Pcd = Pcds[(Name, Guid, PcdType)] 618 Type = PcdType 619 DatumType = Pcd.DatumType 620 Token = Pcd.TokenValue 621 MaxDatumSize = Pcd.MaxDatumSize 622 SkuInfoList = Pcd.SkuInfoList 623 Pb.Pcds[(Name, Guid)] = PcdClassObject(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList, False) 624 break 625 else: 626 # nothing found 627 continue 628 # found in one package, find next PCD 629 break 630 else: 631 EdkLogger.error("AutoGen", PARSER_ERROR, "PCD is not found in any package", ExtraData="%s.%s" % (Guid, Name)) 632 # 633 # Add to database 634 # 635 self.Build[Arch].PlatformDatabase[Dsc] = Pb 636 Pb = None 637 638 ## Generate PackageDatabase 639 # 640 # Go through each arch to get all items in DecDatabase to PackageDatabase 641 # 642 def GenPackageDatabase(self): 643 for Dec in self.DecDatabase.keys(): 644 Package = self.DecDatabase[Dec].Package 645 646 for Arch in self.SupArchList: 647 Pb = PackageBuildClassObject() 648 649 # 650 # Defines 651 # 652 Pb.DescFilePath = Dec 653 Pb.PackageName = Package.Header[Arch].Name 654 if Pb.PackageName == '': 655 EdkLogger.error("AutoGen", PARSER_ERROR, "The BaseName of package %s is not defined for arch %s" % (Dec, Arch)) 656 657 Pb.Guid = Package.Header[Arch].Guid 658 Pb.Version = Package.Header[Arch].Version 659 660 # 661 # Protocols 662 # 663 for Item in Package.ProtocolDeclarations: 664 if Arch in Item.SupArchList: 665 Pb.Protocols[Item.CName] = Item.Guid 666 667 # 668 # Ppis 669 # 670 for Item in Package.PpiDeclarations: 671 if Arch in Item.SupArchList: 672 Pb.Ppis[Item.CName] = Item.Guid 673 674 # 675 # Guids 676 # 677 for Item in Package.GuidDeclarations: 678 if Arch in Item.SupArchList: 679 Pb.Guids[Item.CName] = Item.Guid 680 681 # 682 # Includes 683 # 684 for Item in Package.Includes: 685 if Arch in Item.SupArchList: 686 Pb.Includes.append(Item.FilePath) 687 688 # 689 # LibraryClasses 690 # 691 for Item in Package.LibraryClassDeclarations: 692 if Arch in Item.SupArchList: 693 Pb.LibraryClasses[Item.LibraryClass] = Item.RecommendedInstance 694 695 # 696 # Pcds 697 # 698 for Item in Package.PcdDeclarations: 699 if Arch in Item.SupArchList: 700 Name = Item.CName 701 Guid = Item.TokenSpaceGuidCName 702 Type = Item.ItemType 703 DatumType = Item.DatumType 704 Value = Item.DefaultValue 705 Token = Item.Token 706 MaxDatumSize = Item.MaxDatumSize 707 SkuInfoList = Item.SkuInfoList 708 Pb.Pcds[(Name, Guid, Type)] = PcdClassObject(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList, False) 709 710 # 711 # Add to database 712 # 713 self.Build[Arch].PackageDatabase[Dec] = Pb 714 Pb = None 715 716 ## Generate ModuleDatabase 717 # 718 # Go through each arch to get all items in InfDatabase to ModuleDatabase 719 # 720 def GenModuleDatabase(self, InfList = []): 721 for Inf in self.InfDatabase.keys(): 722 Module = self.InfDatabase[Inf].Module 723 724 for Arch in self.SupArchList: 725 if not self.IsModuleDefinedInPlatform(Inf, Arch, InfList) or Arch not in Module.Header: 726 continue 727 728 ModuleHeader = Module.Header[Arch] 729 Pb = ModuleBuildClassObject() 730 731 # 732 # Defines 733 # 734 Pb.DescFilePath = Inf 735 Pb.BaseName = ModuleHeader.Name 736 if Pb.BaseName == '': 737 EdkLogger.error("AutoGen", PARSER_ERROR, "The BaseName of module %s is not defined for arch %s" % (Inf, Arch)) 738 Pb.Guid = ModuleHeader.Guid 739 Pb.Version = ModuleHeader.Version 740 Pb.ModuleType = ModuleHeader.ModuleType 741 Pb.PcdIsDriver = ModuleHeader.PcdIsDriver 742 Pb.BinaryModule = ModuleHeader.BinaryModule 743 Pb.CustomMakefile = ModuleHeader.CustomMakefile 744 Pb.Shadow = ModuleHeader.Shadow 745 746 # 747 # Specs os Defines 748 # 749 Pb.Specification = ModuleHeader.Specification 750 Pb.Specification[TAB_INF_DEFINES_EDK_RELEASE_VERSION] = ModuleHeader.EdkReleaseVersion 751 Pb.Specification[TAB_INF_DEFINES_EFI_SPECIFICATION_VERSION] = ModuleHeader.UefiSpecificationVersion 752 Pb.Specification[TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION] = ModuleHeader.UefiSpecificationVersion 753 Pb.AutoGenVersion = int(ModuleHeader.InfVersion, 0) 754 755 # 756 # LibraryClass of Defines 757 # 758 for Item in ModuleHeader.LibraryClass: 759 Pb.LibraryClass.append(LibraryClassObject(Item.LibraryClass, Item.SupModuleList, None)) 760 761 # 762 # Module image and library of Defines 763 # 764 for Item in Module.ExternImages: 765 if Item.ModuleEntryPoint != '' and Item.ModuleEntryPoint not in Pb.ModuleEntryPointList: 766 Pb.ModuleEntryPointList.append(Item.ModuleEntryPoint) 767 if Item.ModuleUnloadImage != '' and Item.ModuleUnloadImage not in Pb.ModuleUnloadImageList: 768 Pb.ModuleUnloadImageList.append(Item.ModuleUnloadImage) 769 for Item in Module.ExternLibraries: 770 if Item.Constructor != '' and Item.Constructor not in Pb.ConstructorList: 771 Pb.ConstructorList.append(Item.Constructor) 772 if Item.Destructor != '' and Item.Destructor not in Pb.DestructorList: 773 Pb.DestructorList.append(Item.Destructor) 774 775 # 776 # Binaries 777 # 778 for Item in Module.Binaries: 779 if Arch in Item.SupArchList: 780 FileName = Item.BinaryFile 781 FileType = Item.FileType 782 Target = Item.Target 783 FeatureFlag = Item.FeatureFlag 784 Pb.Binaries.append(ModuleBinaryFileClass(FileName, FileType, Target, FeatureFlag, Arch.split())) 785 786 # 787 # Sources 788 # 789 for Item in Module.Sources: 790 if Arch in Item.SupArchList: 791 SourceFile = Item.SourceFile 792 TagName = Item.TagName 793 ToolCode = Item.ToolCode 794 ToolChainFamily = Item.ToolChainFamily 795 FeatureFlag = Item.FeatureFlag 796 Pb.Sources.append(ModuleSourceFileClass(SourceFile, TagName, ToolCode, ToolChainFamily, FeatureFlag)) 797 798 # 799 # Protocols 800 # 801 for Item in Module.Protocols: 802 if Arch in Item.SupArchList: 803 Pb.Protocols.append(Item.CName) 804 805 # 806 # Ppis 807 # 808 for Item in Module.Ppis: 809 if Arch in Item.SupArchList: 810 Pb.Ppis.append(Item.CName) 811 812 # 813 # Guids 814 # 815 for Item in Module.Guids: 816 if Arch in Item.SupArchList: 817 Pb.Ppis.append(Item.CName) 818 819 # 820 # Includes 821 # 822 for Item in Module.Includes: 823 if Arch in Item.SupArchList: 824 Pb.Includes.append(Item.FilePath) 825 826 # 827 # Packages 828 # 829 for Item in Module.PackageDependencies: 830 if Arch in Item.SupArchList: 831 Pb.Packages.append(Item.FilePath) 832 833 # 834 # BuildOptions 835 # 836 for Item in Module.BuildOptions: 837 if Arch in Item.SupArchList: 838 if (Item.ToolChainFamily, Item.ToolChain) not in Pb.BuildOptions: 839 Pb.BuildOptions[(Item.ToolChainFamily, Item.ToolChain)] = Item.Option 840 else: 841 OptionString = Pb.BuildOptions[(Item.ToolChainFamily, Item.ToolChain)] 842 Pb.BuildOptions[(Item.ToolChainFamily, Item.ToolChain)] = OptionString + " " + Item.Option 843 self.FindBuildOptions(Arch, Inf, Pb.BuildOptions) 844 845 # 846 # Depex 847 # 848 for Item in Module.Depex: 849 if Arch in Item.SupArchList: 850 Pb.Depex = Pb.Depex + Item.Depex + ' ' 851 Pb.Depex = Pb.Depex.strip() 852 853 # 854 # LibraryClasses 855 # 856 for Item in Module.LibraryClasses: 857 if Arch in Item.SupArchList: 858 Lib = Item.LibraryClass 859 RecommendedInstance = Item.RecommendedInstance 860 if Pb.LibraryClass != []: 861 # 862 # For Library 863 # 864 for Libs in Pb.LibraryClass: 865 for Type in Libs.SupModList: 866 Instance = self.FindLibraryClassInstanceOfLibrary(Lib, Arch, Type) 867 if Instance == None: 868 Instance = RecommendedInstance 869 Pb.LibraryClasses[(Lib, Type)] = Instance 870 else: 871 # 872 # For Module 873 # 874 Instance = self.FindLibraryClassInstanceOfModule(Lib, Arch, Pb.ModuleType, Inf) 875 if Instance == None: 876 Instance = RecommendedInstance 877 Pb.LibraryClasses[(Lib, Pb.ModuleType)] = Instance 878 879 # 880 # Libraries 881 # 882 for Item in Module.Libraries: 883 if Arch in Item.SupArchList: 884 Pb.Libraries.append(Item.Library) 885 886 # 887 # Pcds 888 # 889 for Item in Module.PcdCodes: 890 if Arch in Item.SupArchList: 891 Name = Item.CName 892 Guid = Item.TokenSpaceGuidCName 893 Type = Item.ItemType 894 Pb.Pcds[(Name, Guid)] = self.FindPcd(Arch, Inf, Name, Guid, Type) 895 896 # 897 # Add to database 898 # 899 self.Build[Arch].ModuleDatabase[Inf] = Pb 900 Pb = None 901 902 ## Update Libraries Of Platform Database 903 # 904 # @param InfList: A list for all inf files 905 # 906 def UpdateLibrariesOfPlatform(self, InfList = []): 907 for Arch in self.SupArchList: 908 PlatformDatabase = self.Build[Arch].PlatformDatabase 909 for Dsc in PlatformDatabase: 910 Platform = PlatformDatabase[Dsc] 911 for Inf in Platform.Modules: 912 if not self.IsModuleDefinedInPlatform(Inf, Arch, InfList): 913 continue 914 Module = self.Build[Arch].ModuleDatabase[Inf] 915 if Module.LibraryClass == None or Module.LibraryClass == []: 916 self.UpdateLibrariesOfModule(Platform, Module, Arch) 917 for Key in Module.LibraryClasses: 918 Lib = Module.LibraryClasses[Key] 919 if Lib not in Platform.LibraryInstances: 920 Platform.LibraryInstances.append(Lib) 921 922 923 ## Update Libraries Of Module Database 924 # 925 # @param Module: The module need to be updated libraries 926 # @param Arch: The supportted arch of the module 927 # 928 def UpdateLibrariesOfModule(self, Platform, Module, Arch): 929 ModuleDatabase = self.Build[Arch].ModuleDatabase 930 ModuleType = Module.ModuleType 931 932 # check Edk module 933 if Module.AutoGenVersion < 0x00010005: 934 EdkLogger.verbose("") 935 EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), Arch)) 936 LibraryConsumerList = [Module] 937 938 # "CompilerStub" is a must for Edk modules 939 Module.Libraries.append("CompilerStub") 940 while len(LibraryConsumerList) > 0: 941 M = LibraryConsumerList.pop() 942 for LibraryName in M.Libraries: 943 if LibraryName not in Platform.Libraries: 944 EdkLogger.warn("AutoGen", "Library [%s] is not found" % LibraryName, 945 ExtraData="\t%s [%s]" % (str(Module), Arch)) 946 continue 947 948 LibraryFile = Platform.Libraries[LibraryName] 949 if (LibraryName, ModuleType) not in Module.LibraryClasses: 950 Module.LibraryClasses[LibraryName, ModuleType] = LibraryFile 951 LibraryConsumerList.append(ModuleDatabase[LibraryFile]) 952 EdkLogger.verbose("\t" + LibraryName + " : " + LibraryFile) 953 return 954 955 # EdkII module 956 LibraryConsumerList = [Module] 957 Constructor = [] 958 ConsumedByList = sdict() 959 LibraryInstance = sdict() 960 961 EdkLogger.verbose("") 962 EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), Arch)) 963 while len(LibraryConsumerList) > 0: 964 M = LibraryConsumerList.pop() 965 for Key, LibraryPath in M.LibraryClasses.iteritems(): 966 # The "Key" is in format of (library_class_name, supported_module_type) 967 if ModuleType != "USER_DEFINED" and ModuleType not in Key: 968 EdkLogger.debug(EdkLogger.DEBUG_3, "%s for module type %s is not supported (%s)" % (Key + (LibraryPath,))) 969 continue 970 971 LibraryClassName = Key[0] 972 if LibraryClassName not in LibraryInstance or LibraryInstance[LibraryClassName] == None: 973 if LibraryPath == None or LibraryPath == "": 974 LibraryInstance[LibraryClassName] = None 975 continue 976 LibraryModule = ModuleDatabase[LibraryPath] 977 LibraryInstance[LibraryClassName] = LibraryModule 978 LibraryConsumerList.append(LibraryModule) 979 EdkLogger.verbose("\t" + LibraryClassName + " : " + str(LibraryModule)) 980 elif LibraryPath == None or LibraryPath == "": 981 continue 982 else: 983 LibraryModule = LibraryInstance[LibraryClassName] 984 985 if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor: 986 Constructor.append(LibraryModule) 987 988 if LibraryModule not in ConsumedByList: 989 ConsumedByList[LibraryModule] = [] 990 if M != Module: 991 if M in ConsumedByList[LibraryModule]: 992 continue 993 ConsumedByList[LibraryModule].append(M) 994 # 995 # Initialize the sorted output list to the empty set 996 # 997 SortedLibraryList = [] 998 # 999 # Q <- Set of all nodes with no incoming edges 1000 # 1001 LibraryList = [] #LibraryInstance.values() 1002 Q = [] 1003 for LibraryClassName in LibraryInstance: 1004 M = LibraryInstance[LibraryClassName] 1005 if M == None: 1006 EdkLogger.error("AutoGen", AUTOGEN_ERROR, 1007 "Library instance for library class [%s] is not found" % LibraryClassName, 1008 ExtraData="\t%s [%s]" % (str(Module), Arch)) 1009 LibraryList.append(M) 1010 # 1011 # check if there're duplicate library classes 1012 # 1013 for Lc in M.LibraryClass: 1014 if Lc.SupModList != None and ModuleType not in Lc.SupModList: 1015 EdkLogger.error("AutoGen", AUTOGEN_ERROR, 1016 "Module type [%s] is not supported by library instance [%s]" % (ModuleType, str(M)), 1017 ExtraData="\t%s" % str(Module)) 1018 1019 if Lc.LibraryClass in LibraryInstance and str(M) != str(LibraryInstance[Lc.LibraryClass]): 1020 EdkLogger.error("AutoGen", AUTOGEN_ERROR, 1021 "More than one library instance found for library class [%s] in module [%s]" % (Lc.LibraryClass, Module), 1022 ExtraData="\t%s\n\t%s" % (LibraryInstance[Lc.LibraryClass], str(M)) 1023 ) 1024 if ConsumedByList[M] == []: 1025 Q.insert(0, M) 1026 # 1027 # while Q is not empty do 1028 # 1029 while Q != []: 1030 # 1031 # remove node from Q 1032 # 1033 Node = Q.pop() 1034 # 1035 # output Node 1036 # 1037 SortedLibraryList.append(Node) 1038 # 1039 # for each node Item with an edge e from Node to Item do 1040 # 1041 for Item in LibraryList: 1042 if Node not in ConsumedByList[Item]: 1043 continue 1044 # 1045 # remove edge e from the graph 1046 # 1047 ConsumedByList[Item].remove(Node) 1048 # 1049 # If Item has no other incoming edges then 1050 # 1051 if ConsumedByList[Item] == []: 1052 # 1053 # insert Item into Q 1054 # 1055 Q.insert(0, Item) 1056 1057 EdgeRemoved = True 1058 while Q == [] and EdgeRemoved: 1059 EdgeRemoved = False 1060 # 1061 # for each node Item with a Constructor 1062 # 1063 for Item in LibraryList: 1064 if Item in Constructor: 1065 # 1066 # for each Node without a constructor with an edge e from Item to Node 1067 # 1068 for Node in ConsumedByList[Item]: 1069 if Node not in Constructor: 1070 # 1071 # remove edge e from the graph 1072 # 1073 ConsumedByList[Item].remove(Node) 1074 EdgeRemoved = True 1075 if ConsumedByList[Item] == []: 1076 # 1077 # insert Item into Q 1078 # 1079 Q.insert(0, Item) 1080 break 1081 if Q != []: 1082 break 1083 1084 # 1085 # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle 1086 # 1087 for Item in LibraryList: 1088 if ConsumedByList[Item] != [] and Item in Constructor and len(Constructor) > 1: 1089 ErrorMessage = 'Library [%s] with constructors has a cycle' % str(Item) 1090 EdkLogger.error("AutoGen", AUTOGEN_ERROR, ErrorMessage, 1091 "\tconsumed by " + "\n\tconsumed by ".join([str(L) for L in ConsumedByList[Item]])) 1092 if Item not in SortedLibraryList: 1093 SortedLibraryList.append(Item) 1094 1095 # 1096 # Build the list of constructor and destructir names 1097 # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order 1098 # 1099 SortedLibraryList.reverse() 1100 Module.LibraryClasses = sdict() 1101 for L in SortedLibraryList: 1102 for Lc in L.LibraryClass: 1103 Module.LibraryClasses[Lc.LibraryClass, ModuleType] = str(L) 1104 # 1105 # Merge PCDs from library instance 1106 # 1107 for Key in L.Pcds: 1108 if Key not in Module.Pcds: 1109 LibPcd = L.Pcds[Key] 1110 Module.Pcds[Key] = self.FindPcd(Arch, str(Module), LibPcd.TokenCName, LibPcd.TokenSpaceGuidCName, LibPcd.Type) 1111 # 1112 # Merge GUIDs from library instance 1113 # 1114 for CName in L.Guids: 1115 if CName not in Module.Guids: 1116 Module.Guids.append(CName) 1117 # 1118 # Merge Protocols from library instance 1119 # 1120 for CName in L.Protocols: 1121 if CName not in Module.Protocols: 1122 Module.Protocols.append(CName) 1123 # 1124 # Merge Ppis from library instance 1125 # 1126 for CName in L.Ppis: 1127 if CName not in Module.Ppis: 1128 Module.Ppis.append(CName) 1129 1130 ## GenBuildDatabase 1131 # 1132 # Generate build database for all arches 1133 # 1134 # @param PcdsSet: Pcd list for override from Fdf parse result 1135 # @param InfList: Inf list for override from Fdf parse result 1136 # 1137 def GenBuildDatabase(self, PcdsSet = {}, InfList = []): 1138 # 1139 # Add additional inf file defined in Fdf file 1140 # 1141 for InfFile in InfList: 1142 self.AddToInfDatabase(NormPath(InfFile)) 1143 1144 # 1145 # Generate PlatformDatabase, PackageDatabase and ModuleDatabase 1146 # 1147 self.GenPackageDatabase() 1148 self.GenPlatformDatabase(PcdsSet) 1149 self.GenModuleDatabase(InfList) 1150 1151 self.Db.Close() 1152 1153 # 1154 # Update Libraries Of Platform 1155 # 1156 self.UpdateLibrariesOfPlatform(InfList) 1157 1158 # 1159 # Output used Pcds not found in DSC file 1160 # 1161 self.ShowUnFoundPcds() 1162 1163 ## ShowUnFoundPcds() 1164 # 1165 # If there is any pcd used but not defined in DSC 1166 # Print warning message on screen and output a list of pcds 1167 # 1168 def ShowUnFoundPcds(self): 1169 if self.UnFoundPcdInDsc != {}: 1170 WrnMessage = '**** WARNING ****\n' 1171 WrnMessage += 'The following Pcds were not defined in the DSC file: %s\n' % self.DscFileName 1172 WrnMessage += 'The default values were obtained from the DEC file that declares the PCD and the PCD default value\n' 1173 for (Guid, Name, Type, Arch) in self.UnFoundPcdInDsc: 1174 Dec = self.UnFoundPcdInDsc[(Guid, Name, Type, Arch)] 1175 Pcds = self.Build[Arch].PackageDatabase[Dec].Pcds 1176 if (Name, Guid, Type) in Pcds: 1177 Pcd = Pcds[(Name, Guid, Type)] 1178 PcdItemTypeUsed = Pcd.Type 1179 DefaultValue = Pcd.DefaultValue 1180 WrnMessage += '%s.%s: Defined in file %s, PcdItemType is Pcds%s, DefaultValue is %s\n' % (Guid, Name, Dec, PcdItemTypeUsed, DefaultValue) 1181 EdkLogger.verbose(WrnMessage) 1182 1183 ## Create a full path with workspace dir 1184 # 1185 # Convert Filename with workspace dir to create a full path 1186 # 1187 # @param Filename: The filename need to be added workspace dir 1188 # 1189 # @retval string Full path 1190 # 1191 def WorkspaceFile(self, Filename): 1192 return WorkspaceFile(self.WorkspaceDir, Filename) 1193 1194 ## Update LibraryClass of Module 1195 # 1196 # If a module of a platform has its own override libraryclass but the libraryclass not defined in the module 1197 # Add this libraryclass to the module 1198 # 1199 # @param InfFileName: InfFileName specificed in platform 1200 # @param LibraryClass: LibraryClass specificed in platform 1201 # @param Arch: Supportted Arch 1202 # @param InstanceFilePath: InstanceFilePath specificed in platform 1203 # 1204 def UpdateLibraryClassOfModule(self, InfFileName, LibraryClass, Arch, InstanceFilePath): 1205 # 1206 # Update the library instance itself to add this libraryclass name 1207 # 1208 LibraryModule = self.InfDatabase[InstanceFilePath].Module 1209 LibList = LibraryModule.Header[Arch].LibraryClass 1210 NotFound = True 1211 for Lib in LibList: 1212 # 1213 # Find this LibraryClass 1214 # 1215 if Lib.LibraryClass == LibraryClass: 1216 NotFound = False; 1217 break; 1218 if NotFound: 1219 NewLib = LibraryClassClass() 1220 NewLib.LibraryClass = LibraryClass 1221 NewLib.SupModuleList = DataType.SUP_MODULE_LIST # LibraryModule.Header[Arch].ModuleType.split() 1222 LibraryModule.Header[Arch].LibraryClass.append(NewLib) 1223 1224 # 1225 # Add it to LibraryClasses Section for the module which is using the library 1226 # 1227 Module = self.InfDatabase[InfFileName].Module 1228 LibList = Module.LibraryClasses 1229 NotFound = True 1230 for Lib in LibList: 1231 # 1232 # Find this LibraryClass 1233 # 1234 if Lib.LibraryClass == LibraryClass: 1235 if Arch in Lib.SupArchList: 1236 return 1237 else: 1238 Lib.SupArchList.append(Arch) 1239 return 1240 if NotFound: 1241 Lib = LibraryClassClass() 1242 Lib.LibraryClass = LibraryClass 1243 Lib.SupArchList = [Arch] 1244 Module.LibraryClasses.append(Lib) 1245 1246 ## Add Inf file to InfDatabase 1247 # 1248 # Create a Inf instance for input inf file and add it to InfDatabase 1249 # 1250 # @param InfFileName: The InfFileName need to be added to database 1251 # 1252 def AddToInfDatabase(self, InfFileName): 1253 File = self.WorkspaceFile(InfFileName) 1254 if os.path.exists(File) and os.path.isfile(File): 1255 if InfFileName not in self.InfDatabase: 1256 self.InfDatabase[InfFileName] = Inf(File, False, True, self.WorkspaceDir, self.Db, self.SupArchList) 1257 else: 1258 EdkLogger.error("AutoGen", FILE_NOT_FOUND, ExtraData=File) 1259 1260 ## Add Dec file to DecDatabase 1261 # 1262 # Create a Dec instance for input dec file and add it to DecDatabase 1263 # 1264 # @param DecFileName: The DecFileName need to be added to database 1265 # 1266 def AddToDecDatabase(self, DecFileName): 1267 File = self.WorkspaceFile(DecFileName) 1268 if os.path.exists(File) and os.path.isfile(File): 1269 if DecFileName not in self.DecDatabase: 1270 self.DecDatabase[DecFileName] = Dec(File, False, True, self.WorkspaceDir, self.Db, self.SupArchList) 1271 else: 1272 EdkLogger.error("AutoGen", FILE_NOT_FOUND, ExtraData=File) 1273 1274 ## Search LibraryClass Instance for Module 1275 # 1276 # Search PlatformBuildDatabase to find LibraryClass Instance for Module 1277 # Return the instance if found 1278 # 1279 # @param Lib: Input value for Library Class Name 1280 # @param Arch: Supportted Arch 1281 # @param ModuleType: Supportted ModuleType 1282 # @param ModuleName: Input value for Module Name 1283 # 1284 # @retval string Found LibraryClass Instance file path 1285 # 1286 def FindLibraryClassInstanceOfModule(self, Lib, Arch, ModuleType, ModuleName): 1287 # 1288 # First find if exist in <LibraryClass> of <Components> from dsc file 1289 # 1290 for Dsc in self.DscDatabase.keys(): 1291 Platform = self.DscDatabase[Dsc].Platform 1292 for Module in Platform.Modules.ModuleList: 1293 if Arch in Module.SupArchList: 1294 if Module.FilePath == ModuleName: 1295 for LibraryClass in Module.LibraryClasses.LibraryList: 1296 if LibraryClass.Name == Lib: 1297 return LibraryClass.FilePath 1298 # 1299 #Second find if exist in <LibraryClass> of <LibraryClasses> from dsc file 1300 # 1301 return self.FindLibraryClassInstanceOfLibrary(Lib, Arch, ModuleType) 1302 1303 ## Search LibraryClass Instance for Library 1304 # 1305 # Search PlatformBuildDatabase to find LibraryClass Instance for Library 1306 # Return the instance if found 1307 # 1308 # @param Lib: Input value for Library Class Name 1309 # @param Arch: Supportted Arch 1310 # @param Type: Supportted Library Usage Type 1311 # 1312 # @retval string Found LibraryClass Instance file path 1313 # @retval None Not Found 1314 # 1315 def FindLibraryClassInstanceOfLibrary(self, Lib, Arch, Type): 1316 for Dsc in self.DscDatabase.keys(): 1317 Platform = self.DscDatabase[Dsc].Platform 1318 if (Lib, Type) in self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses: 1319 return self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses[(Lib, Type)] 1320 elif (Lib, '') in self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses: 1321 return self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses[(Lib, '')] 1322 return None 1323 1324 ## Find BuildOptions 1325 # 1326 # Search DscDatabase to find component definition of ModuleName 1327 # Override BuildOption if it is defined in component 1328 # 1329 # @param Arch: Supportted Arch 1330 # @param ModuleName: The module which has buildoption definition in component of platform 1331 # @param BuildOptions: The set of all buildopitons 1332 # 1333 def FindBuildOptions(self, Arch, ModuleName, BuildOptions): 1334 for Dsc in self.DscDatabase.keys(): 1335 # 1336 # First find if exist in <BuildOptions> of <Components> from dsc file 1337 # if find, use that override the one defined in inf file 1338 # 1339 Platform = self.DscDatabase[Dsc].Platform 1340 for Module in Platform.Modules.ModuleList: 1341 if Arch in Module.SupArchList: 1342 if Module.FilePath == ModuleName: 1343 for BuildOption in Module.ModuleSaBuildOption.BuildOptionList: 1344 # 1345 # Add to BuildOptions 1346 # 1347 BuildOptions[(BuildOption.ToolChainFamily, BuildOption.ToolChain)] = BuildOption.Option 1348 1349 ## Find Pcd 1350 # 1351 # Search platform database, package database, module database and PcdsSet from Fdf 1352 # Return found Pcd 1353 # 1354 # @param Arch: Supportted Arch 1355 # @param ModuleName: The module which has pcd definition in component of platform 1356 # @param Name: Name of Pcd 1357 # @param Guid: Guid of Pcd 1358 # @param Type: Type of Pcd 1359 # 1360 # @retval PcdClassObject An instance for PcdClassObject with all members filled 1361 # 1362 def FindPcd(self, Arch, ModuleName, Name, Guid, Type): 1363 NewType = '' 1364 DatumType = '' 1365 Value = '' 1366 Token = '' 1367 MaxDatumSize = '' 1368 SkuInfoList = {} 1369 IsOverrided = False 1370 IsFoundInDsc = False 1371 IsFoundInDec = False 1372 FoundInDecFile = '' 1373 1374 # 1375 # Second get information from platform database 1376 # 1377 OwnerPlatform = '' 1378 for Dsc in self.Build[Arch].PlatformDatabase.keys(): 1379 Pcds = self.Build[Arch].PlatformDatabase[Dsc].Pcds 1380 if (Name, Guid) in Pcds: 1381 OwnerPlatform = Dsc 1382 Pcd = Pcds[(Name, Guid)] 1383 if Pcd.Type != '' and Pcd.Type != None: 1384 NewType = Pcd.Type 1385 if NewType in DataType.PCD_DYNAMIC_TYPE_LIST: 1386 NewType = DataType.TAB_PCDS_DYNAMIC 1387 elif NewType in DataType.PCD_DYNAMIC_EX_TYPE_LIST: 1388 NewType = DataType.TAB_PCDS_DYNAMIC_EX 1389 else: 1390 NewType = Type 1391 1392 if Type != '' and Type != NewType: 1393 ErrorMsg = "PCD %s.%s is declared as [%s] in module\n\t%s\n\n"\ 1394 " But it's used as [%s] in platform\n\t%s"\ 1395 % (Guid, Name, Type, ModuleName, NewType, OwnerPlatform) 1396 EdkLogger.error("AutoGen", PARSER_ERROR, ErrorMsg) 1397 1398 1399 if Pcd.DatumType != '' and Pcd.DatumType != None: 1400 DatumType = Pcd.DatumType 1401 if Pcd.TokenValue != '' and Pcd.TokenValue != None: 1402 Token = Pcd.TokenValue 1403 if Pcd.DefaultValue != '' and Pcd.DefaultValue != None: 1404 Value = Pcd.DefaultValue 1405 if Pcd.MaxDatumSize != '' and Pcd.MaxDatumSize != None: 1406 MaxDatumSize = Pcd.MaxDatumSize 1407 SkuInfoList = Pcd.SkuInfoList 1408 1409 IsOverrided = True 1410 IsFoundInDsc = True 1411 break 1412 1413 # 1414 # Third get information from <Pcd> of <Compontents> from module database 1415 # 1416 for Dsc in self.DscDatabase.keys(): 1417 for Module in self.DscDatabase[Dsc].Platform.Modules.ModuleList: 1418 if Arch in Module.SupArchList: 1419 if Module.FilePath == ModuleName: 1420 for Pcd in Module.PcdBuildDefinitions: 1421 if (Name, Guid) == (Pcd.CName, Pcd.TokenSpaceGuidCName): 1422 if Pcd.DefaultValue != '': 1423 Value = Pcd.DefaultValue 1424 if Pcd.MaxDatumSize != '': 1425 MaxDatumSize = Pcd.MaxDatumSize 1426 1427 IsFoundInDsc = True 1428 IsOverrided = True 1429 break 1430 1431 # 1432 # First get information from package database 1433 # 1434 Pcd = None 1435 if NewType == '': 1436 if Type != '': 1437 PcdTypeList = [Type] 1438 else: 1439 PcdTypeList = ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"] 1440 1441 for Dec in self.Build[Arch].PackageDatabase.keys(): 1442 Pcds = self.Build[Arch].PackageDatabase[Dec].Pcds 1443 for PcdType in PcdTypeList: 1444 if (Name, Guid, PcdType) in Pcds: 1445 Pcd = Pcds[(Name, Guid, PcdType)] 1446 NewType = PcdType 1447 IsOverrided = True 1448 IsFoundInDec = True 1449 FoundInDecFile = Dec 1450 break 1451 else: 1452 continue 1453 break 1454 else: 1455 for Dec in self.Build[Arch].PackageDatabase.keys(): 1456 Pcds = self.Build[Arch].PackageDatabase[Dec].Pcds 1457 if (Name, Guid, NewType) in Pcds: 1458 Pcd = Pcds[(Name, Guid, NewType)] 1459 IsOverrided = True 1460 IsFoundInDec = True 1461 FoundInDecFile = Dec 1462 break 1463 1464 if not IsFoundInDec: 1465 ErrorMsg = "Pcd '%s.%s [%s]' defined in module '%s' is not found in any package for Arch '%s'" % (Guid, Name, NewType, ModuleName, Arch) 1466 EdkLogger.error("AutoGen", PARSER_ERROR, ErrorMsg) 1467 1468 # 1469 # Not found in any platform and fdf 1470 # 1471 if not IsFoundInDsc: 1472 Value = Pcd.DefaultValue 1473 if NewType.startswith("Dynamic") and SkuInfoList == {}: 1474 SkuIds = self.Build[Arch].PlatformDatabase.values()[0].SkuIds 1475 SkuInfoList['DEFAULT'] = SkuInfoClass(SkuIdName='DEFAULT', SkuId=SkuIds['DEFAULT'], DefaultValue=Value) 1476 self.UnFoundPcdInDsc[(Guid, Name, NewType, Arch)] = FoundInDecFile 1477 #elif Type != '' and NewType.startswith("Dynamic"): 1478 # NewType = Pcd.Type 1479 DatumType = Pcd.DatumType 1480 if Token in [None, '']: 1481 Token = Pcd.TokenValue 1482 if DatumType == "VOID*" and MaxDatumSize in ['', None]: 1483 EdkLogger.verbose("No MaxDatumSize specified for PCD %s.%s in module [%s]" % (Guid, Name, ModuleName)) 1484 if Value[0] == 'L': 1485 MaxDatumSize = str(len(Value) * 2) 1486 elif Value[0] == '{': 1487 MaxDatumSize = str(len(Value.split(','))) 1488 else: 1489 MaxDatumSize = str(len(Value)) 1490 1491 return PcdClassObject(Name, Guid, NewType, DatumType, Value, Token, MaxDatumSize, SkuInfoList, IsOverrided) 1492 1493 ## Find Supportted Module List Of LibraryClass 1494 # 1495 # Search in InfDatabase, find the supmodulelist of the libraryclass 1496 # 1497 # @param LibraryClass: LibraryClass name for search 1498 # @param OverridedLibraryClassList: A list of all LibraryClass 1499 # @param Arch: Supportted Arch 1500 # 1501 # @retval list SupModuleList 1502 # 1503 def FindSupModuleListOfLibraryClass(self, LibraryClass, OverridedLibraryClassList, Arch): 1504 Name = LibraryClass.Name 1505 FilePath = LibraryClass.FilePath 1506 SupModuleList = copy.copy(LibraryClass.SupModuleList) 1507 1508 # 1509 # If the SupModuleList means all, remove overrided module types of platform 1510 # 1511 if SupModuleList == DataType.SUP_MODULE_LIST: 1512 EdkLogger.debug(EdkLogger.DEBUG_3, "\tLibraryClass %s supports all module types" % Name) 1513 for Item in OverridedLibraryClassList: 1514 # 1515 # Find a library class (Item) with the same name 1516 # 1517 if Item.Name == Name: 1518 # 1519 # Do nothing if it is itself 1520 # 1521 if Item.SupModuleList == DataType.SUP_MODULE_LIST: 1522 continue 1523 # 1524 # If not itself, check arch first 1525 # 1526 if Arch in LibraryClass.SupArchList: 1527 # 1528 # If arch is supportted, remove all related module type 1529 # 1530 if Arch in Item.SupArchList: 1531 for ModuleType in Item.SupModuleList: 1532 EdkLogger.debug(EdkLogger.DEBUG_3, "\tLibraryClass %s has specific defined module types" % Name) 1533 if ModuleType in SupModuleList: 1534 SupModuleList.remove(ModuleType) 1535 1536 return SupModuleList 1537 1538 ## Find Module inf Platform 1539 # 1540 # Check if the module is defined in <Compentent> of <Platform> 1541 # 1542 # @param Inf: Inf file (Module) need to be searched 1543 # @param Arch: Supportted Arch 1544 # @param InfList: A list for all Inf file 1545 # 1546 # @retval True Mudule Found 1547 # @retval Flase Module Not Found 1548 # 1549 def IsModuleDefinedInPlatform(self, Inf, Arch, InfList): 1550 for Dsc in self.DscDatabase.values(): 1551 for LibraryClass in Dsc.Platform.LibraryClasses.LibraryList: 1552 if Inf == LibraryClass.FilePath and Arch in LibraryClass.SupArchList: 1553 return True 1554 for Module in Dsc.Platform.Modules.ModuleList: 1555 if Inf == Module.FilePath and Arch in Module.SupArchList: 1556 return True 1557 for Item in Module.LibraryClasses.LibraryList: 1558 if Inf == Item.FilePath: 1559 return True 1560 for Library in Dsc.Platform.Libraries.LibraryList: 1561 if Inf == Library.FilePath and Arch in Library.SupArchList: 1562 return True 1563 1564 return False 1565 1566 ## Show all content of the workspacebuild 1567 # 1568 # Print each item of the workspacebuild with (Key = Value) pair 1569 # 1570 def ShowWorkspaceBuild(self): 1571 print self.DscDatabase 1572 print self.InfDatabase 1573 print self.DecDatabase 1574 print 'SupArchList', self.SupArchList 1575 print 'BuildTarget', self.BuildTarget 1576 print 'SkuId', self.SkuId 1577 1578 for Arch in self.SupArchList: 1579 print Arch 1580 print 'Platform' 1581 for Platform in self.Build[Arch].PlatformDatabase.keys(): 1582 P = self.Build[Arch].PlatformDatabase[Platform] 1583 print 'DescFilePath = ', P.DescFilePath 1584 print 'PlatformName = ', P.PlatformName 1585 print 'Guid = ', P.Guid 1586 print 'Version = ', P.Version 1587 print 'OutputDirectory = ', P.OutputDirectory 1588 print 'FlashDefinition = ', P.FlashDefinition 1589 print 'SkuIds = ', P.SkuIds 1590 print 'Modules = ', P.Modules 1591 print 'LibraryClasses = ', P.LibraryClasses 1592 print 'Pcds = ', P.Pcds 1593 for item in P.Pcds.keys(): 1594 print P.Pcds[item] 1595 print 'BuildOptions = ', P.BuildOptions 1596 print '' 1597 # End of Platform 1598 1599 print 'package' 1600 for Package in self.Build[Arch].PackageDatabase.keys(): 1601 P = self.Build[Arch].PackageDatabase[Package] 1602 print 'DescFilePath = ', P.DescFilePath 1603 print 'PackageName = ', P.PackageName 1604 print 'Guid = ', P.Guid 1605 print 'Version = ', P.Version 1606 print 'Protocols = ', P.Protocols 1607 print 'Ppis = ', P.Ppis 1608 print 'Guids = ', P.Guids 1609 print 'Includes = ', P.Includes 1610 print 'LibraryClasses = ', P.LibraryClasses 1611 print 'Pcds = ', P.Pcds 1612 for item in P.Pcds.keys(): 1613 print P.Pcds[item] 1614 print '' 1615 # End of Package 1616 1617 print 'module' 1618 for Module in self.Build[Arch].ModuleDatabase.keys(): 1619 P = self.Build[Arch].ModuleDatabase[Module] 1620 print 'DescFilePath = ', P.DescFilePath 1621 print 'BaseName = ', P.BaseName 1622 print 'ModuleType = ', P.ModuleType 1623 print 'Guid = ', P.Guid 1624 print 'Version = ', P.Version 1625 print 'CustomMakefile = ', P.CustomMakefile 1626 print 'Specification = ', P.Specification 1627 print 'Shadow = ', P.Shadow 1628 print 'PcdIsDriver = ', P.PcdIsDriver 1629 for Lib in P.LibraryClass: 1630 print 'LibraryClassDefinition = ', Lib.LibraryClass, 'SupModList = ', Lib.SupModList 1631 print 'ModuleEntryPointList = ', P.ModuleEntryPointList 1632 print 'ModuleUnloadImageList = ', P.ModuleUnloadImageList 1633 print 'ConstructorList = ', P.ConstructorList 1634 print 'DestructorList = ', P.DestructorList 1635 1636 print 'Binaries = ' 1637 for item in P.Binaries: 1638 print item.BinaryFile, item.FeatureFlag, item.SupArchList 1639 print 'Sources = ' 1640 for item in P.Sources: 1641 print item.SourceFile 1642 print 'LibraryClasses = ', P.LibraryClasses 1643 print 'Protocols = ', P.Protocols 1644 print 'Ppis = ', P.Ppis 1645 print 'Guids = ', P.Guids 1646 print 'Includes = ', P.Includes 1647 print 'Packages = ', P.Packages 1648 print 'Pcds = ', P.Pcds 1649 for item in P.Pcds.keys(): 1650 print P.Pcds[item] 1651 print 'BuildOptions = ', P.BuildOptions 1652 print 'Depex = ', P.Depex 1653 print '' 1654 # End of Module 1655 1656## 1657# 1658# This acts like the main() function for the script, unless it is 'import'ed into another 1659# script. 1660# 1661if __name__ == '__main__': 1662 print 'Start!', time.strftime('%H:%M:%S', time.localtime()) 1663 EdkLogger.Initialize() 1664 EdkLogger.SetLevel(EdkLogger.QUIET) 1665 1666 W = os.getenv('WORKSPACE') 1667 Ewb = WorkspaceBuild('Nt32Pkg/Nt32Pkg.dsc', W) 1668 Ewb.GenBuildDatabase({('PcdDevicePathSupportDevicePathFromText', 'gEfiMdeModulePkgTokenSpaceGuid') : 'KKKKKKKKKKKKKKKKKKKKK'}, ['Test.Inf']) 1669 print 'Done!', time.strftime('%H:%M:%S', time.localtime()) 1670 Ewb.ShowWorkspaceBuild() 1671