Fixed several typo in R8.x module support code
[people/mcb30/basetools.git] / Source / Python / Workspace / WorkspaceDatabase.py
1 ## @file\r
2 # This file is used to create a database used by ECC tool\r
3 #\r
4 # Copyright (c) 2007 ~ 2008, Intel Corporation\r
5 # All rights reserved. This program and the accompanying materials\r
6 # are licensed and made available under the terms and conditions of the BSD License\r
7 # which accompanies this 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
13 \r
14 ##\r
15 # Import Modules\r
16 #\r
17 import sqlite3\r
18 import os\r
19 import os.path\r
20 \r
21 import Common.EdkLogger as EdkLogger\r
22 from CommonDataClass.DataClass import *\r
23 from CommonDataClass.ModuleClass import *\r
24 from Common.String import *\r
25 from Common.DataType import *\r
26 from Common.Misc import tdict\r
27 from Common.Misc import sdict\r
28 \r
29 from MetaDataTable import *\r
30 from MetaFileTable import *\r
31 from MetaFileParser import *\r
32 from BuildClassObject import *\r
33 \r
34 def ValidFile(File, Dir='.'):\r
35     Wd = os.getcwd()\r
36     os.chdir(Dir)\r
37     if not os.path.exists(File):\r
38         os.chdir(Wd)\r
39         return False\r
40     os.chdir(Wd)\r
41     return True\r
42 \r
43 class DscBuildData(PlatformBuildClassObject):\r
44     #_PROPERTY_ = {\r
45     #    TAB_DSC_DEFINES_PLATFORM_NAME           : '_PlatformName'\r
46     #    TAB_DSC_DEFINES_PLATFORM_GUID           : '_Guid'\r
47     #    TAB_DSC_DEFINES_PLATFORM_VERSION        : '_Version'\r
48     #    TAB_DSC_DEFINES_DSC_SPECIFICATION       : '_DscSpecification'\r
49     #    TAB_DSC_DEFINES_OUTPUT_DIRECTORY        : '_OutputDirectory'\r
50     #    TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : '_SupArchList'\r
51     #    TAB_DSC_DEFINES_BUILD_TARGETS           : '_BuildTargets'\r
52     #    TAB_DSC_DEFINES_SKUID_IDENTIFIER        : '_SkuId'\r
53     #    TAB_DSC_DEFINES_FLASH_DEFINITION        : '_FlashDefinition'\r
54     #    TAB_DSC_DEFINES_BUILD_NUMBER            : '_BuildNumber'\r
55     #    TAB_DSC_DEFINES_MAKEFILE_NAME           : '_MakefileName'\r
56     #    TAB_DSC_DEFINES_BS_BASE_ADDRESS         : '_BsBaseAddress'\r
57     #    TAB_DSC_DEFINES_RT_BASE_ADDRESS         : '_RtBaseAddress'\r
58     #}\r
59     _PCD_TYPE_STRING_ = {\r
60         MODEL_PCD_FIXED_AT_BUILD        :   "FixedAtBuild",\r
61         MODEL_PCD_PATCHABLE_IN_MODULE   :   "PatchableInModule",\r
62         MODEL_PCD_FEATURE_FLAG          :   "FeatureFlag",\r
63         MODEL_PCD_DYNAMIC               :   "Dynamic",\r
64         MODEL_PCD_DYNAMIC_DEFAULT       :   "Dynamic",\r
65         MODEL_PCD_DYNAMIC_HII           :   "DynamicHii",\r
66         MODEL_PCD_DYNAMIC_VPD           :   "DynamicVpd",\r
67         MODEL_PCD_DYNAMIC_EX            :   "DynamicEx",\r
68         MODEL_PCD_DYNAMIC_EX_DEFAULT    :   "DynamicEx",\r
69         MODEL_PCD_DYNAMIC_EX_HII        :   "DynamicExHii",\r
70         MODEL_PCD_DYNAMIC_EX_VPD        :   "DynamicExVpd",\r
71     }\r
72 \r
73     _NullLibraryNumber = 0\r
74 \r
75     def __init__(self, FilePath, Table, Db, Arch='COMMON', Macros={}):\r
76         self.DescFilePath = FilePath\r
77         self._Table = Table\r
78         self._Db = Db\r
79         self._Arch = Arch\r
80         self._Macros = Macros\r
81         self._Clear()\r
82 \r
83     def __repr__(self):\r
84         S = '[Platform.%s]\n' % self.Arch\r
85         S += "\tName = %s\n" % self.PlatformName\r
86         S += "\tGuid = %s\n" % self.Guid\r
87         S += "\tVer = %s\n" % self.Version\r
88         S += "\n"\r
89         S += "\tSpecification = %s\n" % self.DscSpecification\r
90         S += "\tOutputDirectory = %s\n" % self.OutputDirectory \r
91         S += "\tSupArchList = %s\n" % self.SupArchList     \r
92         S += "\tBuildTargets = %s\n" % self.BuildTargets    \r
93         S += "\tSkuName = %s\n" % self.SkuName           \r
94         S += "\tFlashDefinition = %s\n" % self.FlashDefinition \r
95         S += "\tBuildNumber = %s\n" % self.BuildNumber     \r
96         S += "\tMakefileName = %s\n" % self.MakefileName    \r
97         S += "\tBsBaseAddress = %s\n" % self.BsBaseAddress   \r
98         S += "\tRtBaseAddress = %s\n" % self.RtBaseAddress   \r
99 \r
100         S += '  <SkuId>\n'\r
101         for SkuName in self.SkuIds:\r
102             S += "\t%s = %s\n" % (SkuName, self.SkuIds[SkuName])\r
103 \r
104         #S += '  <LibraryClass>\n'\r
105         #ModuleTypeList = set()\r
106         #LibraryClassList = set()\r
107         #for LibraryClass,ModuleType in self.LibraryClasses:\r
108         #    LibraryClassList.add(LibraryClass)\r
109         #    ModuleTypeList.add(ModuleType)\r
110         #LibraryClassList = list(LibraryClassList)\r
111         #ModuleTypeList = list(ModuleTypeList)\r
112         #LibraryClassList.sort()\r
113         #ModuleTypeList.sort()\r
114         #for LibraryClass in LibraryClassList:\r
115         #    for ModuleType in ModuleTypeList:\r
116         #        if not (LibraryClass,ModuleType) in self.LibraryClasses:\r
117         #            continue \r
118         #        S += "\t%32s, %-24s = %s\n" % (LibraryClass, ModuleType, self.LibraryClasses[LibraryClass,ModuleType])\r
119         \r
120         S += '  <PCD>\n'\r
121         for Name, Guid in self.Pcds:\r
122             S += "\t%s.%s\n\t\t%s\n" % (Guid, Name, str(self.Pcds[Name, Guid]))\r
123         \r
124         S += '  <BuildOption>\n'\r
125         for ToolChainFamily,ToolChain in self.BuildOptions:\r
126             S += "\t%s:%s = %s\n" % (ToolChainFamily, ToolChain, self.BuildOptions[ToolChainFamily, ToolChain])\r
127 \r
128         S += '  <Module>\n'\r
129         S += "\t" + "\n\t".join([str(M) for M in self.Modules]) + '\n'\r
130         return S\r
131 \r
132     ## XXX[key] = value\r
133     #def __setitem__(self, key, value):\r
134     #    self.__dict__[self._PROPERTY_[key]] = value\r
135     #\r
136     ### variable = XXX[key]\r
137     #def __getitem__(self, key):\r
138     #    return self.__dict__[self._PROPERTY_[key]]\r
139     #\r
140     ### "in" test support\r
141     #def __contains__(self, key):\r
142     #    return key in self._PROPERTY_\r
143 \r
144     def _Clear(self):\r
145         self._PlatformName      = None\r
146         self._Guid              = None\r
147         self._Version           = None\r
148         self._DscSpecification  = None\r
149         self._OutputDirectory   = None\r
150         self._SupArchList       = None\r
151         self._BuildTargets      = None\r
152         self._SkuName           = None\r
153         self._FlashDefinition   = None\r
154         self._BuildNumber       = None\r
155         self._MakefileName      = None\r
156         self._BsBaseAddress     = None\r
157         self._RtBaseAddress     = None\r
158         self._SkuIds            = None\r
159         self._Modules           = None\r
160         self._LibraryInstances  = None\r
161         self._LibraryClasses    = None\r
162         self._Libraries         = None\r
163         self._Pcds              = None\r
164         self._BuildOptions      = None\r
165 \r
166     def _GetArch(self):\r
167         return self._Arch\r
168 \r
169     def _SetArch(self, Value):\r
170         if self._Arch == Value:\r
171             return\r
172         self._Arch = Value\r
173         self._Clear()\r
174 \r
175     def _GetPlatformName(self):\r
176         if self._PlatformName == None:\r
177             RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_PLATFORM_NAME, self.Arch)\r
178             self._PlatformName = RecordList[0][0]\r
179         return self._PlatformName\r
180 \r
181     def _GetFileGuid(self):\r
182         if self._Guid == None:\r
183             RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_PLATFORM_GUID, self.Arch)\r
184             self._Guid = RecordList[0][0]\r
185         return self._Guid\r
186 \r
187     def _GetVersion(self):\r
188         if self._Version == None:\r
189             RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_PLATFORM_VERSION, self.Arch)\r
190             self._Version = RecordList[0][0]\r
191         return self._Version\r
192 \r
193     def _GetDscSpec(self):\r
194         if self._DscSpecification == None:\r
195             RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_DSC_SPECIFICATION, self.Arch)\r
196             self._DscSpecification = RecordList[0][0]\r
197         return self._DscSpecification\r
198 \r
199     def _GetOutpuDir(self):\r
200         if self._OutputDirectory == None:\r
201             RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_OUTPUT_DIRECTORY, self.Arch)\r
202             File = NormPath(RecordList[0][0], self._Macros)\r
203             LineNo = RecordList[0][-1]\r
204             self._OutputDirectory = File\r
205         return self._OutputDirectory\r
206 \r
207     def _GetSupArch(self):\r
208         if self._SupArchList == None:\r
209             RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES, self.Arch)\r
210             self._SupArchList = GetSplitValueList(RecordList[0][0], TAB_VALUE_SPLIT)\r
211         return self._SupArchList\r
212 \r
213     def _GetBuildTarget(self):\r
214         if self._BuildTargets == None:\r
215             RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_BUILD_TARGETS, self.Arch)\r
216             self._BuildTargets = GetSplitValueList(RecordList[0][0])\r
217         return self._BuildTargets\r
218 \r
219     def _GetSkuName(self):\r
220         if self._SkuName == None:\r
221             RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_SKUID_IDENTIFIER, self.Arch)\r
222             if len(RecordList) > 0:\r
223                 self._SkuName = RecordList[0][0]\r
224                 if self._SkuName not in self.SkuIds:\r
225                     self._SkuName = 'DEFAULT'\r
226             else:\r
227                 self._SkuName = 'DEFAULT'\r
228         return self._SkuName\r
229 \r
230     def _GetFdfFile(self):\r
231         if self._FlashDefinition == None:\r
232             RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_FLASH_DEFINITION, self.Arch)\r
233             if len(RecordList) > 0:\r
234                 self._FlashDefinition = NormPath(RecordList[0][0])\r
235             else:\r
236                 self._FlashDefinition = ''\r
237         return self._FlashDefinition\r
238 \r
239     def _GetBuildNumber(self):\r
240         if self._BuildNumber == None:\r
241             RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_BUILD_NUMBER, self.Arch)\r
242             if len(RecordList) > 0:\r
243                 self._BuildNumber = RecordList[0][0]\r
244         return self._BuildNumber\r
245 \r
246     def _GetMakefileName(self):\r
247         if self._MakefileName == None:\r
248             RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_MAKEFILE_NAME, self.Arch)\r
249             if len(RecordList):\r
250                 self._MakefileName = RecordList[0][0]\r
251         return self._MakefileName\r
252 \r
253     def _GetBsBaseAddress(self):\r
254         if self._BsBaseAddress == None:\r
255             RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_BS_BASE_ADDRESS, self.Arch)\r
256             if len(RecordList) != 0:\r
257                 self._BsBaseAddress = RecordList[0][0]\r
258         return self._BsBaseAddress\r
259 \r
260     def _GetRtBaseAddress(self):\r
261         if self._RtBaseAddress == None:\r
262             RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_RT_BASE_ADDRESS, self.Arch)\r
263             if len(RecordList):\r
264                 self._RtBaseAddress = RecordList[0][0]\r
265         return self._RtBaseAddress\r
266 \r
267     def _GetSkuIds(self):\r
268         if self._SkuIds == None:\r
269             self._SkuIds = {}\r
270             RecordList = self._Table.Query(MODEL_EFI_SKU_ID)\r
271             for Record in RecordList:\r
272                 self._SkuIds[Record[1]] = Record[0]\r
273         return self._SkuIds\r
274 \r
275     def _GetModules(self):\r
276         if self._Modules == None:\r
277             self._Modules = []\r
278             RecordList = self._Table.Query(MODEL_META_DATA_COMPONENT, Scope1=self.Arch)\r
279             for Record in RecordList:\r
280                 ModuleFile = NormPath(Record[0], self._Macros)\r
281                 ModuleId = Record[5]\r
282                 LineNo = Record[6]\r
283                 if not ValidFile(ModuleFile):\r
284                     EdkLogger.error('build', FILE_NOT_FOUND, File=self.DescFilePath, \r
285                                     ExtraData=ModuleFile, Line=LineNo)\r
286                 if ModuleFile in self._Modules:\r
287                     continue\r
288                 Module = self._Db.BuildObject[ModuleFile, MODEL_FILE_INF, self._Arch]\r
289                 # only merge library classes and PCD for non-library module\r
290                 if Module.LibraryClass == None or Module.LibraryClass == []:\r
291                     if Module.AutoGenVersion < 0x00010005:\r
292                         self._ResolveLibraryReference(Module)\r
293                     else:\r
294                         self._MergeModuleInfo(Module, ModuleId)\r
295                 self._UpdateModulePcd(Module, ModuleId)\r
296                 self._MergeModuleBuildOption(Module, ModuleId)\r
297                 self._Modules.append(Module)\r
298         return self._Modules\r
299 \r
300     def _MergeModuleInfo(self, Module, ModuleId):\r
301         ModuleType = Module.ModuleType\r
302         # merge library class/instance information\r
303         for LibraryClass in Module.LibraryClasses:\r
304             if self.LibraryClasses[LibraryClass, ModuleType] == None: continue\r
305             Module.LibraryClasses[LibraryClass] = self.LibraryClasses[LibraryClass, ModuleType]\r
306         RecordList = self._Table.Query(MODEL_EFI_LIBRARY_CLASS, Scope1=self.Arch, BelongsToItem=ModuleId)\r
307         for Record in RecordList:\r
308             LibraryClass = Record[0]\r
309             LibraryPath = NormPath(Record[1], self._Macros)\r
310             LineNo = Record[-1]\r
311             if not ValidFile(LibraryPath):\r
312                 EdkLogger.error('build', FILE_NOT_FOUND, ExtraData=LibraryPath,\r
313                                 File=self.DescFilePath, Line=LineNo)\r
314             if LibraryClass == '' or LibraryClass == 'NULL':\r
315                 LibraryClass = 'NULL%d' % (self._NullLibraryNumber + 1)\r
316                 LibraryInstance = self._Db.BuildObject[LibraryPath, MODEL_FILE_INF, self._Arch]\r
317                 LibraryInstance.LibraryClass.append(LibraryClassObject(LibraryClass, [ModuleType]))\r
318             Module.LibraryClasses[LibraryClass] = LibraryPath\r
319 \r
320         # R9 module\r
321         LibraryConsumerList = [Module]\r
322         Constructor         = []\r
323         ConsumedByList      = sdict()\r
324         LibraryInstance     = sdict()\r
325 \r
326         EdkLogger.verbose("")\r
327         EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))\r
328         while len(LibraryConsumerList) > 0:\r
329             M = LibraryConsumerList.pop()\r
330             for LibraryClassName in M.LibraryClasses:\r
331                 LibraryPath = M.LibraryClasses[LibraryClassName]\r
332                 if LibraryPath == None or LibraryPath == "":\r
333                     LibraryPath = self.LibraryClasses[LibraryClassName, ModuleType]\r
334                     if LibraryPath == None and LibraryClassName not in LibraryInstance:\r
335                         LibraryInstance[LibraryClassName] = None\r
336                         continue\r
337                 if LibraryClassName not in LibraryInstance:\r
338                     LibraryModule = self._Db.BuildObject[LibraryPath, MODEL_FILE_INF, self._Arch]\r
339                     LibraryInstance[LibraryClassName] = LibraryModule\r
340                     LibraryConsumerList.append(LibraryModule)\r
341                     EdkLogger.verbose("\t" + str(LibraryClassName) + " : " + str(LibraryModule))\r
342                 else:\r
343                     LibraryModule = LibraryInstance[LibraryClassName]\r
344 \r
345                 if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor:\r
346                     Constructor.append(LibraryModule)\r
347 \r
348                 if LibraryModule not in ConsumedByList:\r
349                     ConsumedByList[LibraryModule] = []\r
350                 if M != Module:\r
351                     if M in ConsumedByList[LibraryModule]:\r
352                         continue\r
353                     ConsumedByList[LibraryModule].append(M)\r
354         #\r
355         # Initialize the sorted output list to the empty set\r
356         #\r
357         SortedLibraryList = []\r
358         #\r
359         # Q <- Set of all nodes with no incoming edges\r
360         #\r
361         LibraryList = [] #LibraryInstance.values()\r
362         Q = []\r
363         for LibraryClassName in LibraryInstance:\r
364             M = LibraryInstance[LibraryClassName]\r
365             if M == None:\r
366                 EdkLogger.error("AutoGen", AUTOGEN_ERROR,\r
367                                 "Library instance for library class [%s] is not found" % LibraryClassName,\r
368                                 ExtraData="\t%s [%s]" % (str(Module), self.Arch))\r
369             LibraryList.append(M)\r
370             #\r
371             # check if there're duplicate library classes\r
372             #\r
373             for Lc in M.LibraryClass:\r
374                 if Lc.SupModList != None and ModuleType not in Lc.SupModList:\r
375                     EdkLogger.error("AutoGen", AUTOGEN_ERROR,\r
376                                     "Module type [%s] is not supported by library instance [%s]" % (ModuleType, str(M)),\r
377                                     ExtraData="\t%s" % str(Module))\r
378 \r
379                 if Lc.LibraryClass in LibraryInstance and str(M) != str(LibraryInstance[Lc.LibraryClass]):\r
380                     EdkLogger.error("AutoGen", AUTOGEN_ERROR,\r
381                                     "More than one library instance found for library class [%s] in module [%s]" % (Lc.LibraryClass, Module),\r
382                                     ExtraData="\t%s\n\t%s" % (LibraryInstance[Lc.LibraryClass], str(M))\r
383                                     )\r
384             if ConsumedByList[M] == []:\r
385                 Q.insert(0, M)\r
386         #\r
387         # while Q is not empty do\r
388         #\r
389         while Q != []:\r
390             #\r
391             # remove node from Q\r
392             #\r
393             Node = Q.pop()\r
394             #\r
395             # output Node\r
396             #\r
397             SortedLibraryList.append(Node)\r
398             #\r
399             # for each node Item with an edge e from Node to Item do\r
400             #\r
401             for Item in LibraryList:\r
402                 if Node not in ConsumedByList[Item]:\r
403                     continue\r
404                 #\r
405                 # remove edge e from the graph\r
406                 #\r
407                 ConsumedByList[Item].remove(Node)\r
408                 #\r
409                 # If Item has no other incoming edges then\r
410                 #\r
411                 if ConsumedByList[Item] == []:\r
412                     #\r
413                     # insert Item into Q\r
414                     #\r
415                     Q.insert(0, Item)\r
416 \r
417             EdgeRemoved = True\r
418             while Q == [] and EdgeRemoved:\r
419                 EdgeRemoved = False\r
420                 #\r
421                 # for each node Item with a Constructor\r
422                 #\r
423                 for Item in LibraryList:\r
424                     if Item in Constructor:\r
425                         #\r
426                         # for each Node without a constructor with an edge e from Item to Node\r
427                         #\r
428                         for Node in ConsumedByList[Item]:\r
429                             if Node not in Constructor:\r
430                                 #\r
431                                 # remove edge e from the graph\r
432                                 #\r
433                                 ConsumedByList[Item].remove(Node)\r
434                                 EdgeRemoved = True\r
435                                 if ConsumedByList[Item] == []:\r
436                                     #\r
437                                     # insert Item into Q\r
438                                     #\r
439                                     Q.insert(0, Item)\r
440                                     break\r
441                     if Q != []:\r
442                         break\r
443 \r
444         #\r
445         # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle\r
446         #\r
447         for Item in LibraryList:\r
448             if ConsumedByList[Item] != [] and Item in Constructor and len(Constructor) > 1:\r
449                 ErrorMessage = 'Library [%s] with constructors has a cycle' % str(Item)\r
450                 EdkLogger.error("AutoGen", AUTOGEN_ERROR, ErrorMessage,\r
451                                 "\tconsumed by " + "\n\tconsumed by ".join([str(L) for L in ConsumedByList[Item]]))\r
452             if Item not in SortedLibraryList:\r
453                 SortedLibraryList.append(Item)\r
454 \r
455         #\r
456         # Build the list of constructor and destructir names\r
457         # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order\r
458         #\r
459         SortedLibraryList.reverse()\r
460         Module.LibraryClasses = sdict()\r
461         for L in SortedLibraryList:\r
462             Module.LibraryClasses[L.LibraryClass[0].LibraryClass, ModuleType] = L\r
463             #\r
464             # Merge PCDs from library instance\r
465             #\r
466             for Key in L.Pcds:\r
467                 if Key not in Module.Pcds:\r
468                     Module.Pcds[Key] = L.Pcds[Key]\r
469             #\r
470             # Merge GUIDs from library instance\r
471             #\r
472             for CName in L.Guids:\r
473                 if CName not in Module.Guids:\r
474                     Module.Guids.append(CName)\r
475             #\r
476             # Merge Protocols from library instance\r
477             #\r
478             for CName in L.Protocols:\r
479                 if CName not in Module.Protocols:\r
480                     Module.Protocols.append(CName)\r
481             #\r
482             # Merge Ppis from library instance\r
483             #\r
484             for CName in L.Ppis:\r
485                 if CName not in Module.Ppis:\r
486                     Module.Ppis.append(CName)\r
487 \r
488     ##\r
489     # for R8.x modules\r
490     # \r
491     def _ResolveLibraryReference(self, Module):\r
492         EdkLogger.verbose("")\r
493         EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self._Arch))\r
494         LibraryConsumerList = [Module]\r
495 \r
496         # "CompilerStub" is a must for R8 modules\r
497         Module.Libraries.append("CompilerStub")\r
498         while len(LibraryConsumerList) > 0:\r
499             M = LibraryConsumerList.pop()\r
500             for LibraryName in M.Libraries:\r
501                 if LibraryName not in self.Libraries:\r
502                     EdkLogger.warn("AutoGen", "Library [%s] is not found" % LibraryName,\r
503                                     ExtraData="\t%s [%s]" % (str(Module), self._Arch))\r
504                     continue\r
505 \r
506                 Library = self.Libraries[LibraryName]\r
507                 if (LibraryName, Module.ModuleType) not in Module.LibraryClasses:\r
508                     Module.LibraryClasses[LibraryName, Module.ModuleType] = Library\r
509                     LibraryConsumerList.append(Library)\r
510                     EdkLogger.verbose("\t" + LibraryName + " : " + str(Library))\r
511 \r
512     def _UpdateModulePcd(self, Module, ModuleId):\r
513         for Name,Guid in Module.Pcds:\r
514             PcdInModule = Module.Pcds[Name,Guid]\r
515             if (Name,Guid) in self.Pcds:\r
516                 PcdInPlatform = self.Pcds[Name,Guid]\r
517                 # \r
518                 # in case there's PCDs coming from FDF file, which have no type given.\r
519                 # at this point, PcdInModule.Type has the type found from dependent\r
520                 # package\r
521                 # \r
522                 if PcdInPlatform.Type != None and PcdInPlatform.Type != '':\r
523                     PcdInModule.Type = PcdInPlatform.Type\r
524                 PcdInModule.MaxDatumSize = PcdInPlatform.MaxDatumSize\r
525                 PcdInModule.SkuInfoList = PcdInPlatform.SkuInfoList\r
526                 if PcdInPlatform.DefaultValue not in [None, '']:\r
527                     PcdInModule.DefaultValue = PcdInPlatform.DefaultValue\r
528                 if PcdInPlatform.TokenValue not in [None, '']:\r
529                     PcdInModule.TokenValue = PcdInPlatform.TokenValue\r
530                 if PcdInPlatform.MaxDatumSize not in [None, '']:\r
531                     PcdInModule.MaxDatumSize = PcdInPlatform.MaxDatumSize\r
532                 if PcdInPlatform.DatumType not in [None, '']:\r
533                     PcdInModule.DatumType = PcdInPlatform.DatumType\r
534 \r
535             if PcdInModule.DatumType == "VOID*" and PcdInModule.MaxDatumSize in ['', None]:\r
536                 EdkLogger.verbose("No MaxDatumSize specified for PCD %s.%s in module [%s]" % (Guid, Name, str(Module)))\r
537                 Value = PcdInModule.DefaultValue\r
538                 if Value[0] == 'L':\r
539                     PcdInModule.MaxDatumSize = str(len(Value) * 2)\r
540                 elif Value[0] == '{':\r
541                     PcdInModule.MaxDatumSize = str(len(Value.split(',')))\r
542                 else:\r
543                     PcdInModule.MaxDatumSize = str(len(Value))\r
544 \r
545         RecordList = self._Table.Query(MODEL_PCD_FIXED_AT_BUILD, Scope1=self.Arch, BelongsToItem=ModuleId)\r
546         for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
547             if (PcdCName, TokenSpaceGuid) not in Module.Pcds:\r
548                 continue\r
549             TokenList = GetSplitValueList(Setting)\r
550             Pcd = Module.Pcds[PcdCName, TokenSpaceGuid]\r
551             Pcd.DefaultValue = TokenList[0]\r
552             if len(TokenList) > 1:\r
553                 Pcd.MaxDatumSize = TokenList[1]\r
554             Pcd.Type = self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD]\r
555 \r
556         RecordList = self._Table.Query(MODEL_PCD_PATCHABLE_IN_MODULE, Scope1=self.Arch, BelongsToItem=ModuleId)\r
557         for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
558             if (PcdCName, TokenSpaceGuid) not in Module.Pcds:\r
559                 continue\r
560             TokenList = GetSplitValueList(Setting)\r
561             Pcd = Module.Pcds[PcdCName, TokenSpaceGuid]\r
562             Pcd.DefaultValue = TokenList[0]\r
563             if len(TokenList) > 1:\r
564                 Pcd.MaxDatumSize = TokenList[1]\r
565             Pcd.Type = self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]\r
566 \r
567         RecordList = self._Table.Query(MODEL_PCD_FEATURE_FLAG, Scope1=self.Arch, BelongsToItem=ModuleId)\r
568         for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
569             if (PcdCName, TokenSpaceGuid) not in Module.Pcds:\r
570                 continue\r
571             TokenList = GetSplitValueList(Setting)\r
572             Pcd = Module.Pcds[PcdCName, TokenSpaceGuid]\r
573             Pcd.DefaultValue = TokenList[0]\r
574             if len(TokenList) > 1:\r
575                 Pcd.MaxDatumSize = TokenList[1]\r
576             Pcd.Type = self._PCD_TYPE_STRING_[MODEL_PCD_FEATURE_FLAG]\r
577 \r
578         RecordList = self._Table.Query(MODEL_PCD_DYNAMIC, Scope1=self.Arch, BelongsToItem=ModuleId)\r
579         for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
580             if (PcdCName, TokenSpaceGuid) not in Module.Pcds:\r
581                 continue\r
582             Pcd.DefaultValue = Setting\r
583             Pcd.Type = self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC]\r
584 \r
585         RecordList = self._Table.Query(MODEL_PCD_DYNAMIC_EX, Scope1=self.Arch, BelongsToItem=ModuleId)\r
586         for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
587             if (PcdCName, TokenSpaceGuid) not in Module.Pcds:\r
588                 continue\r
589             Pcd.DefaultValue = Setting\r
590             Pcd.Type = self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX]\r
591 \r
592     def _MergeModuleBuildOption(self, Module, ModuleId):\r
593         RecordList = self._Table.Query(MODEL_META_DATA_BUILD_OPTION, Scope1=self.Arch, BelongsToItem=ModuleId)\r
594         for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
595             if (ToolChainFamily, ToolChain) not in Module.BuildOptions:\r
596                 Module.BuildOptions[ToolChainFamily, ToolChain] = Option\r
597             else:\r
598                 OptionString = Module.BuildOptions[ToolChainFamily, ToolChain]\r
599                 Module.BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option\r
600 \r
601     def _GetLibraryInstances(self):\r
602         if self._LibraryInstances == None:\r
603             self._LibraryInstances = []\r
604             for Module in self.Modules:\r
605                 for Key in Module.LibraryClasses:\r
606                     Lib = Module.LibraryClasses[Key]\r
607                     if Lib in [None, ''] or Lib in self._LibraryInstances:\r
608                         continue\r
609                     self._LibraryInstances.append(Lib)\r
610         return self._LibraryInstances\r
611 \r
612     def _GetLibraryClasses(self):\r
613         if self._LibraryClasses == None:\r
614             LibraryClassDict = tdict(True, 3)\r
615             LibraryClassSet = set()\r
616             ModuleTypeSet = set()\r
617             RecordList = self._Table.Query(MODEL_EFI_LIBRARY_CLASS, Scope1=self.Arch)\r
618             for LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy, LineNo in RecordList:\r
619                 LibraryClassSet.add(LibraryClass)\r
620                 ModuleTypeSet.add(ModuleType)\r
621                 LibraryInstance = NormPath(LibraryInstance, self._Macros)\r
622                 if not ValidFile(LibraryInstance):\r
623                     EdkLogger.error('build', FILE_NOT_FOUND, File=self.DescFilePath, \r
624                                     ExtraData=LibraryInstance, Line=LineNo)\r
625                 LibraryClassDict[Arch, ModuleType, LibraryClass] = LibraryInstance\r
626 \r
627             self._LibraryClasses = tdict(True)\r
628             for LibraryClass in LibraryClassSet:\r
629                 for ModuleType in ModuleTypeSet:\r
630                     LibraryInstance = LibraryClassDict[self.Arch, ModuleType, LibraryClass]\r
631                     if LibraryInstance == None:\r
632                         continue\r
633                     self._LibraryClasses[LibraryClass, ModuleType] = LibraryInstance\r
634         return self._LibraryClasses\r
635 \r
636     def _GetLibraries(self):\r
637         if self._Libraries == None:\r
638             self._Libraries = sdict()\r
639             RecordList = self._Table.Query(MODEL_EFI_LIBRARY_INSTANCE, Scope1=self.Arch)\r
640             for Record in RecordList:\r
641                 File = NormPath(Record[0], self._Macros)\r
642                 LineNo = Record[-1]\r
643                 if not ValidFile(File):\r
644                     EdkLogger.error('build', FILE_NOT_FOUND, ExtraData=File,\r
645                                     File=self.DescFilePath, Line=LineNo)\r
646                 Library = self._Db.BuildObject[File, MODEL_FILE_INF, self._Arch]\r
647                 self._Libraries[Library.BaseName] = Library\r
648         return self._Libraries\r
649 \r
650     def _GetPcds(self):\r
651         if self._Pcds == None:\r
652             self._Pcds = {}\r
653             self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
654             self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
655             self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
656             self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT))\r
657             self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII))\r
658             self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD))\r
659             self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT))\r
660             self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII))\r
661             self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD))\r
662         return self._Pcds\r
663 \r
664     def _GetBuildOptions(self):\r
665         if self._BuildOptions == None:\r
666             self._BuildOptions = {}\r
667             RecordList = self._Table.Query(MODEL_META_DATA_BUILD_OPTION)\r
668             for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
669                 self._BuildOptions[ToolChainFamily, ToolChain] = Option\r
670         return self._BuildOptions\r
671 \r
672     def _GetPcd(self, Type):\r
673         Pcds = {}\r
674         PcdDict = tdict(True, 3)\r
675         PcdSet = set()\r
676         # Find out all possible PCD candidates for self.Arch\r
677         RecordList = self._Table.Query(Type, Scope1=self.Arch)\r
678         for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
679             PcdSet.add((PcdCName, TokenSpaceGuid))\r
680             PcdDict[Arch, PcdCName, TokenSpaceGuid] = Setting\r
681         # Remove redundant PCD candidates\r
682         for PcdCName, TokenSpaceGuid in PcdSet:\r
683             ValueList = ['', '', '']\r
684             Setting = PcdDict[self.Arch, PcdCName, TokenSpaceGuid]\r
685             if Setting == None:\r
686                 continue\r
687             TokenList = Setting.split(TAB_VALUE_SPLIT)\r
688             ValueList[0:len(TokenList)] = TokenList\r
689             PcdValue, DatumType, MaxDatumSize = ValueList\r
690             Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
691                                                 PcdCName,\r
692                                                 TokenSpaceGuid,\r
693                                                 self._PCD_TYPE_STRING_[Type],\r
694                                                 DatumType,\r
695                                                 PcdValue,\r
696                                                 '',\r
697                                                 MaxDatumSize,\r
698                                                 {},\r
699                                                 True\r
700                                                 )\r
701         return Pcds\r
702 \r
703     def _GetDynamicPcd(self, Type):\r
704         Pcds = {}\r
705         PcdDict = tdict(True, 4)\r
706         PcdSet = set()\r
707         RecordList = self._Table.Query(Type, Scope1=self.Arch)\r
708         for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
709             PcdSet.add((PcdCName, TokenSpaceGuid))\r
710             PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
711 \r
712         for PcdCName, TokenSpaceGuid in PcdSet:\r
713             ValueList = ['', '', '']\r
714             Setting = PcdDict[self.Arch, self.SkuName, PcdCName, TokenSpaceGuid]\r
715             if Setting == None:\r
716                 continue\r
717             TokenList = Setting.split(TAB_VALUE_SPLIT)\r
718             ValueList[0:len(TokenList)] = TokenList\r
719             PcdValue, DatumType, MaxDatumSize = ValueList\r
720 \r
721             SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], '', '', '', '', '', PcdValue)\r
722             Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
723                                                 PcdCName,\r
724                                                 TokenSpaceGuid,\r
725                                                 self._PCD_TYPE_STRING_[Type],\r
726                                                 DatumType,\r
727                                                 PcdValue,\r
728                                                 '',\r
729                                                 MaxDatumSize,\r
730                                                 {self.SkuName : SkuInfo},\r
731                                                 True\r
732                                                 )\r
733         return Pcds\r
734 \r
735     def _GetDynamicHiiPcd(self, Type):\r
736         Pcds = {}\r
737         PcdDict = tdict(True, 4)\r
738         PcdSet = set()\r
739         RecordList = self._Table.Query(Type, Scope1=self.Arch)\r
740         for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
741             PcdSet.add((PcdCName, TokenSpaceGuid))\r
742             PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
743 \r
744         for PcdCName, TokenSpaceGuid in PcdSet:\r
745             ValueList = ['', '', '', '']\r
746             Setting = PcdDict[self.Arch, self.SkuName, PcdCName, TokenSpaceGuid]\r
747             if Setting == None:\r
748                 continue\r
749             TokenList = Setting.split(TAB_VALUE_SPLIT)\r
750             ValueList[0:len(TokenList)] = TokenList\r
751             VariableName, VariableGuid, VariableOffset, DefaultValue = ValueList\r
752             SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue)\r
753             Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
754                                                 PcdCName,\r
755                                                 TokenSpaceGuid,\r
756                                                 self._PCD_TYPE_STRING_[Type],\r
757                                                 '',\r
758                                                 DefaultValue,\r
759                                                 '',\r
760                                                 '',\r
761                                                 {self.SkuName : SkuInfo},\r
762                                                 True\r
763                                                 )\r
764         return Pcds\r
765 \r
766     def _GetDynamicVpdPcd(self, Type):\r
767         Pcds = {}\r
768         PcdDict = tdict(True, 4)\r
769         PcdSet = set()\r
770         RecordList = self._Table.Query(Type, Scope1=self.Arch)\r
771         for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
772             PcdSet.add((PcdCName, TokenSpaceGuid))\r
773             PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
774 \r
775         for PcdCName, TokenSpaceGuid in PcdSet:\r
776             ValueList = ['', '']\r
777             Setting = PcdDict[self.Arch, self.SkuName, PcdCName, TokenSpaceGuid]\r
778             if Setting == None:\r
779                 continue\r
780             TokenList = Setting.split(TAB_VALUE_SPLIT)\r
781             ValueList[0:len(TokenList)] = TokenList\r
782             VpdOffset, MaxDatumSize = ValueList\r
783 \r
784             SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], '', '', '', '', VpdOffset)\r
785             Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
786                                                 PcdCName,\r
787                                                 TokenSpaceGuid,\r
788                                                 self._PCD_TYPE_STRING_[Type],\r
789                                                 '',\r
790                                                 '',\r
791                                                 '',\r
792                                                 MaxDatumSize,\r
793                                                 {self.SkuName : SkuInfo},\r
794                                                 True\r
795                                                 )\r
796         return Pcds\r
797 \r
798     def AddModule(self, FilePath):\r
799         Module = self._Db.BuildObject[FilePath, MODEL_FILE_INF, self._Arch]\r
800         self._Modules.append(NormPath(Module))\r
801 \r
802     def AddPcd(self, Name, Guid, Value):\r
803         if (Name, Guid) not in self.Pcds:\r
804             self.Pcds[Name, Guid] = PcdClassObject(\r
805                                         Name,\r
806                                         Guid,\r
807                                         '',\r
808                                         '',\r
809                                         '',\r
810                                         '',\r
811                                         '',\r
812                                         {},\r
813                                         True\r
814                                         )\r
815         self.Pcds[Name, Guid].DefaultValue = Value\r
816 \r
817     Arch                = property(_GetArch, _SetArch)\r
818     Platform            = property(_GetPlatformName)\r
819     PlatformName        = property(_GetPlatformName)\r
820     Guid                = property(_GetFileGuid)\r
821     Version             = property(_GetVersion)\r
822     DscSpecification    = property(_GetDscSpec)\r
823     OutputDirectory     = property(_GetOutpuDir)\r
824     SupArchList         = property(_GetSupArch)\r
825     BuildTargets        = property(_GetBuildTarget)\r
826     SkuName             = property(_GetSkuName)\r
827     FlashDefinition     = property(_GetFdfFile)\r
828     BuildNumber         = property(_GetBuildNumber)\r
829     MakefileName        = property(_GetMakefileName)\r
830     BsBaseAddress       = property(_GetBsBaseAddress)\r
831     RtBaseAddress       = property(_GetRtBaseAddress)\r
832 \r
833     SkuIds              = property(_GetSkuIds)\r
834     Modules             = property(_GetModules)\r
835     LibraryInstances    = property(_GetLibraryInstances)\r
836     LibraryClasses      = property(_GetLibraryClasses)\r
837     Libraries           = property(_GetLibraries)\r
838     Pcds                = property(_GetPcds)\r
839     BuildOptions        = property(_GetBuildOptions)\r
840 \r
841 class DecBuildData(PackageBuildClassObject):\r
842     _PCD_TYPE_STRING_ = {\r
843         MODEL_PCD_FIXED_AT_BUILD        :   "FixedAtBuild",\r
844         MODEL_PCD_PATCHABLE_IN_MODULE   :   "PatchableInModule",\r
845         MODEL_PCD_FEATURE_FLAG          :   "FeatureFlag",\r
846         MODEL_PCD_DYNAMIC               :   "Dynamic",\r
847         MODEL_PCD_DYNAMIC_DEFAULT       :   "Dynamic",\r
848         MODEL_PCD_DYNAMIC_HII           :   "DynamicHii",\r
849         MODEL_PCD_DYNAMIC_VPD           :   "DynamicVpd",\r
850         MODEL_PCD_DYNAMIC_EX            :   "DynamicEx",\r
851         MODEL_PCD_DYNAMIC_EX_DEFAULT    :   "DynamicEx",\r
852         MODEL_PCD_DYNAMIC_EX_HII        :   "DynamicExHii",\r
853         MODEL_PCD_DYNAMIC_EX_VPD        :   "DynamicExVpd",\r
854     }\r
855 \r
856     def __init__(self, FilePath, Table, Db, Arch='COMMON', Macros={}):\r
857         self.DescFilePath = FilePath\r
858         self._PackageDir = os.path.dirname(FilePath)\r
859         self._Table = Table\r
860         self._Arch = Arch\r
861         self._Macros = Macros\r
862         self._Clear()\r
863 \r
864     def __repr__(self):\r
865         S = "[Package]\n"\r
866         S += "\tNAME = %s\n" % self.PackageName\r
867         S += "\tGUID = %s\n" % self.Guid\r
868         S += "\tVER  = %s\n" % self.Version\r
869 \r
870         S += '  <Protocol>\n'\r
871         for Name in self.Protocols:\r
872             S += "\t%s = %s\n" % (Name, self.Protocols[Name])\r
873 \r
874         S += '  <Ppi>\n'\r
875         for Name in self.Ppis:\r
876             S += "\t%s = %s\n" % (Name, self.Ppis[Name])\r
877 \r
878         S += '  <Guid>\n'\r
879         for Name in self.Guids:\r
880             S += "\t%s = %s\n" % (Name, self.Guids[Name])\r
881 \r
882         S += '  <Include>\n\t'\r
883         S += "\n\t".join(self.Includes) + '\n'\r
884 \r
885         S += '  <LibraryClass>\n'\r
886         for LibraryClass in self.LibraryClasses:\r
887             S += "\t%s = %s\n" % (LibraryClass, self.LibraryClasses[LibraryClass])\r
888 \r
889         S += '  <PCD>\n'\r
890         for Name,Guid,Type in self.Pcds:\r
891             S += "\t%s.%s-%s\n\t\t%s\n" % (Guid, Name, Type, str(self.Pcds[Name, Guid, Type]))\r
892         return S\r
893 \r
894     def _Clear(self):\r
895         self._PackageName       = None\r
896         self._Guid              = None\r
897         self._Version           = None\r
898         self._Protocols         = None\r
899         self._Ppis              = None\r
900         self._Guids             = None\r
901         self._Includes          = None\r
902         self._LibraryClasses    = None\r
903         self._Pcds              = None\r
904 \r
905     def _GetArch(self):\r
906         return self._Arch\r
907 \r
908     def _SetArch(self, Value):\r
909         if self._Arch == Value:\r
910             return\r
911         self._Arch = Value\r
912         self._Clear()\r
913 \r
914     def _GetPackageName(self):\r
915         if self._PackageName == None:\r
916             RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DEC_DEFINES_PACKAGE_NAME)\r
917             if len(RecordList) == 0:\r
918                 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_NAME", ExtraData=self.DescFilePath)\r
919             self._PackageName = RecordList[0][0]\r
920         return self._PackageName\r
921 \r
922     def _GetFileGuid(self):\r
923         if self._Guid == None:\r
924             RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DEC_DEFINES_PACKAGE_GUID)\r
925             if len(RecordList) == 0:\r
926                 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_GUID", ExtraData=self.DescFilePath)\r
927             self._Guid = RecordList[0][0]\r
928         return self._Guid\r
929 \r
930     def _GetVersion(self):\r
931         if self._Version == None:\r
932             RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DEC_DEFINES_PACKAGE_VERSION)\r
933             if len(RecordList) == 0:\r
934                 self._Version = ''\r
935             self._Version = RecordList[0][0]\r
936         return self._Version\r
937 \r
938     def _GetProtocol(self):\r
939         if self._Protocols == None:\r
940             ProtocolDict = tdict(True)\r
941             NameSet = set()\r
942             RecordList = self._Table.Query(MODEL_EFI_PROTOCOL, Arch=self.Arch)\r
943             for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:\r
944                 NameSet.add(Name)\r
945                 ProtocolDict[Arch, Name] = Guid\r
946             self._Protocols = sdict()\r
947             for Name in NameSet:\r
948                 self._Protocols[Name] = ProtocolDict[self.Arch, Name]\r
949         return self._Protocols\r
950 \r
951     def _GetPpi(self):\r
952         if self._Ppis == None:\r
953             PpiDict = tdict(True)\r
954             NameSet = set()\r
955             RecordList = self._Table.Query(MODEL_EFI_PPI, Arch=self.Arch)\r
956             for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:\r
957                 NameSet.add(Name)\r
958                 PpiDict[Arch, Name] = Guid\r
959             self._Ppis = sdict()\r
960             for Name in NameSet:\r
961                 self._Ppis[Name] = PpiDict[self.Arch, Name]\r
962         return self._Ppis\r
963 \r
964     def _GetGuid(self):\r
965         if self._Guids == None:\r
966             GuidDict = tdict(True)\r
967             NameSet = set()\r
968             RecordList = self._Table.Query(MODEL_EFI_GUID, Arch=self.Arch)\r
969             for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:\r
970                 NameSet.add(Name)\r
971                 GuidDict[Arch, Name] = Guid\r
972             self._Guids = sdict()\r
973             for Name in NameSet:\r
974                 self._Guids[Name] = GuidDict[self.Arch, Name]\r
975         return self._Guids\r
976 \r
977     def _GetInclude(self):\r
978         if self._Includes == None:\r
979             self._Includes = []\r
980             RecordList = self._Table.Query(MODEL_EFI_INCLUDE, Arch=self.Arch)\r
981             for Record in RecordList:\r
982                 File = NormPath(Record[0], self._Macros)\r
983                 LineNo = Record[-1]\r
984                 if not ValidFile(File, self._PackageDir):\r
985                     EdkLogger.error('build', FILE_NOT_FOUND, ExtraData=File,\r
986                                     File=self.DescFilePath, Line=LineNo)\r
987                 self._Includes.append(File)\r
988         return self._Includes\r
989 \r
990     def _GetLibraryClass(self):\r
991         if self._LibraryClasses == None:\r
992             LibraryClassDict = tdict(True)\r
993             LibraryClassSet = set()\r
994             RecordList = self._Table.Query(MODEL_EFI_LIBRARY_CLASS, Arch=self.Arch)\r
995             for LibraryClass, File, Dummy, Arch, ID, LineNo in RecordList:\r
996                 File = NormPath(File, self._Macros)\r
997                 if not ValidFile(File, self._PackageDir):\r
998                     EdkLogger.error('build', FILE_NOT_FOUND, ExtraData=File,\r
999                                     File=self.DescFilePath, Line=LineNo)\r
1000                 LibraryClassSet.add(LibraryClass)\r
1001                 LibraryClassDict[Arch, LibraryClass] = File\r
1002             self._LibraryClasses = sdict()\r
1003             for LibraryClass in LibraryClassSet:\r
1004                 self._LibraryClasses[LibraryClass] = LibraryClassDict[self.Arch, LibraryClass]\r
1005         return self._LibraryClasses\r
1006 \r
1007     def _GetPcds(self):\r
1008         if self._Pcds == None:\r
1009             self._Pcds = {}\r
1010             self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
1011             self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
1012             self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
1013             self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC))\r
1014             self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))\r
1015         return self._Pcds\r
1016 \r
1017     def _GetPcd(self, Type):\r
1018         Pcds = {}\r
1019         PcdDict = tdict(True, 3)\r
1020         PcdSet = set()\r
1021         RecordList = self._Table.Query(Type, Arch=self._Arch)\r
1022         for TokenSpaceGuid, PcdCName, Setting, Arch, Dummy1, Dummy2 in RecordList:\r
1023             PcdDict[Arch, PcdCName, TokenSpaceGuid] = Setting\r
1024             PcdSet.add((PcdCName, TokenSpaceGuid))\r
1025 \r
1026         for PcdCName, TokenSpaceGuid in PcdSet:\r
1027             ValueList = ['', '', '']\r
1028             Setting = PcdDict[self.Arch, PcdCName, TokenSpaceGuid]\r
1029             if Setting == None:\r
1030                 continue\r
1031             TokenList = Setting.split(TAB_VALUE_SPLIT)\r
1032             ValueList[0:len(TokenList)] = TokenList\r
1033             DefaultValue, DatumType, TokenNumber = ValueList\r
1034             Pcds[PcdCName, TokenSpaceGuid, self._PCD_TYPE_STRING_[Type]] = PcdClassObject(\r
1035                                                                             PcdCName,\r
1036                                                                             TokenSpaceGuid,\r
1037                                                                             self._PCD_TYPE_STRING_[Type],\r
1038                                                                             DatumType,\r
1039                                                                             DefaultValue,\r
1040                                                                             TokenNumber,\r
1041                                                                             '',\r
1042                                                                             {},\r
1043                                                                             True\r
1044                                                                             )\r
1045         return Pcds\r
1046 \r
1047 \r
1048     Arch            = property(_GetArch, _SetArch)\r
1049     PackageName     = property(_GetPackageName)\r
1050     Guid            = property(_GetFileGuid)\r
1051     Version         = property(_GetVersion)\r
1052 \r
1053     Protocols       = property(_GetProtocol)\r
1054     Ppis            = property(_GetPpi)\r
1055     Guids           = property(_GetGuid)\r
1056     Includes        = property(_GetInclude)\r
1057     LibraryClasses  = property(_GetLibraryClass)\r
1058     Pcds            = property(_GetPcds)\r
1059 \r
1060 class InfBuildData(ModuleBuildClassObject):\r
1061     _PCD_TYPE_STRING_ = {\r
1062         MODEL_PCD_FIXED_AT_BUILD        :   "FixedAtBuild",\r
1063         MODEL_PCD_PATCHABLE_IN_MODULE   :   "PatchableInModule",\r
1064         MODEL_PCD_FEATURE_FLAG          :   "FeatureFlag",\r
1065         MODEL_PCD_DYNAMIC               :   "Dynamic",\r
1066         MODEL_PCD_DYNAMIC_DEFAULT       :   "Dynamic",\r
1067         MODEL_PCD_DYNAMIC_HII           :   "DynamicHii",\r
1068         MODEL_PCD_DYNAMIC_VPD           :   "DynamicVpd",\r
1069         MODEL_PCD_DYNAMIC_EX            :   "DynamicEx",\r
1070         MODEL_PCD_DYNAMIC_EX_DEFAULT    :   "DynamicEx",\r
1071         MODEL_PCD_DYNAMIC_EX_HII        :   "DynamicExHii",\r
1072         MODEL_PCD_DYNAMIC_EX_VPD        :   "DynamicExVpd",\r
1073     }\r
1074 \r
1075     _PROPERTY_ = {\r
1076         #\r
1077         # Required Fields\r
1078         #\r
1079         TAB_INF_DEFINES_BASE_NAME                   : "_BaseName",\r
1080         TAB_INF_DEFINES_FILE_GUID                   : "_Guid",\r
1081         TAB_INF_DEFINES_MODULE_TYPE                 : "_ModuleType",\r
1082         #\r
1083         # Optional Fields\r
1084         #\r
1085         TAB_INF_DEFINES_INF_VERSION                 : "_AutoGenVersion",\r
1086         TAB_INF_DEFINES_COMPONENT_TYPE              : "_ComponentType",\r
1087         TAB_INF_DEFINES_MAKEFILE_NAME               : "_CustomMakefile",\r
1088         TAB_INF_DEFINES_CUSTOM_MAKEFILE             : "_CustomMakefile",\r
1089         TAB_INF_DEFINES_VERSION_NUMBER              : "_Version",\r
1090         TAB_INF_DEFINES_VERSION_STRING              : "_Version",\r
1091         TAB_INF_DEFINES_VERSION                     : "_Version",\r
1092         TAB_INF_DEFINES_PCD_IS_DRIVER               : "_PcdIsDriver",\r
1093         TAB_INF_DEFINES_SHADOW                      : "_Shadow",\r
1094         TAB_INF_DEFINES_CUSTOM_MAKEFILE             : "_CustomMakefile",\r
1095     }\r
1096 \r
1097     _MODULE_TYPE_ = {\r
1098         "LIBRARY"               :   "BASE",\r
1099         "SECURITY_CORE"         :   "SEC",\r
1100         "PEI_CORE"              :   "PEI_CORE",\r
1101         "COMBINED_PEIM_DRIVER"  :   "PEIM",\r
1102         "PIC_PEIM"              :   "PEIM",\r
1103         "RELOCATABLE_PEIM"      :   "PEIM",\r
1104         "PE32_PEIM"             :   "PEIM",\r
1105         "BS_DRIVER"             :   "DXE_DRIVER",\r
1106         "RT_DRIVER"             :   "DXE_RUNTIME_DRIVER",\r
1107         "SAL_RT_DRIVER"         :   "DXE_SAL_DRIVER",\r
1108     #    "BS_DRIVER"             :   "DXE_SMM_DRIVER",\r
1109     #    "BS_DRIVER"             :   "UEFI_DRIVER",\r
1110         "APPLICATION"           :   "UEFI_APPLICATION",\r
1111         "LOGO"                  :   "BASE",\r
1112     }\r
1113     \r
1114     _NMAKE_FLAG_PATTERN_ = re.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re.UNICODE)\r
1115     _TOOL_CODE_ = {\r
1116         "C"         :   "CC",\r
1117         "LIB"       :   "SLINK",\r
1118         "LINK"      :   "DLINK",\r
1119     }\r
1120     \r
1121 \r
1122     def __init__(self, FilePath, Table, Db, Arch='COMMON', Macros={}):\r
1123         self.DescFilePath = FilePath\r
1124         self._ModuleDir = os.path.dirname(FilePath)\r
1125         self._Table = Table\r
1126         self._Db = Db\r
1127         self._Arch = Arch\r
1128         self._Platform = 'COMMON'\r
1129         self._Macros = Macros\r
1130         self._Clear()\r
1131 \r
1132     def Print(self):\r
1133         S = '[%s.%s]\n' % (self.DescFilePath, self.Arch)\r
1134         S += '\tName = ' + self.BaseName + '\n'\r
1135         S += '\tGuid = ' + self.Guid + '\n'\r
1136         S += '\tVer  = ' + self.Version + '\n'\r
1137         S += '\tInfVersion = ' + self.AutoGenVersion + '\n'\r
1138         S += '\tModuleType = ' + self.ModuleType + '\n'\r
1139         S += '\tComponentType = ' + self.ComponentType + '\n'\r
1140         S += '\tPcdIsDriver = ' + str(self.PcdIsDriver) + '\n'\r
1141         S += '\tCustomMakefile = ' + self.CustomMakefile + '\n'\r
1142         S += '\tSpecification = ' + str(self.Specification) + '\n'\r
1143         S += '\tShadow = ' + str(self.Shadow) + '\n'\r
1144         S += '\tPcdIsDriver = ' + str(self.PcdIsDriver) + '\n'\r
1145         for Lib in self.LibraryClass:\r
1146             S += '\tLibraryClassDefinition = ' + str(Lib.LibraryClass) + ' SupModList = ' + str(Lib.SupModList) + '\n'\r
1147         S += '\tModuleEntryPointList = ' + str(self.ModuleEntryPointList) + '\n'\r
1148         S += '\tModuleUnloadImageList = ' + str(self.ModuleUnloadImageList) + '\n'\r
1149         S += '\tConstructorList = ' + str(self.ConstructorList) + '\n'\r
1150         S += '\tDestructorList = ' + str(self.DestructorList) + '\n'\r
1151 \r
1152         S += '  <Binaries>\n'\r
1153         for item in self.Binaries:\r
1154             S += "\t" + item.BinaryFile + item.FeatureFlag + item.SupArchList + '\n'\r
1155 \r
1156         S += '  <Sources>\n'\r
1157         for item in self.Sources:\r
1158             S += "\t" + item.SourceFile + '\n'\r
1159 \r
1160         S += '  <LibraryClasses>\n'\r
1161         S += '\t' + '\n\t'.join([Key for Key in self.LibraryClasses]) + '\n'\r
1162 \r
1163         S += '  <Protocols>\n'\r
1164         S += '\t' + '\n\t'.join(self.Protocols) + '\n'\r
1165 \r
1166         S += '  <Ppis>\n'\r
1167         S += '\t' + '\n\t'.join(self.Ppis) + '\n'\r
1168 \r
1169         S += '  <Guids>\n'\r
1170         S += '\t' + '\n\t'.join(self.Guids) + '\n'\r
1171 \r
1172         S += '  <Includes>\n'\r
1173         S += '\t' + '\n\t'.join(self.Includes) + '\n'\r
1174 \r
1175         S += '  <Packages>\n'\r
1176         S += '\t' + '\n\t'.join([str(P) for P in self.Packages]) + '\n'\r
1177 \r
1178         S += '  <Pcds>\n'\r
1179         for Name,Guid in self.Pcds.keys():\r
1180             S += "\t%s.%s\n\t\t%s\n" % (Guid, Name, str(self.Pcds[Name,Guid]))\r
1181 \r
1182         S += '  <BuildOptions\n'\r
1183         S += '\t' + '\n\t'.join(self.BuildOptions.values()) + '\n'\r
1184 \r
1185         S += '  <Depex>\n'\r
1186         S += '\t' + str(self.Depex) + '\n'\r
1187 \r
1188         S += '\n'\r
1189         return S\r
1190 \r
1191     ## XXX[key] = value\r
1192     def __setitem__(self, key, value):\r
1193         self.__dict__[self._PROPERTY_[key]] = value\r
1194     ## value = XXX[key]\r
1195     def __getitem__(self, key):\r
1196         return self.__dict__[self._PROPERTY_[key]]\r
1197     ## "in" test support\r
1198     def __contains__(self, key):\r
1199         return key in self._PROPERTY_\r
1200 \r
1201     def _Clear(self):\r
1202         self._Header_               = None\r
1203         self._AutoGenVersion        = None\r
1204         self._DescFilePath          = None\r
1205         self._BaseName              = None\r
1206         self._ModuleType            = None\r
1207         self._ComponentType         = None\r
1208         self._Guid                  = None\r
1209         self._Version               = None\r
1210         self._PcdIsDriver           = None\r
1211         self._BinaryModule          = None\r
1212         self._Shadow                = None\r
1213         self._CustomMakefile        = None\r
1214         self._Specification         = None\r
1215         self._LibraryClass          = None\r
1216         self._ModuleEntryPointList  = None\r
1217         self._ModuleUnloadImageList = None\r
1218         self._ConstructorList       = None\r
1219         self._DestructorList        = None\r
1220         self._Binaries              = None\r
1221         self._Sources               = None\r
1222         self._LibraryClasses        = None\r
1223         self._Libraries             = None\r
1224         self._Protocols             = None\r
1225         self._Ppis                  = None\r
1226         self._Guids                 = None\r
1227         self._Includes              = None\r
1228         self._Packages              = None\r
1229         self._Pcds                  = None\r
1230         self._BuildOptions          = None\r
1231         self._Depex                 = None\r
1232 \r
1233     def _GetArch(self):\r
1234         return self._Arch\r
1235 \r
1236     def _SetArch(self, Value):\r
1237         if self._Arch == Value:\r
1238             return\r
1239         self._Arch = Value\r
1240         self._Clear()\r
1241 \r
1242     def _GetPlatform(self):\r
1243         return self._Platform\r
1244 \r
1245     def _SetPlatform(self, Value):\r
1246         self._Platform = Value\r
1247 \r
1248     def _GetHeaderInfo(self):\r
1249         RecordList = self._Table.Query(MODEL_META_DATA_HEADER, Arch=self._Arch, Platform=self._Platform)\r
1250         for Record in RecordList:\r
1251             Name = Record[0]\r
1252             if Name in self:\r
1253                 self[Name] = Record[1]\r
1254             elif Name == 'EFI_SPECIFICATION_VERSION':\r
1255                 if self._Specification == None:\r
1256                     self._Specification = sdict()\r
1257                 self._Specification[Name] = Record[1]\r
1258             elif Name == 'EDK_RELEASE_VERSION':\r
1259                 if self._Specification == None:\r
1260                     self._Specification = sdict()\r
1261                 self._Specification[Name] = Record[1]\r
1262             elif Name == 'LIBRARY_CLASS':\r
1263                 if self._LibraryClass == None:\r
1264                     self._LibraryClass = []\r
1265                 ValueList = GetSplitValueList(Record[1])\r
1266                 LibraryClass = ValueList[0]\r
1267                 if len(ValueList) > 1:\r
1268                     SupModuleList = GetSplitValueList(ValueList[1], ' ')\r
1269                 else:\r
1270                     SupModuleList = SUP_MODULE_LIST\r
1271                 self._LibraryClass.append(LibraryClassObject(LibraryClass, SupModuleList))\r
1272             elif Name == 'ENTRY_POINT':\r
1273                 if self._ModuleEntryPointList == None:\r
1274                     self._ModuleEntryPointList = []\r
1275                 self._ModuleEntryPointList.append(Record[1])\r
1276             elif Name == 'UNLOAD_IMAGE':\r
1277                 if self._ModuleUnloadImageList == None:\r
1278                     self._ModuleUnloadImageList = []\r
1279                 if Record[1] == '':\r
1280                     continue\r
1281                 self._ModuleUnloadImageList.append(Record[1])\r
1282             elif Name == 'CONSTRUCTOR':\r
1283                 if self._ConstructorList == None:\r
1284                     self._ConstructorList = []\r
1285                 if Record[1] == '':\r
1286                     continue\r
1287                 self._ConstructorList.append(Record[1])\r
1288             elif Name == 'DESTRUCTOR':\r
1289                 if self._DestructorList == None:\r
1290                     self._DestructorList = []\r
1291                 if Record[1] == '':\r
1292                     continue\r
1293                 self._DestructorList.append(Record[1])\r
1294 \r
1295         # \r
1296         # R8.x modules\r
1297         # \r
1298         if self._AutoGenVersion < 0x00010005:   # _AutoGenVersion may be None, which is less than anything\r
1299             if self._ComponentType in self._MODULE_TYPE_:\r
1300                 self._ModuleType = self._MODULE_TYPE_[self._ComponentType]\r
1301             if self._ComponentType == 'LIBRARY':\r
1302                 self._LibraryClass = [LibraryClassObject(self._BaseName, SUP_MODULE_LIST)]\r
1303             # make use some [nmake] section macros\r
1304             RecordList = self._Table.Query(MODEL_META_DATA_NMAKE, Arch=self._Arch, Platform=self._Platform)\r
1305             for Name,Value,Dummy,Arch,Platform,ID,LineNo in RecordList:\r
1306                 if Name == "IMAGE_ENTRY_POINT":\r
1307                     if self._ModuleEntryPointList == None:\r
1308                         self._ModuleEntryPointList = []\r
1309                     self._ModuleEntryPointList.append(Value)\r
1310                 elif Name == "DPX_SOURCE":\r
1311                     File = NormPath(Value, self._Macros)\r
1312                     if not ValidFile(File, self._ModuleDir):\r
1313                         EdkLogger.error('build', FILE_NOT_FOUND, ExtraData=File,\r
1314                                         File=self.DescFilePath, Line=LineNo)\r
1315                     if self._Sources == None:\r
1316                         self._Sources = []\r
1317                     self._Sources.append(ModuleSourceFileClass(File, "", "", "", ""))\r
1318                 else:\r
1319                     ToolList = self._NMAKE_FLAG_PATTERN_.findall(Name)\r
1320                     if len(ToolList) == 0 or len(ToolList) != 1:\r
1321                         EdkLogger.warn("\nbuild", "Don't know how to do with macro [%s]" % Name, \r
1322                                        File=self.DescFilePath, Line=LineNo)\r
1323                     else:\r
1324                         if self._BuildOptions == None:\r
1325                             self._BuildOptions = sdict()\r
1326 \r
1327                         if ToolList[0] in self._TOOL_CODE_:\r
1328                             Tool = self._TOOL_CODE_[ToolList[0]]\r
1329                         else:\r
1330                             Tool = ToolList[0]\r
1331                         ToolChain = "*_*_*_%s_FLAGS" % Tool\r
1332                         ToolChainFamily = 'MSFT'    # R8.x only support MSFT tool chain\r
1333                         if (ToolChainFamily, ToolChain) not in self._BuildOptions:\r
1334                             self._BuildOptions[ToolChainFamily, ToolChain] = Value\r
1335                         else:\r
1336                             OptionString = self._BuildOptions[ToolChainFamily, ToolChain]\r
1337                             self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Value\r
1338 \r
1339         self._Header_ = 'DUMMY'\r
1340 \r
1341     def _GetInfVersion(self):\r
1342         if self._AutoGenVersion == None:\r
1343             if self._Header_ == None:\r
1344                 self._GetHeaderInfo()\r
1345             if self._AutoGenVersion == None:\r
1346                 self._AutoGenVersion = 0x00010000\r
1347         return self._AutoGenVersion\r
1348 \r
1349     def _GetBaseName(self):\r
1350         if self._BaseName == None:\r
1351             if self._Header_ == None:\r
1352                 self._GetHeaderInfo()\r
1353             if self._BaseName == None:\r
1354                 self._BaseName = ''\r
1355         return self._BaseName\r
1356 \r
1357     def _GetModuleType(self):\r
1358         if self._ModuleType == None:\r
1359             if self._Header_ == None:\r
1360                 self._GetHeaderInfo()\r
1361             if self._ModuleType == None:\r
1362                 self._ModuleType = 'BASE'\r
1363         return self._ModuleType\r
1364 \r
1365     def _GetComponentType(self):\r
1366         if self._ComponentType == None:\r
1367             if self._Header_ == None:\r
1368                 self._GetHeaderInfo()\r
1369             if self._ComponentType == None:\r
1370                 self._ComponentType = ''\r
1371         return self._ComponentType\r
1372 \r
1373     def _GetFileGuid(self):\r
1374         if self._Guid == None:\r
1375             if self._Header_ == None:\r
1376                 self._GetHeaderInfo()\r
1377             if self._Guid == None:\r
1378                 self._Guid = '00000000-0000-0000-000000000000'\r
1379         return self._Guid\r
1380 \r
1381     def _GetVersion(self):\r
1382         if self._Version == None:\r
1383             if self._Header_ == None:\r
1384                 self._GetHeaderInfo()\r
1385             if self._Version == None:\r
1386                 self._Version = '0.0'\r
1387         return self._Version\r
1388 \r
1389     def _GetPcdIsDriver(self):\r
1390         if self._PcdIsDriver == None:\r
1391             if self._Header_ == None:\r
1392                 self._GetHeaderInfo()\r
1393             if self._PcdIsDriver == None:\r
1394                 self._PcdIsDriver = ''\r
1395         return self._PcdIsDriver\r
1396 \r
1397     def _GetShadow(self):\r
1398         if self._Shadow == None:\r
1399             if self._Header_ == None:\r
1400                 self._GetHeaderInfo()\r
1401             if self._Shadow != None and self._Shadow.upper() == 'TRUE':\r
1402                 self._Shadow = True\r
1403             else:\r
1404                 self._Shadow = False\r
1405         return self._Shadow\r
1406 \r
1407     def _GetMakefile(self):\r
1408         if self._CustomMakefile == None:\r
1409             if self._Header_ == None:\r
1410                 self._GetHeaderInfo()\r
1411             if self._CustomMakefile == None:\r
1412                 self._CustomMakefile = ''\r
1413         return self._CustomMakefile\r
1414 \r
1415     def _GetSpec(self):\r
1416         if self._Specification == None:\r
1417             if self._Header_ == None:\r
1418                 self._GetHeaderInfo()\r
1419             if self._Specification == None:\r
1420                 self._Specification = {}\r
1421         return self._Specification\r
1422 \r
1423     def _GetLibraryClass(self):\r
1424         if self._LibraryClass == None:\r
1425             if self._Header_ == None:\r
1426                 self._GetHeaderInfo()\r
1427             if self._LibraryClass == None:\r
1428                 self._LibraryClass = []\r
1429         return self._LibraryClass\r
1430 \r
1431     def _GetEntryPoint(self):\r
1432         if self._ModuleEntryPointList == None:\r
1433             if self._Header_ == None:\r
1434                 self._GetHeaderInfo()\r
1435             if self._ModuleEntryPointList == None:\r
1436                 self._ModuleEntryPointList = []\r
1437         return self._ModuleEntryPointList\r
1438 \r
1439     def _GetUnloadImage(self):\r
1440         if self._ModuleUnloadImageList == None:\r
1441             if self._Header_ == None:\r
1442                 self._GetHeaderInfo()\r
1443             if self._ModuleUnloadImageList == None:\r
1444                 self._ModuleUnloadImageList = []\r
1445         return self._ModuleUnloadImageList\r
1446 \r
1447     def _GetConstructor(self):\r
1448         if self._ConstructorList == None:\r
1449             if self._Header_ == None:\r
1450                 self._GetHeaderInfo()\r
1451             if self._ConstructorList == None:\r
1452                 self._ConstructorList = []\r
1453         return self._ConstructorList\r
1454 \r
1455     def _GetDestructor(self):\r
1456         if self._DestructorList == None:\r
1457             if self._Header_ == None:\r
1458                 self._GetHeaderInfo()\r
1459             if self._DestructorList == None:\r
1460                 self._DestructorList = []\r
1461         return self._DestructorList\r
1462                         \r
1463     def _GetBinaryFiles(self):\r
1464         if self._Binaries == None:\r
1465             self._Binaries = []\r
1466             RecordList = self._Table.Query(MODEL_EFI_BINARY_FILE, Arch=self._Arch, Platform=self._Platform)\r
1467             for Record in RecordList:\r
1468                 FileType = Record[0]\r
1469                 File = NormPath(Record[1], self._Macros)\r
1470                 LineNo = Record[-1]\r
1471                 if not ValidFile(File, self._ModuleDir):\r
1472                     EdkLogger.error('build', FILE_NOT_FOUND, ExtraData=File,\r
1473                                     File=self.DescFilePath, Line=LineNo)\r
1474                 Target = Record[2]\r
1475                 FeatureFlag = Record[3]\r
1476                 self._Binaries.append(ModuleBinaryFileClass(File, FileType, Target, FeatureFlag, self._Arch))\r
1477         return self._Binaries\r
1478 \r
1479     def _GetSourceFiles(self):\r
1480         if self._Sources == None:\r
1481             self._Sources = []\r
1482             RecordList = self._Table.Query(MODEL_EFI_SOURCE_FILE, Arch=self._Arch, Platform=self._Platform)\r
1483             for Record in RecordList:\r
1484                 File = NormPath(Record[0], self._Macros)\r
1485                 LineNo = Record[-1]\r
1486                 if not ValidFile(File, self._ModuleDir):\r
1487                     EdkLogger.error('build', FILE_NOT_FOUND, ExtraData=File,\r
1488                                     File=self.DescFilePath, Line=LineNo)\r
1489                 ToolChainFamily = Record[1]\r
1490                 TagName = Record[2]\r
1491                 ToolCode = Record[3]\r
1492                 FeatureFlag = Record[4]\r
1493                 self._Sources.append(ModuleSourceFileClass(File, TagName, ToolCode, ToolChainFamily, FeatureFlag))\r
1494         return self._Sources\r
1495 \r
1496     def _GetLibraryClassUses(self):\r
1497         if self._LibraryClasses == None:\r
1498             self._LibraryClasses = sdict()\r
1499             RecordList = self._Table.Query(MODEL_EFI_LIBRARY_CLASS, Arch=self._Arch, Platform=self._Platform)\r
1500             for Record in RecordList:\r
1501                 Lib = Record[0]\r
1502                 Instance = Record[1]\r
1503                 if Instance != None and Instance != '':\r
1504                     Instance = NormPath(Instance, self._Macros)\r
1505                 self._LibraryClasses[Lib] = Instance\r
1506         return self._LibraryClasses\r
1507 \r
1508     def _SetLibraryClassUses(self, Value):\r
1509         self._LibraryClasses = Value\r
1510 \r
1511     def _GetLibraryInstances(self):\r
1512         if self._Libraries == None:\r
1513             self._Libraries = []\r
1514             RecordList = self._Table.Query(MODEL_EFI_LIBRARY_INSTANCE, Arch=self._Arch, Platform=self._Platform)\r
1515             for Record in RecordList:\r
1516                 self._Libraries.append(Record[0])\r
1517         return self._Libraries\r
1518 \r
1519     def _GetProtocols(self):\r
1520         if self._Protocols == None:\r
1521             self._Protocols = []\r
1522             RecordList = self._Table.Query(MODEL_EFI_PROTOCOL, Arch=self._Arch, Platform=self._Platform)\r
1523             for Record in RecordList:\r
1524                 self._Protocols.append(Record[0])\r
1525         return self._Protocols\r
1526 \r
1527     def _GetPpis(self):\r
1528         if self._Ppis == None:\r
1529             self._Ppis = []\r
1530             RecordList = self._Table.Query(MODEL_EFI_PPI, Arch=self._Arch, Platform=self._Platform)\r
1531             for Record in RecordList:\r
1532                 self._Ppis.append(Record[0])\r
1533         return self._Ppis\r
1534 \r
1535     def _GetGuids(self):\r
1536         if self._Guids == None:\r
1537             self._Guids = []\r
1538             RecordList = self._Table.Query(MODEL_EFI_GUID, Arch=self._Arch, Platform=self._Platform)\r
1539             for Record in RecordList:\r
1540                 self._Guids.append(Record[0])\r
1541         return self._Guids\r
1542 \r
1543     def _GetIncludes(self):\r
1544         if self._Includes == None:\r
1545             self._Includes = []\r
1546             RecordList = self._Table.Query(MODEL_EFI_INCLUDE, Arch=self._Arch, Platform=self._Platform)\r
1547             for Record in RecordList:\r
1548                 File = NormPath(Record[0], self._Macros)\r
1549                 LineNo = Record[-1]\r
1550                 #if File[0] == '.':\r
1551                 #    if not ValidFile(File, self._ModuleDir):\r
1552                 #        EdkLogger.error('build', FILE_NOT_FOUND, ExtraData=File,\r
1553                 #                        File=self.DescFilePath, Line=LineNo)\r
1554                 #else:\r
1555                 #    if not ValidFile(File):\r
1556                 #        EdkLogger.error('build', FILE_NOT_FOUND, ExtraData=File,\r
1557                 #                        File=self.DescFilePath, Line=LineNo)\r
1558                 self._Includes.append(File)\r
1559         return self._Includes\r
1560 \r
1561     def _GetPackages(self):\r
1562         if self._Packages == None:\r
1563             self._Packages = []\r
1564             RecordList = self._Table.Query(MODEL_META_DATA_PACKAGE, Arch=self._Arch, Platform=self._Platform)\r
1565             for Record in RecordList:\r
1566                 File = NormPath(Record[0], self._Macros)\r
1567                 LineNo = Record[-1]\r
1568                 if not ValidFile(File):\r
1569                     EdkLogger.error('build', FILE_NOT_FOUND, ExtraData=File,\r
1570                                     File=self.DescFilePath, Line=LineNo)\r
1571                 Package = self._Db.BuildObject[File, MODEL_FILE_DEC, self._Arch]\r
1572                 self._Packages.append(Package)\r
1573         return self._Packages\r
1574 \r
1575     def _GetPcds(self):\r
1576         if self._Pcds == None:\r
1577             self._Pcds = {}\r
1578             self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
1579             self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
1580             self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
1581             self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC))\r
1582             self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))\r
1583         return self._Pcds\r
1584 \r
1585     def _GetBuildOptions(self):\r
1586         if self._BuildOptions == None:\r
1587             self._BuildOptions = sdict()\r
1588             RecordList = self._Table.Query(MODEL_META_DATA_BUILD_OPTION, Arch=self._Arch, Platform=self._Platform)\r
1589             for Record in RecordList:\r
1590                 ToolChainFamily = Record[0]\r
1591                 ToolChain = Record[1]\r
1592                 Option = Record[2]\r
1593                 if (ToolChainFamily, ToolChain) not in self._BuildOptions:\r
1594                     self._BuildOptions[ToolChainFamily, ToolChain] = Option\r
1595                 else:\r
1596                     OptionString = self._BuildOptions[ToolChainFamily, ToolChain]\r
1597                     self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option\r
1598         return self._BuildOptions\r
1599 \r
1600     def _GetDepex(self):\r
1601         if self._Depex == None:\r
1602             self._Depex = ''\r
1603             RecordList = self._Table.Query(MODEL_EFI_DEPEX, Arch=self._Arch, Platform=self._Platform)\r
1604             for Record in RecordList:\r
1605                 self._Depex += ' ' + Record[0]\r
1606         return self._Depex\r
1607 \r
1608     def _GetPcd(self, Type):\r
1609         Pcds = {}\r
1610         PcdDict = tdict(True, 4)\r
1611         PcdSet = set()\r
1612         RecordList = self._Table.Query(Type, Arch=self.Arch, Platform=self.Platform)\r
1613         for TokenSpaceGuid, PcdCName, Setting, Arch, Platform, Dummy1, Dummy2 in RecordList:\r
1614             PcdDict[Arch, Platform, PcdCName, TokenSpaceGuid] = Setting\r
1615             PcdSet.add((PcdCName, TokenSpaceGuid))\r
1616 \r
1617         for PcdCName, TokenSpaceGuid in PcdSet:\r
1618             ValueList = ['', '']\r
1619             Setting = PcdDict[self.Arch, self.Platform, PcdCName, TokenSpaceGuid]\r
1620             if Setting == None:\r
1621                 continue\r
1622             TokenList = Setting.split(TAB_VALUE_SPLIT)\r
1623             ValueList[0:len(TokenList)] = TokenList\r
1624             DefaultValue = ValueList[0]\r
1625             Pcd = PcdClassObject(\r
1626                     PcdCName,\r
1627                     TokenSpaceGuid,\r
1628                     '',\r
1629                     '',\r
1630                     DefaultValue,\r
1631                     '',\r
1632                     '',\r
1633                     {},\r
1634                     True\r
1635                     )\r
1636             # get necessary info from package declaring this PCD\r
1637             for Package in self.Packages:\r
1638                 # \r
1639                 # 'dynamic' in INF means its type is determined by platform;\r
1640                 # if platform doesn't give its type, use 'lowest' one in the \r
1641                 # following order, if any\r
1642                 # \r
1643                 #   "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"\r
1644                 # \r
1645                 PcdType = self._PCD_TYPE_STRING_[Type]\r
1646                 if Type in [MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]:\r
1647                     for T in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:\r
1648                         if (PcdCName, TokenSpaceGuid, T) in Package.Pcds:\r
1649                             PcdType = T\r
1650                             break\r
1651 \r
1652                 if (PcdCName, TokenSpaceGuid, PcdType) in Package.Pcds:\r
1653                     PcdInPackage = Package.Pcds[PcdCName, TokenSpaceGuid, PcdType]\r
1654                     Pcd.Type = PcdType\r
1655                     Pcd.TokenValue = PcdInPackage.TokenValue\r
1656                     Pcd.DatumType = PcdInPackage.DatumType\r
1657                     Pcd.MaxDatumSize = PcdInPackage.MaxDatumSize\r
1658                     if Pcd.DefaultValue in [None, '']:\r
1659                         Pcd.DefaultValue = PcdInPackage.DefaultValue\r
1660                     break\r
1661             else:\r
1662                 EdkLogger.error(\r
1663                             'build', \r
1664                             PARSER_ERROR,\r
1665                             "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdCName, self.DescFilePath),\r
1666                             ExtraData="\t%s" % '\n\t'.join([str(P) for P in self.Packages])\r
1667                             )\r
1668             Pcds[PcdCName, TokenSpaceGuid] = Pcd\r
1669         return Pcds\r
1670 \r
1671     Arch                    = property(_GetArch, _SetArch)\r
1672     Platform                = property(_GetPlatform, _SetPlatform)\r
1673 \r
1674     AutoGenVersion          = property(_GetInfVersion)\r
1675     BaseName                = property(_GetBaseName)\r
1676     ModuleType              = property(_GetModuleType)\r
1677     ComponentType           = property(_GetComponentType)\r
1678     Guid                    = property(_GetFileGuid)\r
1679     Version                 = property(_GetVersion)\r
1680     PcdIsDriver             = property(_GetPcdIsDriver)\r
1681     Shadow                  = property(_GetShadow)\r
1682     CustomMakefile          = property(_GetMakefile)\r
1683     Specification           = property(_GetSpec)\r
1684     LibraryClass            = property(_GetLibraryClass)\r
1685     ModuleEntryPointList    = property(_GetEntryPoint)\r
1686     ModuleUnloadImageList   = property(_GetUnloadImage)\r
1687     ConstructorList         = property(_GetConstructor)\r
1688     DestructorList          = property(_GetDestructor)\r
1689 \r
1690     Binaries                = property(_GetBinaryFiles)\r
1691     Sources                 = property(_GetSourceFiles)\r
1692     LibraryClasses          = property(_GetLibraryClassUses, _SetLibraryClassUses)\r
1693     Libraries               = property(_GetLibraryInstances)\r
1694     Protocols               = property(_GetProtocols)\r
1695     Ppis                    = property(_GetPpis)\r
1696     Guids                   = property(_GetGuids)\r
1697     Includes                = property(_GetIncludes)\r
1698     Packages                = property(_GetPackages)\r
1699     Pcds                    = property(_GetPcds)\r
1700     BuildOptions            = property(_GetBuildOptions)\r
1701     Depex                   = property(_GetDepex)\r
1702 \r
1703 \r
1704 ## Database\r
1705 #\r
1706 # This class defined the build databse\r
1707 # During the phase of initialization, the database will create all tables and\r
1708 # insert all records of table DataModel\r
1709\r
1710 # @param object:      Inherited from object class\r
1711 # @param DbPath:      A string for the path of the ECC database\r
1712 #\r
1713 # @var Conn:          Connection of the ECC database\r
1714 # @var Cur:           Cursor of the connection\r
1715 # @var TblDataModel:  Local instance for TableDataModel\r
1716 #\r
1717 class WorkspaceDatabase(object):\r
1718     _FILE_TYPE_ = {\r
1719         ".INF"  : MODEL_FILE_INF,\r
1720         ".DEC"  : MODEL_FILE_DEC,\r
1721         ".DSC"  : MODEL_FILE_DSC,\r
1722         ".FDF"  : MODEL_FILE_FDF,\r
1723     }\r
1724 \r
1725     _FILE_PARSER_ = {\r
1726         MODEL_FILE_INF  :   InfParser,\r
1727         MODEL_FILE_DEC  :   DecParser,\r
1728         MODEL_FILE_DSC  :   DscParser,\r
1729         MODEL_FILE_FDF  :   None, #FdfParser,\r
1730     }\r
1731 \r
1732     _FILE_TABLE_ = {\r
1733         MODEL_FILE_INF  :   ModuleTable,\r
1734         MODEL_FILE_DEC  :   PackageTable,\r
1735         MODEL_FILE_DSC  :   PlatformTable,\r
1736     }\r
1737 \r
1738     class BuildObjectFactory(object):\r
1739         _GENERATOR_ = {\r
1740             MODEL_FILE_INF  :   InfBuildData,\r
1741             MODEL_FILE_DEC  :   DecBuildData,\r
1742             MODEL_FILE_DSC  :   DscBuildData,\r
1743             MODEL_FILE_FDF  :   None #FlashDefTable,\r
1744         }\r
1745 \r
1746         _CACHE_ = {}    # FilePath  : <object>\r
1747 \r
1748         def __init__(self, WorkspaceDb):\r
1749             self.WorkspaceDb = WorkspaceDb\r
1750 \r
1751         # key = (FilePath, FileType, Arch='COMMON', Platform='COMMON')\r
1752         def __getitem__(self, Key):\r
1753             FilePath = Key[0]\r
1754             FileType = Key[1]\r
1755             if len(Key) > 2:\r
1756                 Arch = Key[2]\r
1757             else:\r
1758                 Arch = 'COMMON'\r
1759             Key = (FilePath, Arch)\r
1760             if Key in self._CACHE_:\r
1761                 return self._CACHE_[Key]\r
1762 \r
1763             self.WorkspaceDb[FilePath] = FileType\r
1764             if FileType not in self._GENERATOR_:\r
1765                 return None\r
1766 \r
1767             # create temp table for current file\r
1768             Table = self.WorkspaceDb[FilePath]\r
1769             BuildObject = self._GENERATOR_[FileType](\r
1770                                     FilePath, \r
1771                                     Table, \r
1772                                     self.WorkspaceDb, \r
1773                                     Arch, \r
1774                                     self.WorkspaceDb._GlobalMacros\r
1775                                     )\r
1776             self._CACHE_[Key] = BuildObject\r
1777             return BuildObject\r
1778 \r
1779     class TransformObjectFactory:\r
1780         def __init__(self, WorkspaceDb):\r
1781             self.WorkspaceDb = WorkspaceDb\r
1782 \r
1783         # key = FilePath\r
1784         def __getitem__(self, Key):\r
1785             pass\r
1786 \r
1787     def __init__(self, DbPath, GlobalMacros={}):\r
1788         self._GlobalMacros = GlobalMacros\r
1789 \r
1790         DbDir = os.path.split(DbPath)[0]\r
1791         if not os.path.exists(DbDir):\r
1792             os.makedirs(DbDir)\r
1793 \r
1794         self.Conn = sqlite3.connect(DbPath, isolation_level='DEFERRED')\r
1795         self.Conn.execute("PRAGMA synchronous=OFF")\r
1796         self.Conn.execute("PRAGMA temp_store=MEMORY")\r
1797         self.Conn.execute("PRAGMA count_changes=OFF")\r
1798         self.Conn.execute("PRAGMA cache_size=8192")\r
1799         #self.Conn.execute("PRAGMA page_size=8192")\r
1800 \r
1801         # to avoid non-ascii character conversion issue\r
1802         self.Conn.text_factory = str\r
1803         self.Cur = self.Conn.cursor()\r
1804 \r
1805         self.TblDataModel = TableDataModel(self.Cur)\r
1806         self.TblFile = TableFile(self.Cur)\r
1807 \r
1808         self.BuildObject = WorkspaceDatabase.BuildObjectFactory(self)\r
1809         self.TransformObject = WorkspaceDatabase.TransformObjectFactory(self)\r
1810     \r
1811     ## Initialize build database\r
1812     #\r
1813     # 1. Delete all old existing tables\r
1814     # 2. Create new tables\r
1815     # 3. Initialize table DataModel\r
1816     #\r
1817     def InitDatabase(self):\r
1818         EdkLogger.verbose("\nInitialize ECC database started ...")\r
1819         \r
1820         #\r
1821         # Create new tables\r
1822         #\r
1823         self.TblDataModel.Create(False)\r
1824         self.TblFile.Create(False)\r
1825         \r
1826         #\r
1827         # Initialize table DataModel\r
1828         #\r
1829         self.TblDataModel.InitTable()\r
1830         EdkLogger.verbose("Initialize build database ... DONE!")\r
1831 \r
1832     ## Query a table\r
1833     #\r
1834     # @param Table:  The instance of the table to be queried\r
1835     #\r
1836     def QueryTable(self, Table):\r
1837         Table.Query()\r
1838     \r
1839     ## Close entire database\r
1840     #\r
1841     # Commit all first \r
1842     # Close the connection and cursor\r
1843     #\r
1844     def Close(self):\r
1845         self.Conn.commit()\r
1846         self.Cur.close()\r
1847         self.Conn.close()\r
1848 \r
1849     def GetFileId(self, FilePath):\r
1850         return self.TblFile.GetFileId(FilePath)\r
1851 \r
1852     def GetFileType(self, FileId):\r
1853         return self.TblFile.GetFileType(FileId)\r
1854 \r
1855     def GetTimeStamp(self, FileId):\r
1856         return self.TblFile.GetFileTimeStamp(FileId)\r
1857 \r
1858     def SetTimeStamp(self, FileId, TimeStamp):\r
1859         return self.TblFile.SetFileTimeStamp(FileId, TimeStamp)\r
1860 \r
1861     def CheckIntegrity(self, TableName):\r
1862         Result = self.Cur.execute("select min(ID) from %s" % (TableName)).fetchall()\r
1863         if Result[0][0] != -1:\r
1864             return False\r
1865         return True\r
1866 \r
1867     def GetTableName(self, FileType, FileId):\r
1868         return "_%s_%s" % (FileType, FileId)\r
1869 \r
1870     ## TRICK: \r
1871     # Key = FilePath\r
1872     # Value = FileType\r
1873     def __setitem__(self, FilePath, FileType):\r
1874         FileId = self.GetFileId(FilePath)\r
1875         if FileId != None:\r
1876             TimeStamp = os.stat(FilePath)[8]\r
1877             TableName = self.GetTableName(FileType, FileId)\r
1878             if TimeStamp != self.GetTimeStamp(FileId):\r
1879                 self.SetTimeStamp(FileId, TimeStamp)\r
1880             else:\r
1881                 if self.CheckIntegrity(TableName) == True:\r
1882                     return\r
1883         else:\r
1884             FileId = self.TblFile.InsertFile(FilePath, FileType)\r
1885             TableName = self.GetTableName(FileType, FileId)\r
1886 \r
1887         FileTable = self._FILE_TABLE_[FileType](self.Cur, TableName, FileId)\r
1888         FileTable.Create()\r
1889         Parser = self._FILE_PARSER_[FileType](FilePath, FileId, FileType, FileTable)\r
1890         Parser.Start()\r
1891 \r
1892     ## Return a temp table containing all content of the given file\r
1893     # \r
1894     def __getitem__(self, FileInfo):\r
1895         if type(FileInfo) == type(''):\r
1896             FileId = self.GetFileId(FileInfo)\r
1897         else:\r
1898             FileId = FileInfo\r
1899         if FileId == None:\r
1900             return None\r
1901         FileType = self.GetFileType(FileId)\r
1902         if FileType not in self._FILE_TABLE_:\r
1903             return None\r
1904 \r
1905         TableName = "_%s_%s" % (FileType, FileId)\r
1906         FileTable = self._FILE_TABLE_[FileType](self.Cur, TableName, FileId)\r
1907         return FileTable\r
1908 \r
1909     ## Resolve cross-references between platfor, packages and modules\r
1910     def _PostFix(self):\r
1911         pass\r
1912 \r
1913 ##\r
1914 #\r
1915 # This acts like the main() function for the script, unless it is 'import'ed into another\r
1916 # script.\r
1917 #\r
1918 if __name__ == '__main__':\r
1919     EdkLogger.Initialize()\r
1920     EdkLogger.SetLevel(EdkLogger.DEBUG_0)\r
1921     \r
1922     Db = WorkspaceDatabase(DATABASE_PATH)\r
1923     Db.InitDatabase()\r
1924     Db.QueryTable(Db.TblDataModel)   \r
1925     Db.QueryTable(Db.TblFile)\r
1926     Db.QueryTable(Db.TblDsc)\r
1927     Db.Close()\r
1928