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