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