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