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