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