1## @file 2# 3# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR> 4# 5# SPDX-License-Identifier: BSD-2-Clause-Patent 6 7from plugins.EdkPlugins.basemodel import ini 8from plugins.EdkPlugins.edk2.model import dsc 9from plugins.EdkPlugins.edk2.model import inf 10from plugins.EdkPlugins.edk2.model import dec 11import os 12from plugins.EdkPlugins.basemodel.message import * 13 14class SurfaceObject(object): 15 _objs = {} 16 17 def __new__(cls, *args, **kwargs): 18 """Maintain only a single instance of this object 19 @return: instance of this class 20 21 """ 22 obj = object.__new__(cls) 23 if "None" not in cls._objs: 24 cls._objs["None"] = [] 25 cls._objs["None"].append(obj) 26 27 return obj 28 29 def __init__(self, parent, workspace): 30 self._parent = parent 31 self._fileObj = None 32 self._workspace = workspace 33 self._isModify = False 34 self._modifiedObjs = [] 35 36 def __del__(self): 37 pass 38 39 def Destroy(self): 40 key = self.GetRelativeFilename() 41 self.GetFileObj().Destroy(self) 42 del self._fileObj 43 # dereference self from _objs arrary 44 assert key in self._objs, "when destory, object is not in obj list" 45 assert self in self._objs[key], "when destory, object is not in obj list" 46 self._objs[key].remove(self) 47 if len(self._objs[key]) == 0: 48 del self._objs[key] 49 50 def GetParent(self): 51 return self._parent 52 53 def GetWorkspace(self): 54 return self._workspace 55 56 def GetFileObjectClass(self): 57 return ini.BaseINIFile 58 59 def GetFilename(self): 60 return self.GetFileObj().GetFilename() 61 62 def GetFileObj(self): 63 return self._fileObj 64 65 def GetRelativeFilename(self): 66 fullPath = self.GetFilename() 67 return fullPath[len(self._workspace) + 1:] 68 69 def Load(self, relativePath): 70 # if has been loaded, directly return 71 if self._fileObj is not None: return True 72 73 relativePath = os.path.normpath(relativePath) 74 fullPath = os.path.join(self._workspace, relativePath) 75 fullPath = os.path.normpath(fullPath) 76 77 if not os.path.exists(fullPath): 78 ErrorMsg("file does not exist!", fullPath) 79 return False 80 81 self._fileObj = self.GetFileObjectClass()(fullPath, self) 82 83 if not self._fileObj.Parse(): 84 ErrorMsg("Fail to parse file!", fullPath) 85 return False 86 87 # remove self from None list to list with filename as key 88 cls = self.__class__ 89 if self not in cls._objs["None"]: 90 ErrorMsg("Sufrace object does not be create into None list") 91 cls._objs["None"].remove(self) 92 if relativePath not in cls._objs: 93 cls._objs[relativePath] = [] 94 cls._objs[relativePath].append(self) 95 96 return True 97 98 def Reload(self, force=False): 99 ret = True 100 # whether require must be update 101 if force: 102 ret = self.GetFileObj().Reload(True) 103 else: 104 if self.IsModified(): 105 if self.GetFileObj().IsModified(): 106 ret = self.GetFileObj().Reload() 107 return ret 108 109 def Modify(self, modify=True, modifiedObj=None): 110 if modify: 111 #LogMsg("%s is modified, modified object is %s" % (self.GetFilename(), modifiedObj)) 112 if issubclass(modifiedObj.__class__, ini.BaseINIFile) and self._isModify: 113 return 114 self._isModify = modify 115 self.GetParent().Modify(modify, self) 116 else: 117 self._isModify = modify 118 119 def IsModified(self): 120 return self._isModify 121 122 def GetModifiedObjs(self): 123 return self._modifiedObjs 124 125 def FilterObjsByArch(self, objs, arch): 126 arr = [] 127 for obj in objs: 128 if obj.GetArch().lower() == 'common': 129 arr.append(obj) 130 continue 131 if obj.GetArch().lower() == arch.lower(): 132 arr.append(obj) 133 continue 134 return arr 135 136class Platform(SurfaceObject): 137 def __init__(self, parent, workspace): 138 SurfaceObject.__init__(self, parent, workspace) 139 self._modules = [] 140 self._packages = [] 141 142 def Destroy(self): 143 for module in self._modules: 144 module.Destroy() 145 del self._modules[:] 146 147 del self._packages[:] 148 SurfaceObject.Destroy(self) 149 150 def GetName(self): 151 return self.GetFileObj().GetDefine("PLATFORM_NAME") 152 153 def GetFileObjectClass(self): 154 return dsc.DSCFile 155 156 def GetModuleCount(self): 157 if self.GetFileObj() is None: 158 ErrorMsg("Fail to get module count because DSC file has not been load!") 159 160 return len(self.GetFileObj().GetComponents()) 161 162 def GetSupportArchs(self): 163 return self.GetFileObj().GetDefine("SUPPORTED_ARCHITECTURES").strip().split('#')[0].split('|') 164 165 def LoadModules(self, precallback=None, postcallback=None): 166 for obj in self.GetFileObj().GetComponents(): 167 mFilename = obj.GetFilename() 168 if precallback is not None: 169 precallback(self, mFilename) 170 arch = obj.GetArch() 171 if arch.lower() == 'common': 172 archarr = self.GetSupportArchs() 173 else: 174 archarr = [arch] 175 for arch in archarr: 176 module = Module(self, self.GetWorkspace()) 177 if module.Load(mFilename, arch, obj.GetOveridePcds(), obj.GetOverideLibs()): 178 self._modules.append(module) 179 if postcallback is not None: 180 postcallback(self, module) 181 else: 182 del module 183 ErrorMsg("Fail to load module %s" % mFilename) 184 185 def GetModules(self): 186 return self._modules 187 188 def GetLibraryPath(self, classname, arch, type): 189 objs = self.GetFileObj().GetSectionObjectsByName("libraryclasses") 190 191 for obj in objs: 192 if classname.lower() != obj.GetClass().lower(): 193 continue 194 if obj.GetArch().lower() != 'common' and \ 195 obj.GetArch().lower() != arch.lower(): 196 continue 197 198 if obj.GetModuleType().lower() != 'common' and \ 199 obj.GetModuleType().lower() != type.lower(): 200 continue 201 202 return obj.GetInstance() 203 204 ErrorMsg("Fail to get library class %s [%s][%s] from platform %s" % (classname, arch, type, self.GetFilename())) 205 return None 206 207 def GetPackage(self, path): 208 package = self.GetParent().GetPackage(path) 209 if package not in self._packages: 210 self._packages.append(package) 211 return package 212 213 def GetPcdBuildObjs(self, name, arch=None): 214 arr = [] 215 objs = self.GetFileObj().GetSectionObjectsByName('pcds') 216 for obj in objs: 217 if obj.GetPcdName().lower() == name.lower(): 218 arr.append(obj) 219 if arch is not None: 220 arr = self.FilterObjsByArch(arr, arch) 221 return arr 222 223 def Reload(self, callback=None): 224 # do not care force paramter for platform object 225 isFileChanged = self.GetFileObj().IsModified() 226 ret = SurfaceObject.Reload(self, False) 227 if not ret: return False 228 if isFileChanged: 229 # destroy all modules and reload them again 230 for obj in self._modules: 231 obj.Destroy() 232 del self._modules[:] 233 del self._packages[:] 234 self.LoadModules(callback) 235 else: 236 for obj in self._modules: 237 callback(self, obj.GetFilename()) 238 obj.Reload() 239 240 self.Modify(False) 241 return True 242 243 def Modify(self, modify=True, modifiedObj=None): 244 if modify: 245 #LogMsg("%s is modified, modified object is %s" % (self.GetFilename(), modifiedObj)) 246 if issubclass(modifiedObj.__class__, ini.BaseINIFile) and self._isModify: 247 return 248 self._isModify = modify 249 self.GetParent().Modify(modify, self) 250 else: 251 if self.GetFileObj().IsModified(): 252 return 253 for obj in self._modules: 254 if obj.IsModified(): 255 return 256 257 self._isModify = modify 258 self.GetParent().Modify(modify, self) 259 260 def GetModuleObject(self, relativePath, arch): 261 path = os.path.normpath(relativePath) 262 for obj in self._modules: 263 if obj.GetRelativeFilename() == path: 264 if arch.lower() == 'common': 265 return obj 266 if obj.GetArch() == arch: 267 return obj 268 return None 269 270 def GenerateFullReferenceDsc(self): 271 oldDsc = self.GetFileObj() 272 newDsc = dsc.DSCFile() 273 newDsc.CopySectionsByName(oldDsc, 'defines') 274 newDsc.CopySectionsByName(oldDsc, 'SkuIds') 275 276 # 277 # Dynamic common section should also be copied 278 # 279 newDsc.CopySectionsByName(oldDsc, 'PcdsDynamicDefault') 280 newDsc.CopySectionsByName(oldDsc, 'PcdsDynamicHii') 281 newDsc.CopySectionsByName(oldDsc, 'PcdsDynamicVpd') 282 newDsc.CopySectionsByName(oldDsc, 'PcdsDynamicEx') 283 284 sects = oldDsc.GetSectionByName('Components') 285 for oldSect in sects: 286 newSect = newDsc.AddNewSection(oldSect.GetName()) 287 for oldComObj in oldSect.GetObjects(): 288 module = self.GetModuleObject(oldComObj.GetFilename(), oldSect.GetArch()) 289 if module is None: continue 290 291 newComObj = dsc.DSCComponentObject(newSect) 292 newComObj.SetFilename(oldComObj.GetFilename()) 293 294 # add all library instance for override section 295 libdict = module.GetLibraries() 296 for libclass in libdict.keys(): 297 if libdict[libclass] is not None: 298 newComObj.AddOverideLib(libclass, libdict[libclass].GetRelativeFilename().replace('\\', '/')) 299 300 # add all pcds for override section 301 pcddict = module.GetPcds() 302 for pcd in pcddict.values(): 303 buildPcd = pcd.GetBuildObj() 304 buildType = buildPcd.GetPcdType() 305 buildValue = None 306 if buildType.lower() == 'pcdsdynamichii' or \ 307 buildType.lower() == 'pcdsdynamicvpd' or \ 308 buildType.lower() == 'pcdsdynamicdefault': 309 buildType = 'PcdsDynamic' 310 if buildType != 'PcdsDynamic': 311 buildValue = buildPcd.GetPcdValue() 312 newComObj.AddOveridePcd(buildPcd.GetPcdName(), 313 buildType, 314 buildValue) 315 newSect.AddObject(newComObj) 316 return newDsc 317 318class Module(SurfaceObject): 319 def __init__(self, parent, workspace): 320 SurfaceObject.__init__(self, parent, workspace) 321 self._arch = 'common' 322 self._parent = parent 323 self._overidePcds = {} 324 self._overideLibs = {} 325 self._libs = {} 326 self._pcds = {} 327 self._ppis = [] 328 self._protocols = [] 329 self._depexs = [] 330 self._guids = [] 331 self._packages = [] 332 333 def Destroy(self): 334 for lib in self._libs.values(): 335 if lib is not None: 336 lib.Destroy() 337 self._libs.clear() 338 339 for pcd in self._pcds.values(): 340 pcd.Destroy() 341 self._pcds.clear() 342 343 for ppi in self._ppis: 344 ppi.DeRef(self) 345 del self._ppis[:] 346 347 for protocol in self._protocols: 348 if protocol is not None: 349 protocol.DeRef(self) 350 del self._protocols[:] 351 352 for guid in self._guids: 353 if guid is not None: 354 guid.DeRef(self) 355 del self._guids[:] 356 357 del self._packages[:] 358 del self._depexs[:] 359 SurfaceObject.Destroy(self) 360 361 def GetFileObjectClass(self): 362 return inf.INFFile 363 364 def GetLibraries(self): 365 return self._libs 366 367 def Load(self, filename, arch='common', overidePcds=None, overideLibs=None): 368 if not SurfaceObject.Load(self, filename): 369 return False 370 371 self._arch = arch 372 if overidePcds is not None: 373 self._overideLibs = overideLibs 374 if overideLibs is not None: 375 self._overidePcds = overidePcds 376 377 self._SearchLibraries() 378 self._SearchPackage() 379 self._SearchSurfaceItems() 380 return True 381 382 def GetArch(self): 383 return self._arch 384 385 def GetModuleName(self): 386 return self.GetFileObj().GetDefine("BASE_NAME") 387 388 def GetModuleType(self): 389 return self.GetFileObj().GetDefine("MODULE_TYPE") 390 391 def GetPlatform(self): 392 return self.GetParent() 393 394 def GetModuleObj(self): 395 return self 396 397 def GetPcds(self): 398 pcds = self._pcds.copy() 399 for lib in self._libs.values(): 400 if lib is None: continue 401 for name in lib._pcds.keys(): 402 pcds[name] = lib._pcds[name] 403 return pcds 404 405 def GetPpis(self): 406 ppis = [] 407 ppis += self._ppis 408 for lib in self._libs.values(): 409 if lib is None: continue 410 ppis += lib._ppis 411 return ppis 412 413 def GetProtocols(self): 414 pros = [] 415 pros = self._protocols 416 for lib in self._libs.values(): 417 if lib is None: continue 418 pros += lib._protocols 419 return pros 420 421 def GetGuids(self): 422 guids = [] 423 guids += self._guids 424 for lib in self._libs.values(): 425 if lib is None: continue 426 guids += lib._guids 427 return guids 428 429 def GetDepexs(self): 430 deps = [] 431 deps += self._depexs 432 for lib in self._libs.values(): 433 if lib is None: continue 434 deps += lib._depexs 435 return deps 436 437 def IsLibrary(self): 438 return self.GetFileObj().GetDefine("LIBRARY_CLASS") is not None 439 440 def GetLibraryInstance(self, classname, arch, type): 441 if classname not in self._libs.keys(): 442 # find in overide lib firstly 443 if classname in self._overideLibs.keys(): 444 self._libs[classname] = Library(self, self.GetWorkspace()) 445 self._libs[classname].Load(self._overideLibs[classname]) 446 return self._libs[classname] 447 448 parent = self.GetParent() 449 if issubclass(parent.__class__, Platform): 450 path = parent.GetLibraryPath(classname, arch, type) 451 if path is None: 452 ErrorMsg('Fail to get library instance for %s' % classname, self.GetFilename()) 453 return None 454 self._libs[classname] = Library(self, self.GetWorkspace()) 455 if not self._libs[classname].Load(path, self.GetArch()): 456 self._libs[classname] = None 457 else: 458 self._libs[classname] = parent.GetLibraryInstance(classname, arch, type) 459 return self._libs[classname] 460 461 def GetSourceObjs(self): 462 return self.GetFileObj().GetSectionObjectsByName('source') 463 464 def _SearchLibraries(self): 465 objs = self.GetFileObj().GetSectionObjectsByName('libraryclasses') 466 arch = self.GetArch() 467 type = self.GetModuleType() 468 for obj in objs: 469 if obj.GetArch().lower() != 'common' and \ 470 obj.GetArch().lower() not in self.GetPlatform().GetSupportArchs(): 471 continue 472 classname = obj.GetClass() 473 instance = self.GetLibraryInstance(classname, arch, type) 474 if not self.IsLibrary() and instance is not None: 475 instance._isInherit = False 476 477 if classname not in self._libs.keys(): 478 self._libs[classname] = instance 479 480 def _SearchSurfaceItems(self): 481 # get surface item from self's inf 482 pcds = [] 483 ppis = [] 484 pros = [] 485 deps = [] 486 guids = [] 487 if self.GetFileObj() is not None: 488 pcds = self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('pcd'), 489 self.GetArch()) 490 for pcd in pcds: 491 if pcd.GetPcdName() not in self._pcds.keys(): 492 pcdItem = PcdItem(pcd.GetPcdName(), self, pcd) 493 self._pcds[pcd.GetPcdName()] = ModulePcd(self, 494 pcd.GetPcdName(), 495 pcd, 496 pcdItem) 497 498 ppis += self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('ppis'), 499 self.GetArch()) 500 501 for ppi in ppis: 502 item = PpiItem(ppi.GetName(), self, ppi) 503 if item not in self._ppis: 504 self._ppis.append(item) 505 506 pros += self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('protocols'), 507 self.GetArch()) 508 509 for pro in pros: 510 item = ProtocolItem(pro.GetName(), self, pro) 511 if item not in self._protocols: 512 self._protocols.append(item) 513 514 deps += self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('depex'), 515 self.GetArch()) 516 for dep in deps: 517 item = DepexItem(self, dep) 518 self._depexs.append(item) 519 520 guids += self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('guids'), 521 self.GetArch()) 522 for guid in guids: 523 item = GuidItem(guid.GetName(), self, guid) 524 if item not in self._guids: 525 self._guids.append(item) 526 527 def _SearchPackage(self): 528 objs = self.GetFileObj().GetSectionObjectsByName('packages') 529 for obj in objs: 530 package = self.GetPlatform().GetPackage(obj.GetPath()) 531 if package is not None: 532 self._packages.append(package) 533 534 def GetPackages(self): 535 return self._packages 536 537 def GetPcdObjects(self): 538 if self.GetFileObj() is None: 539 return [] 540 541 return self.GetFileObj().GetSectionObjectsByName('pcd') 542 543 def GetLibraryClassHeaderFilePath(self): 544 lcname = self.GetFileObj().GetProduceLibraryClass() 545 if lcname is None: return None 546 547 pkgs = self.GetPackages() 548 for package in pkgs: 549 path = package.GetLibraryClassHeaderPathByName(lcname) 550 if path is not None: 551 return os.path.realpath(os.path.join(package.GetFileObj().GetPackageRootPath(), path)) 552 return None 553 554 def Reload(self, force=False, callback=None): 555 if callback is not None: 556 callback(self, "Starting reload...") 557 558 ret = SurfaceObject.Reload(self, force) 559 if not ret: return False 560 561 if not force and not self.IsModified(): 562 return True 563 564 for lib in self._libs.values(): 565 if lib is not None: 566 lib.Destroy() 567 self._libs.clear() 568 569 for pcd in self._pcds.values(): 570 pcd.Destroy() 571 self._pcds.clear() 572 573 for ppi in self._ppis: 574 ppi.DeRef(self) 575 del self._ppis[:] 576 577 for protocol in self._protocols: 578 protocol.DeRef(self) 579 del self._protocols[:] 580 581 for guid in self._guids: 582 guid.DeRef(self) 583 del self._guids[:] 584 585 del self._packages[:] 586 del self._depexs[:] 587 588 if callback is not None: 589 callback(self, "Searching libraries...") 590 self._SearchLibraries() 591 if callback is not None: 592 callback(self, "Searching packages...") 593 self._SearchPackage() 594 if callback is not None: 595 callback(self, "Searching surface items...") 596 self._SearchSurfaceItems() 597 598 self.Modify(False) 599 return True 600 601 def Modify(self, modify=True, modifiedObj=None): 602 if modify: 603 #LogMsg("%s is modified, modified object is %s" % (self.GetFilename(), modifiedObj)) 604 if issubclass(modifiedObj.__class__, ini.BaseINIFile) and self._isModify: 605 return 606 self._isModify = modify 607 self.GetParent().Modify(modify, self) 608 else: 609 if self.GetFileObj().IsModified(): 610 return 611 612 self._isModify = modify 613 self.GetParent().Modify(modify, self) 614 615class Library(Module): 616 def __init__(self, parent, workspace): 617 Module.__init__(self, parent, workspace) 618 self._isInherit = True 619 620 def IsInherit(self): 621 return self._isInherit 622 623 def GetModuleType(self): 624 return self.GetParent().GetModuleType() 625 626 def GetPlatform(self): 627 return self.GetParent().GetParent() 628 629 def GetModuleObj(self): 630 return self.GetParent() 631 632 def GetArch(self): 633 return self.GetParent().GetArch() 634 635 def Destroy(self): 636 self._libs.clear() 637 self._pcds.clear() 638 SurfaceObject.Destroy(self) 639 640class Package(SurfaceObject): 641 def __init__(self, parent, workspace): 642 SurfaceObject.__init__(self, parent, workspace) 643 self._pcds = {} 644 self._guids = {} 645 self._protocols = {} 646 self._ppis = {} 647 648 def GetPcds(self): 649 return self._pcds 650 651 def GetPpis(self): 652 return list(self._ppis.values()) 653 654 def GetProtocols(self): 655 return list(self._protocols.values()) 656 657 def GetGuids(self): 658 return list(self._guids.values()) 659 660 def Destroy(self): 661 for pcd in self._pcds.values(): 662 if pcd is not None: 663 pcd.Destroy() 664 for guid in self._guids.values(): 665 if guid is not None: 666 guid.Destroy() 667 for protocol in self._protocols.values(): 668 if protocol is not None: 669 protocol.Destroy() 670 for ppi in self._ppis.values(): 671 if ppi is not None: 672 ppi.Destroy() 673 self._pcds.clear() 674 self._guids.clear() 675 self._protocols.clear() 676 self._ppis.clear() 677 self._pcds.clear() 678 SurfaceObject.Destroy(self) 679 680 def Load(self, relativePath): 681 ret = SurfaceObject.Load(self, relativePath) 682 if not ret: return False 683 pcds = self.GetFileObj().GetSectionObjectsByName('pcds') 684 for pcd in pcds: 685 if pcd.GetPcdName() in self._pcds.keys(): 686 if self._pcds[pcd.GetPcdName()] is not None: 687 self._pcds[pcd.GetPcdName()].AddDecObj(pcd) 688 else: 689 self._pcds[pcd.GetPcdName()] = PcdItem(pcd.GetPcdName(), self, pcd) 690 691 guids = self.GetFileObj().GetSectionObjectsByName('guids') 692 for guid in guids: 693 if guid.GetName() not in self._guids.keys(): 694 self._guids[guid.GetName()] = GuidItem(guid.GetName(), self, guid) 695 else: 696 WarnMsg("Duplicate definition for %s" % guid.GetName()) 697 698 ppis = self.GetFileObj().GetSectionObjectsByName('ppis') 699 for ppi in ppis: 700 if ppi.GetName() not in self._ppis.keys(): 701 self._ppis[ppi.GetName()] = PpiItem(ppi.GetName(), self, ppi) 702 else: 703 WarnMsg("Duplicate definition for %s" % ppi.GetName()) 704 705 protocols = self.GetFileObj().GetSectionObjectsByName('protocols') 706 for protocol in protocols: 707 if protocol.GetName() not in self._protocols.keys(): 708 self._protocols[protocol.GetName()] = ProtocolItem(protocol.GetName(), self, protocol) 709 else: 710 WarnMsg("Duplicate definition for %s" % protocol.GetName()) 711 712 return True 713 714 def GetFileObjectClass(self): 715 return dec.DECFile 716 717 def GetName(self): 718 return self.GetFileObj().GetDefine("PACKAGE_NAME") 719 720 def GetPcdDefineObjs(self, name=None): 721 arr = [] 722 objs = self.GetFileObj().GetSectionObjectsByName('pcds') 723 if name is None: return objs 724 725 for obj in objs: 726 if obj.GetPcdName().lower() == name.lower(): 727 arr.append(obj) 728 return arr 729 730 def GetLibraryClassObjs(self): 731 return self.GetFileObj().GetSectionObjectsByName('libraryclasses') 732 733 def Modify(self, modify=True, modifiedObj=None): 734 if modify: 735 self._isModify = modify 736 self.GetParent().Modify(modify, self) 737 else: 738 if self.GetFileObj().IsModified(): 739 return 740 741 self._isModify = modify 742 self.GetParent().Modify(modify, self) 743 744 def GetLibraryClassHeaderPathByName(self, clsname): 745 objs = self.GetLibraryClassObjs() 746 for obj in objs: 747 if obj.GetClassName() == clsname: 748 return obj.GetHeaderFile() 749 return None 750 751class DepexItem(object): 752 def __init__(self, parent, infObj): 753 self._parent = parent 754 self._infObj = infObj 755 756 def GetDepexString(self): 757 return str(self._infObj) 758 759 def GetInfObject(self): 760 return self._infObj 761 762class ModulePcd(object): 763 _type_mapping = {'FeaturePcd': 'PcdsFeatureFlag', 764 'FixedPcd': 'PcdsFixedAtBuild', 765 'PatchPcd': 'PcdsPatchableInModule'} 766 767 def __init__(self, parent, name, infObj, pcdItem): 768 assert issubclass(parent.__class__, Module), "Module's PCD's parent must be module!" 769 assert pcdItem is not None, 'Pcd %s does not in some package!' % name 770 771 self._name = name 772 self._parent = parent 773 self._pcdItem = pcdItem 774 self._infObj = infObj 775 776 def GetName(self): 777 return self._name 778 779 def GetParent(self): 780 return self._name 781 782 def GetArch(self): 783 return self._parent.GetArch() 784 785 def Destroy(self): 786 self._pcdItem.DeRef(self._parent) 787 self._infObj = None 788 789 def GetBuildObj(self): 790 platformInfos = self._parent.GetPlatform().GetPcdBuildObjs(self._name, self.GetArch()) 791 modulePcdType = self._infObj.GetPcdType() 792 793 # if platform do not gives pcd's value, get default value from package 794 if len(platformInfos) == 0: 795 if modulePcdType.lower() == 'pcd': 796 return self._pcdItem.GetDecObject() 797 else: 798 for obj in self._pcdItem.GetDecObjects(): 799 if modulePcdType not in self._type_mapping.keys(): 800 ErrorMsg("Invalid PCD type %s" % modulePcdType) 801 return None 802 803 if self._type_mapping[modulePcdType] == obj.GetPcdType(): 804 return obj 805 ErrorMsg ('Module PCD type %s does not in valied range [%s] in package!' % \ 806 (modulePcdType)) 807 else: 808 if modulePcdType.lower() == 'pcd': 809 if len(platformInfos) > 1: 810 WarnMsg("Find more than one value for PCD %s in platform %s" % \ 811 (self._name, self._parent.GetPlatform().GetFilename())) 812 return platformInfos[0] 813 else: 814 for obj in platformInfos: 815 if modulePcdType not in self._type_mapping.keys(): 816 ErrorMsg("Invalid PCD type %s" % modulePcdType) 817 return None 818 819 if self._type_mapping[modulePcdType] == obj.GetPcdType(): 820 return obj 821 822 ErrorMsg('Can not find value for pcd %s in pcd type %s' % \ 823 (self._name, modulePcdType)) 824 return None 825 826 827class SurfaceItem(object): 828 _objs = {} 829 830 def __new__(cls, *args, **kwargs): 831 """Maintain only a single instance of this object 832 @return: instance of this class 833 834 """ 835 name = args[0] 836 parent = args[1] 837 fileObj = args[2] 838 if issubclass(parent.__class__, Package): 839 if name in cls._objs.keys(): 840 ErrorMsg("%s item is duplicated defined in packages: %s and %s" % 841 (name, parent.GetFilename(), cls._objs[name].GetParent().GetFilename())) 842 return None 843 obj = object.__new__(cls) 844 cls._objs[name] = obj 845 return obj 846 elif issubclass(parent.__class__, Module): 847 if name not in cls._objs.keys(): 848 ErrorMsg("%s item does not defined in any package! It is used by module %s" % \ 849 (name, parent.GetFilename())) 850 return None 851 return cls._objs[name] 852 853 return None 854 855 856 def __init__(self, name, parent, fileObj): 857 if issubclass(parent.__class__, Package): 858 self._name = name 859 self._parent = parent 860 self._decObj = [fileObj] 861 self._refMods = {} 862 else: 863 self.RefModule(parent, fileObj) 864 865 @classmethod 866 def GetObjectDict(cls): 867 return cls._objs 868 869 def GetParent(self): 870 return self._parent 871 872 def GetReference(self): 873 return self._refMods 874 875 def RefModule(self, mObj, infObj): 876 if mObj in self._refMods.keys(): 877 return 878 self._refMods[mObj] = infObj 879 880 def DeRef(self, mObj): 881 if mObj not in self._refMods.keys(): 882 WarnMsg("%s is not referenced by module %s" % (self._name, mObj.GetFilename())) 883 return 884 del self._refMods[mObj] 885 886 def Destroy(self): 887 self._refMods.clear() 888 cls = self.__class__ 889 del cls._objs[self._name] 890 891 def GetName(self): 892 return self._name 893 894 def GetDecObject(self): 895 return self._decObj[0] 896 897 def GetDecObjects(self): 898 return self._decObj 899 900class PcdItem(SurfaceItem): 901 def AddDecObj(self, fileObj): 902 for decObj in self._decObj: 903 if decObj.GetFilename() != fileObj.GetFilename(): 904 ErrorMsg("Pcd %s defined in more than one packages : %s and %s" % \ 905 (self._name, decObj.GetFilename(), fileObj.GetFilename())) 906 return 907 if decObj.GetPcdType() == fileObj.GetPcdType() and \ 908 decObj.GetArch().lower() == fileObj.GetArch(): 909 ErrorMsg("Pcd %s is duplicated defined in pcd type %s in package %s" % \ 910 (self._name, decObj.GetPcdType(), decObj.GetFilename())) 911 return 912 self._decObj.append(fileObj) 913 914 def GetValidPcdType(self): 915 types = [] 916 for obj in self._decObj: 917 if obj.GetPcdType() not in types: 918 types += obj.GetPcdType() 919 return types 920 921class GuidItem(SurfaceItem): 922 pass 923 924class PpiItem(SurfaceItem): 925 pass 926 927class ProtocolItem(SurfaceItem): 928 pass 929