]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
46179a39e9b5a6427eab28b4aa93ba58e843f0fc
[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 PublicNameList = []
1414 # find out all protocol definitions for specific and 'common' arch
1415 RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch]
1416 for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
1417 if PrivateFlag == 'PRIVATE':
1418 if Name not in PrivateNameList:
1419 PrivateNameList.append(Name)
1420 PrivateProtocolDict[Arch, Name] = Guid
1421 if Name in PublicNameList:
1422 EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
1423 else:
1424 if Name not in PublicNameList:
1425 PublicNameList.append(Name)
1426 if Name in PrivateNameList:
1427 EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
1428 if Name not in NameList:
1429 NameList.append(Name)
1430 ProtocolDict[Arch, Name] = Guid
1431 # use sdict to keep the order
1432 self._Protocols = sdict()
1433 self._PrivateProtocols = sdict()
1434 for Name in NameList:
1435 #
1436 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1437 # will automatically turn to 'common' ARCH for trying
1438 #
1439 self._Protocols[Name] = ProtocolDict[self._Arch, Name]
1440 for Name in PrivateNameList:
1441 self._PrivateProtocols[Name] = PrivateProtocolDict[self._Arch, Name]
1442 return self._Protocols
1443
1444 ## Retrieve PPI definitions (name/value pairs)
1445 def _GetPpi(self):
1446 if self._Ppis == None:
1447 #
1448 # tdict is a special kind of dict, used for selecting correct
1449 # PPI defition for given ARCH
1450 #
1451 PpiDict = tdict(True)
1452 PrivatePpiDict = tdict(True)
1453 NameList = []
1454 PrivateNameList = []
1455 PublicNameList = []
1456 # find out all PPI definitions for specific arch and 'common' arch
1457 RecordList = self._RawData[MODEL_EFI_PPI, self._Arch]
1458 for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
1459 if PrivateFlag == 'PRIVATE':
1460 if Name not in PrivateNameList:
1461 PrivateNameList.append(Name)
1462 PrivatePpiDict[Arch, Name] = Guid
1463 if Name in PublicNameList:
1464 EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
1465 else:
1466 if Name not in PublicNameList:
1467 PublicNameList.append(Name)
1468 if Name in PrivateNameList:
1469 EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
1470 if Name not in NameList:
1471 NameList.append(Name)
1472 PpiDict[Arch, Name] = Guid
1473 # use sdict to keep the order
1474 self._Ppis = sdict()
1475 self._PrivatePpis = sdict()
1476 for Name in NameList:
1477 #
1478 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1479 # will automatically turn to 'common' ARCH for trying
1480 #
1481 self._Ppis[Name] = PpiDict[self._Arch, Name]
1482 for Name in PrivateNameList:
1483 self._PrivatePpis[Name] = PrivatePpiDict[self._Arch, Name]
1484 return self._Ppis
1485
1486 ## Retrieve GUID definitions (name/value pairs)
1487 def _GetGuid(self):
1488 if self._Guids == None:
1489 #
1490 # tdict is a special kind of dict, used for selecting correct
1491 # GUID defition for given ARCH
1492 #
1493 GuidDict = tdict(True)
1494 PrivateGuidDict = tdict(True)
1495 NameList = []
1496 PrivateNameList = []
1497 PublicNameList = []
1498 # find out all protocol definitions for specific and 'common' arch
1499 RecordList = self._RawData[MODEL_EFI_GUID, self._Arch]
1500 for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
1501 if PrivateFlag == 'PRIVATE':
1502 if Name not in PrivateNameList:
1503 PrivateNameList.append(Name)
1504 PrivateGuidDict[Arch, Name] = Guid
1505 if Name in PublicNameList:
1506 EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
1507 else:
1508 if Name not in PublicNameList:
1509 PublicNameList.append(Name)
1510 if Name in PrivateNameList:
1511 EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
1512 if Name not in NameList:
1513 NameList.append(Name)
1514 GuidDict[Arch, Name] = Guid
1515 # use sdict to keep the order
1516 self._Guids = sdict()
1517 self._PrivateGuids = sdict()
1518 for Name in NameList:
1519 #
1520 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1521 # will automatically turn to 'common' ARCH for trying
1522 #
1523 self._Guids[Name] = GuidDict[self._Arch, Name]
1524 for Name in PrivateNameList:
1525 self._PrivateGuids[Name] = PrivateGuidDict[self._Arch, Name]
1526 return self._Guids
1527
1528 ## Retrieve public include paths declared in this package
1529 def _GetInclude(self):
1530 if self._Includes == None:
1531 self._Includes = []
1532 self._PrivateIncludes = []
1533 PublicInclues = []
1534 RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch]
1535 Macros = self._Macros
1536 Macros["EDK_SOURCE"] = GlobalData.gEcpSource
1537 for Record in RecordList:
1538 File = PathClass(NormPath(Record[0], Macros), self._PackageDir, Arch=self._Arch)
1539 LineNo = Record[-1]
1540 # validate the path
1541 ErrorCode, ErrorInfo = File.Validate()
1542 if ErrorCode != 0:
1543 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
1544
1545 # avoid duplicate include path
1546 if File not in self._Includes:
1547 self._Includes.append(File)
1548 if Record[4] == 'PRIVATE':
1549 if File not in self._PrivateIncludes:
1550 self._PrivateIncludes.append(File)
1551 if File in PublicInclues:
1552 EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % File, File=self.MetaFile, Line=LineNo)
1553 else:
1554 if File not in PublicInclues:
1555 PublicInclues.append(File)
1556 if File in self._PrivateIncludes:
1557 EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % File, File=self.MetaFile, Line=LineNo)
1558
1559 return self._Includes
1560
1561 ## Retrieve library class declarations (not used in build at present)
1562 def _GetLibraryClass(self):
1563 if self._LibraryClasses == None:
1564 #
1565 # tdict is a special kind of dict, used for selecting correct
1566 # library class declaration for given ARCH
1567 #
1568 LibraryClassDict = tdict(True)
1569 LibraryClassSet = set()
1570 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch]
1571 Macros = self._Macros
1572 for LibraryClass, File, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
1573 File = PathClass(NormPath(File, Macros), self._PackageDir, Arch=self._Arch)
1574 # check the file validation
1575 ErrorCode, ErrorInfo = File.Validate()
1576 if ErrorCode != 0:
1577 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
1578 LibraryClassSet.add(LibraryClass)
1579 LibraryClassDict[Arch, LibraryClass] = File
1580 self._LibraryClasses = sdict()
1581 for LibraryClass in LibraryClassSet:
1582 self._LibraryClasses[LibraryClass] = LibraryClassDict[self._Arch, LibraryClass]
1583 return self._LibraryClasses
1584
1585 ## Retrieve PCD declarations
1586 def _GetPcds(self):
1587 if self._Pcds == None:
1588 self._Pcds = sdict()
1589 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))
1590 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))
1591 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))
1592 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC))
1593 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))
1594 return self._Pcds
1595
1596 ## Retrieve PCD declarations for given type
1597 def _GetPcd(self, Type):
1598 Pcds = sdict()
1599 #
1600 # tdict is a special kind of dict, used for selecting correct
1601 # PCD declaration for given ARCH
1602 #
1603 PcdDict = tdict(True, 3)
1604 # for summarizing PCD
1605 PcdSet = set()
1606 # find out all PCDs of the 'type'
1607 RecordList = self._RawData[Type, self._Arch]
1608 for TokenSpaceGuid, PcdCName, Setting, Arch, PrivateFlag, Dummy1, Dummy2 in RecordList:
1609 PcdDict[Arch, PcdCName, TokenSpaceGuid] = Setting
1610 PcdSet.add((PcdCName, TokenSpaceGuid))
1611
1612 for PcdCName, TokenSpaceGuid in PcdSet:
1613 #
1614 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1615 # will automatically turn to 'common' ARCH and try again
1616 #
1617 Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid]
1618 if Setting == None:
1619 continue
1620
1621 DefaultValue, DatumType, TokenNumber = AnalyzePcdData(Setting)
1622
1623 validateranges, validlists, expressions = self._RawData.GetValidExpression(TokenSpaceGuid, PcdCName)
1624 Pcds[PcdCName, TokenSpaceGuid, self._PCD_TYPE_STRING_[Type]] = PcdClassObject(
1625 PcdCName,
1626 TokenSpaceGuid,
1627 self._PCD_TYPE_STRING_[Type],
1628 DatumType,
1629 DefaultValue,
1630 TokenNumber,
1631 '',
1632 {},
1633 False,
1634 None,
1635 list(validateranges),
1636 list(validlists),
1637 list(expressions)
1638 )
1639 return Pcds
1640
1641
1642 _Macros = property(_GetMacros)
1643 Arch = property(_GetArch, _SetArch)
1644 PackageName = property(_GetPackageName)
1645 Guid = property(_GetFileGuid)
1646 Version = property(_GetVersion)
1647
1648 Protocols = property(_GetProtocol)
1649 Ppis = property(_GetPpi)
1650 Guids = property(_GetGuid)
1651 Includes = property(_GetInclude)
1652 LibraryClasses = property(_GetLibraryClass)
1653 Pcds = property(_GetPcds)
1654
1655 ## Module build information from INF file
1656 #
1657 # This class is used to retrieve information stored in database and convert them
1658 # into ModuleBuildClassObject form for easier use for AutoGen.
1659 #
1660 class InfBuildData(ModuleBuildClassObject):
1661 # dict used to convert PCD type in database to string used by build tool
1662 _PCD_TYPE_STRING_ = {
1663 MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild",
1664 MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule",
1665 MODEL_PCD_FEATURE_FLAG : "FeatureFlag",
1666 MODEL_PCD_DYNAMIC : "Dynamic",
1667 MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic",
1668 MODEL_PCD_DYNAMIC_HII : "DynamicHii",
1669 MODEL_PCD_DYNAMIC_VPD : "DynamicVpd",
1670 MODEL_PCD_DYNAMIC_EX : "DynamicEx",
1671 MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx",
1672 MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii",
1673 MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd",
1674 }
1675
1676 # dict used to convert part of [Defines] to members of InfBuildData directly
1677 _PROPERTY_ = {
1678 #
1679 # Required Fields
1680 #
1681 TAB_INF_DEFINES_BASE_NAME : "_BaseName",
1682 TAB_INF_DEFINES_FILE_GUID : "_Guid",
1683 TAB_INF_DEFINES_MODULE_TYPE : "_ModuleType",
1684 #
1685 # Optional Fields
1686 #
1687 #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
1688 TAB_INF_DEFINES_COMPONENT_TYPE : "_ComponentType",
1689 TAB_INF_DEFINES_MAKEFILE_NAME : "_MakefileName",
1690 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
1691 TAB_INF_DEFINES_DPX_SOURCE :"_DxsFile",
1692 TAB_INF_DEFINES_VERSION_NUMBER : "_Version",
1693 TAB_INF_DEFINES_VERSION_STRING : "_Version",
1694 TAB_INF_DEFINES_VERSION : "_Version",
1695 TAB_INF_DEFINES_PCD_IS_DRIVER : "_PcdIsDriver",
1696 TAB_INF_DEFINES_SHADOW : "_Shadow",
1697
1698 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH : "_SourceOverridePath",
1699 }
1700
1701 # dict used to convert Component type to Module type
1702 _MODULE_TYPE_ = {
1703 "LIBRARY" : "BASE",
1704 "SECURITY_CORE" : "SEC",
1705 "PEI_CORE" : "PEI_CORE",
1706 "COMBINED_PEIM_DRIVER" : "PEIM",
1707 "PIC_PEIM" : "PEIM",
1708 "RELOCATABLE_PEIM" : "PEIM",
1709 "PE32_PEIM" : "PEIM",
1710 "BS_DRIVER" : "DXE_DRIVER",
1711 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
1712 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
1713 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
1714 # "SMM_DRIVER" : "DXE_SMM_DRIVER",
1715 # "BS_DRIVER" : "DXE_SMM_DRIVER",
1716 # "BS_DRIVER" : "UEFI_DRIVER",
1717 "APPLICATION" : "UEFI_APPLICATION",
1718 "LOGO" : "BASE",
1719 }
1720
1721 # regular expression for converting XXX_FLAGS in [nmake] section to new type
1722 _NMAKE_FLAG_PATTERN_ = re.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re.UNICODE)
1723 # dict used to convert old tool name used in [nmake] section to new ones
1724 _TOOL_CODE_ = {
1725 "C" : "CC",
1726 "LIB" : "SLINK",
1727 "LINK" : "DLINK",
1728 }
1729
1730
1731 ## Constructor of DscBuildData
1732 #
1733 # Initialize object of DscBuildData
1734 #
1735 # @param FilePath The path of platform description file
1736 # @param RawData The raw data of DSC file
1737 # @param BuildDataBase Database used to retrieve module/package information
1738 # @param Arch The target architecture
1739 # @param Platform The name of platform employing this module
1740 # @param Macros Macros used for replacement in DSC file
1741 #
1742 def __init__(self, FilePath, RawData, BuildDatabase, Arch='COMMON', Target=None, Toolchain=None):
1743 self.MetaFile = FilePath
1744 self._ModuleDir = FilePath.Dir
1745 self._RawData = RawData
1746 self._Bdb = BuildDatabase
1747 self._Arch = Arch
1748 self._Target = Target
1749 self._Toolchain = Toolchain
1750 self._Platform = 'COMMON'
1751 self._SourceOverridePath = None
1752 if FilePath.Key in GlobalData.gOverrideDir:
1753 self._SourceOverridePath = GlobalData.gOverrideDir[FilePath.Key]
1754 self._Clear()
1755
1756 ## XXX[key] = value
1757 def __setitem__(self, key, value):
1758 self.__dict__[self._PROPERTY_[key]] = value
1759
1760 ## value = XXX[key]
1761 def __getitem__(self, key):
1762 return self.__dict__[self._PROPERTY_[key]]
1763
1764 ## "in" test support
1765 def __contains__(self, key):
1766 return key in self._PROPERTY_
1767
1768 ## Set all internal used members of InfBuildData to None
1769 def _Clear(self):
1770 self._HeaderComments = None
1771 self._TailComments = None
1772 self._Header_ = None
1773 self._AutoGenVersion = None
1774 self._BaseName = None
1775 self._DxsFile = None
1776 self._ModuleType = None
1777 self._ComponentType = None
1778 self._BuildType = None
1779 self._Guid = None
1780 self._Version = None
1781 self._PcdIsDriver = None
1782 self._BinaryModule = None
1783 self._Shadow = None
1784 self._MakefileName = None
1785 self._CustomMakefile = None
1786 self._Specification = None
1787 self._LibraryClass = None
1788 self._ModuleEntryPointList = None
1789 self._ModuleUnloadImageList = None
1790 self._ConstructorList = None
1791 self._DestructorList = None
1792 self._Defs = None
1793 self._Binaries = None
1794 self._Sources = None
1795 self._LibraryClasses = None
1796 self._Libraries = None
1797 self._Protocols = None
1798 self._ProtocolComments = None
1799 self._Ppis = None
1800 self._PpiComments = None
1801 self._Guids = None
1802 self._GuidsUsedByPcd = sdict()
1803 self._GuidComments = None
1804 self._Includes = None
1805 self._Packages = None
1806 self._Pcds = None
1807 self._PcdComments = None
1808 self._BuildOptions = None
1809 self._Depex = None
1810 self._DepexExpression = None
1811 self.__Macros = None
1812
1813 ## Get current effective macros
1814 def _GetMacros(self):
1815 if self.__Macros == None:
1816 self.__Macros = {}
1817 # EDK_GLOBAL defined macros can be applied to EDK module
1818 if self.AutoGenVersion < 0x00010005:
1819 self.__Macros.update(GlobalData.gEdkGlobal)
1820 self.__Macros.update(GlobalData.gGlobalDefines)
1821 return self.__Macros
1822
1823 ## Get architecture
1824 def _GetArch(self):
1825 return self._Arch
1826
1827 ## Set architecture
1828 #
1829 # Changing the default ARCH to another may affect all other information
1830 # because all information in a platform may be ARCH-related. That's
1831 # why we need to clear all internal used members, in order to cause all
1832 # information to be re-retrieved.
1833 #
1834 # @param Value The value of ARCH
1835 #
1836 def _SetArch(self, Value):
1837 if self._Arch == Value:
1838 return
1839 self._Arch = Value
1840 self._Clear()
1841
1842 ## Return the name of platform employing this module
1843 def _GetPlatform(self):
1844 return self._Platform
1845
1846 ## Change the name of platform employing this module
1847 #
1848 # Changing the default name of platform to another may affect some information
1849 # because they may be PLATFORM-related. That's why we need to clear all internal
1850 # used members, in order to cause all information to be re-retrieved.
1851 #
1852 def _SetPlatform(self, Value):
1853 if self._Platform == Value:
1854 return
1855 self._Platform = Value
1856 self._Clear()
1857 def _GetHeaderComments(self):
1858 if not self._HeaderComments:
1859 self._HeaderComments = []
1860 RecordList = self._RawData[MODEL_META_DATA_HEADER_COMMENT]
1861 for Record in RecordList:
1862 self._HeaderComments.append(Record[0])
1863 return self._HeaderComments
1864 def _GetTailComments(self):
1865 if not self._TailComments:
1866 self._TailComments = []
1867 RecordList = self._RawData[MODEL_META_DATA_TAIL_COMMENT]
1868 for Record in RecordList:
1869 self._TailComments.append(Record[0])
1870 return self._TailComments
1871 ## Retrieve all information in [Defines] section
1872 #
1873 # (Retriving all [Defines] information in one-shot is just to save time.)
1874 #
1875 def _GetHeaderInfo(self):
1876 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]
1877 for Record in RecordList:
1878 Name, Value = Record[1], ReplaceMacro(Record[2], self._Macros, False)
1879 # items defined _PROPERTY_ don't need additional processing
1880 if Name in self:
1881 self[Name] = Value
1882 if self._Defs == None:
1883 self._Defs = sdict()
1884 self._Defs[Name] = Value
1885 # some special items in [Defines] section need special treatment
1886 elif Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
1887 if Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
1888 Name = 'UEFI_SPECIFICATION_VERSION'
1889 if self._Specification == None:
1890 self._Specification = sdict()
1891 self._Specification[Name] = GetHexVerValue(Value)
1892 if self._Specification[Name] == None:
1893 EdkLogger.error("build", FORMAT_NOT_SUPPORTED,
1894 "'%s' format is not supported for %s" % (Value, Name),
1895 File=self.MetaFile, Line=Record[-1])
1896 elif Name == 'LIBRARY_CLASS':
1897 if self._LibraryClass == None:
1898 self._LibraryClass = []
1899 ValueList = GetSplitValueList(Value)
1900 LibraryClass = ValueList[0]
1901 if len(ValueList) > 1:
1902 SupModuleList = GetSplitValueList(ValueList[1], ' ')
1903 else:
1904 SupModuleList = SUP_MODULE_LIST
1905 self._LibraryClass.append(LibraryClassObject(LibraryClass, SupModuleList))
1906 elif Name == 'ENTRY_POINT':
1907 if self._ModuleEntryPointList == None:
1908 self._ModuleEntryPointList = []
1909 self._ModuleEntryPointList.append(Value)
1910 elif Name == 'UNLOAD_IMAGE':
1911 if self._ModuleUnloadImageList == None:
1912 self._ModuleUnloadImageList = []
1913 if not Value:
1914 continue
1915 self._ModuleUnloadImageList.append(Value)
1916 elif Name == 'CONSTRUCTOR':
1917 if self._ConstructorList == None:
1918 self._ConstructorList = []
1919 if not Value:
1920 continue
1921 self._ConstructorList.append(Value)
1922 elif Name == 'DESTRUCTOR':
1923 if self._DestructorList == None:
1924 self._DestructorList = []
1925 if not Value:
1926 continue
1927 self._DestructorList.append(Value)
1928 elif Name == TAB_INF_DEFINES_CUSTOM_MAKEFILE:
1929 TokenList = GetSplitValueList(Value)
1930 if self._CustomMakefile == None:
1931 self._CustomMakefile = {}
1932 if len(TokenList) < 2:
1933 self._CustomMakefile['MSFT'] = TokenList[0]
1934 self._CustomMakefile['GCC'] = TokenList[0]
1935 else:
1936 if TokenList[0] not in ['MSFT', 'GCC']:
1937 EdkLogger.error("build", FORMAT_NOT_SUPPORTED,
1938 "No supported family [%s]" % TokenList[0],
1939 File=self.MetaFile, Line=Record[-1])
1940 self._CustomMakefile[TokenList[0]] = TokenList[1]
1941 else:
1942 if self._Defs == None:
1943 self._Defs = sdict()
1944 self._Defs[Name] = Value
1945
1946 #
1947 # Retrieve information in sections specific to Edk.x modules
1948 #
1949 if self.AutoGenVersion >= 0x00010005:
1950 if not self._ModuleType:
1951 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,
1952 "MODULE_TYPE is not given", File=self.MetaFile)
1953 if self._ModuleType not in SUP_MODULE_LIST:
1954 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]
1955 for Record in RecordList:
1956 Name = Record[1]
1957 if Name == "MODULE_TYPE":
1958 LineNo = Record[6]
1959 break
1960 EdkLogger.error("build", FORMAT_NOT_SUPPORTED,
1961 "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self._ModuleType, ' '.join(l for l in SUP_MODULE_LIST)),
1962 File=self.MetaFile, Line=LineNo)
1963 if (self._Specification == None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (int(self._Specification['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
1964 if self._ModuleType == SUP_MODULE_SMM_CORE:
1965 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)
1966 if self._Defs and 'PCI_DEVICE_ID' in self._Defs and 'PCI_VENDOR_ID' in self._Defs \
1967 and 'PCI_CLASS_CODE' in self._Defs and 'PCI_REVISION' in self._Defs:
1968 self._BuildType = 'UEFI_OPTIONROM'
1969 if 'PCI_COMPRESS' in self._Defs:
1970 if self._Defs['PCI_COMPRESS'] not in ('TRUE', 'FALSE'):
1971 EdkLogger.error("build", FORMAT_INVALID, "Expected TRUE/FALSE for PCI_COMPRESS: %s" %self.MetaFile)
1972
1973 elif self._Defs and 'UEFI_HII_RESOURCE_SECTION' in self._Defs \
1974 and self._Defs['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
1975 self._BuildType = 'UEFI_HII'
1976 else:
1977 self._BuildType = self._ModuleType.upper()
1978
1979 if self._DxsFile:
1980 File = PathClass(NormPath(self._DxsFile), self._ModuleDir, Arch=self._Arch)
1981 # check the file validation
1982 ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)
1983 if ErrorCode != 0:
1984 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,
1985 File=self.MetaFile, Line=LineNo)
1986 if self.Sources == None:
1987 self._Sources = []
1988 self._Sources.append(File)
1989 else:
1990 if not self._ComponentType:
1991 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,
1992 "COMPONENT_TYPE is not given", File=self.MetaFile)
1993 self._BuildType = self._ComponentType.upper()
1994 if self._ComponentType in self._MODULE_TYPE_:
1995 self._ModuleType = self._MODULE_TYPE_[self._ComponentType]
1996 if self._ComponentType == 'LIBRARY':
1997 self._LibraryClass = [LibraryClassObject(self._BaseName, SUP_MODULE_LIST)]
1998 # make use some [nmake] section macros
1999 Macros = self._Macros
2000 Macros["EDK_SOURCE"] = GlobalData.gEcpSource
2001 Macros['PROCESSOR'] = self._Arch
2002 RecordList = self._RawData[MODEL_META_DATA_NMAKE, self._Arch, self._Platform]
2003 for Name, Value, Dummy, Arch, Platform, ID, LineNo in RecordList:
2004 Value = ReplaceMacro(Value, Macros, True)
2005 if Name == "IMAGE_ENTRY_POINT":
2006 if self._ModuleEntryPointList == None:
2007 self._ModuleEntryPointList = []
2008 self._ModuleEntryPointList.append(Value)
2009 elif Name == "DPX_SOURCE":
2010 File = PathClass(NormPath(Value), self._ModuleDir, Arch=self._Arch)
2011 # check the file validation
2012 ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)
2013 if ErrorCode != 0:
2014 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,
2015 File=self.MetaFile, Line=LineNo)
2016 if self.Sources == None:
2017 self._Sources = []
2018 self._Sources.append(File)
2019 else:
2020 ToolList = self._NMAKE_FLAG_PATTERN_.findall(Name)
2021 if len(ToolList) == 0 or len(ToolList) != 1:
2022 pass
2023 # EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
2024 # File=self.MetaFile, Line=LineNo)
2025 else:
2026 if self._BuildOptions == None:
2027 self._BuildOptions = sdict()
2028
2029 if ToolList[0] in self._TOOL_CODE_:
2030 Tool = self._TOOL_CODE_[ToolList[0]]
2031 else:
2032 Tool = ToolList[0]
2033 ToolChain = "*_*_*_%s_FLAGS" % Tool
2034 ToolChainFamily = 'MSFT' # Edk.x only support MSFT tool chain
2035 #ignore not replaced macros in value
2036 ValueList = GetSplitList(' ' + Value, '/D')
2037 Dummy = ValueList[0]
2038 for Index in range(1, len(ValueList)):
2039 if ValueList[Index][-1] == '=' or ValueList[Index] == '':
2040 continue
2041 Dummy = Dummy + ' /D ' + ValueList[Index]
2042 Value = Dummy.strip()
2043 if (ToolChainFamily, ToolChain) not in self._BuildOptions:
2044 self._BuildOptions[ToolChainFamily, ToolChain] = Value
2045 else:
2046 OptionString = self._BuildOptions[ToolChainFamily, ToolChain]
2047 self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Value
2048 # set _Header to non-None in order to avoid database re-querying
2049 self._Header_ = 'DUMMY'
2050
2051 ## Retrieve file version
2052 def _GetInfVersion(self):
2053 if self._AutoGenVersion == None:
2054 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]
2055 for Record in RecordList:
2056 if Record[1] == TAB_INF_DEFINES_INF_VERSION:
2057 if '.' in Record[2]:
2058 ValueList = Record[2].split('.')
2059 Major = '%04o' % int(ValueList[0], 0)
2060 Minor = '%04o' % int(ValueList[1], 0)
2061 self._AutoGenVersion = int('0x' + Major + Minor, 0)
2062 else:
2063 self._AutoGenVersion = int(Record[2], 0)
2064 break
2065 if self._AutoGenVersion == None:
2066 self._AutoGenVersion = 0x00010000
2067 return self._AutoGenVersion
2068
2069 ## Retrieve BASE_NAME
2070 def _GetBaseName(self):
2071 if self._BaseName == None:
2072 if self._Header_ == None:
2073 self._GetHeaderInfo()
2074 if self._BaseName == None:
2075 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BASE_NAME name", File=self.MetaFile)
2076 return self._BaseName
2077
2078 ## Retrieve DxsFile
2079 def _GetDxsFile(self):
2080 if self._DxsFile == None:
2081 if self._Header_ == None:
2082 self._GetHeaderInfo()
2083 if self._DxsFile == None:
2084 self._DxsFile = ''
2085 return self._DxsFile
2086
2087 ## Retrieve MODULE_TYPE
2088 def _GetModuleType(self):
2089 if self._ModuleType == None:
2090 if self._Header_ == None:
2091 self._GetHeaderInfo()
2092 if self._ModuleType == None:
2093 self._ModuleType = 'BASE'
2094 if self._ModuleType not in SUP_MODULE_LIST:
2095 self._ModuleType = "USER_DEFINED"
2096 return self._ModuleType
2097
2098 ## Retrieve COMPONENT_TYPE
2099 def _GetComponentType(self):
2100 if self._ComponentType == None:
2101 if self._Header_ == None:
2102 self._GetHeaderInfo()
2103 if self._ComponentType == None:
2104 self._ComponentType = 'USER_DEFINED'
2105 return self._ComponentType
2106
2107 ## Retrieve "BUILD_TYPE"
2108 def _GetBuildType(self):
2109 if self._BuildType == None:
2110 if self._Header_ == None:
2111 self._GetHeaderInfo()
2112 if not self._BuildType:
2113 self._BuildType = "BASE"
2114 return self._BuildType
2115
2116 ## Retrieve file guid
2117 def _GetFileGuid(self):
2118 if self._Guid == None:
2119 if self._Header_ == None:
2120 self._GetHeaderInfo()
2121 if self._Guid == None:
2122 self._Guid = '00000000-0000-0000-0000-000000000000'
2123 return self._Guid
2124
2125 ## Retrieve module version
2126 def _GetVersion(self):
2127 if self._Version == None:
2128 if self._Header_ == None:
2129 self._GetHeaderInfo()
2130 if self._Version == None:
2131 self._Version = '0.0'
2132 return self._Version
2133
2134 ## Retrieve PCD_IS_DRIVER
2135 def _GetPcdIsDriver(self):
2136 if self._PcdIsDriver == None:
2137 if self._Header_ == None:
2138 self._GetHeaderInfo()
2139 if self._PcdIsDriver == None:
2140 self._PcdIsDriver = ''
2141 return self._PcdIsDriver
2142
2143 ## Retrieve SHADOW
2144 def _GetShadow(self):
2145 if self._Shadow == None:
2146 if self._Header_ == None:
2147 self._GetHeaderInfo()
2148 if self._Shadow != None and self._Shadow.upper() == 'TRUE':
2149 self._Shadow = True
2150 else:
2151 self._Shadow = False
2152 return self._Shadow
2153
2154 ## Retrieve CUSTOM_MAKEFILE
2155 def _GetMakefile(self):
2156 if self._CustomMakefile == None:
2157 if self._Header_ == None:
2158 self._GetHeaderInfo()
2159 if self._CustomMakefile == None:
2160 self._CustomMakefile = {}
2161 return self._CustomMakefile
2162
2163 ## Retrieve EFI_SPECIFICATION_VERSION
2164 def _GetSpec(self):
2165 if self._Specification == None:
2166 if self._Header_ == None:
2167 self._GetHeaderInfo()
2168 if self._Specification == None:
2169 self._Specification = {}
2170 return self._Specification
2171
2172 ## Retrieve LIBRARY_CLASS
2173 def _GetLibraryClass(self):
2174 if self._LibraryClass == None:
2175 if self._Header_ == None:
2176 self._GetHeaderInfo()
2177 if self._LibraryClass == None:
2178 self._LibraryClass = []
2179 return self._LibraryClass
2180
2181 ## Retrieve ENTRY_POINT
2182 def _GetEntryPoint(self):
2183 if self._ModuleEntryPointList == None:
2184 if self._Header_ == None:
2185 self._GetHeaderInfo()
2186 if self._ModuleEntryPointList == None:
2187 self._ModuleEntryPointList = []
2188 return self._ModuleEntryPointList
2189
2190 ## Retrieve UNLOAD_IMAGE
2191 def _GetUnloadImage(self):
2192 if self._ModuleUnloadImageList == None:
2193 if self._Header_ == None:
2194 self._GetHeaderInfo()
2195 if self._ModuleUnloadImageList == None:
2196 self._ModuleUnloadImageList = []
2197 return self._ModuleUnloadImageList
2198
2199 ## Retrieve CONSTRUCTOR
2200 def _GetConstructor(self):
2201 if self._ConstructorList == None:
2202 if self._Header_ == None:
2203 self._GetHeaderInfo()
2204 if self._ConstructorList == None:
2205 self._ConstructorList = []
2206 return self._ConstructorList
2207
2208 ## Retrieve DESTRUCTOR
2209 def _GetDestructor(self):
2210 if self._DestructorList == None:
2211 if self._Header_ == None:
2212 self._GetHeaderInfo()
2213 if self._DestructorList == None:
2214 self._DestructorList = []
2215 return self._DestructorList
2216
2217 ## Retrieve definies other than above ones
2218 def _GetDefines(self):
2219 if self._Defs == None:
2220 if self._Header_ == None:
2221 self._GetHeaderInfo()
2222 if self._Defs == None:
2223 self._Defs = sdict()
2224 return self._Defs
2225
2226 ## Retrieve binary files
2227 def _GetBinaries(self):
2228 if self._Binaries == None:
2229 self._Binaries = []
2230 RecordList = self._RawData[MODEL_EFI_BINARY_FILE, self._Arch, self._Platform]
2231 Macros = self._Macros
2232 Macros["EDK_SOURCE"] = GlobalData.gEcpSource
2233 Macros['PROCESSOR'] = self._Arch
2234 for Record in RecordList:
2235 FileType = Record[0]
2236 LineNo = Record[-1]
2237 Target = 'COMMON'
2238 FeatureFlag = []
2239 if Record[2]:
2240 TokenList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)
2241 if TokenList:
2242 Target = TokenList[0]
2243 if len(TokenList) > 1:
2244 FeatureFlag = Record[1:]
2245
2246 File = PathClass(NormPath(Record[1], Macros), self._ModuleDir, '', FileType, True, self._Arch, '', Target)
2247 # check the file validation
2248 ErrorCode, ErrorInfo = File.Validate()
2249 if ErrorCode != 0:
2250 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
2251 self._Binaries.append(File)
2252 return self._Binaries
2253
2254 ## Retrieve binary files with error check.
2255 def _GetBinaryFiles(self):
2256 Binaries = self._GetBinaries()
2257 if GlobalData.gIgnoreSource and Binaries == []:
2258 ErrorInfo = "The INF file does not contain any Binaries to use in creating the image\n"
2259 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, ExtraData=ErrorInfo, File=self.MetaFile)
2260
2261 return Binaries
2262 ## Check whether it exists the binaries with current ARCH in AsBuild INF
2263 def _IsSupportedArch(self):
2264 if self._GetBinaries() and not self._GetSourceFiles():
2265 return True
2266 else:
2267 return False
2268 ## Retrieve source files
2269 def _GetSourceFiles(self):
2270 #Ignore all source files in a binary build mode
2271 if GlobalData.gIgnoreSource:
2272 self._Sources = []
2273 return self._Sources
2274
2275 if self._Sources == None:
2276 self._Sources = []
2277 RecordList = self._RawData[MODEL_EFI_SOURCE_FILE, self._Arch, self._Platform]
2278 Macros = self._Macros
2279 for Record in RecordList:
2280 LineNo = Record[-1]
2281 ToolChainFamily = Record[1]
2282 TagName = Record[2]
2283 ToolCode = Record[3]
2284 FeatureFlag = Record[4]
2285 if self.AutoGenVersion < 0x00010005:
2286 Macros["EDK_SOURCE"] = GlobalData.gEcpSource
2287 Macros['PROCESSOR'] = self._Arch
2288 SourceFile = NormPath(Record[0], Macros)
2289 if SourceFile[0] == os.path.sep:
2290 SourceFile = mws.join(GlobalData.gWorkspace, SourceFile[1:])
2291 # old module source files (Edk)
2292 File = PathClass(SourceFile, self._ModuleDir, self._SourceOverridePath,
2293 '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)
2294 # check the file validation
2295 ErrorCode, ErrorInfo = File.Validate(CaseSensitive=False)
2296 if ErrorCode != 0:
2297 if File.Ext.lower() == '.h':
2298 EdkLogger.warn('build', 'Include file not found', ExtraData=ErrorInfo,
2299 File=self.MetaFile, Line=LineNo)
2300 continue
2301 else:
2302 EdkLogger.error('build', ErrorCode, ExtraData=File, File=self.MetaFile, Line=LineNo)
2303 else:
2304 File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, '',
2305 '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)
2306 # check the file validation
2307 ErrorCode, ErrorInfo = File.Validate()
2308 if ErrorCode != 0:
2309 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
2310
2311 self._Sources.append(File)
2312 return self._Sources
2313
2314 ## Retrieve library classes employed by this module
2315 def _GetLibraryClassUses(self):
2316 if self._LibraryClasses == None:
2317 self._LibraryClasses = sdict()
2318 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, self._Platform]
2319 for Record in RecordList:
2320 Lib = Record[0]
2321 Instance = Record[1]
2322 if Instance:
2323 Instance = NormPath(Instance, self._Macros)
2324 self._LibraryClasses[Lib] = Instance
2325 return self._LibraryClasses
2326
2327 ## Retrieve library names (for Edk.x style of modules)
2328 def _GetLibraryNames(self):
2329 if self._Libraries == None:
2330 self._Libraries = []
2331 RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch, self._Platform]
2332 for Record in RecordList:
2333 LibraryName = ReplaceMacro(Record[0], self._Macros, False)
2334 # in case of name with '.lib' extension, which is unusual in Edk.x inf
2335 LibraryName = os.path.splitext(LibraryName)[0]
2336 if LibraryName not in self._Libraries:
2337 self._Libraries.append(LibraryName)
2338 return self._Libraries
2339
2340 def _GetProtocolComments(self):
2341 self._GetProtocols()
2342 return self._ProtocolComments
2343 ## Retrieve protocols consumed/produced by this module
2344 def _GetProtocols(self):
2345 if self._Protocols == None:
2346 self._Protocols = sdict()
2347 self._ProtocolComments = sdict()
2348 RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform]
2349 for Record in RecordList:
2350 CName = Record[0]
2351 Value = ProtocolValue(CName, self.Packages, self.MetaFile.Path)
2352 if Value == None:
2353 PackageList = "\n\t".join([str(P) for P in self.Packages])
2354 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
2355 "Value of Protocol [%s] is not found under [Protocols] section in" % CName,
2356 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])
2357 self._Protocols[CName] = Value
2358 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]
2359 Comments = []
2360 for CmtRec in CommentRecords:
2361 Comments.append(CmtRec[0])
2362 self._ProtocolComments[CName] = Comments
2363 return self._Protocols
2364
2365 def _GetPpiComments(self):
2366 self._GetPpis()
2367 return self._PpiComments
2368 ## Retrieve PPIs consumed/produced by this module
2369 def _GetPpis(self):
2370 if self._Ppis == None:
2371 self._Ppis = sdict()
2372 self._PpiComments = sdict()
2373 RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform]
2374 for Record in RecordList:
2375 CName = Record[0]
2376 Value = PpiValue(CName, self.Packages, self.MetaFile.Path)
2377 if Value == None:
2378 PackageList = "\n\t".join([str(P) for P in self.Packages])
2379 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
2380 "Value of PPI [%s] is not found under [Ppis] section in " % CName,
2381 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])
2382 self._Ppis[CName] = Value
2383 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]
2384 Comments = []
2385 for CmtRec in CommentRecords:
2386 Comments.append(CmtRec[0])
2387 self._PpiComments[CName] = Comments
2388 return self._Ppis
2389
2390 def _GetGuidComments(self):
2391 self._GetGuids()
2392 return self._GuidComments
2393 ## Retrieve GUIDs consumed/produced by this module
2394 def _GetGuids(self):
2395 if self._Guids == None:
2396 self._Guids = sdict()
2397 self._GuidComments = sdict()
2398 RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform]
2399 for Record in RecordList:
2400 CName = Record[0]
2401 Value = GuidValue(CName, self.Packages, self.MetaFile.Path)
2402 if Value == None:
2403 PackageList = "\n\t".join([str(P) for P in self.Packages])
2404 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
2405 "Value of Guid [%s] is not found under [Guids] section in" % CName,
2406 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])
2407 self._Guids[CName] = Value
2408 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]
2409 Comments = []
2410 for CmtRec in CommentRecords:
2411 Comments.append(CmtRec[0])
2412 self._GuidComments[CName] = Comments
2413 return self._Guids
2414
2415 ## Retrieve include paths necessary for this module (for Edk.x style of modules)
2416 def _GetIncludes(self):
2417 if self._Includes == None:
2418 self._Includes = []
2419 if self._SourceOverridePath:
2420 self._Includes.append(self._SourceOverridePath)
2421
2422 Macros = self._Macros
2423 if 'PROCESSOR' in GlobalData.gEdkGlobal.keys():
2424 Macros['PROCESSOR'] = GlobalData.gEdkGlobal['PROCESSOR']
2425 else:
2426 Macros['PROCESSOR'] = self._Arch
2427 RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch, self._Platform]
2428 for Record in RecordList:
2429 if Record[0].find('EDK_SOURCE') > -1:
2430 Macros['EDK_SOURCE'] = GlobalData.gEcpSource
2431 File = NormPath(Record[0], self._Macros)
2432 if File[0] == '.':
2433 File = os.path.join(self._ModuleDir, File)
2434 else:
2435 File = os.path.join(GlobalData.gWorkspace, File)
2436 File = RealPath(os.path.normpath(File))
2437 if File:
2438 self._Includes.append(File)
2439
2440 #TRICK: let compiler to choose correct header file
2441 Macros['EDK_SOURCE'] = GlobalData.gEdkSource
2442 File = NormPath(Record[0], self._Macros)
2443 if File[0] == '.':
2444 File = os.path.join(self._ModuleDir, File)
2445 else:
2446 File = os.path.join(GlobalData.gWorkspace, File)
2447 File = RealPath(os.path.normpath(File))
2448 if File:
2449 self._Includes.append(File)
2450 else:
2451 File = NormPath(Record[0], Macros)
2452 if File[0] == '.':
2453 File = os.path.join(self._ModuleDir, File)
2454 else:
2455 File = mws.join(GlobalData.gWorkspace, File)
2456 File = RealPath(os.path.normpath(File))
2457 if File:
2458 self._Includes.append(File)
2459 if not File and Record[0].find('EFI_SOURCE') > -1:
2460 # tricky to regard WorkSpace as EFI_SOURCE
2461 Macros['EFI_SOURCE'] = GlobalData.gWorkspace
2462 File = NormPath(Record[0], Macros)
2463 if File[0] == '.':
2464 File = os.path.join(self._ModuleDir, File)
2465 else:
2466 File = os.path.join(GlobalData.gWorkspace, File)
2467 File = RealPath(os.path.normpath(File))
2468 if File:
2469 self._Includes.append(File)
2470 return self._Includes
2471
2472 ## Retrieve packages this module depends on
2473 def _GetPackages(self):
2474 if self._Packages == None:
2475 self._Packages = []
2476 RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch, self._Platform]
2477 Macros = self._Macros
2478 Macros['EDK_SOURCE'] = GlobalData.gEcpSource
2479 for Record in RecordList:
2480 File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
2481 LineNo = Record[-1]
2482 # check the file validation
2483 ErrorCode, ErrorInfo = File.Validate('.dec')
2484 if ErrorCode != 0:
2485 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
2486 # parse this package now. we need it to get protocol/ppi/guid value
2487 Package = self._Bdb[File, self._Arch, self._Target, self._Toolchain]
2488 self._Packages.append(Package)
2489 return self._Packages
2490
2491 ## Retrieve PCD comments
2492 def _GetPcdComments(self):
2493 self._GetPcds()
2494 return self._PcdComments
2495 ## Retrieve PCDs used in this module
2496 def _GetPcds(self):
2497 if self._Pcds == None:
2498 self._Pcds = sdict()
2499 self._PcdComments = sdict()
2500 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))
2501 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))
2502 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))
2503 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC))
2504 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))
2505 return self._Pcds
2506
2507 ## Retrieve build options specific to this module
2508 def _GetBuildOptions(self):
2509 if self._BuildOptions == None:
2510 self._BuildOptions = sdict()
2511 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, self._Platform]
2512 for Record in RecordList:
2513 ToolChainFamily = Record[0]
2514 ToolChain = Record[1]
2515 Option = Record[2]
2516 if (ToolChainFamily, ToolChain) not in self._BuildOptions or Option.startswith('='):
2517 self._BuildOptions[ToolChainFamily, ToolChain] = Option
2518 else:
2519 # concatenate the option string if they're for the same tool
2520 OptionString = self._BuildOptions[ToolChainFamily, ToolChain]
2521 self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option
2522 return self._BuildOptions
2523
2524 ## Retrieve dependency expression
2525 def _GetDepex(self):
2526 if self._Depex == None:
2527 self._Depex = tdict(False, 2)
2528 RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]
2529
2530 # If the module has only Binaries and no Sources, then ignore [Depex]
2531 if self.Sources == None or self.Sources == []:
2532 if self.Binaries != None and self.Binaries != []:
2533 return self._Depex
2534
2535 # PEIM and DXE drivers must have a valid [Depex] section
2536 if len(self.LibraryClass) == 0 and len(RecordList) == 0:
2537 if self.ModuleType == 'DXE_DRIVER' or self.ModuleType == 'PEIM' or self.ModuleType == 'DXE_SMM_DRIVER' or \
2538 self.ModuleType == 'DXE_SAL_DRIVER' or self.ModuleType == 'DXE_RUNTIME_DRIVER':
2539 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
2540 % self.ModuleType, File=self.MetaFile)
2541
2542 if len(RecordList) != 0 and self.ModuleType == 'USER_DEFINED':
2543 for Record in RecordList:
2544 if Record[4] not in ['PEIM', 'DXE_DRIVER', 'DXE_SMM_DRIVER']:
2545 EdkLogger.error('build', FORMAT_INVALID,
2546 "'%s' module must specify the type of [Depex] section" % self.ModuleType,
2547 File=self.MetaFile)
2548
2549 Depex = sdict()
2550 for Record in RecordList:
2551 DepexStr = ReplaceMacro(Record[0], self._Macros, False)
2552 Arch = Record[3]
2553 ModuleType = Record[4]
2554 TokenList = DepexStr.split()
2555 if (Arch, ModuleType) not in Depex:
2556 Depex[Arch, ModuleType] = []
2557 DepexList = Depex[Arch, ModuleType]
2558 for Token in TokenList:
2559 if Token in DEPEX_SUPPORTED_OPCODE:
2560 DepexList.append(Token)
2561 elif Token.endswith(".inf"): # module file name
2562 ModuleFile = os.path.normpath(Token)
2563 Module = self.BuildDatabase[ModuleFile]
2564 if Module == None:
2565 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "Module is not found in active platform",
2566 ExtraData=Token, File=self.MetaFile, Line=Record[-1])
2567 DepexList.append(Module.Guid)
2568 else:
2569 # get the GUID value now
2570 Value = ProtocolValue(Token, self.Packages, self.MetaFile.Path)
2571 if Value == None:
2572 Value = PpiValue(Token, self.Packages, self.MetaFile.Path)
2573 if Value == None:
2574 Value = GuidValue(Token, self.Packages, self.MetaFile.Path)
2575 if Value == None:
2576 PackageList = "\n\t".join([str(P) for P in self.Packages])
2577 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
2578 "Value of [%s] is not found in" % Token,
2579 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])
2580 DepexList.append(Value)
2581 for Arch, ModuleType in Depex:
2582 self._Depex[Arch, ModuleType] = Depex[Arch, ModuleType]
2583 return self._Depex
2584
2585 ## Retrieve depedency expression
2586 def _GetDepexExpression(self):
2587 if self._DepexExpression == None:
2588 self._DepexExpression = tdict(False, 2)
2589 RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]
2590 DepexExpression = sdict()
2591 for Record in RecordList:
2592 DepexStr = ReplaceMacro(Record[0], self._Macros, False)
2593 Arch = Record[3]
2594 ModuleType = Record[4]
2595 TokenList = DepexStr.split()
2596 if (Arch, ModuleType) not in DepexExpression:
2597 DepexExpression[Arch, ModuleType] = ''
2598 for Token in TokenList:
2599 DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType] + Token.strip() + ' '
2600 for Arch, ModuleType in DepexExpression:
2601 self._DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType]
2602 return self._DepexExpression
2603
2604 def GetGuidsUsedByPcd(self):
2605 return self._GuidsUsedByPcd
2606 ## Retrieve PCD for given type
2607 def _GetPcd(self, Type):
2608 Pcds = sdict()
2609 PcdDict = tdict(True, 4)
2610 PcdList = []
2611 RecordList = self._RawData[Type, self._Arch, self._Platform]
2612 for TokenSpaceGuid, PcdCName, Setting, Arch, Platform, Id, LineNo in RecordList:
2613 PcdDict[Arch, Platform, PcdCName, TokenSpaceGuid] = (Setting, LineNo)
2614 PcdList.append((PcdCName, TokenSpaceGuid))
2615 # get the guid value
2616 if TokenSpaceGuid not in self.Guids:
2617 Value = GuidValue(TokenSpaceGuid, self.Packages, self.MetaFile.Path)
2618 if Value == None:
2619 PackageList = "\n\t".join([str(P) for P in self.Packages])
2620 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
2621 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid,
2622 ExtraData=PackageList, File=self.MetaFile, Line=LineNo)
2623 self.Guids[TokenSpaceGuid] = Value
2624 self._GuidsUsedByPcd[TokenSpaceGuid] = Value
2625 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Id]
2626 Comments = []
2627 for CmtRec in CommentRecords:
2628 Comments.append(CmtRec[0])
2629 self._PcdComments[TokenSpaceGuid, PcdCName] = Comments
2630
2631 # resolve PCD type, value, datum info, etc. by getting its definition from package
2632 for PcdCName, TokenSpaceGuid in PcdList:
2633 PcdRealName = PcdCName
2634 Setting, LineNo = PcdDict[self._Arch, self.Platform, PcdCName, TokenSpaceGuid]
2635 if Setting == None:
2636 continue
2637 ValueList = AnalyzePcdData(Setting)
2638 DefaultValue = ValueList[0]
2639 Pcd = PcdClassObject(
2640 PcdCName,
2641 TokenSpaceGuid,
2642 '',
2643 '',
2644 DefaultValue,
2645 '',
2646 '',
2647 {},
2648 False,
2649 self.Guids[TokenSpaceGuid]
2650 )
2651 if Type == MODEL_PCD_PATCHABLE_IN_MODULE and ValueList[1]:
2652 # Patch PCD: TokenSpace.PcdCName|Value|Offset
2653 Pcd.Offset = ValueList[1]
2654
2655 if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:
2656 for Package in self.Packages:
2657 for key in Package.Pcds:
2658 if (Package.Pcds[key].TokenCName, Package.Pcds[key].TokenSpaceGuidCName) == (PcdRealName, TokenSpaceGuid):
2659 for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:
2660 Pcd_Type = item[0].split('_')[-1]
2661 if Pcd_Type == Package.Pcds[key].Type:
2662 Value = Package.Pcds[key]
2663 Value.TokenCName = Package.Pcds[key].TokenCName + '_' + Pcd_Type
2664 if len(key) == 2:
2665 newkey = (Value.TokenCName, key[1])
2666 elif len(key) == 3:
2667 newkey = (Value.TokenCName, key[1], key[2])
2668 del Package.Pcds[key]
2669 Package.Pcds[newkey] = Value
2670 break
2671 else:
2672 pass
2673 else:
2674 pass
2675
2676 # get necessary info from package declaring this PCD
2677 for Package in self.Packages:
2678 #
2679 # 'dynamic' in INF means its type is determined by platform;
2680 # if platform doesn't give its type, use 'lowest' one in the
2681 # following order, if any
2682 #
2683 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
2684 #
2685 PcdType = self._PCD_TYPE_STRING_[Type]
2686 if Type == MODEL_PCD_DYNAMIC:
2687 Pcd.Pending = True
2688 for T in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
2689 if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:
2690 for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:
2691 if str(item[0]).endswith(T) and (item[0], item[1], T) in Package.Pcds:
2692 PcdType = T
2693 PcdCName = item[0]
2694 break
2695 else:
2696 pass
2697 break
2698 else:
2699 if (PcdRealName, TokenSpaceGuid, T) in Package.Pcds:
2700 PcdType = T
2701 break
2702
2703 else:
2704 Pcd.Pending = False
2705 if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:
2706 for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:
2707 Pcd_Type = item[0].split('_')[-1]
2708 if Pcd_Type == PcdType:
2709 PcdCName = item[0]
2710 break
2711 else:
2712 pass
2713 else:
2714 pass
2715
2716 if (PcdCName, TokenSpaceGuid, PcdType) in Package.Pcds:
2717 PcdInPackage = Package.Pcds[PcdCName, TokenSpaceGuid, PcdType]
2718 Pcd.Type = PcdType
2719 Pcd.TokenValue = PcdInPackage.TokenValue
2720
2721 #
2722 # Check whether the token value exist or not.
2723 #
2724 if Pcd.TokenValue == None or Pcd.TokenValue == "":
2725 EdkLogger.error(
2726 'build',
2727 FORMAT_INVALID,
2728 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid, PcdRealName, str(Package)),
2729 File=self.MetaFile, Line=LineNo,
2730 ExtraData=None
2731 )
2732 #
2733 # Check hexadecimal token value length and format.
2734 #
2735 ReIsValidPcdTokenValue = re.compile(r"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re.DOTALL)
2736 if Pcd.TokenValue.startswith("0x") or Pcd.TokenValue.startswith("0X"):
2737 if ReIsValidPcdTokenValue.match(Pcd.TokenValue) == None:
2738 EdkLogger.error(
2739 'build',
2740 FORMAT_INVALID,
2741 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd.TokenValue, TokenSpaceGuid, PcdRealName, str(Package)),
2742 File=self.MetaFile, Line=LineNo,
2743 ExtraData=None
2744 )
2745
2746 #
2747 # Check decimal token value length and format.
2748 #
2749 else:
2750 try:
2751 TokenValueInt = int (Pcd.TokenValue, 10)
2752 if (TokenValueInt < 0 or TokenValueInt > 4294967295):
2753 EdkLogger.error(
2754 'build',
2755 FORMAT_INVALID,
2756 "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)),
2757 File=self.MetaFile, Line=LineNo,
2758 ExtraData=None
2759 )
2760 except:
2761 EdkLogger.error(
2762 'build',
2763 FORMAT_INVALID,
2764 "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)),
2765 File=self.MetaFile, Line=LineNo,
2766 ExtraData=None
2767 )
2768
2769 Pcd.DatumType = PcdInPackage.DatumType
2770 Pcd.MaxDatumSize = PcdInPackage.MaxDatumSize
2771 Pcd.InfDefaultValue = Pcd.DefaultValue
2772 if Pcd.DefaultValue in [None, '']:
2773 Pcd.DefaultValue = PcdInPackage.DefaultValue
2774 break
2775 else:
2776 EdkLogger.error(
2777 'build',
2778 FORMAT_INVALID,
2779 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdRealName, self.MetaFile),
2780 File=self.MetaFile, Line=LineNo,
2781 ExtraData="\t%s" % '\n\t'.join([str(P) for P in self.Packages])
2782 )
2783 Pcds[PcdCName, TokenSpaceGuid] = Pcd
2784
2785 return Pcds
2786
2787 ## check whether current module is binary module
2788 def _IsBinaryModule(self):
2789 if self.Binaries and not self.Sources:
2790 return True
2791 elif GlobalData.gIgnoreSource:
2792 return True
2793 else:
2794 return False
2795
2796 _Macros = property(_GetMacros)
2797 Arch = property(_GetArch, _SetArch)
2798 Platform = property(_GetPlatform, _SetPlatform)
2799
2800 HeaderComments = property(_GetHeaderComments)
2801 TailComments = property(_GetTailComments)
2802 AutoGenVersion = property(_GetInfVersion)
2803 BaseName = property(_GetBaseName)
2804 ModuleType = property(_GetModuleType)
2805 ComponentType = property(_GetComponentType)
2806 BuildType = property(_GetBuildType)
2807 Guid = property(_GetFileGuid)
2808 Version = property(_GetVersion)
2809 PcdIsDriver = property(_GetPcdIsDriver)
2810 Shadow = property(_GetShadow)
2811 CustomMakefile = property(_GetMakefile)
2812 Specification = property(_GetSpec)
2813 LibraryClass = property(_GetLibraryClass)
2814 ModuleEntryPointList = property(_GetEntryPoint)
2815 ModuleUnloadImageList = property(_GetUnloadImage)
2816 ConstructorList = property(_GetConstructor)
2817 DestructorList = property(_GetDestructor)
2818 Defines = property(_GetDefines)
2819 DxsFile = property(_GetDxsFile)
2820
2821 Binaries = property(_GetBinaryFiles)
2822 Sources = property(_GetSourceFiles)
2823 LibraryClasses = property(_GetLibraryClassUses)
2824 Libraries = property(_GetLibraryNames)
2825 Protocols = property(_GetProtocols)
2826 ProtocolComments = property(_GetProtocolComments)
2827 Ppis = property(_GetPpis)
2828 PpiComments = property(_GetPpiComments)
2829 Guids = property(_GetGuids)
2830 GuidComments = property(_GetGuidComments)
2831 Includes = property(_GetIncludes)
2832 Packages = property(_GetPackages)
2833 Pcds = property(_GetPcds)
2834 PcdComments = property(_GetPcdComments)
2835 BuildOptions = property(_GetBuildOptions)
2836 Depex = property(_GetDepex)
2837 DepexExpression = property(_GetDepexExpression)
2838 IsBinaryModule = property(_IsBinaryModule)
2839 IsSupportedArch = property(_IsSupportedArch)
2840
2841 ## Database
2842 #
2843 # This class defined the build database for all modules, packages and platform.
2844 # It will call corresponding parser for the given file if it cannot find it in
2845 # the database.
2846 #
2847 # @param DbPath Path of database file
2848 # @param GlobalMacros Global macros used for replacement during file parsing
2849 # @prarm RenewDb=False Create new database file if it's already there
2850 #
2851 class WorkspaceDatabase(object):
2852
2853
2854 #
2855 # internal class used for call corresponding file parser and caching the result
2856 # to avoid unnecessary re-parsing
2857 #
2858 class BuildObjectFactory(object):
2859
2860 _FILE_TYPE_ = {
2861 ".inf" : MODEL_FILE_INF,
2862 ".dec" : MODEL_FILE_DEC,
2863 ".dsc" : MODEL_FILE_DSC,
2864 }
2865
2866 # file parser
2867 _FILE_PARSER_ = {
2868 MODEL_FILE_INF : InfParser,
2869 MODEL_FILE_DEC : DecParser,
2870 MODEL_FILE_DSC : DscParser,
2871 }
2872
2873 # convert to xxxBuildData object
2874 _GENERATOR_ = {
2875 MODEL_FILE_INF : InfBuildData,
2876 MODEL_FILE_DEC : DecBuildData,
2877 MODEL_FILE_DSC : DscBuildData,
2878 }
2879
2880 _CACHE_ = {} # (FilePath, Arch) : <object>
2881
2882 # constructor
2883 def __init__(self, WorkspaceDb):
2884 self.WorkspaceDb = WorkspaceDb
2885
2886 # key = (FilePath, Arch=None)
2887 def __contains__(self, Key):
2888 FilePath = Key[0]
2889 if len(Key) > 1:
2890 Arch = Key[1]
2891 else:
2892 Arch = None
2893 return (FilePath, Arch) in self._CACHE_
2894
2895 # key = (FilePath, Arch=None, Target=None, Toochain=None)
2896 def __getitem__(self, Key):
2897 FilePath = Key[0]
2898 KeyLength = len(Key)
2899 if KeyLength > 1:
2900 Arch = Key[1]
2901 else:
2902 Arch = None
2903 if KeyLength > 2:
2904 Target = Key[2]
2905 else:
2906 Target = None
2907 if KeyLength > 3:
2908 Toolchain = Key[3]
2909 else:
2910 Toolchain = None
2911
2912 # if it's generated before, just return the cached one
2913 Key = (FilePath, Arch, Target, Toolchain)
2914 if Key in self._CACHE_:
2915 return self._CACHE_[Key]
2916
2917 # check file type
2918 Ext = FilePath.Type
2919 if Ext not in self._FILE_TYPE_:
2920 return None
2921 FileType = self._FILE_TYPE_[Ext]
2922 if FileType not in self._GENERATOR_:
2923 return None
2924
2925 # get the parser ready for this file
2926 MetaFile = self._FILE_PARSER_[FileType](
2927 FilePath,
2928 FileType,
2929 Arch,
2930 MetaFileStorage(self.WorkspaceDb.Cur, FilePath, FileType)
2931 )
2932 # alwasy do post-process, in case of macros change
2933 MetaFile.DoPostProcess()
2934 # object the build is based on
2935 BuildObject = self._GENERATOR_[FileType](
2936 FilePath,
2937 MetaFile,
2938 self,
2939 Arch,
2940 Target,
2941 Toolchain
2942 )
2943 self._CACHE_[Key] = BuildObject
2944 return BuildObject
2945
2946 # placeholder for file format conversion
2947 class TransformObjectFactory:
2948 def __init__(self, WorkspaceDb):
2949 self.WorkspaceDb = WorkspaceDb
2950
2951 # key = FilePath, Arch
2952 def __getitem__(self, Key):
2953 pass
2954
2955 ## Constructor of WorkspaceDatabase
2956 #
2957 # @param DbPath Path of database file
2958 # @param GlobalMacros Global macros used for replacement during file parsing
2959 # @prarm RenewDb=False Create new database file if it's already there
2960 #
2961 def __init__(self, DbPath, RenewDb=False):
2962 self._DbClosedFlag = False
2963 if not DbPath:
2964 DbPath = os.path.normpath(mws.join(GlobalData.gWorkspace, 'Conf', GlobalData.gDatabasePath))
2965
2966 # don't create necessary path for db in memory
2967 if DbPath != ':memory:':
2968 DbDir = os.path.split(DbPath)[0]
2969 if not os.path.exists(DbDir):
2970 os.makedirs(DbDir)
2971
2972 # remove db file in case inconsistency between db and file in file system
2973 if self._CheckWhetherDbNeedRenew(RenewDb, DbPath):
2974 os.remove(DbPath)
2975
2976 # create db with optimized parameters
2977 self.Conn = sqlite3.connect(DbPath, isolation_level='DEFERRED')
2978 self.Conn.execute("PRAGMA synchronous=OFF")
2979 self.Conn.execute("PRAGMA temp_store=MEMORY")
2980 self.Conn.execute("PRAGMA count_changes=OFF")
2981 self.Conn.execute("PRAGMA cache_size=8192")
2982 #self.Conn.execute("PRAGMA page_size=8192")
2983
2984 # to avoid non-ascii character conversion issue
2985 self.Conn.text_factory = str
2986 self.Cur = self.Conn.cursor()
2987
2988 # create table for internal uses
2989 self.TblDataModel = TableDataModel(self.Cur)
2990 self.TblFile = TableFile(self.Cur)
2991 self.Platform = None
2992
2993 # conversion object for build or file format conversion purpose
2994 self.BuildObject = WorkspaceDatabase.BuildObjectFactory(self)
2995 self.TransformObject = WorkspaceDatabase.TransformObjectFactory(self)
2996
2997 ## Check whether workspace database need to be renew.
2998 # The renew reason maybe:
2999 # 1) If user force to renew;
3000 # 2) If user do not force renew, and
3001 # a) If the time of last modified python source is newer than database file;
3002 # b) If the time of last modified frozen executable file is newer than database file;
3003 #
3004 # @param force User force renew database
3005 # @param DbPath The absolute path of workspace database file
3006 #
3007 # @return Bool value for whether need renew workspace databse
3008 #
3009 def _CheckWhetherDbNeedRenew (self, force, DbPath):
3010 # if database does not exist, we need do nothing
3011 if not os.path.exists(DbPath): return False
3012
3013 # if user force to renew database, then not check whether database is out of date
3014 if force: return True
3015
3016 #
3017 # Check the time of last modified source file or build.exe
3018 # if is newer than time of database, then database need to be re-created.
3019 #
3020 timeOfToolModified = 0
3021 if hasattr(sys, "frozen"):
3022 exePath = os.path.abspath(sys.executable)
3023 timeOfToolModified = os.stat(exePath).st_mtime
3024 else:
3025 curPath = os.path.dirname(__file__) # curPath is the path of WorkspaceDatabase.py
3026 rootPath = os.path.split(curPath)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python
3027 if rootPath == "" or rootPath == None:
3028 EdkLogger.verbose("\nFail to find the root path of build.exe or python sources, so can not \
3029 determine whether database file is out of date!\n")
3030
3031 # walk the root path of source or build's binary to get the time last modified.
3032
3033 for root, dirs, files in os.walk (rootPath):
3034 for dir in dirs:
3035 # bypass source control folder
3036 if dir.lower() in [".svn", "_svn", "cvs"]:
3037 dirs.remove(dir)
3038
3039 for file in files:
3040 ext = os.path.splitext(file)[1]
3041 if ext.lower() == ".py": # only check .py files
3042 fd = os.stat(os.path.join(root, file))
3043 if timeOfToolModified < fd.st_mtime:
3044 timeOfToolModified = fd.st_mtime
3045 if timeOfToolModified > os.stat(DbPath).st_mtime:
3046 EdkLogger.verbose("\nWorkspace database is out of data!")
3047 return True
3048
3049 return False
3050
3051 ## Initialize build database
3052 def InitDatabase(self):
3053 EdkLogger.verbose("\nInitialize build database started ...")
3054
3055 #
3056 # Create new tables
3057 #
3058 self.TblDataModel.Create(False)
3059 self.TblFile.Create(False)
3060
3061 #
3062 # Initialize table DataModel
3063 #
3064 self.TblDataModel.InitTable()
3065 EdkLogger.verbose("Initialize build database ... DONE!")
3066
3067 ## Query a table
3068 #
3069 # @param Table: The instance of the table to be queried
3070 #
3071 def QueryTable(self, Table):
3072 Table.Query()
3073
3074 def __del__(self):
3075 self.Close()
3076
3077 ## Close entire database
3078 #
3079 # Commit all first
3080 # Close the connection and cursor
3081 #
3082 def Close(self):
3083 if not self._DbClosedFlag:
3084 self.Conn.commit()
3085 self.Cur.close()
3086 self.Conn.close()
3087 self._DbClosedFlag = True
3088
3089 ## Summarize all packages in the database
3090 def GetPackageList(self, Platform, Arch, TargetName, ToolChainTag):
3091 self.Platform = Platform
3092 PackageList = []
3093 Pa = self.BuildObject[self.Platform, 'COMMON']
3094 #
3095 # Get Package related to Modules
3096 #
3097 for Module in Pa.Modules:
3098 ModuleObj = self.BuildObject[Module, Arch, TargetName, ToolChainTag]
3099 for Package in ModuleObj.Packages:
3100 if Package not in PackageList:
3101 PackageList.append(Package)
3102 #
3103 # Get Packages related to Libraries
3104 #
3105 for Lib in Pa.LibraryInstances:
3106 LibObj = self.BuildObject[Lib, Arch, TargetName, ToolChainTag]
3107 for Package in LibObj.Packages:
3108 if Package not in PackageList:
3109 PackageList.append(Package)
3110
3111 return PackageList
3112
3113 ## Summarize all platforms in the database
3114 def _GetPlatformList(self):
3115 PlatformList = []
3116 for PlatformFile in self.TblFile.GetFileList(MODEL_FILE_DSC):
3117 try:
3118 Platform = self.BuildObject[PathClass(PlatformFile), 'COMMON']
3119 except:
3120 Platform = None
3121 if Platform != None:
3122 PlatformList.append(Platform)
3123 return PlatformList
3124
3125 def _MapPlatform(self, Dscfile):
3126 Platform = self.BuildObject[PathClass(Dscfile), 'COMMON']
3127 if Platform == None:
3128 EdkLogger.error('build', PARSER_ERROR, "Failed to parser DSC file: %s" % Dscfile)
3129 return Platform
3130
3131 PlatformList = property(_GetPlatformList)
3132
3133 ##
3134 #
3135 # This acts like the main() function for the script, unless it is 'import'ed into another
3136 # script.
3137 #
3138 if __name__ == '__main__':
3139 pass
3140