baseobject.py 31 KB

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