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