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