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