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