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