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