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