]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
Sync BaseTools Branch (version r2362) to EDKII main trunk.
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / WorkspaceDatabase.py
CommitLineData
52302d4d
LG
1## @file\r
2# This file is used to create a database used by build tool\r
3#\r
da92f276 4# Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>\r
40d841f6 5# This program and the accompanying materials\r
52302d4d
LG
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
17import sqlite3\r
18import os\r
19import os.path\r
20import pickle\r
e56468c0 21import uuid\r
52302d4d
LG
22\r
23import Common.EdkLogger as EdkLogger\r
24import Common.GlobalData as GlobalData\r
25\r
26from Common.String import *\r
27from Common.DataType import *\r
28from Common.Misc import *\r
29from types import *\r
30\r
31from CommonDataClass.CommonClass import SkuInfoClass\r
32\r
33from MetaDataTable import *\r
34from MetaFileTable import *\r
35from MetaFileParser import *\r
36from BuildClassObject import *\r
37\r
38## Platform build information from DSC file\r
39#\r
40# This class is used to retrieve information stored in database and convert them\r
41# into PlatformBuildClassObject form for easier use for AutoGen.\r
42#\r
43class DscBuildData(PlatformBuildClassObject):\r
44 # dict used to convert PCD type in database to string used by build tool\r
45 _PCD_TYPE_STRING_ = {\r
46 MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild",\r
47 MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule",\r
48 MODEL_PCD_FEATURE_FLAG : "FeatureFlag",\r
49 MODEL_PCD_DYNAMIC : "Dynamic",\r
50 MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic",\r
51 MODEL_PCD_DYNAMIC_HII : "DynamicHii",\r
52 MODEL_PCD_DYNAMIC_VPD : "DynamicVpd",\r
53 MODEL_PCD_DYNAMIC_EX : "DynamicEx",\r
54 MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx",\r
55 MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii",\r
56 MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd",\r
57 }\r
58\r
59 # dict used to convert part of [Defines] to members of DscBuildData directly\r
60 _PROPERTY_ = {\r
61 #\r
62 # Required Fields\r
63 #\r
64 TAB_DSC_DEFINES_PLATFORM_NAME : "_PlatformName",\r
65 TAB_DSC_DEFINES_PLATFORM_GUID : "_Guid",\r
66 TAB_DSC_DEFINES_PLATFORM_VERSION : "_Version",\r
67 TAB_DSC_DEFINES_DSC_SPECIFICATION : "_DscSpecification",\r
68 #TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",\r
69 #TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",\r
70 #TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",\r
71 #TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName",\r
72 #TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",\r
73 TAB_DSC_DEFINES_BUILD_NUMBER : "_BuildNumber",\r
74 TAB_DSC_DEFINES_MAKEFILE_NAME : "_MakefileName",\r
75 TAB_DSC_DEFINES_BS_BASE_ADDRESS : "_BsBaseAddress",\r
76 TAB_DSC_DEFINES_RT_BASE_ADDRESS : "_RtBaseAddress",\r
6780eef1
LG
77 #TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",\r
78 #TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",\r
52302d4d
LG
79 }\r
80\r
81 # used to compose dummy library class name for those forced library instances\r
82 _NullLibraryNumber = 0\r
83\r
84 ## Constructor of DscBuildData\r
85 #\r
86 # Initialize object of DscBuildData\r
87 #\r
88 # @param FilePath The path of platform description file\r
89 # @param RawData The raw data of DSC file\r
90 # @param BuildDataBase Database used to retrieve module/package information\r
91 # @param Arch The target architecture\r
92 # @param Platform (not used for DscBuildData)\r
93 # @param Macros Macros used for replacement in DSC file\r
94 #\r
95 def __init__(self, FilePath, RawData, BuildDataBase, Arch='COMMON', Platform='DUMMY', Macros={}):\r
96 self.MetaFile = FilePath\r
97 self._RawData = RawData\r
98 self._Bdb = BuildDataBase\r
99 self._Arch = Arch\r
100 self._Macros = Macros\r
101 self._Clear()\r
102 RecordList = self._RawData[MODEL_META_DATA_DEFINE, self._Arch]\r
103 for Record in RecordList:\r
104 GlobalData.gEdkGlobal[Record[0]] = Record[1]\r
e56468c0 105 \r
106 RecordList = self._RawData[MODEL_META_DATA_GLOBAL_DEFINE, self._Arch]\r
107 for Record in RecordList:\r
108 GlobalData.gGlobalDefines[Record[0]] = Record[1]\r
52302d4d
LG
109\r
110 ## XXX[key] = value\r
111 def __setitem__(self, key, value):\r
112 self.__dict__[self._PROPERTY_[key]] = value\r
113\r
114 ## value = XXX[key]\r
115 def __getitem__(self, key):\r
116 return self.__dict__[self._PROPERTY_[key]]\r
117\r
118 ## "in" test support\r
119 def __contains__(self, key):\r
120 return key in self._PROPERTY_\r
121\r
122 ## Set all internal used members of DscBuildData to None\r
123 def _Clear(self):\r
124 self._Header = None\r
125 self._PlatformName = None\r
126 self._Guid = None\r
127 self._Version = None\r
128 self._DscSpecification = None\r
129 self._OutputDirectory = None\r
130 self._SupArchList = None\r
131 self._BuildTargets = None\r
132 self._SkuName = None\r
133 self._FlashDefinition = None\r
134 self._BuildNumber = None\r
135 self._MakefileName = None\r
136 self._BsBaseAddress = None\r
137 self._RtBaseAddress = None\r
138 self._SkuIds = None\r
139 self._Modules = None\r
140 self._LibraryInstances = None\r
141 self._LibraryClasses = None\r
142 self._Pcds = None\r
143 self._BuildOptions = None\r
144 self._LoadFixAddress = None\r
6780eef1
LG
145 self._RFCLanguages = None\r
146 self._ISOLanguages = None\r
e56468c0 147 self._VpdToolGuid = None\r
52302d4d
LG
148\r
149 ## Get architecture\r
150 def _GetArch(self):\r
151 return self._Arch\r
152\r
153 ## Set architecture\r
154 #\r
155 # Changing the default ARCH to another may affect all other information\r
156 # because all information in a platform may be ARCH-related. That's\r
157 # why we need to clear all internal used members, in order to cause all\r
158 # information to be re-retrieved.\r
159 #\r
160 # @param Value The value of ARCH\r
161 #\r
162 def _SetArch(self, Value):\r
163 if self._Arch == Value:\r
164 return\r
165 self._Arch = Value\r
166 self._Clear()\r
167\r
168 ## Retrieve all information in [Defines] section\r
169 #\r
170 # (Retriving all [Defines] information in one-shot is just to save time.)\r
171 #\r
172 def _GetHeaderInfo(self):\r
173 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch]\r
174 for Record in RecordList:\r
175 Name = Record[0]\r
176 # items defined _PROPERTY_ don't need additional processing\r
177 if Name in self:\r
178 self[Name] = Record[1]\r
179 # some special items in [Defines] section need special treatment\r
180 elif Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY:\r
181 self._OutputDirectory = NormPath(Record[1], self._Macros)\r
182 if ' ' in self._OutputDirectory:\r
183 EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in OUTPUT_DIRECTORY",\r
184 File=self.MetaFile, Line=Record[-1],\r
185 ExtraData=self._OutputDirectory)\r
186 elif Name == TAB_DSC_DEFINES_FLASH_DEFINITION:\r
187 self._FlashDefinition = PathClass(NormPath(Record[1], self._Macros), GlobalData.gWorkspace)\r
188 ErrorCode, ErrorInfo = self._FlashDefinition.Validate('.fdf')\r
189 if ErrorCode != 0:\r
190 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=Record[-1],\r
191 ExtraData=ErrorInfo)\r
192 elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES:\r
193 self._SupArchList = GetSplitValueList(Record[1], TAB_VALUE_SPLIT)\r
194 elif Name == TAB_DSC_DEFINES_BUILD_TARGETS:\r
195 self._BuildTargets = GetSplitValueList(Record[1])\r
196 elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER:\r
197 if self._SkuName == None:\r
198 self._SkuName = Record[1]\r
199 elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS:\r
200 self._LoadFixAddress = Record[1]\r
6780eef1
LG
201 elif Name == TAB_DSC_DEFINES_RFC_LANGUAGES:\r
202 if not Record[1] or Record[1][0] != '"' or Record[1][-1] != '"' or len(Record[1]) == 1:\r
203 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for RFC_LANGUAGES must have double quotes around it, for example: RFC_LANGUAGES = "en-us;zh-hans"',\r
204 File=self.MetaFile, Line=Record[-1])\r
205 LanguageCodes = Record[1][1:-1]\r
206 if not LanguageCodes:\r
207 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',\r
208 File=self.MetaFile, Line=Record[-1]) \r
209 LanguageList = GetSplitValueList(LanguageCodes, TAB_SEMI_COLON_SPLIT)\r
210 # check whether there is empty entries in the list\r
211 if None in LanguageList:\r
212 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more empty language code is in RFC_LANGUAGES statement',\r
213 File=self.MetaFile, Line=Record[-1]) \r
214 self._RFCLanguages = LanguageList\r
215 elif Name == TAB_DSC_DEFINES_ISO_LANGUAGES:\r
216 if not Record[1] or Record[1][0] != '"' or Record[1][-1] != '"' or len(Record[1]) == 1:\r
217 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',\r
218 File=self.MetaFile, Line=Record[-1])\r
219 LanguageCodes = Record[1][1:-1]\r
220 if not LanguageCodes:\r
221 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',\r
222 File=self.MetaFile, Line=Record[-1]) \r
223 if len(LanguageCodes)%3:\r
224 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'bad ISO639-2 format for ISO_LANGUAGES',\r
225 File=self.MetaFile, Line=Record[-1])\r
226 LanguageList = []\r
227 for i in range(0, len(LanguageCodes), 3):\r
228 LanguageList.append(LanguageCodes[i:i+3])\r
229 self._ISOLanguages = LanguageList \r
e56468c0 230 elif Name == TAB_DSC_DEFINES_VPD_TOOL_GUID:\r
231 #\r
232 # try to convert GUID to a real UUID value to see whether the GUID is format \r
233 # for VPD_TOOL_GUID is correct.\r
234 #\r
235 try:\r
236 uuid.UUID(Record[1])\r
237 except:\r
238 EdkLogger.error("build", FORMAT_INVALID, "Invalid GUID format for VPD_TOOL_GUID", File=self.MetaFile)\r
08dd311f 239 self._VpdToolGuid = Record[1] \r
52302d4d
LG
240 # set _Header to non-None in order to avoid database re-querying\r
241 self._Header = 'DUMMY'\r
242\r
243 ## Retrieve platform name\r
244 def _GetPlatformName(self):\r
245 if self._PlatformName == None:\r
246 if self._Header == None:\r
247 self._GetHeaderInfo()\r
248 if self._PlatformName == None:\r
249 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_NAME", File=self.MetaFile)\r
250 return self._PlatformName\r
251\r
252 ## Retrieve file guid\r
253 def _GetFileGuid(self):\r
254 if self._Guid == None:\r
255 if self._Header == None:\r
256 self._GetHeaderInfo()\r
257 if self._Guid == None:\r
258 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No FILE_GUID", File=self.MetaFile)\r
259 return self._Guid\r
260\r
261 ## Retrieve platform version\r
262 def _GetVersion(self):\r
263 if self._Version == None:\r
264 if self._Header == None:\r
265 self._GetHeaderInfo()\r
266 if self._Version == None:\r
267 self._Version = ''\r
268 return self._Version\r
269\r
270 ## Retrieve platform description file version\r
271 def _GetDscSpec(self):\r
272 if self._DscSpecification == None:\r
273 if self._Header == None:\r
274 self._GetHeaderInfo()\r
275 if self._DscSpecification == None:\r
276 self._DscSpecification = ''\r
277 return self._DscSpecification\r
278\r
279 ## Retrieve OUTPUT_DIRECTORY\r
280 def _GetOutpuDir(self):\r
281 if self._OutputDirectory == None:\r
282 if self._Header == None:\r
283 self._GetHeaderInfo()\r
284 if self._OutputDirectory == None:\r
285 self._OutputDirectory = os.path.join("Build", self._PlatformName)\r
286 return self._OutputDirectory\r
287\r
288 ## Retrieve SUPPORTED_ARCHITECTURES\r
289 def _GetSupArch(self):\r
290 if self._SupArchList == None:\r
291 if self._Header == None:\r
292 self._GetHeaderInfo()\r
293 if self._SupArchList == None:\r
294 self._SupArchList = ARCH_LIST\r
295 return self._SupArchList\r
296\r
297 ## Retrieve BUILD_TARGETS\r
298 def _GetBuildTarget(self):\r
299 if self._BuildTargets == None:\r
300 if self._Header == None:\r
301 self._GetHeaderInfo()\r
302 if self._BuildTargets == None:\r
b36d134f 303 self._BuildTargets = ['DEBUG', 'RELEASE', 'NOOPT']\r
52302d4d
LG
304 return self._BuildTargets\r
305\r
306 ## Retrieve SKUID_IDENTIFIER\r
307 def _GetSkuName(self):\r
308 if self._SkuName == None:\r
309 if self._Header == None:\r
310 self._GetHeaderInfo()\r
311 if self._SkuName == None or self._SkuName not in self.SkuIds:\r
312 self._SkuName = 'DEFAULT'\r
313 return self._SkuName\r
314\r
315 ## Override SKUID_IDENTIFIER\r
316 def _SetSkuName(self, Value):\r
317 if Value in self.SkuIds:\r
318 self._SkuName = Value\r
e56468c0 319 # Needs to re-retrieve the PCD information\r
320 self._Pcds = None\r
52302d4d
LG
321\r
322 def _GetFdfFile(self):\r
323 if self._FlashDefinition == None:\r
324 if self._Header == None:\r
325 self._GetHeaderInfo()\r
326 if self._FlashDefinition == None:\r
327 self._FlashDefinition = ''\r
328 return self._FlashDefinition\r
329\r
330 ## Retrieve FLASH_DEFINITION\r
331 def _GetBuildNumber(self):\r
332 if self._BuildNumber == None:\r
333 if self._Header == None:\r
334 self._GetHeaderInfo()\r
335 if self._BuildNumber == None:\r
336 self._BuildNumber = ''\r
337 return self._BuildNumber\r
338\r
339 ## Retrieve MAKEFILE_NAME\r
340 def _GetMakefileName(self):\r
341 if self._MakefileName == None:\r
342 if self._Header == None:\r
343 self._GetHeaderInfo()\r
344 if self._MakefileName == None:\r
345 self._MakefileName = ''\r
346 return self._MakefileName\r
347\r
348 ## Retrieve BsBaseAddress\r
349 def _GetBsBaseAddress(self):\r
350 if self._BsBaseAddress == None:\r
351 if self._Header == None:\r
352 self._GetHeaderInfo()\r
353 if self._BsBaseAddress == None:\r
354 self._BsBaseAddress = ''\r
355 return self._BsBaseAddress\r
356\r
357 ## Retrieve RtBaseAddress\r
358 def _GetRtBaseAddress(self):\r
359 if self._RtBaseAddress == None:\r
360 if self._Header == None:\r
361 self._GetHeaderInfo()\r
362 if self._RtBaseAddress == None:\r
363 self._RtBaseAddress = ''\r
364 return self._RtBaseAddress\r
365\r
366 ## Retrieve the top address for the load fix address\r
367 def _GetLoadFixAddress(self):\r
368 if self._LoadFixAddress == None:\r
369 if self._Header == None:\r
370 self._GetHeaderInfo()\r
371 if self._LoadFixAddress == None:\r
372 self._LoadFixAddress = ''\r
373 return self._LoadFixAddress\r
374\r
6780eef1
LG
375 ## Retrieve RFCLanguage filter\r
376 def _GetRFCLanguages(self):\r
377 if self._RFCLanguages == None:\r
378 if self._Header == None:\r
379 self._GetHeaderInfo()\r
380 if self._RFCLanguages == None:\r
381 self._RFCLanguages = []\r
382 return self._RFCLanguages\r
383\r
384 ## Retrieve ISOLanguage filter\r
385 def _GetISOLanguages(self):\r
386 if self._ISOLanguages == None:\r
387 if self._Header == None:\r
388 self._GetHeaderInfo()\r
389 if self._ISOLanguages == None:\r
390 self._ISOLanguages = []\r
391 return self._ISOLanguages\r
392\r
e56468c0 393 ## Retrieve the GUID string for VPD tool\r
394 def _GetVpdToolGuid(self):\r
395 if self._VpdToolGuid == None:\r
396 if self._Header == None:\r
397 self._GetHeaderInfo()\r
398 if self._VpdToolGuid == None:\r
399 self._VpdToolGuid = ''\r
400 return self._VpdToolGuid\r
08dd311f 401 \r
52302d4d
LG
402 ## Retrieve [SkuIds] section information\r
403 def _GetSkuIds(self):\r
404 if self._SkuIds == None:\r
405 self._SkuIds = {}\r
406 RecordList = self._RawData[MODEL_EFI_SKU_ID]\r
407 for Record in RecordList:\r
408 if Record[0] in [None, '']:\r
409 EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID number',\r
410 File=self.MetaFile, Line=Record[-1])\r
411 if Record[1] in [None, '']:\r
412 EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID name',\r
413 File=self.MetaFile, Line=Record[-1])\r
414 self._SkuIds[Record[1]] = Record[0]\r
415 if 'DEFAULT' not in self._SkuIds:\r
416 self._SkuIds['DEFAULT'] = 0\r
417 return self._SkuIds\r
418\r
419 ## Retrieve [Components] section information\r
420 def _GetModules(self):\r
421 if self._Modules != None:\r
422 return self._Modules\r
423\r
424 self._Modules = sdict()\r
425 RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]\r
426 Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource}\r
427 Macros.update(self._Macros)\r
428 for Record in RecordList:\r
429 ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
430 ModuleId = Record[5]\r
431 LineNo = Record[6]\r
432\r
433 # check the file validation\r
434 ErrorCode, ErrorInfo = ModuleFile.Validate('.inf')\r
435 if ErrorCode != 0:\r
436 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
437 ExtraData=ErrorInfo)\r
438 # Check duplication\r
439 if ModuleFile in self._Modules:\r
440 EdkLogger.error('build', FILE_DUPLICATED, File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)\r
441\r
442 Module = ModuleBuildClassObject()\r
443 Module.MetaFile = ModuleFile\r
444\r
445 # get module override path\r
446 RecordList = self._RawData[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH, self._Arch, None, ModuleId]\r
447 if RecordList != []:\r
448 Module.SourceOverridePath = os.path.join(GlobalData.gWorkspace, NormPath(RecordList[0][0], Macros))\r
449\r
450 # Check if the source override path exists\r
451 if not os.path.isdir(Module.SourceOverridePath):\r
452 EdkLogger.error('build', FILE_NOT_FOUND, Message = 'Source override path does not exist:', File=self.MetaFile, ExtraData=Module.SourceOverridePath, Line=LineNo)\r
453 \r
454 #Add to GlobalData Variables\r
455 GlobalData.gOverrideDir[ModuleFile.Key] = Module.SourceOverridePath\r
456\r
457 # get module private library instance\r
458 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, ModuleId]\r
459 for Record in RecordList:\r
460 LibraryClass = Record[0]\r
461 LibraryPath = PathClass(NormPath(Record[1], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
462 LineNo = Record[-1]\r
463\r
464 # check the file validation\r
465 ErrorCode, ErrorInfo = LibraryPath.Validate('.inf')\r
466 if ErrorCode != 0:\r
467 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
468 ExtraData=ErrorInfo)\r
469\r
470 if LibraryClass == '' or LibraryClass == 'NULL':\r
471 self._NullLibraryNumber += 1\r
472 LibraryClass = 'NULL%d' % self._NullLibraryNumber\r
473 EdkLogger.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile, LibraryPath, LibraryClass))\r
474 Module.LibraryClasses[LibraryClass] = LibraryPath\r
475 if LibraryPath not in self.LibraryInstances:\r
476 self.LibraryInstances.append(LibraryPath)\r
477\r
478 # get module private PCD setting\r
479 for Type in [MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE, \\r
480 MODEL_PCD_FEATURE_FLAG, MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]:\r
481 RecordList = self._RawData[Type, self._Arch, None, ModuleId]\r
482 for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
483 TokenList = GetSplitValueList(Setting)\r
484 DefaultValue = TokenList[0]\r
485 if len(TokenList) > 1:\r
486 MaxDatumSize = TokenList[1]\r
487 else:\r
488 MaxDatumSize = ''\r
489 TypeString = self._PCD_TYPE_STRING_[Type]\r
490 Pcd = PcdClassObject(\r
491 PcdCName,\r
492 TokenSpaceGuid,\r
493 TypeString,\r
494 '',\r
495 DefaultValue,\r
496 '',\r
497 MaxDatumSize,\r
498 {},\r
e56468c0 499 False,\r
52302d4d
LG
500 None\r
501 )\r
502 Module.Pcds[PcdCName, TokenSpaceGuid] = Pcd\r
503\r
504 # get module private build options\r
505 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, None, ModuleId]\r
506 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
507 if (ToolChainFamily, ToolChain) not in Module.BuildOptions:\r
508 Module.BuildOptions[ToolChainFamily, ToolChain] = Option\r
509 else:\r
510 OptionString = Module.BuildOptions[ToolChainFamily, ToolChain]\r
511 Module.BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option\r
512\r
513 self._Modules[ModuleFile] = Module\r
514 return self._Modules\r
515\r
516 ## Retrieve all possible library instances used in this platform\r
517 def _GetLibraryInstances(self):\r
518 if self._LibraryInstances == None:\r
519 self._GetLibraryClasses()\r
520 return self._LibraryInstances\r
521\r
522 ## Retrieve [LibraryClasses] information\r
523 def _GetLibraryClasses(self):\r
524 if self._LibraryClasses == None:\r
525 self._LibraryInstances = []\r
526 #\r
527 # tdict is a special dict kind of type, used for selecting correct\r
528 # library instance for given library class and module type\r
529 #\r
530 LibraryClassDict = tdict(True, 3)\r
531 # track all library class names\r
532 LibraryClassSet = set()\r
533 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch]\r
534 Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource}\r
535 Macros.update(self._Macros)\r
536 for Record in RecordList:\r
537 LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy, LineNo = Record\r
538 if LibraryClass == '' or LibraryClass == 'NULL':\r
539 self._NullLibraryNumber += 1\r
540 LibraryClass = 'NULL%d' % self._NullLibraryNumber\r
541 EdkLogger.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch, LibraryInstance, LibraryClass))\r
542 LibraryClassSet.add(LibraryClass)\r
543 LibraryInstance = PathClass(NormPath(LibraryInstance, Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
544 # check the file validation\r
545 ErrorCode, ErrorInfo = LibraryInstance.Validate('.inf')\r
546 if ErrorCode != 0:\r
547 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
548 ExtraData=ErrorInfo)\r
549\r
550 if ModuleType != 'COMMON' and ModuleType not in SUP_MODULE_LIST:\r
551 EdkLogger.error('build', OPTION_UNKNOWN, "Unknown module type [%s]" % ModuleType,\r
552 File=self.MetaFile, ExtraData=LibraryInstance, Line=LineNo)\r
553 LibraryClassDict[Arch, ModuleType, LibraryClass] = LibraryInstance\r
554 if LibraryInstance not in self._LibraryInstances:\r
555 self._LibraryInstances.append(LibraryInstance)\r
556\r
557 # resolve the specific library instance for each class and each module type\r
558 self._LibraryClasses = tdict(True)\r
559 for LibraryClass in LibraryClassSet:\r
560 # try all possible module types\r
561 for ModuleType in SUP_MODULE_LIST:\r
562 LibraryInstance = LibraryClassDict[self._Arch, ModuleType, LibraryClass]\r
563 if LibraryInstance == None:\r
564 continue\r
565 self._LibraryClasses[LibraryClass, ModuleType] = LibraryInstance\r
566\r
b36d134f 567 # for EDK style library instances, which are listed in different section\r
52302d4d
LG
568 RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch]\r
569 for Record in RecordList:\r
570 File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
571 LineNo = Record[-1]\r
572 # check the file validation\r
573 ErrorCode, ErrorInfo = File.Validate('.inf')\r
574 if ErrorCode != 0:\r
575 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
576 ExtraData=ErrorInfo)\r
577 if File not in self._LibraryInstances:\r
578 self._LibraryInstances.append(File)\r
579 #\r
580 # we need the module name as the library class name, so we have\r
581 # to parse it here. (self._Bdb[] will trigger a file parse if it\r
582 # hasn't been parsed)\r
583 #\r
584 Library = self._Bdb[File, self._Arch]\r
585 self._LibraryClasses[Library.BaseName, ':dummy:'] = Library\r
586 return self._LibraryClasses\r
587\r
588 ## Retrieve all PCD settings in platform\r
589 def _GetPcds(self):\r
590 if self._Pcds == None:\r
591 self._Pcds = {}\r
592 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
593 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
594 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
595 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT))\r
596 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII))\r
597 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD))\r
598 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT))\r
599 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII))\r
600 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD))\r
601 return self._Pcds\r
602\r
603 ## Retrieve [BuildOptions]\r
604 def _GetBuildOptions(self):\r
605 if self._BuildOptions == None:\r
606 self._BuildOptions = {}\r
607 #\r
608 # Retrieve build option for EDKII style module\r
609 #\r
610 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, 'COMMON', EDKII_NAME]\r
611 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
612 self._BuildOptions[ToolChainFamily, ToolChain, EDKII_NAME] = Option\r
613 #\r
614 # Retrieve build option for EDK style module\r
615 #\r
616 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, 'COMMON', EDK_NAME] \r
617 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
618 self._BuildOptions[ToolChainFamily, ToolChain, EDK_NAME] = Option\r
619 return self._BuildOptions\r
620\r
621 ## Retrieve non-dynamic PCD settings\r
622 #\r
623 # @param Type PCD type\r
624 #\r
625 # @retval a dict object contains settings of given PCD type\r
626 #\r
627 def _GetPcd(self, Type):\r
628 Pcds = {}\r
629 #\r
630 # tdict is a special dict kind of type, used for selecting correct\r
631 # PCD settings for certain ARCH\r
632 #\r
633 PcdDict = tdict(True, 3)\r
634 PcdSet = set()\r
635 # Find out all possible PCD candidates for self._Arch\r
636 RecordList = self._RawData[Type, self._Arch]\r
637 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
638 PcdSet.add((PcdCName, TokenSpaceGuid))\r
639 PcdDict[Arch, PcdCName, TokenSpaceGuid] = Setting\r
640 # Remove redundant PCD candidates\r
641 for PcdCName, TokenSpaceGuid in PcdSet:\r
52302d4d
LG
642 Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid]\r
643 if Setting == None:\r
644 continue\r
6780eef1 645 PcdValue, DatumType, MaxDatumSize = AnalyzePcdData(Setting)\r
52302d4d
LG
646 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
647 PcdCName,\r
648 TokenSpaceGuid,\r
649 self._PCD_TYPE_STRING_[Type],\r
650 DatumType,\r
651 PcdValue,\r
652 '',\r
653 MaxDatumSize,\r
654 {},\r
e56468c0 655 False,\r
52302d4d
LG
656 None\r
657 )\r
658 return Pcds\r
659\r
660 ## Retrieve dynamic PCD settings\r
661 #\r
662 # @param Type PCD type\r
663 #\r
664 # @retval a dict object contains settings of given PCD type\r
665 #\r
666 def _GetDynamicPcd(self, Type):\r
667 Pcds = {}\r
668 #\r
669 # tdict is a special dict kind of type, used for selecting correct\r
670 # PCD settings for certain ARCH and SKU\r
671 #\r
672 PcdDict = tdict(True, 4)\r
6780eef1 673 PcdList = []\r
52302d4d
LG
674 # Find out all possible PCD candidates for self._Arch\r
675 RecordList = self._RawData[Type, self._Arch]\r
676 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
6780eef1 677 PcdList.append((PcdCName, TokenSpaceGuid))\r
52302d4d
LG
678 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
679 # Remove redundant PCD candidates, per the ARCH and SKU\r
6780eef1 680 for PcdCName, TokenSpaceGuid in PcdList:\r
52302d4d
LG
681 Setting = PcdDict[self._Arch, self.SkuName, PcdCName, TokenSpaceGuid]\r
682 if Setting == None:\r
683 continue\r
6780eef1
LG
684 \r
685 PcdValue, DatumType, MaxDatumSize = AnalyzePcdData(Setting)\r
686 \r
52302d4d
LG
687 SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], '', '', '', '', '', PcdValue)\r
688 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
689 PcdCName,\r
690 TokenSpaceGuid,\r
691 self._PCD_TYPE_STRING_[Type],\r
692 DatumType,\r
693 PcdValue,\r
694 '',\r
695 MaxDatumSize,\r
696 {self.SkuName : SkuInfo},\r
e56468c0 697 False,\r
52302d4d
LG
698 None\r
699 )\r
700 return Pcds\r
701\r
702 ## Retrieve dynamic HII PCD settings\r
703 #\r
704 # @param Type PCD type\r
705 #\r
706 # @retval a dict object contains settings of given PCD type\r
707 #\r
708 def _GetDynamicHiiPcd(self, Type):\r
709 Pcds = {}\r
710 #\r
711 # tdict is a special dict kind of type, used for selecting correct\r
712 # PCD settings for certain ARCH and SKU\r
713 #\r
714 PcdDict = tdict(True, 4)\r
715 PcdSet = set()\r
716 RecordList = self._RawData[Type, self._Arch]\r
717 # Find out all possible PCD candidates for self._Arch\r
718 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
719 PcdSet.add((PcdCName, TokenSpaceGuid))\r
720 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
721 # Remove redundant PCD candidates, per the ARCH and SKU\r
722 for PcdCName, TokenSpaceGuid in PcdSet:\r
52302d4d
LG
723 Setting = PcdDict[self._Arch, self.SkuName, PcdCName, TokenSpaceGuid]\r
724 if Setting == None:\r
725 continue\r
6780eef1 726 VariableName, VariableGuid, VariableOffset, DefaultValue = AnalyzeHiiPcdData(Setting)\r
52302d4d
LG
727 SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue)\r
728 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
729 PcdCName,\r
730 TokenSpaceGuid,\r
731 self._PCD_TYPE_STRING_[Type],\r
732 '',\r
733 DefaultValue,\r
734 '',\r
735 '',\r
736 {self.SkuName : SkuInfo},\r
e56468c0 737 False,\r
52302d4d
LG
738 None\r
739 )\r
740 return Pcds\r
741\r
742 ## Retrieve dynamic VPD PCD settings\r
743 #\r
744 # @param Type PCD type\r
745 #\r
746 # @retval a dict object contains settings of given PCD type\r
747 #\r
748 def _GetDynamicVpdPcd(self, Type):\r
749 Pcds = {}\r
750 #\r
751 # tdict is a special dict kind of type, used for selecting correct\r
752 # PCD settings for certain ARCH and SKU\r
753 #\r
754 PcdDict = tdict(True, 4)\r
6780eef1 755 PcdList = []\r
52302d4d
LG
756 # Find out all possible PCD candidates for self._Arch\r
757 RecordList = self._RawData[Type, self._Arch]\r
758 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
6780eef1 759 PcdList.append((PcdCName, TokenSpaceGuid))\r
52302d4d
LG
760 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
761 # Remove redundant PCD candidates, per the ARCH and SKU\r
6780eef1 762 for PcdCName, TokenSpaceGuid in PcdList:\r
52302d4d
LG
763 Setting = PcdDict[self._Arch, self.SkuName, PcdCName, TokenSpaceGuid]\r
764 if Setting == None:\r
765 continue\r
e56468c0 766 #\r
767 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue\r
768 # For the Integer & Boolean type, the optional data can only be InitialValue.\r
769 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype\r
770 # until the DEC parser has been called.\r
771 # \r
6780eef1 772 VpdOffset, MaxDatumSize, InitialValue = AnalyzeVpdPcdData(Setting)\r
e56468c0 773\r
774 SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], '', '', '', '', VpdOffset, InitialValue)\r
52302d4d
LG
775 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
776 PcdCName,\r
777 TokenSpaceGuid,\r
778 self._PCD_TYPE_STRING_[Type],\r
779 '',\r
780 '',\r
781 '',\r
782 MaxDatumSize,\r
783 {self.SkuName : SkuInfo},\r
e56468c0 784 False,\r
52302d4d
LG
785 None\r
786 )\r
787 return Pcds\r
788\r
789 ## Add external modules\r
790 #\r
791 # The external modules are mostly those listed in FDF file, which don't\r
792 # need "build".\r
793 #\r
794 # @param FilePath The path of module description file\r
795 #\r
796 def AddModule(self, FilePath):\r
797 FilePath = NormPath(FilePath)\r
798 if FilePath not in self.Modules:\r
799 Module = ModuleBuildClassObject()\r
800 Module.MetaFile = FilePath\r
801 self.Modules.append(Module)\r
802\r
803 ## Add external PCDs\r
804 #\r
805 # The external PCDs are mostly those listed in FDF file to specify address\r
806 # or offset information.\r
807 #\r
808 # @param Name Name of the PCD\r
809 # @param Guid Token space guid of the PCD\r
810 # @param Value Value of the PCD\r
811 #\r
812 def AddPcd(self, Name, Guid, Value):\r
813 if (Name, Guid) not in self.Pcds:\r
e56468c0 814 self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)\r
52302d4d
LG
815 self.Pcds[Name, Guid].DefaultValue = Value\r
816\r
817 Arch = property(_GetArch, _SetArch)\r
818 Platform = property(_GetPlatformName)\r
819 PlatformName = property(_GetPlatformName)\r
820 Guid = property(_GetFileGuid)\r
821 Version = property(_GetVersion)\r
822 DscSpecification = property(_GetDscSpec)\r
823 OutputDirectory = property(_GetOutpuDir)\r
824 SupArchList = property(_GetSupArch)\r
825 BuildTargets = property(_GetBuildTarget)\r
826 SkuName = property(_GetSkuName, _SetSkuName)\r
827 FlashDefinition = property(_GetFdfFile)\r
828 BuildNumber = property(_GetBuildNumber)\r
829 MakefileName = property(_GetMakefileName)\r
830 BsBaseAddress = property(_GetBsBaseAddress)\r
831 RtBaseAddress = property(_GetRtBaseAddress)\r
832 LoadFixAddress = property(_GetLoadFixAddress)\r
6780eef1
LG
833 RFCLanguages = property(_GetRFCLanguages)\r
834 ISOLanguages = property(_GetISOLanguages)\r
08dd311f 835 VpdToolGuid = property(_GetVpdToolGuid) \r
52302d4d
LG
836 SkuIds = property(_GetSkuIds)\r
837 Modules = property(_GetModules)\r
838 LibraryInstances = property(_GetLibraryInstances)\r
839 LibraryClasses = property(_GetLibraryClasses)\r
840 Pcds = property(_GetPcds)\r
841 BuildOptions = property(_GetBuildOptions)\r
842\r
e56468c0 843## Platform build information from DEC file\r
52302d4d
LG
844#\r
845# This class is used to retrieve information stored in database and convert them\r
846# into PackageBuildClassObject form for easier use for AutoGen.\r
847#\r
848class DecBuildData(PackageBuildClassObject):\r
849 # dict used to convert PCD type in database to string used by build tool\r
850 _PCD_TYPE_STRING_ = {\r
851 MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild",\r
852 MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule",\r
853 MODEL_PCD_FEATURE_FLAG : "FeatureFlag",\r
854 MODEL_PCD_DYNAMIC : "Dynamic",\r
855 MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic",\r
856 MODEL_PCD_DYNAMIC_HII : "DynamicHii",\r
857 MODEL_PCD_DYNAMIC_VPD : "DynamicVpd",\r
858 MODEL_PCD_DYNAMIC_EX : "DynamicEx",\r
859 MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx",\r
860 MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii",\r
861 MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd",\r
862 }\r
863\r
864 # dict used to convert part of [Defines] to members of DecBuildData directly\r
865 _PROPERTY_ = {\r
866 #\r
867 # Required Fields\r
868 #\r
869 TAB_DEC_DEFINES_PACKAGE_NAME : "_PackageName",\r
870 TAB_DEC_DEFINES_PACKAGE_GUID : "_Guid",\r
871 TAB_DEC_DEFINES_PACKAGE_VERSION : "_Version",\r
e56468c0 872 TAB_DEC_DEFINES_PKG_UNI_FILE : "_PkgUniFile",\r
52302d4d
LG
873 }\r
874\r
875\r
876 ## Constructor of DecBuildData\r
877 #\r
878 # Initialize object of DecBuildData\r
879 #\r
880 # @param FilePath The path of package description file\r
881 # @param RawData The raw data of DEC file\r
882 # @param BuildDataBase Database used to retrieve module information\r
883 # @param Arch The target architecture\r
884 # @param Platform (not used for DecBuildData)\r
885 # @param Macros Macros used for replacement in DSC file\r
886 #\r
887 def __init__(self, File, RawData, BuildDataBase, Arch='COMMON', Platform='DUMMY', Macros={}):\r
888 self.MetaFile = File\r
889 self._PackageDir = File.Dir\r
890 self._RawData = RawData\r
891 self._Bdb = BuildDataBase\r
892 self._Arch = Arch\r
893 self._Macros = Macros\r
894 self._Clear()\r
895\r
896 ## XXX[key] = value\r
897 def __setitem__(self, key, value):\r
898 self.__dict__[self._PROPERTY_[key]] = value\r
899\r
900 ## value = XXX[key]\r
901 def __getitem__(self, key):\r
902 return self.__dict__[self._PROPERTY_[key]]\r
903\r
904 ## "in" test support\r
905 def __contains__(self, key):\r
906 return key in self._PROPERTY_\r
907\r
908 ## Set all internal used members of DecBuildData to None\r
909 def _Clear(self):\r
910 self._Header = None\r
911 self._PackageName = None\r
912 self._Guid = None\r
913 self._Version = None\r
e56468c0 914 self._PkgUniFile = None\r
52302d4d
LG
915 self._Protocols = None\r
916 self._Ppis = None\r
917 self._Guids = None\r
918 self._Includes = None\r
919 self._LibraryClasses = None\r
920 self._Pcds = None\r
921\r
922 ## Get architecture\r
923 def _GetArch(self):\r
924 return self._Arch\r
925\r
926 ## Set architecture\r
927 #\r
928 # Changing the default ARCH to another may affect all other information\r
929 # because all information in a platform may be ARCH-related. That's\r
930 # why we need to clear all internal used members, in order to cause all\r
931 # information to be re-retrieved.\r
932 #\r
933 # @param Value The value of ARCH\r
934 #\r
935 def _SetArch(self, Value):\r
936 if self._Arch == Value:\r
937 return\r
938 self._Arch = Value\r
939 self._Clear()\r
940\r
941 ## Retrieve all information in [Defines] section\r
942 #\r
943 # (Retriving all [Defines] information in one-shot is just to save time.)\r
944 #\r
945 def _GetHeaderInfo(self):\r
946 RecordList = self._RawData[MODEL_META_DATA_HEADER]\r
947 for Record in RecordList:\r
948 Name = Record[0]\r
949 if Name in self:\r
950 self[Name] = Record[1]\r
951 self._Header = 'DUMMY'\r
952\r
953 ## Retrieve package name\r
954 def _GetPackageName(self):\r
955 if self._PackageName == None:\r
956 if self._Header == None:\r
957 self._GetHeaderInfo()\r
958 if self._PackageName == None:\r
959 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_NAME", File=self.MetaFile)\r
960 return self._PackageName\r
961\r
962 ## Retrieve file guid\r
963 def _GetFileGuid(self):\r
964 if self._Guid == None:\r
965 if self._Header == None:\r
966 self._GetHeaderInfo()\r
967 if self._Guid == None:\r
968 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_GUID", File=self.MetaFile)\r
969 return self._Guid\r
970\r
971 ## Retrieve package version\r
972 def _GetVersion(self):\r
973 if self._Version == None:\r
974 if self._Header == None:\r
975 self._GetHeaderInfo()\r
976 if self._Version == None:\r
977 self._Version = ''\r
978 return self._Version\r
979\r
980 ## Retrieve protocol definitions (name/value pairs)\r
981 def _GetProtocol(self):\r
982 if self._Protocols == None:\r
983 #\r
984 # tdict is a special kind of dict, used for selecting correct\r
985 # protocol defition for given ARCH\r
986 #\r
987 ProtocolDict = tdict(True)\r
988 NameList = []\r
989 # find out all protocol definitions for specific and 'common' arch\r
990 RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch]\r
991 for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:\r
992 if Name not in NameList:\r
993 NameList.append(Name)\r
994 ProtocolDict[Arch, Name] = Guid\r
995 # use sdict to keep the order\r
996 self._Protocols = sdict()\r
997 for Name in NameList:\r
998 #\r
999 # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
1000 # will automatically turn to 'common' ARCH for trying\r
1001 #\r
1002 self._Protocols[Name] = ProtocolDict[self._Arch, Name]\r
1003 return self._Protocols\r
1004\r
1005 ## Retrieve PPI definitions (name/value pairs)\r
1006 def _GetPpi(self):\r
1007 if self._Ppis == None:\r
1008 #\r
1009 # tdict is a special kind of dict, used for selecting correct\r
1010 # PPI defition for given ARCH\r
1011 #\r
1012 PpiDict = tdict(True)\r
1013 NameList = []\r
1014 # find out all PPI definitions for specific arch and 'common' arch\r
1015 RecordList = self._RawData[MODEL_EFI_PPI, 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 # use sdict to keep the order\r
1021 self._Ppis = sdict()\r
1022 for Name in NameList:\r
1023 #\r
1024 # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
1025 # will automatically turn to 'common' ARCH for trying\r
1026 #\r
1027 self._Ppis[Name] = PpiDict[self._Arch, Name]\r
1028 return self._Ppis\r
1029\r
1030 ## Retrieve GUID definitions (name/value pairs)\r
1031 def _GetGuid(self):\r
1032 if self._Guids == None:\r
1033 #\r
1034 # tdict is a special kind of dict, used for selecting correct\r
1035 # GUID defition for given ARCH\r
1036 #\r
1037 GuidDict = tdict(True)\r
1038 NameList = []\r
1039 # find out all protocol definitions for specific and 'common' arch\r
1040 RecordList = self._RawData[MODEL_EFI_GUID, self._Arch]\r
1041 for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:\r
1042 if Name not in NameList:\r
1043 NameList.append(Name)\r
1044 GuidDict[Arch, Name] = Guid\r
1045 # use sdict to keep the order\r
1046 self._Guids = sdict()\r
1047 for Name in NameList:\r
1048 #\r
1049 # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
1050 # will automatically turn to 'common' ARCH for trying\r
1051 #\r
1052 self._Guids[Name] = GuidDict[self._Arch, Name]\r
1053 return self._Guids\r
1054\r
1055 ## Retrieve public include paths declared in this package\r
1056 def _GetInclude(self):\r
1057 if self._Includes == None:\r
1058 self._Includes = []\r
1059 RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch]\r
1060 Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource}\r
1061 Macros.update(self._Macros)\r
1062 for Record in RecordList:\r
1063 File = PathClass(NormPath(Record[0], Macros), self._PackageDir, Arch=self._Arch)\r
1064 LineNo = Record[-1]\r
1065 # validate the path\r
1066 ErrorCode, ErrorInfo = File.Validate()\r
1067 if ErrorCode != 0:\r
1068 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
1069\r
1070 # avoid duplicate include path\r
1071 if File not in self._Includes:\r
1072 self._Includes.append(File)\r
1073 return self._Includes\r
1074\r
1075 ## Retrieve library class declarations (not used in build at present)\r
1076 def _GetLibraryClass(self):\r
1077 if self._LibraryClasses == None:\r
1078 #\r
1079 # tdict is a special kind of dict, used for selecting correct\r
1080 # library class declaration for given ARCH\r
1081 #\r
1082 LibraryClassDict = tdict(True)\r
1083 LibraryClassSet = set()\r
1084 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch]\r
1085 Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource}\r
1086 Macros.update(self._Macros)\r
1087 for LibraryClass, File, Dummy, Arch, ID, LineNo in RecordList:\r
1088 File = PathClass(NormPath(File, Macros), self._PackageDir, Arch=self._Arch)\r
1089 # check the file validation\r
1090 ErrorCode, ErrorInfo = File.Validate()\r
1091 if ErrorCode != 0:\r
1092 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
1093 LibraryClassSet.add(LibraryClass)\r
1094 LibraryClassDict[Arch, LibraryClass] = File\r
1095 self._LibraryClasses = sdict()\r
1096 for LibraryClass in LibraryClassSet:\r
1097 self._LibraryClasses[LibraryClass] = LibraryClassDict[self._Arch, LibraryClass]\r
1098 return self._LibraryClasses\r
1099\r
1100 ## Retrieve PCD declarations\r
1101 def _GetPcds(self):\r
1102 if self._Pcds == None:\r
1103 self._Pcds = {}\r
1104 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
1105 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
1106 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
1107 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC))\r
1108 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))\r
1109 return self._Pcds\r
1110\r
1111 ## Retrieve PCD declarations for given type\r
1112 def _GetPcd(self, Type):\r
1113 Pcds = {}\r
1114 #\r
1115 # tdict is a special kind of dict, used for selecting correct\r
1116 # PCD declaration for given ARCH\r
1117 #\r
1118 PcdDict = tdict(True, 3)\r
1119 # for summarizing PCD\r
1120 PcdSet = set()\r
1121 # find out all PCDs of the 'type'\r
1122 RecordList = self._RawData[Type, self._Arch]\r
1123 for TokenSpaceGuid, PcdCName, Setting, Arch, Dummy1, Dummy2 in RecordList:\r
1124 PcdDict[Arch, PcdCName, TokenSpaceGuid] = Setting\r
1125 PcdSet.add((PcdCName, TokenSpaceGuid))\r
1126\r
1127 for PcdCName, TokenSpaceGuid in PcdSet:\r
52302d4d
LG
1128 #\r
1129 # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
1130 # will automatically turn to 'common' ARCH and try again\r
1131 #\r
1132 Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid]\r
1133 if Setting == None:\r
1134 continue\r
6780eef1
LG
1135\r
1136 DefaultValue, DatumType, TokenNumber = AnalyzePcdData(Setting)\r
1137 \r
52302d4d
LG
1138 Pcds[PcdCName, TokenSpaceGuid, self._PCD_TYPE_STRING_[Type]] = PcdClassObject(\r
1139 PcdCName,\r
1140 TokenSpaceGuid,\r
1141 self._PCD_TYPE_STRING_[Type],\r
1142 DatumType,\r
1143 DefaultValue,\r
1144 TokenNumber,\r
1145 '',\r
1146 {},\r
e56468c0 1147 False,\r
52302d4d
LG
1148 None\r
1149 )\r
1150 return Pcds\r
1151\r
1152\r
1153 Arch = property(_GetArch, _SetArch)\r
1154 PackageName = property(_GetPackageName)\r
1155 Guid = property(_GetFileGuid)\r
1156 Version = property(_GetVersion)\r
1157\r
1158 Protocols = property(_GetProtocol)\r
1159 Ppis = property(_GetPpi)\r
1160 Guids = property(_GetGuid)\r
1161 Includes = property(_GetInclude)\r
1162 LibraryClasses = property(_GetLibraryClass)\r
1163 Pcds = property(_GetPcds)\r
1164\r
1165## Module build information from INF file\r
1166#\r
1167# This class is used to retrieve information stored in database and convert them\r
1168# into ModuleBuildClassObject form for easier use for AutoGen.\r
1169#\r
1170class InfBuildData(ModuleBuildClassObject):\r
1171 # dict used to convert PCD type in database to string used by build tool\r
1172 _PCD_TYPE_STRING_ = {\r
1173 MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild",\r
1174 MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule",\r
1175 MODEL_PCD_FEATURE_FLAG : "FeatureFlag",\r
1176 MODEL_PCD_DYNAMIC : "Dynamic",\r
1177 MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic",\r
1178 MODEL_PCD_DYNAMIC_HII : "DynamicHii",\r
1179 MODEL_PCD_DYNAMIC_VPD : "DynamicVpd",\r
1180 MODEL_PCD_DYNAMIC_EX : "DynamicEx",\r
1181 MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx",\r
1182 MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii",\r
1183 MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd",\r
1184 }\r
1185\r
1186 # dict used to convert part of [Defines] to members of InfBuildData directly\r
1187 _PROPERTY_ = {\r
1188 #\r
1189 # Required Fields\r
1190 #\r
1191 TAB_INF_DEFINES_BASE_NAME : "_BaseName",\r
1192 TAB_INF_DEFINES_FILE_GUID : "_Guid",\r
1193 TAB_INF_DEFINES_MODULE_TYPE : "_ModuleType",\r
1194 #\r
1195 # Optional Fields\r
1196 #\r
1197 TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",\r
1198 TAB_INF_DEFINES_COMPONENT_TYPE : "_ComponentType",\r
1199 TAB_INF_DEFINES_MAKEFILE_NAME : "_MakefileName",\r
1200 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",\r
b36d134f 1201 TAB_INF_DEFINES_DPX_SOURCE :"_DxsFile",\r
52302d4d
LG
1202 TAB_INF_DEFINES_VERSION_NUMBER : "_Version",\r
1203 TAB_INF_DEFINES_VERSION_STRING : "_Version",\r
1204 TAB_INF_DEFINES_VERSION : "_Version",\r
1205 TAB_INF_DEFINES_PCD_IS_DRIVER : "_PcdIsDriver",\r
1206 TAB_INF_DEFINES_SHADOW : "_Shadow",\r
1207\r
1208 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH : "_SourceOverridePath",\r
1209 }\r
1210\r
1211 # dict used to convert Component type to Module type\r
1212 _MODULE_TYPE_ = {\r
1213 "LIBRARY" : "BASE",\r
1214 "SECURITY_CORE" : "SEC",\r
1215 "PEI_CORE" : "PEI_CORE",\r
1216 "COMBINED_PEIM_DRIVER" : "PEIM",\r
1217 "PIC_PEIM" : "PEIM",\r
1218 "RELOCATABLE_PEIM" : "PEIM",\r
1219 "PE32_PEIM" : "PEIM",\r
1220 "BS_DRIVER" : "DXE_DRIVER",\r
1221 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",\r
1222 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",\r
1223 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",\r
1224 # "SMM_DRIVER" : "DXE_SMM_DRIVER",\r
1225 # "BS_DRIVER" : "DXE_SMM_DRIVER",\r
1226 # "BS_DRIVER" : "UEFI_DRIVER",\r
1227 "APPLICATION" : "UEFI_APPLICATION",\r
1228 "LOGO" : "BASE",\r
1229 }\r
1230\r
1231 # regular expression for converting XXX_FLAGS in [nmake] section to new type\r
1232 _NMAKE_FLAG_PATTERN_ = re.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re.UNICODE)\r
1233 # dict used to convert old tool name used in [nmake] section to new ones\r
1234 _TOOL_CODE_ = {\r
1235 "C" : "CC",\r
1236 "LIB" : "SLINK",\r
1237 "LINK" : "DLINK",\r
1238 }\r
1239\r
1240\r
1241 ## Constructor of DscBuildData\r
1242 #\r
1243 # Initialize object of DscBuildData\r
1244 #\r
1245 # @param FilePath The path of platform description file\r
1246 # @param RawData The raw data of DSC file\r
1247 # @param BuildDataBase Database used to retrieve module/package information\r
1248 # @param Arch The target architecture\r
1249 # @param Platform The name of platform employing this module\r
1250 # @param Macros Macros used for replacement in DSC file\r
1251 #\r
1252 def __init__(self, FilePath, RawData, BuildDatabase, Arch='COMMON', Platform='COMMON', Macros={}):\r
1253 self.MetaFile = FilePath\r
1254 self._ModuleDir = FilePath.Dir\r
1255 self._RawData = RawData\r
1256 self._Bdb = BuildDatabase\r
1257 self._Arch = Arch\r
1258 self._Platform = 'COMMON'\r
1259 self._Macros = Macros\r
1260 self._SourceOverridePath = None\r
1261 if FilePath.Key in GlobalData.gOverrideDir:\r
1262 self._SourceOverridePath = GlobalData.gOverrideDir[FilePath.Key]\r
1263 self._Clear()\r
1264\r
1265 ## XXX[key] = value\r
1266 def __setitem__(self, key, value):\r
1267 self.__dict__[self._PROPERTY_[key]] = value\r
1268\r
1269 ## value = XXX[key]\r
1270 def __getitem__(self, key):\r
1271 return self.__dict__[self._PROPERTY_[key]]\r
1272\r
1273 ## "in" test support\r
1274 def __contains__(self, key):\r
1275 return key in self._PROPERTY_\r
1276\r
1277 ## Set all internal used members of InfBuildData to None\r
1278 def _Clear(self):\r
1279 self._Header_ = None\r
1280 self._AutoGenVersion = None\r
1281 self._BaseName = None\r
b36d134f 1282 self._DxsFile = None\r
52302d4d
LG
1283 self._ModuleType = None\r
1284 self._ComponentType = None\r
1285 self._BuildType = None\r
1286 self._Guid = None\r
1287 self._Version = None\r
1288 self._PcdIsDriver = None\r
1289 self._BinaryModule = None\r
1290 self._Shadow = None\r
1291 self._MakefileName = None\r
1292 self._CustomMakefile = None\r
1293 self._Specification = None\r
1294 self._LibraryClass = None\r
1295 self._ModuleEntryPointList = None\r
1296 self._ModuleUnloadImageList = None\r
1297 self._ConstructorList = None\r
1298 self._DestructorList = None\r
1299 self._Defs = None\r
1300 self._Binaries = None\r
1301 self._Sources = None\r
1302 self._LibraryClasses = None\r
1303 self._Libraries = None\r
1304 self._Protocols = None\r
1305 self._Ppis = None\r
1306 self._Guids = None\r
1307 self._Includes = None\r
1308 self._Packages = None\r
1309 self._Pcds = None\r
1310 self._BuildOptions = None\r
1311 self._Depex = None\r
1312 self._DepexExpression = None\r
1313 #self._SourceOverridePath = None\r
1314\r
1315 ## Get architecture\r
1316 def _GetArch(self):\r
1317 return self._Arch\r
1318\r
1319 ## Set architecture\r
1320 #\r
1321 # Changing the default ARCH to another may affect all other information\r
1322 # because all information in a platform may be ARCH-related. That's\r
1323 # why we need to clear all internal used members, in order to cause all\r
1324 # information to be re-retrieved.\r
1325 #\r
1326 # @param Value The value of ARCH\r
1327 #\r
1328 def _SetArch(self, Value):\r
1329 if self._Arch == Value:\r
1330 return\r
1331 self._Arch = Value\r
1332 self._Clear()\r
1333\r
1334 ## Return the name of platform employing this module\r
1335 def _GetPlatform(self):\r
1336 return self._Platform\r
1337\r
1338 ## Change the name of platform employing this module\r
1339 #\r
1340 # Changing the default name of platform to another may affect some information\r
1341 # because they may be PLATFORM-related. That's why we need to clear all internal\r
1342 # used members, in order to cause all information to be re-retrieved.\r
1343 #\r
1344 def _SetPlatform(self, Value):\r
1345 if self._Platform == Value:\r
1346 return\r
1347 self._Platform = Value\r
1348 self._Clear()\r
1349\r
1350 ## Retrieve all information in [Defines] section\r
1351 #\r
1352 # (Retriving all [Defines] information in one-shot is just to save time.)\r
1353 #\r
1354 def _GetHeaderInfo(self):\r
1355 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
1356 for Record in RecordList:\r
1357 Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)\r
1358 Name = Record[0]\r
1359 # items defined _PROPERTY_ don't need additional processing\r
1360 if Name in self:\r
1361 self[Name] = Record[1]\r
1362 # some special items in [Defines] section need special treatment\r
08dd311f
LG
1363 elif Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):\r
1364 if Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):\r
1365 Name = 'UEFI_SPECIFICATION_VERSION'\r
52302d4d
LG
1366 if self._Specification == None:\r
1367 self._Specification = sdict()\r
08dd311f
LG
1368 self._Specification[Name] = GetHexVerValue(Record[1])\r
1369 if self._Specification[Name] == None:\r
1370 EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
1371 "'%s' format is not supported for %s" % (Record[1], Name),\r
1372 File=self.MetaFile, Line=Record[-1])\r
52302d4d
LG
1373 elif Name == 'LIBRARY_CLASS':\r
1374 if self._LibraryClass == None:\r
1375 self._LibraryClass = []\r
1376 ValueList = GetSplitValueList(Record[1])\r
1377 LibraryClass = ValueList[0]\r
1378 if len(ValueList) > 1:\r
1379 SupModuleList = GetSplitValueList(ValueList[1], ' ')\r
1380 else:\r
1381 SupModuleList = SUP_MODULE_LIST\r
1382 self._LibraryClass.append(LibraryClassObject(LibraryClass, SupModuleList))\r
1383 elif Name == 'ENTRY_POINT':\r
1384 if self._ModuleEntryPointList == None:\r
1385 self._ModuleEntryPointList = []\r
1386 self._ModuleEntryPointList.append(Record[1])\r
1387 elif Name == 'UNLOAD_IMAGE':\r
1388 if self._ModuleUnloadImageList == None:\r
1389 self._ModuleUnloadImageList = []\r
1390 if Record[1] == '':\r
1391 continue\r
1392 self._ModuleUnloadImageList.append(Record[1])\r
1393 elif Name == 'CONSTRUCTOR':\r
1394 if self._ConstructorList == None:\r
1395 self._ConstructorList = []\r
1396 if Record[1] == '':\r
1397 continue\r
1398 self._ConstructorList.append(Record[1])\r
1399 elif Name == 'DESTRUCTOR':\r
1400 if self._DestructorList == None:\r
1401 self._DestructorList = []\r
1402 if Record[1] == '':\r
1403 continue\r
1404 self._DestructorList.append(Record[1])\r
1405 elif Name == TAB_INF_DEFINES_CUSTOM_MAKEFILE:\r
1406 TokenList = GetSplitValueList(Record[1])\r
1407 if self._CustomMakefile == None:\r
1408 self._CustomMakefile = {}\r
1409 if len(TokenList) < 2:\r
1410 self._CustomMakefile['MSFT'] = TokenList[0]\r
1411 self._CustomMakefile['GCC'] = TokenList[0]\r
1412 else:\r
1413 if TokenList[0] not in ['MSFT', 'GCC']:\r
1414 EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
1415 "No supported family [%s]" % TokenList[0],\r
1416 File=self.MetaFile, Line=Record[-1])\r
1417 self._CustomMakefile[TokenList[0]] = TokenList[1]\r
1418 else:\r
1419 if self._Defs == None:\r
1420 self._Defs = sdict()\r
1421 self._Defs[Name] = Record[1]\r
1422\r
1423 #\r
b36d134f 1424 # Retrieve information in sections specific to EDK.x modules\r
52302d4d
LG
1425 #\r
1426 if self._AutoGenVersion >= 0x00010005: # _AutoGenVersion may be None, which is less than anything\r
1427 if not self._ModuleType:\r
1428 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,\r
1429 "MODULE_TYPE is not given", File=self.MetaFile)\r
da92f276
LG
1430 if self._ModuleType not in SUP_MODULE_LIST:\r
1431 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
1432 for Record in RecordList:\r
1433 Name = Record[0]\r
1434 if Name == "MODULE_TYPE":\r
1435 LineNo = Record[6]\r
1436 break\r
1437 EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
1438 "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self._ModuleType,' '.join(l for l in SUP_MODULE_LIST)), \r
1439 File=self.MetaFile, Line=LineNo) \r
1440 if (self._Specification == None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (int(self._Specification['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):\r
52302d4d
LG
1441 if self._ModuleType == SUP_MODULE_SMM_CORE:\r
1442 EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.MetaFile) \r
1443 if self._Defs and 'PCI_DEVICE_ID' in self._Defs and 'PCI_VENDOR_ID' in self._Defs \\r
1444 and 'PCI_CLASS_CODE' in self._Defs:\r
1445 self._BuildType = 'UEFI_OPTIONROM'\r
1446 elif self._Defs and 'UEFI_HII_RESOURCE_SECTION' in self._Defs \\r
1447 and self._Defs['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':\r
1448 self._BuildType = 'UEFI_HII'\r
1449 else:\r
1450 self._BuildType = self._ModuleType.upper()\r
b36d134f
LG
1451 \r
1452 if self._DxsFile:\r
1453 File = PathClass(NormPath(self._DxsFile), self._ModuleDir, Arch=self._Arch)\r
1454 # check the file validation\r
1455 ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)\r
1456 if ErrorCode != 0:\r
1457 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,\r
1458 File=self.MetaFile, Line=LineNo)\r
1459 if self.Sources == None:\r
1460 self._Sources = []\r
1461 self._Sources.append(File)\r
52302d4d
LG
1462 else:\r
1463 self._BuildType = self._ComponentType.upper()\r
1464 if not self._ComponentType:\r
1465 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,\r
1466 "COMPONENT_TYPE is not given", File=self.MetaFile)\r
1467 if self._ComponentType in self._MODULE_TYPE_:\r
1468 self._ModuleType = self._MODULE_TYPE_[self._ComponentType]\r
1469 if self._ComponentType == 'LIBRARY':\r
1470 self._LibraryClass = [LibraryClassObject(self._BaseName, SUP_MODULE_LIST)]\r
1471 # make use some [nmake] section macros\r
1472 RecordList = self._RawData[MODEL_META_DATA_NMAKE, self._Arch, self._Platform]\r
1473 for Name,Value,Dummy,Arch,Platform,ID,LineNo in RecordList:\r
1474 Value = Value.replace('$(PROCESSOR)', self._Arch)\r
1475 Name = Name.replace('$(PROCESSOR)', self._Arch)\r
1476 Name, Value = ReplaceMacros((Name, Value), GlobalData.gEdkGlobal, True)\r
1477 if Name == "IMAGE_ENTRY_POINT":\r
1478 if self._ModuleEntryPointList == None:\r
1479 self._ModuleEntryPointList = []\r
1480 self._ModuleEntryPointList.append(Value)\r
1481 elif Name == "DPX_SOURCE":\r
1482 Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource}\r
1483 Macros.update(self._Macros)\r
1484 File = PathClass(NormPath(Value, Macros), self._ModuleDir, Arch=self._Arch)\r
1485 # check the file validation\r
1486 ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)\r
1487 if ErrorCode != 0:\r
1488 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,\r
1489 File=self.MetaFile, Line=LineNo)\r
1490 if self.Sources == None:\r
1491 self._Sources = []\r
1492 self._Sources.append(File)\r
1493 else:\r
1494 ToolList = self._NMAKE_FLAG_PATTERN_.findall(Name)\r
1495 if len(ToolList) == 0 or len(ToolList) != 1:\r
1496 pass\r
1497# EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,\r
1498# File=self.MetaFile, Line=LineNo)\r
1499 else:\r
1500 if self._BuildOptions == None:\r
1501 self._BuildOptions = sdict()\r
1502\r
1503 if ToolList[0] in self._TOOL_CODE_:\r
1504 Tool = self._TOOL_CODE_[ToolList[0]]\r
1505 else:\r
1506 Tool = ToolList[0]\r
1507 ToolChain = "*_*_*_%s_FLAGS" % Tool\r
b36d134f 1508 ToolChainFamily = 'MSFT' # EDK.x only support MSFT tool chain\r
52302d4d
LG
1509 #ignore not replaced macros in value\r
1510 ValueList = GetSplitValueList(' ' + Value, '/D')\r
1511 Dummy = ValueList[0]\r
1512 for Index in range(1, len(ValueList)):\r
1513 if ValueList[Index][-1] == '=' or ValueList[Index] == '':\r
1514 continue\r
1515 Dummy = Dummy + ' /D ' + ValueList[Index]\r
1516 Value = Dummy.strip()\r
1517 if (ToolChainFamily, ToolChain) not in self._BuildOptions:\r
1518 self._BuildOptions[ToolChainFamily, ToolChain] = Value\r
1519 else:\r
1520 OptionString = self._BuildOptions[ToolChainFamily, ToolChain]\r
1521 self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Value\r
1522 # set _Header to non-None in order to avoid database re-querying\r
1523 self._Header_ = 'DUMMY'\r
1524\r
1525 ## Retrieve file version\r
1526 def _GetInfVersion(self):\r
1527 if self._AutoGenVersion == None:\r
1528 if self._Header_ == None:\r
1529 self._GetHeaderInfo()\r
1530 if self._AutoGenVersion == None:\r
1531 self._AutoGenVersion = 0x00010000\r
1532 return self._AutoGenVersion\r
1533\r
1534 ## Retrieve BASE_NAME\r
1535 def _GetBaseName(self):\r
1536 if self._BaseName == None:\r
1537 if self._Header_ == None:\r
1538 self._GetHeaderInfo()\r
1539 if self._BaseName == None:\r
1540 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BASE_NAME name", File=self.MetaFile)\r
1541 return self._BaseName\r
1542\r
b36d134f
LG
1543 ## Retrieve DxsFile\r
1544 def _GetDxsFile(self):\r
1545 if self._DxsFile == None:\r
1546 if self._Header_ == None:\r
1547 self._GetHeaderInfo()\r
1548 if self._DxsFile == None:\r
1549 self._DxsFile = ''\r
1550 return self._DxsFile\r
1551\r
52302d4d
LG
1552 ## Retrieve MODULE_TYPE\r
1553 def _GetModuleType(self):\r
1554 if self._ModuleType == None:\r
1555 if self._Header_ == None:\r
1556 self._GetHeaderInfo()\r
1557 if self._ModuleType == None:\r
1558 self._ModuleType = 'BASE'\r
1559 if self._ModuleType not in SUP_MODULE_LIST:\r
1560 self._ModuleType = "USER_DEFINED"\r
1561 return self._ModuleType\r
1562\r
1563 ## Retrieve COMPONENT_TYPE\r
1564 def _GetComponentType(self):\r
1565 if self._ComponentType == None:\r
1566 if self._Header_ == None:\r
1567 self._GetHeaderInfo()\r
1568 if self._ComponentType == None:\r
1569 self._ComponentType = 'USER_DEFINED'\r
1570 return self._ComponentType\r
1571\r
1572 ## Retrieve "BUILD_TYPE"\r
1573 def _GetBuildType(self):\r
1574 if self._BuildType == None:\r
1575 if self._Header_ == None:\r
1576 self._GetHeaderInfo()\r
1577 if not self._BuildType:\r
1578 self._BuildType = "BASE"\r
1579 return self._BuildType\r
1580\r
1581 ## Retrieve file guid\r
1582 def _GetFileGuid(self):\r
1583 if self._Guid == None:\r
1584 if self._Header_ == None:\r
1585 self._GetHeaderInfo()\r
1586 if self._Guid == None:\r
1587 self._Guid = '00000000-0000-0000-000000000000'\r
1588 return self._Guid\r
1589\r
1590 ## Retrieve module version\r
1591 def _GetVersion(self):\r
1592 if self._Version == None:\r
1593 if self._Header_ == None:\r
1594 self._GetHeaderInfo()\r
1595 if self._Version == None:\r
1596 self._Version = '0.0'\r
1597 return self._Version\r
1598\r
1599 ## Retrieve PCD_IS_DRIVER\r
1600 def _GetPcdIsDriver(self):\r
1601 if self._PcdIsDriver == None:\r
1602 if self._Header_ == None:\r
1603 self._GetHeaderInfo()\r
1604 if self._PcdIsDriver == None:\r
1605 self._PcdIsDriver = ''\r
1606 return self._PcdIsDriver\r
1607\r
1608 ## Retrieve SHADOW\r
1609 def _GetShadow(self):\r
1610 if self._Shadow == None:\r
1611 if self._Header_ == None:\r
1612 self._GetHeaderInfo()\r
1613 if self._Shadow != None and self._Shadow.upper() == 'TRUE':\r
1614 self._Shadow = True\r
1615 else:\r
1616 self._Shadow = False\r
1617 return self._Shadow\r
1618\r
1619 ## Retrieve CUSTOM_MAKEFILE\r
1620 def _GetMakefile(self):\r
1621 if self._CustomMakefile == None:\r
1622 if self._Header_ == None:\r
1623 self._GetHeaderInfo()\r
1624 if self._CustomMakefile == None:\r
1625 self._CustomMakefile = {}\r
1626 return self._CustomMakefile\r
1627\r
1628 ## Retrieve EFI_SPECIFICATION_VERSION\r
1629 def _GetSpec(self):\r
1630 if self._Specification == None:\r
1631 if self._Header_ == None:\r
1632 self._GetHeaderInfo()\r
1633 if self._Specification == None:\r
1634 self._Specification = {}\r
1635 return self._Specification\r
1636\r
1637 ## Retrieve LIBRARY_CLASS\r
1638 def _GetLibraryClass(self):\r
1639 if self._LibraryClass == None:\r
1640 if self._Header_ == None:\r
1641 self._GetHeaderInfo()\r
1642 if self._LibraryClass == None:\r
1643 self._LibraryClass = []\r
1644 return self._LibraryClass\r
1645\r
1646 ## Retrieve ENTRY_POINT\r
1647 def _GetEntryPoint(self):\r
1648 if self._ModuleEntryPointList == None:\r
1649 if self._Header_ == None:\r
1650 self._GetHeaderInfo()\r
1651 if self._ModuleEntryPointList == None:\r
1652 self._ModuleEntryPointList = []\r
1653 return self._ModuleEntryPointList\r
1654\r
1655 ## Retrieve UNLOAD_IMAGE\r
1656 def _GetUnloadImage(self):\r
1657 if self._ModuleUnloadImageList == None:\r
1658 if self._Header_ == None:\r
1659 self._GetHeaderInfo()\r
1660 if self._ModuleUnloadImageList == None:\r
1661 self._ModuleUnloadImageList = []\r
1662 return self._ModuleUnloadImageList\r
1663\r
1664 ## Retrieve CONSTRUCTOR\r
1665 def _GetConstructor(self):\r
1666 if self._ConstructorList == None:\r
1667 if self._Header_ == None:\r
1668 self._GetHeaderInfo()\r
1669 if self._ConstructorList == None:\r
1670 self._ConstructorList = []\r
1671 return self._ConstructorList\r
1672\r
1673 ## Retrieve DESTRUCTOR\r
1674 def _GetDestructor(self):\r
1675 if self._DestructorList == None:\r
1676 if self._Header_ == None:\r
1677 self._GetHeaderInfo()\r
1678 if self._DestructorList == None:\r
1679 self._DestructorList = []\r
1680 return self._DestructorList\r
1681\r
1682 ## Retrieve definies other than above ones\r
1683 def _GetDefines(self):\r
1684 if self._Defs == None:\r
1685 if self._Header_ == None:\r
1686 self._GetHeaderInfo()\r
1687 if self._Defs == None:\r
1688 self._Defs = sdict()\r
1689 return self._Defs\r
1690\r
1691 ## Retrieve binary files\r
1692 def _GetBinaryFiles(self):\r
1693 if self._Binaries == None:\r
1694 self._Binaries = []\r
1695 RecordList = self._RawData[MODEL_EFI_BINARY_FILE, self._Arch, self._Platform]\r
1696 Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource, 'PROCESSOR':self._Arch}\r
1697 Macros.update(self._Macros)\r
1698 for Record in RecordList:\r
1699 Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)\r
1700 FileType = Record[0]\r
1701 LineNo = Record[-1]\r
1702 Target = 'COMMON'\r
1703 FeatureFlag = []\r
1704 if Record[2]:\r
1705 TokenList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)\r
1706 if TokenList:\r
1707 Target = TokenList[0]\r
1708 if len(TokenList) > 1:\r
1709 FeatureFlag = Record[1:]\r
1710\r
1711 File = PathClass(NormPath(Record[1], Macros), self._ModuleDir, '', FileType, True, self._Arch, '', Target)\r
1712 # check the file validation\r
1713 ErrorCode, ErrorInfo = File.Validate()\r
1714 if ErrorCode != 0:\r
1715 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
1716 self._Binaries.append(File)\r
1717 return self._Binaries\r
1718\r
1719 ## Retrieve source files\r
1720 def _GetSourceFiles(self):\r
1721 if self._Sources == None:\r
1722 self._Sources = []\r
1723 RecordList = self._RawData[MODEL_EFI_SOURCE_FILE, self._Arch, self._Platform]\r
1724 Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource, 'PROCESSOR':self._Arch}\r
1725 Macros.update(self._Macros)\r
1726 for Record in RecordList:\r
1727 Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)\r
1728 LineNo = Record[-1]\r
1729 ToolChainFamily = Record[1]\r
1730 TagName = Record[2]\r
1731 ToolCode = Record[3]\r
1732 FeatureFlag = Record[4]\r
1733 if self._AutoGenVersion < 0x00010005:\r
b36d134f 1734 # old module source files (EDK)\r
52302d4d
LG
1735 File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, self._SourceOverridePath,\r
1736 '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)\r
1737 # check the file validation\r
1738 ErrorCode, ErrorInfo = File.Validate(CaseSensitive=False)\r
1739 if ErrorCode != 0:\r
1740 if File.Ext.lower() == '.h':\r
1741 EdkLogger.warn('build', 'Include file not found', ExtraData=ErrorInfo,\r
1742 File=self.MetaFile, Line=LineNo)\r
1743 continue\r
1744 else:\r
1745 EdkLogger.error('build', ErrorCode, ExtraData=File, File=self.MetaFile, Line=LineNo)\r
1746 else:\r
1747 File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, '',\r
1748 '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)\r
1749 # check the file validation\r
1750 ErrorCode, ErrorInfo = File.Validate()\r
1751 if ErrorCode != 0:\r
1752 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
1753\r
1754 self._Sources.append(File)\r
1755 return self._Sources\r
1756\r
1757 ## Retrieve library classes employed by this module\r
1758 def _GetLibraryClassUses(self):\r
1759 if self._LibraryClasses == None:\r
1760 self._LibraryClasses = sdict()\r
1761 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, self._Platform]\r
1762 for Record in RecordList:\r
1763 Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)\r
1764 Lib = Record[0]\r
1765 Instance = Record[1]\r
1766 if Instance != None and Instance != '':\r
1767 Instance = NormPath(Instance, self._Macros)\r
1768 self._LibraryClasses[Lib] = Instance\r
1769 return self._LibraryClasses\r
1770\r
b36d134f 1771 ## Retrieve library names (for EDK.x style of modules)\r
52302d4d
LG
1772 def _GetLibraryNames(self):\r
1773 if self._Libraries == None:\r
1774 self._Libraries = []\r
1775 RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch, self._Platform]\r
1776 for Record in RecordList:\r
b36d134f 1777 # in case of name with '.lib' extension, which is unusual in EDK.x inf\r
52302d4d
LG
1778 Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)\r
1779 LibraryName = os.path.splitext(Record[0])[0]\r
1780 if LibraryName not in self._Libraries:\r
1781 self._Libraries.append(LibraryName)\r
1782 return self._Libraries\r
1783\r
1784 ## Retrieve protocols consumed/produced by this module\r
1785 def _GetProtocols(self):\r
1786 if self._Protocols == None:\r
1787 self._Protocols = sdict()\r
1788 RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform]\r
1789 for Record in RecordList:\r
1790 CName = Record[0]\r
1791 Value = ProtocolValue(CName, self.Packages)\r
1792 if Value == None:\r
1793 PackageList = "\n\t".join([str(P) for P in self.Packages])\r
1794 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
1795 "Value of Protocol [%s] is not found under [Protocols] section in" % CName,\r
1796 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
1797 self._Protocols[CName] = Value\r
1798 return self._Protocols\r
1799\r
1800 ## Retrieve PPIs consumed/produced by this module\r
1801 def _GetPpis(self):\r
1802 if self._Ppis == None:\r
1803 self._Ppis = sdict()\r
1804 RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform]\r
1805 for Record in RecordList:\r
1806 CName = Record[0]\r
1807 Value = PpiValue(CName, self.Packages)\r
1808 if Value == None:\r
1809 PackageList = "\n\t".join([str(P) for P in self.Packages])\r
1810 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
1811 "Value of PPI [%s] is not found under [Ppis] section in " % CName,\r
1812 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
1813 self._Ppis[CName] = Value\r
1814 return self._Ppis\r
1815\r
1816 ## Retrieve GUIDs consumed/produced by this module\r
1817 def _GetGuids(self):\r
1818 if self._Guids == None:\r
1819 self._Guids = sdict()\r
1820 RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform]\r
1821 for Record in RecordList:\r
1822 CName = Record[0]\r
1823 Value = GuidValue(CName, self.Packages)\r
1824 if Value == None:\r
1825 PackageList = "\n\t".join([str(P) for P in self.Packages])\r
1826 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
1827 "Value of Guid [%s] is not found under [Guids] section in" % CName,\r
1828 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
1829 self._Guids[CName] = Value\r
1830 return self._Guids\r
1831\r
b36d134f 1832 ## Retrieve include paths necessary for this module (for EDK.x style of modules)\r
52302d4d
LG
1833 def _GetIncludes(self):\r
1834 if self._Includes == None:\r
1835 self._Includes = []\r
1836 if self._SourceOverridePath:\r
1837 self._Includes.append(self._SourceOverridePath)\r
1838 RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch, self._Platform]\r
b36d134f 1839 # [includes] section must be used only in old (EDK.x) inf file\r
52302d4d
LG
1840 if self.AutoGenVersion >= 0x00010005 and len(RecordList) > 0:\r
1841 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, "No [include] section allowed",\r
1842 File=self.MetaFile, Line=RecordList[0][-1]-1)\r
1843 for Record in RecordList:\r
1844 Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)\r
1845 Record[0] = Record[0].replace('$(PROCESSOR)', self._Arch)\r
1846 Record[0] = ReplaceMacro(Record[0], {'EFI_SOURCE' : GlobalData.gEfiSource}, False)\r
1847 if Record[0].find('EDK_SOURCE') > -1:\r
1848 File = NormPath(ReplaceMacro(Record[0], {'EDK_SOURCE' : GlobalData.gEcpSource}, False), self._Macros)\r
1849 if File[0] == '.':\r
1850 File = os.path.join(self._ModuleDir, File)\r
1851 else:\r
1852 File = os.path.join(GlobalData.gWorkspace, File)\r
1853 File = RealPath(os.path.normpath(File))\r
1854 if File:\r
1855 self._Includes.append(File)\r
1856\r
1857 #TRICK: let compiler to choose correct header file\r
1858 File = NormPath(ReplaceMacro(Record[0], {'EDK_SOURCE' : GlobalData.gEdkSource}, False), self._Macros)\r
1859 if File[0] == '.':\r
1860 File = os.path.join(self._ModuleDir, File)\r
1861 else:\r
1862 File = os.path.join(GlobalData.gWorkspace, File)\r
1863 File = RealPath(os.path.normpath(File))\r
1864 if File:\r
1865 self._Includes.append(File)\r
1866 else:\r
1867 File = NormPath(Record[0], self._Macros)\r
1868 if File[0] == '.':\r
1869 File = os.path.join(self._ModuleDir, File)\r
1870 else:\r
1871 File = os.path.join(GlobalData.gWorkspace, File)\r
1872 File = RealPath(os.path.normpath(File))\r
1873 if File:\r
1874 self._Includes.append(File)\r
1875 return self._Includes\r
1876\r
1877 ## Retrieve packages this module depends on\r
1878 def _GetPackages(self):\r
1879 if self._Packages == None:\r
1880 self._Packages = []\r
1881 RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch, self._Platform]\r
1882 Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource}\r
1883 Macros.update(self._Macros)\r
1884 for Record in RecordList:\r
1885 File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
1886 LineNo = Record[-1]\r
1887 # check the file validation\r
1888 ErrorCode, ErrorInfo = File.Validate('.dec')\r
1889 if ErrorCode != 0:\r
1890 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
1891 # parse this package now. we need it to get protocol/ppi/guid value\r
1892 Package = self._Bdb[File, self._Arch]\r
1893 self._Packages.append(Package)\r
1894 return self._Packages\r
1895\r
1896 ## Retrieve PCDs used in this module\r
1897 def _GetPcds(self):\r
1898 if self._Pcds == None:\r
79b74a03 1899 self._Pcds = sdict()\r
52302d4d
LG
1900 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
1901 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
1902 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
1903 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC))\r
1904 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))\r
1905 return self._Pcds\r
1906\r
1907 ## Retrieve build options specific to this module\r
1908 def _GetBuildOptions(self):\r
1909 if self._BuildOptions == None:\r
1910 self._BuildOptions = sdict()\r
1911 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, self._Platform]\r
1912 for Record in RecordList:\r
1913 ToolChainFamily = Record[0]\r
1914 ToolChain = Record[1]\r
1915 Option = Record[2]\r
1916 if (ToolChainFamily, ToolChain) not in self._BuildOptions:\r
1917 self._BuildOptions[ToolChainFamily, ToolChain] = Option\r
1918 else:\r
1919 # concatenate the option string if they're for the same tool\r
1920 OptionString = self._BuildOptions[ToolChainFamily, ToolChain]\r
1921 self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option\r
1922 return self._BuildOptions\r
1923\r
1924 ## Retrieve depedency expression\r
1925 def _GetDepex(self):\r
1926 if self._Depex == None:\r
1927 self._Depex = tdict(False, 2)\r
1928 RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]\r
da92f276
LG
1929 \r
1930 # If the module has only Binaries and no Sources, then ignore [Depex] \r
1931 if self.Sources == None or self.Sources == []:\r
1932 if self.Binaries <> None and self.Binaries <> []:\r
1933 return self._Depex\r
1934 \r
52302d4d
LG
1935 # PEIM and DXE drivers must have a valid [Depex] section\r
1936 if len(self.LibraryClass) == 0 and len(RecordList) == 0:\r
1937 if self.ModuleType == 'DXE_DRIVER' or self.ModuleType == 'PEIM' or self.ModuleType == 'DXE_SMM_DRIVER' or \\r
1938 self.ModuleType == 'DXE_SAL_DRIVER' or self.ModuleType == 'DXE_RUNTIME_DRIVER':\r
1939 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \\r
1940 % self.ModuleType, File=self.MetaFile)\r
1941\r
1942 Depex = {}\r
1943 for Record in RecordList:\r
1944 Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)\r
1945 Arch = Record[3]\r
1946 ModuleType = Record[4]\r
1947 TokenList = Record[0].split()\r
1948 if (Arch, ModuleType) not in Depex:\r
1949 Depex[Arch, ModuleType] = []\r
1950 DepexList = Depex[Arch, ModuleType]\r
1951 for Token in TokenList:\r
1952 if Token in DEPEX_SUPPORTED_OPCODE:\r
1953 DepexList.append(Token)\r
1954 elif Token.endswith(".inf"): # module file name\r
1955 ModuleFile = os.path.normpath(Token)\r
1956 Module = self.BuildDatabase[ModuleFile]\r
1957 if Module == None:\r
1958 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "Module is not found in active platform",\r
1959 ExtraData=Token, File=self.MetaFile, Line=Record[-1])\r
1960 DepexList.append(Module.Guid)\r
1961 else:\r
1962 # get the GUID value now\r
1963 Value = ProtocolValue(Token, self.Packages)\r
1964 if Value == None:\r
1965 Value = PpiValue(Token, self.Packages)\r
1966 if Value == None:\r
1967 Value = GuidValue(Token, self.Packages)\r
1968 if Value == None:\r
1969 PackageList = "\n\t".join([str(P) for P in self.Packages])\r
1970 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
1971 "Value of [%s] is not found in" % Token,\r
1972 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
1973 DepexList.append(Value)\r
1974 for Arch, ModuleType in Depex:\r
1975 self._Depex[Arch, ModuleType] = Depex[Arch, ModuleType]\r
1976 return self._Depex\r
1977\r
1978 ## Retrieve depedency expression\r
1979 def _GetDepexExpression(self):\r
1980 if self._DepexExpression == None:\r
1981 self._DepexExpression = tdict(False, 2)\r
1982 RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]\r
1983 DepexExpression = {}\r
1984 for Record in RecordList:\r
1985 Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)\r
1986 Arch = Record[3]\r
1987 ModuleType = Record[4]\r
1988 TokenList = Record[0].split()\r
1989 if (Arch, ModuleType) not in DepexExpression:\r
1990 DepexExpression[Arch, ModuleType] = ''\r
1991 for Token in TokenList:\r
1992 DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType] + Token.strip() + ' '\r
1993 for Arch, ModuleType in DepexExpression:\r
1994 self._DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType]\r
1995 return self._DepexExpression\r
1996\r
1997 ## Retrieve PCD for given type\r
1998 def _GetPcd(self, Type):\r
79b74a03 1999 Pcds = sdict()\r
52302d4d 2000 PcdDict = tdict(True, 4)\r
6780eef1 2001 PcdList = []\r
52302d4d
LG
2002 RecordList = self._RawData[Type, self._Arch, self._Platform]\r
2003 for TokenSpaceGuid, PcdCName, Setting, Arch, Platform, Dummy1, LineNo in RecordList:\r
2004 PcdDict[Arch, Platform, PcdCName, TokenSpaceGuid] = (Setting, LineNo)\r
6780eef1 2005 PcdList.append((PcdCName, TokenSpaceGuid))\r
52302d4d
LG
2006 # get the guid value\r
2007 if TokenSpaceGuid not in self.Guids:\r
2008 Value = GuidValue(TokenSpaceGuid, self.Packages)\r
2009 if Value == None:\r
2010 PackageList = "\n\t".join([str(P) for P in self.Packages])\r
2011 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
2012 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid,\r
2013 ExtraData=PackageList, File=self.MetaFile, Line=LineNo)\r
2014 self.Guids[TokenSpaceGuid] = Value\r
2015\r
2016 # resolve PCD type, value, datum info, etc. by getting its definition from package\r
6780eef1 2017 for PcdCName, TokenSpaceGuid in PcdList:\r
52302d4d
LG
2018 Setting, LineNo = PcdDict[self._Arch, self.Platform, PcdCName, TokenSpaceGuid]\r
2019 if Setting == None:\r
2020 continue\r
6780eef1 2021 ValueList = AnalyzePcdData(Setting)\r
52302d4d
LG
2022 DefaultValue = ValueList[0]\r
2023 Pcd = PcdClassObject(\r
2024 PcdCName,\r
2025 TokenSpaceGuid,\r
2026 '',\r
2027 '',\r
2028 DefaultValue,\r
2029 '',\r
2030 '',\r
2031 {},\r
e56468c0 2032 False,\r
52302d4d
LG
2033 self.Guids[TokenSpaceGuid]\r
2034 )\r
2035\r
2036 # get necessary info from package declaring this PCD\r
2037 for Package in self.Packages:\r
2038 #\r
2039 # 'dynamic' in INF means its type is determined by platform;\r
2040 # if platform doesn't give its type, use 'lowest' one in the\r
2041 # following order, if any\r
2042 #\r
2043 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"\r
2044 #\r
2045 PcdType = self._PCD_TYPE_STRING_[Type]\r
e56468c0 2046 if Type == MODEL_PCD_DYNAMIC:\r
52302d4d
LG
2047 Pcd.Pending = True\r
2048 for T in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:\r
2049 if (PcdCName, TokenSpaceGuid, T) in Package.Pcds:\r
2050 PcdType = T\r
2051 break\r
2052 else:\r
2053 Pcd.Pending = False\r
2054\r
2055 if (PcdCName, TokenSpaceGuid, PcdType) in Package.Pcds:\r
2056 PcdInPackage = Package.Pcds[PcdCName, TokenSpaceGuid, PcdType]\r
2057 Pcd.Type = PcdType\r
2058 Pcd.TokenValue = PcdInPackage.TokenValue\r
6780eef1
LG
2059 \r
2060 #\r
2061 # Check whether the token value exist or not.\r
2062 #\r
2063 if Pcd.TokenValue == None or Pcd.TokenValue == "":\r
2064 EdkLogger.error(\r
2065 'build',\r
2066 FORMAT_INVALID,\r
2067 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid, PcdCName, str(Package)),\r
2068 File =self.MetaFile, Line=LineNo,\r
2069 ExtraData=None\r
2070 ) \r
2071 #\r
2072 # Check hexadecimal token value length and format.\r
2073 #\r
79b74a03 2074 ReIsValidPcdTokenValue = re.compile(r"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re.DOTALL)\r
6780eef1 2075 if Pcd.TokenValue.startswith("0x") or Pcd.TokenValue.startswith("0X"):\r
79b74a03 2076 if ReIsValidPcdTokenValue.match(Pcd.TokenValue) == None:\r
6780eef1
LG
2077 EdkLogger.error(\r
2078 'build',\r
2079 FORMAT_INVALID,\r
2080 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)),\r
2081 File =self.MetaFile, Line=LineNo,\r
2082 ExtraData=None\r
2083 )\r
2084 \r
2085 #\r
2086 # Check decimal token value length and format.\r
2087 # \r
2088 else:\r
2089 try:\r
2090 TokenValueInt = int (Pcd.TokenValue, 10)\r
2091 if (TokenValueInt < 0 or TokenValueInt > 4294967295):\r
2092 EdkLogger.error(\r
2093 'build',\r
2094 FORMAT_INVALID,\r
2095 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, as a decimal it should between: 0 - 4294967295!"% (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)),\r
2096 File =self.MetaFile, Line=LineNo,\r
2097 ExtraData=None\r
2098 ) \r
2099 except:\r
2100 EdkLogger.error(\r
2101 'build',\r
2102 FORMAT_INVALID,\r
2103 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, it should be hexadecimal or decimal!"% (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)),\r
2104 File =self.MetaFile, Line=LineNo,\r
2105 ExtraData=None\r
2106 )\r
2107 \r
52302d4d
LG
2108 Pcd.DatumType = PcdInPackage.DatumType\r
2109 Pcd.MaxDatumSize = PcdInPackage.MaxDatumSize\r
2110 Pcd.InfDefaultValue = Pcd.DefaultValue\r
2111 if Pcd.DefaultValue in [None, '']:\r
2112 Pcd.DefaultValue = PcdInPackage.DefaultValue\r
2113 break\r
2114 else:\r
2115 EdkLogger.error(\r
2116 'build',\r
6780eef1 2117 FORMAT_INVALID,\r
52302d4d
LG
2118 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdCName, self.MetaFile),\r
2119 File =self.MetaFile, Line=LineNo,\r
2120 ExtraData="\t%s" % '\n\t'.join([str(P) for P in self.Packages])\r
2121 )\r
2122 Pcds[PcdCName, TokenSpaceGuid] = Pcd\r
6780eef1 2123\r
52302d4d
LG
2124 return Pcds\r
2125\r
2126 Arch = property(_GetArch, _SetArch)\r
2127 Platform = property(_GetPlatform, _SetPlatform)\r
2128\r
2129 AutoGenVersion = property(_GetInfVersion)\r
2130 BaseName = property(_GetBaseName)\r
2131 ModuleType = property(_GetModuleType)\r
2132 ComponentType = property(_GetComponentType)\r
2133 BuildType = property(_GetBuildType)\r
2134 Guid = property(_GetFileGuid)\r
2135 Version = property(_GetVersion)\r
2136 PcdIsDriver = property(_GetPcdIsDriver)\r
2137 Shadow = property(_GetShadow)\r
2138 CustomMakefile = property(_GetMakefile)\r
2139 Specification = property(_GetSpec)\r
2140 LibraryClass = property(_GetLibraryClass)\r
2141 ModuleEntryPointList = property(_GetEntryPoint)\r
2142 ModuleUnloadImageList = property(_GetUnloadImage)\r
2143 ConstructorList = property(_GetConstructor)\r
2144 DestructorList = property(_GetDestructor)\r
2145 Defines = property(_GetDefines)\r
b36d134f
LG
2146 DxsFile = property(_GetDxsFile)\r
2147 \r
52302d4d
LG
2148 Binaries = property(_GetBinaryFiles)\r
2149 Sources = property(_GetSourceFiles)\r
2150 LibraryClasses = property(_GetLibraryClassUses)\r
2151 Libraries = property(_GetLibraryNames)\r
2152 Protocols = property(_GetProtocols)\r
2153 Ppis = property(_GetPpis)\r
2154 Guids = property(_GetGuids)\r
2155 Includes = property(_GetIncludes)\r
2156 Packages = property(_GetPackages)\r
2157 Pcds = property(_GetPcds)\r
2158 BuildOptions = property(_GetBuildOptions)\r
2159 Depex = property(_GetDepex)\r
2160 DepexExpression = property(_GetDepexExpression)\r
2161\r
2162## Database\r
2163#\r
e56468c0 2164# This class defined the build database for all modules, packages and platform.\r
52302d4d
LG
2165# It will call corresponding parser for the given file if it cannot find it in\r
2166# the database.\r
2167#\r
2168# @param DbPath Path of database file\r
2169# @param GlobalMacros Global macros used for replacement during file parsing\r
2170# @prarm RenewDb=False Create new database file if it's already there\r
2171#\r
2172class WorkspaceDatabase(object):\r
2173 # file parser\r
2174 _FILE_PARSER_ = {\r
2175 MODEL_FILE_INF : InfParser,\r
2176 MODEL_FILE_DEC : DecParser,\r
2177 MODEL_FILE_DSC : DscParser,\r
2178 MODEL_FILE_FDF : None, #FdfParser,\r
2179 MODEL_FILE_CIF : None\r
2180 }\r
2181\r
2182 # file table\r
2183 _FILE_TABLE_ = {\r
2184 MODEL_FILE_INF : ModuleTable,\r
2185 MODEL_FILE_DEC : PackageTable,\r
2186 MODEL_FILE_DSC : PlatformTable,\r
2187 }\r
2188\r
2189 # default database file path\r
2190 _DB_PATH_ = "Conf/.cache/build.db"\r
2191\r
2192 #\r
2193 # internal class used for call corresponding file parser and caching the result\r
2194 # to avoid unnecessary re-parsing\r
2195 #\r
2196 class BuildObjectFactory(object):\r
2197 _FILE_TYPE_ = {\r
2198 ".inf" : MODEL_FILE_INF,\r
2199 ".dec" : MODEL_FILE_DEC,\r
2200 ".dsc" : MODEL_FILE_DSC,\r
2201 ".fdf" : MODEL_FILE_FDF,\r
2202 }\r
2203\r
2204 # convert to xxxBuildData object\r
2205 _GENERATOR_ = {\r
2206 MODEL_FILE_INF : InfBuildData,\r
2207 MODEL_FILE_DEC : DecBuildData,\r
2208 MODEL_FILE_DSC : DscBuildData,\r
2209 MODEL_FILE_FDF : None #FlashDefTable,\r
2210 }\r
2211\r
2212 _CACHE_ = {} # (FilePath, Arch) : <object>\r
2213\r
2214 # constructor\r
2215 def __init__(self, WorkspaceDb):\r
2216 self.WorkspaceDb = WorkspaceDb\r
2217\r
2218 # key = (FilePath, Arch='COMMON')\r
2219 def __contains__(self, Key):\r
2220 FilePath = Key[0]\r
2221 Arch = 'COMMON'\r
2222 if len(Key) > 1:\r
2223 Arch = Key[1]\r
2224 return (FilePath, Arch) in self._CACHE_\r
2225\r
2226 # key = (FilePath, Arch='COMMON')\r
2227 def __getitem__(self, Key):\r
2228 FilePath = Key[0]\r
2229 Arch = 'COMMON'\r
2230 Platform = 'COMMON'\r
2231 if len(Key) > 1:\r
2232 Arch = Key[1]\r
2233 if len(Key) > 2:\r
2234 Platform = Key[2]\r
2235\r
2236 # if it's generated before, just return the cached one\r
2237 Key = (FilePath, Arch)\r
2238 if Key in self._CACHE_:\r
2239 return self._CACHE_[Key]\r
2240\r
2241 # check file type\r
2242 Ext = FilePath.Ext.lower()\r
2243 if Ext not in self._FILE_TYPE_:\r
2244 return None\r
2245 FileType = self._FILE_TYPE_[Ext]\r
2246 if FileType not in self._GENERATOR_:\r
2247 return None\r
2248\r
2249 # get table for current file\r
2250 MetaFile = self.WorkspaceDb[FilePath, FileType, self.WorkspaceDb._GlobalMacros]\r
2251 BuildObject = self._GENERATOR_[FileType](\r
2252 FilePath,\r
2253 MetaFile,\r
2254 self,\r
2255 Arch,\r
2256 Platform,\r
2257 self.WorkspaceDb._GlobalMacros,\r
2258 )\r
2259 self._CACHE_[Key] = BuildObject\r
2260 return BuildObject\r
2261\r
2262 # placeholder for file format conversion\r
2263 class TransformObjectFactory:\r
2264 def __init__(self, WorkspaceDb):\r
2265 self.WorkspaceDb = WorkspaceDb\r
2266\r
2267 # key = FilePath, Arch\r
2268 def __getitem__(self, Key):\r
2269 pass\r
2270\r
2271 ## Constructor of WorkspaceDatabase\r
2272 #\r
2273 # @param DbPath Path of database file\r
2274 # @param GlobalMacros Global macros used for replacement during file parsing\r
2275 # @prarm RenewDb=False Create new database file if it's already there\r
2276 #\r
2277 def __init__(self, DbPath, GlobalMacros={}, RenewDb=False):\r
4234283c 2278 self._DbClosedFlag = False\r
52302d4d
LG
2279 self._GlobalMacros = GlobalMacros\r
2280\r
2281 if DbPath == None or DbPath == '':\r
2282 DbPath = os.path.normpath(os.path.join(GlobalData.gWorkspace, self._DB_PATH_))\r
2283\r
2284 # don't create necessary path for db in memory\r
2285 if DbPath != ':memory:':\r
2286 DbDir = os.path.split(DbPath)[0]\r
2287 if not os.path.exists(DbDir):\r
2288 os.makedirs(DbDir)\r
2289\r
2290 # remove db file in case inconsistency between db and file in file system\r
2291 if self._CheckWhetherDbNeedRenew(RenewDb, DbPath):\r
2292 os.remove(DbPath)\r
2293 \r
2294 # create db with optimized parameters\r
2295 self.Conn = sqlite3.connect(DbPath, isolation_level='DEFERRED')\r
2296 self.Conn.execute("PRAGMA synchronous=OFF")\r
2297 self.Conn.execute("PRAGMA temp_store=MEMORY")\r
2298 self.Conn.execute("PRAGMA count_changes=OFF")\r
2299 self.Conn.execute("PRAGMA cache_size=8192")\r
2300 #self.Conn.execute("PRAGMA page_size=8192")\r
2301\r
2302 # to avoid non-ascii character conversion issue\r
2303 self.Conn.text_factory = str\r
2304 self.Cur = self.Conn.cursor()\r
2305\r
2306 # create table for internal uses\r
2307 self.TblDataModel = TableDataModel(self.Cur)\r
2308 self.TblFile = TableFile(self.Cur)\r
2309\r
2310 # conversion object for build or file format conversion purpose\r
2311 self.BuildObject = WorkspaceDatabase.BuildObjectFactory(self)\r
2312 self.TransformObject = WorkspaceDatabase.TransformObjectFactory(self)\r
2313\r
2314 ## Check whether workspace database need to be renew.\r
2315 # The renew reason maybe:\r
2316 # 1) If user force to renew;\r
2317 # 2) If user do not force renew, and\r
2318 # a) If the time of last modified python source is newer than database file;\r
2319 # b) If the time of last modified frozen executable file is newer than database file;\r
2320 #\r
2321 # @param force User force renew database\r
2322 # @param DbPath The absolute path of workspace database file\r
2323 #\r
2324 # @return Bool value for whether need renew workspace databse\r
2325 #\r
2326 def _CheckWhetherDbNeedRenew (self, force, DbPath):\r
2327 DbDir = os.path.split(DbPath)[0]\r
2328 MacroFilePath = os.path.normpath(os.path.join(DbDir, "build.mac"))\r
2329 MacroMatch = False\r
2330 if os.path.exists(MacroFilePath) and os.path.isfile(MacroFilePath):\r
2331 LastMacros = None\r
2332 try:\r
2333 f = open(MacroFilePath,'r')\r
2334 LastMacros = pickle.load(f)\r
2335 f.close()\r
2336 except IOError:\r
2337 pass\r
2338 except:\r
2339 f.close()\r
2340\r
2341 if LastMacros != None and type(LastMacros) is DictType:\r
2342 if LastMacros == self._GlobalMacros:\r
2343 MacroMatch = True\r
2344 for Macro in LastMacros.keys():\r
2345 if not (Macro in self._GlobalMacros and LastMacros[Macro] == self._GlobalMacros[Macro]):\r
2346 MacroMatch = False;\r
2347 break;\r
2348\r
2349 if not MacroMatch:\r
2350 # save command line macros to file\r
2351 try:\r
2352 f = open(MacroFilePath,'w')\r
2353 pickle.dump(self._GlobalMacros, f, 2)\r
2354 f.close()\r
2355 except IOError:\r
2356 pass\r
2357 except:\r
2358 f.close()\r
2359\r
2360 force = True\r
2361\r
2362 # if database does not exist, we need do nothing\r
2363 if not os.path.exists(DbPath): return False\r
2364 \r
2365 # if user force to renew database, then not check whether database is out of date\r
2366 if force: return True\r
2367 \r
2368 # \r
2369 # Check the time of last modified source file or build.exe\r
2370 # if is newer than time of database, then database need to be re-created.\r
2371 #\r
2372 timeOfToolModified = 0\r
2373 if hasattr(sys, "frozen"):\r
2374 exePath = os.path.abspath(sys.executable)\r
2375 timeOfToolModified = os.stat(exePath).st_mtime\r
2376 else:\r
2377 curPath = os.path.dirname(__file__) # curPath is the path of WorkspaceDatabase.py\r
2378 rootPath = os.path.split(curPath)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python\r
2379 if rootPath == "" or rootPath == None:\r
2380 EdkLogger.verbose("\nFail to find the root path of build.exe or python sources, so can not \\r
2381determine whether database file is out of date!\n")\r
2382 \r
2383 # walk the root path of source or build's binary to get the time last modified.\r
2384 \r
2385 for root, dirs, files in os.walk (rootPath):\r
2386 for dir in dirs:\r
2387 # bypass source control folder \r
2388 if dir.lower() in [".svn", "_svn", "cvs"]:\r
2389 dirs.remove(dir)\r
2390 \r
2391 for file in files:\r
2392 ext = os.path.splitext(file)[1]\r
2393 if ext.lower() == ".py": # only check .py files\r
2394 fd = os.stat(os.path.join(root, file))\r
2395 if timeOfToolModified < fd.st_mtime:\r
2396 timeOfToolModified = fd.st_mtime\r
2397 if timeOfToolModified > os.stat(DbPath).st_mtime:\r
2398 EdkLogger.verbose("\nWorkspace database is out of data!")\r
2399 return True\r
2400 \r
2401 return False\r
2402 \r
2403 ## Initialize build database\r
2404 def InitDatabase(self):\r
2405 EdkLogger.verbose("\nInitialize build database started ...")\r
2406\r
2407 #\r
2408 # Create new tables\r
2409 #\r
2410 self.TblDataModel.Create(False)\r
2411 self.TblFile.Create(False)\r
2412\r
2413 #\r
2414 # Initialize table DataModel\r
2415 #\r
2416 self.TblDataModel.InitTable()\r
2417 EdkLogger.verbose("Initialize build database ... DONE!")\r
2418\r
2419 ## Query a table\r
2420 #\r
2421 # @param Table: The instance of the table to be queried\r
2422 #\r
2423 def QueryTable(self, Table):\r
2424 Table.Query()\r
2425\r
2426 ## Close entire database\r
2427 #\r
2428 # Commit all first\r
2429 # Close the connection and cursor\r
2430 #\r
2431 def Close(self):\r
4234283c
LG
2432 if not self._DbClosedFlag:\r
2433 self.Conn.commit()\r
2434 self.Cur.close()\r
2435 self.Conn.close()\r
2436 self._DbClosedFlag = True\r
52302d4d
LG
2437\r
2438 ## Get unique file ID for the gvien file\r
2439 def GetFileId(self, FilePath):\r
2440 return self.TblFile.GetFileId(FilePath)\r
2441\r
2442 ## Get file type value for the gvien file ID\r
2443 def GetFileType(self, FileId):\r
2444 return self.TblFile.GetFileType(FileId)\r
2445\r
2446 ## Get time stamp stored in file table\r
2447 def GetTimeStamp(self, FileId):\r
2448 return self.TblFile.GetFileTimeStamp(FileId)\r
2449\r
2450 ## Update time stamp in file table\r
2451 def SetTimeStamp(self, FileId, TimeStamp):\r
2452 return self.TblFile.SetFileTimeStamp(FileId, TimeStamp)\r
2453\r
2454 ## Check if a table integrity flag exists or not\r
2455 def CheckIntegrity(self, TableName):\r
2456 try:\r
2457 Result = self.Cur.execute("select min(ID) from %s" % (TableName)).fetchall()\r
2458 if Result[0][0] != -1:\r
2459 return False\r
9053bc51 2460 #\r
2461 # Check whether the meta data file has external dependency by comparing the time stamp\r
2462 #\r
2463 Sql = "select Value1, Value2 from %s where Model=%d" % (TableName, MODEL_EXTERNAL_DEPENDENCY)\r
2464 for Dependency in self.Cur.execute(Sql).fetchall():\r
2465 if str(os.stat(Dependency[0])[8]) != Dependency[1]:\r
2466 return False\r
52302d4d
LG
2467 except:\r
2468 return False\r
2469 return True\r
2470\r
2471 ## Compose table name for given file type and file ID\r
2472 def GetTableName(self, FileType, FileId):\r
2473 return "_%s_%s" % (FileType, FileId)\r
2474\r
2475 ## Return a temp table containing all content of the given file\r
2476 #\r
2477 # @param FileInfo The tuple containing path and type of a file\r
2478 #\r
2479 def __getitem__(self, FileInfo):\r
2480 FilePath, FileType, Macros = FileInfo\r
2481 if FileType not in self._FILE_TABLE_:\r
2482 return None\r
2483\r
2484 # flag used to indicate if it's parsed or not\r
2485 FilePath = str(FilePath)\r
2486 Parsed = False\r
2487 FileId = self.GetFileId(FilePath)\r
2488 if FileId != None:\r
2489 TimeStamp = os.stat(FilePath)[8]\r
2490 TableName = self.GetTableName(FileType, FileId)\r
2491 if TimeStamp != self.GetTimeStamp(FileId):\r
2492 # update the timestamp in database\r
2493 self.SetTimeStamp(FileId, TimeStamp)\r
2494 else:\r
2495 # if the table exists and is integrity, don't parse it\r
2496 Parsed = self.CheckIntegrity(TableName)\r
2497 else:\r
2498 FileId = self.TblFile.InsertFile(FilePath, FileType)\r
2499 TableName = self.GetTableName(FileType, FileId)\r
2500\r
2501 FileTable = self._FILE_TABLE_[FileType](self.Cur, TableName, FileId)\r
2502 FileTable.Create(not Parsed)\r
2503 Parser = self._FILE_PARSER_[FileType](FilePath, FileType, FileTable, Macros)\r
2504 # set the "Finished" flag in parser in order to avoid re-parsing (if parsed)\r
2505 Parser.Finished = Parsed\r
2506 return Parser\r
2507\r
2508 ## Summarize all packages in the database\r
2509 def _GetPackageList(self):\r
2510 PackageList = []\r
2511 for Module in self.ModuleList:\r
2512 for Package in Module.Packages:\r
2513 if Package not in PackageList:\r
2514 PackageList.append(Package)\r
2515 return PackageList\r
2516\r
2517 ## Summarize all platforms in the database\r
2518 def _GetPlatformList(self):\r
2519 PlatformList = []\r
2520 for PlatformFile in self.TblFile.GetFileList(MODEL_FILE_DSC):\r
2521 try:\r
2522 Platform = self.BuildObject[PathClass(PlatformFile), 'COMMON']\r
2523 except:\r
2524 Platform = None\r
2525 if Platform != None:\r
2526 PlatformList.append(Platform)\r
2527 return PlatformList\r
2528\r
2529 ## Summarize all modules in the database\r
2530 def _GetModuleList(self):\r
2531 ModuleList = []\r
2532 for ModuleFile in self.TblFile.GetFileList(MODEL_FILE_INF):\r
2533 try:\r
2534 Module = self.BuildObject[PathClass(ModuleFile), 'COMMON']\r
2535 except:\r
2536 Module = None\r
2537 if Module != None:\r
2538 ModuleList.append(Module)\r
2539 return ModuleList\r
2540\r
2541 PlatformList = property(_GetPlatformList)\r
2542 PackageList = property(_GetPackageList)\r
2543 ModuleList = property(_GetModuleList)\r
2544\r
2545##\r
2546#\r
2547# This acts like the main() function for the script, unless it is 'import'ed into another\r
2548# script.\r
2549#\r
2550if __name__ == '__main__':\r
2551 pass\r
2552\r