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