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