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