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