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