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