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