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