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