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