]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Workspace/DscBuildData.py
BaseTools: Workspace classes refactor properties
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / DscBuildData.py
1 ## @file
2 # This file is used to create a database used by build tool
3 #
4 # Copyright (c) 2008 - 2018, 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 ## Platform build information from DSC file
16 #
17 # This class is used to retrieve information stored in database and convert them
18 # into PlatformBuildClassObject form for easier use for AutoGen.
19 #
20 from __future__ import print_function
21 from __future__ import absolute_import
22 from Common.StringUtils import *
23 from Common.DataType import *
24 from Common.Misc import *
25 from types import *
26 from Common.Expression import *
27 from CommonDataClass.CommonClass import SkuInfoClass
28 from Common.TargetTxtClassObject import *
29 from Common.ToolDefClassObject import *
30 from .MetaDataTable import *
31 from .MetaFileTable import *
32 from .MetaFileParser import *
33
34 from .WorkspaceCommon import GetDeclaredPcd
35 from Common.Misc import AnalyzeDscPcd
36 from Common.Misc import ProcessDuplicatedInf
37 import re
38 from Common.Parsing import IsValidWord
39 from Common.VariableAttributes import VariableAttributes
40 import Common.GlobalData as GlobalData
41 import subprocess
42 from Common.Misc import SaveFileOnChange
43 from Workspace.BuildClassObject import PlatformBuildClassObject, StructurePcd, PcdClassObject, ModuleBuildClassObject
44 from collections import OrderedDict, defaultdict
45
46 PcdValueInitName = 'PcdValueInit'
47
48 PcdMainCHeader = '''
49 /**
50 DO NOT EDIT
51 FILE auto-generated
52 **/
53
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <string.h>
57 #include <PcdValueCommon.h>
58 '''
59
60 PcdMainCEntry = '''
61 int
62 main (
63 int argc,
64 char *argv[]
65 )
66 {
67 return PcdValueMain (argc, argv);
68 }
69 '''
70
71 PcdMakefileHeader = '''
72 #
73 # DO NOT EDIT
74 # This file is auto-generated by build utility
75 #
76
77 '''
78
79 WindowsCFLAGS = 'CFLAGS = $(CFLAGS) /wd4200 /wd4034 /wd4101 '
80 LinuxCFLAGS = 'BUILD_CFLAGS += -Wno-pointer-to-int-cast -Wno-unused-variable '
81 PcdMakefileEnd = '''
82 !INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.common
83
84 LIBS = $(LIB_PATH)\Common.lib
85
86 !INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.app
87 '''
88
89 PcdGccMakefile = '''
90 MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C
91 LIBS = -lCommon
92 '''
93
94 variablePattern = re.compile(r'[\t\s]*0[xX][a-fA-F0-9]+$')
95 SkuIdPattern = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*$')
96 ## regular expressions for finding decimal and hex numbers
97 Pattern = re.compile('^[1-9]\d*|0$')
98 HexPattern = re.compile(r'0[xX][0-9a-fA-F]+$')
99 ## Regular expression for finding header file inclusions
100 from AutoGen.GenMake import gIncludePattern
101
102 ## Find dependencies for one source file
103 #
104 # By searching recursively "#include" directive in file, find out all the
105 # files needed by given source file. The dependecies will be only searched
106 # in given search path list.
107 #
108 # @param SearchPathList The list of search path
109 #
110 # @retval list The list of files the given source file depends on
111 #
112 def GetDependencyList(FileStack, SearchPathList):
113 DepDb = dict()
114 DependencySet = set(FileStack)
115 while len(FileStack) > 0:
116 F = FileStack.pop()
117 FullPathDependList = []
118 CurrentFileDependencyList = []
119 if F in DepDb:
120 CurrentFileDependencyList = DepDb[F]
121 else:
122 try:
123 Fd = open(F, 'r')
124 FileContent = Fd.read()
125 except BaseException as X:
126 EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=F + "\n\t" + str(X))
127 finally:
128 if "Fd" in dir(locals()):
129 Fd.close()
130
131 if len(FileContent) == 0:
132 continue
133
134 if FileContent[0] == 0xff or FileContent[0] == 0xfe:
135 FileContent = unicode(FileContent, "utf-16")
136 IncludedFileList = gIncludePattern.findall(FileContent)
137
138 for Inc in IncludedFileList:
139 Inc = Inc.strip()
140 Inc = os.path.normpath(Inc)
141 CurrentFileDependencyList.append(Inc)
142 DepDb[F] = CurrentFileDependencyList
143
144 CurrentFilePath = os.path.dirname(F)
145 PathList = [CurrentFilePath] + SearchPathList
146 for Inc in CurrentFileDependencyList:
147 for SearchPath in PathList:
148 FilePath = os.path.join(SearchPath, Inc)
149 if not os.path.exists(FilePath):
150 continue
151 if FilePath not in DependencySet:
152 FileStack.append(FilePath)
153 FullPathDependList.append(FilePath)
154 break
155 DependencySet.update(FullPathDependList)
156 DependencyList = list(DependencySet) # remove duplicate ones
157
158 return DependencyList
159
160 class DscBuildData(PlatformBuildClassObject):
161 # dict used to convert PCD type in database to string used by build tool
162 _PCD_TYPE_STRING_ = {
163 MODEL_PCD_FIXED_AT_BUILD : TAB_PCDS_FIXED_AT_BUILD,
164 MODEL_PCD_PATCHABLE_IN_MODULE : TAB_PCDS_PATCHABLE_IN_MODULE,
165 MODEL_PCD_FEATURE_FLAG : TAB_PCDS_FEATURE_FLAG,
166 MODEL_PCD_DYNAMIC : TAB_PCDS_DYNAMIC,
167 MODEL_PCD_DYNAMIC_DEFAULT : TAB_PCDS_DYNAMIC,
168 MODEL_PCD_DYNAMIC_HII : TAB_PCDS_DYNAMIC_HII,
169 MODEL_PCD_DYNAMIC_VPD : TAB_PCDS_DYNAMIC_VPD,
170 MODEL_PCD_DYNAMIC_EX : TAB_PCDS_DYNAMIC_EX,
171 MODEL_PCD_DYNAMIC_EX_DEFAULT : TAB_PCDS_DYNAMIC_EX,
172 MODEL_PCD_DYNAMIC_EX_HII : TAB_PCDS_DYNAMIC_EX_HII,
173 MODEL_PCD_DYNAMIC_EX_VPD : TAB_PCDS_DYNAMIC_EX_VPD,
174 }
175
176 # dict used to convert part of [Defines] to members of DscBuildData directly
177 _PROPERTY_ = {
178 #
179 # Required Fields
180 #
181 TAB_DSC_DEFINES_PLATFORM_NAME : "_PlatformName",
182 TAB_DSC_DEFINES_PLATFORM_GUID : "_Guid",
183 TAB_DSC_DEFINES_PLATFORM_VERSION : "_Version",
184 TAB_DSC_DEFINES_DSC_SPECIFICATION : "_DscSpecification",
185 # TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
186 # TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
187 # TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
188 TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName",
189 # TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
190 TAB_DSC_DEFINES_BUILD_NUMBER : "_BuildNumber",
191 TAB_DSC_DEFINES_MAKEFILE_NAME : "_MakefileName",
192 TAB_DSC_DEFINES_BS_BASE_ADDRESS : "_BsBaseAddress",
193 TAB_DSC_DEFINES_RT_BASE_ADDRESS : "_RtBaseAddress",
194 # TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
195 # TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
196 }
197
198 # used to compose dummy library class name for those forced library instances
199 _NullLibraryNumber = 0
200
201 ## Constructor of DscBuildData
202 #
203 # Initialize object of DscBuildData
204 #
205 # @param FilePath The path of platform description file
206 # @param RawData The raw data of DSC file
207 # @param BuildDataBase Database used to retrieve module/package information
208 # @param Arch The target architecture
209 # @param Platform (not used for DscBuildData)
210 # @param Macros Macros used for replacement in DSC file
211 #
212 def __init__(self, FilePath, RawData, BuildDataBase, Arch=TAB_ARCH_COMMON, Target=None, Toolchain=None):
213 self.MetaFile = FilePath
214 self._RawData = RawData
215 self._Bdb = BuildDataBase
216 self._Arch = Arch
217 self._Target = Target
218 self._Toolchain = Toolchain
219 self._ToolChainFamily = None
220 self._Clear()
221 self._HandleOverridePath()
222 self.WorkspaceDir = os.getenv("WORKSPACE") if os.getenv("WORKSPACE") else ""
223 self.DefaultStores = None
224 self.SkuIdMgr = SkuClass(self.SkuName, self.SkuIds)
225
226 @property
227 def OutputPath(self):
228 if os.getenv("WORKSPACE"):
229 return os.path.join(os.getenv("WORKSPACE"), self.OutputDirectory, self._Target + "_" + self._Toolchain, PcdValueInitName)
230 else:
231 return os.path.dirname(self.DscFile)
232
233 ## XXX[key] = value
234 def __setitem__(self, key, value):
235 self.__dict__[self._PROPERTY_[key]] = value
236
237 ## value = XXX[key]
238 def __getitem__(self, key):
239 return self.__dict__[self._PROPERTY_[key]]
240
241 ## "in" test support
242 def __contains__(self, key):
243 return key in self._PROPERTY_
244
245 ## Set all internal used members of DscBuildData to None
246 def _Clear(self):
247 self._Header = None
248 self._PlatformName = None
249 self._Guid = None
250 self._Version = None
251 self._DscSpecification = None
252 self._OutputDirectory = None
253 self._SupArchList = None
254 self._BuildTargets = None
255 self._SkuName = None
256 self._PcdInfoFlag = None
257 self._VarCheckFlag = None
258 self._FlashDefinition = None
259 self._Prebuild = None
260 self._Postbuild = None
261 self._BuildNumber = None
262 self._MakefileName = None
263 self._BsBaseAddress = None
264 self._RtBaseAddress = None
265 self._SkuIds = None
266 self._Modules = None
267 self._LibraryInstances = None
268 self._LibraryClasses = None
269 self._Pcds = None
270 self._DecPcds = None
271 self._BuildOptions = None
272 self._ModuleTypeOptions = None
273 self._LoadFixAddress = None
274 self._RFCLanguages = None
275 self._ISOLanguages = None
276 self._VpdToolGuid = None
277 self._MacroDict = None
278 self.DefaultStores = None
279
280 ## handle Override Path of Module
281 def _HandleOverridePath(self):
282 RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]
283 for Record in RecordList:
284 ModuleId = Record[6]
285 LineNo = Record[7]
286 ModuleFile = PathClass(NormPath(Record[0]), GlobalData.gWorkspace, Arch=self._Arch)
287 RecordList = self._RawData[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH, self._Arch, None, ModuleId]
288 if RecordList != []:
289 SourceOverridePath = mws.join(GlobalData.gWorkspace, NormPath(RecordList[0][0]))
290
291 # Check if the source override path exists
292 if not os.path.isdir(SourceOverridePath):
293 EdkLogger.error('build', FILE_NOT_FOUND, Message='Source override path does not exist:', File=self.MetaFile, ExtraData=SourceOverridePath, Line=LineNo)
294
295 # Add to GlobalData Variables
296 GlobalData.gOverrideDir[ModuleFile.Key] = SourceOverridePath
297
298 ## Get current effective macros
299 @property
300 def _Macros(self):
301 if self._MacroDict is None:
302 self._MacroDict = {}
303 self._MacroDict.update(GlobalData.gPlatformDefines)
304 self._MacroDict.update(GlobalData.gGlobalDefines)
305 self._MacroDict.update(GlobalData.gCommandLineDefines)
306 return self._MacroDict
307
308 ## Get architecture
309 @property
310 def Arch(self):
311 return self._Arch
312
313 ## Retrieve all information in [Defines] section
314 #
315 # (Retriving all [Defines] information in one-shot is just to save time.)
316 #
317 def _GetHeaderInfo(self):
318 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch]
319 for Record in RecordList:
320 Name = Record[1]
321 # items defined _PROPERTY_ don't need additional processing
322
323 # some special items in [Defines] section need special treatment
324 if Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY:
325 self._OutputDirectory = NormPath(Record[2], self._Macros)
326 if ' ' in self._OutputDirectory:
327 EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in OUTPUT_DIRECTORY",
328 File=self.MetaFile, Line=Record[-1],
329 ExtraData=self._OutputDirectory)
330 elif Name == TAB_DSC_DEFINES_FLASH_DEFINITION:
331 self._FlashDefinition = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace)
332 ErrorCode, ErrorInfo = self._FlashDefinition.Validate('.fdf')
333 if ErrorCode != 0:
334 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=Record[-1],
335 ExtraData=ErrorInfo)
336 elif Name == TAB_DSC_PREBUILD:
337 PrebuildValue = Record[2]
338 if Record[2][0] == '"':
339 if Record[2][-1] != '"':
340 EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_PREBUILD,
341 File=self.MetaFile, Line=Record[-1])
342 PrebuildValue = Record[2][1:-1]
343 self._Prebuild = PrebuildValue
344 elif Name == TAB_DSC_POSTBUILD:
345 PostbuildValue = Record[2]
346 if Record[2][0] == '"':
347 if Record[2][-1] != '"':
348 EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_POSTBUILD,
349 File=self.MetaFile, Line=Record[-1])
350 PostbuildValue = Record[2][1:-1]
351 self._Postbuild = PostbuildValue
352 elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES:
353 self._SupArchList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)
354 elif Name == TAB_DSC_DEFINES_BUILD_TARGETS:
355 self._BuildTargets = GetSplitValueList(Record[2])
356 elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER:
357 if self._SkuName is None:
358 self._SkuName = Record[2]
359 if GlobalData.gSKUID_CMD:
360 self._SkuName = GlobalData.gSKUID_CMD
361 elif Name == TAB_DSC_DEFINES_PCD_INFO_GENERATION:
362 self._PcdInfoFlag = Record[2]
363 elif Name == TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION:
364 self._VarCheckFlag = Record[2]
365 elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS:
366 try:
367 self._LoadFixAddress = int (Record[2], 0)
368 except:
369 EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record[2]))
370 elif Name == TAB_DSC_DEFINES_RFC_LANGUAGES:
371 if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:
372 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"',
373 File=self.MetaFile, Line=Record[-1])
374 LanguageCodes = Record[2][1:-1]
375 if not LanguageCodes:
376 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
377 File=self.MetaFile, Line=Record[-1])
378 LanguageList = GetSplitValueList(LanguageCodes, TAB_SEMI_COLON_SPLIT)
379 # check whether there is empty entries in the list
380 if None in LanguageList:
381 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more empty language code is in RFC_LANGUAGES statement',
382 File=self.MetaFile, Line=Record[-1])
383 self._RFCLanguages = LanguageList
384 elif Name == TAB_DSC_DEFINES_ISO_LANGUAGES:
385 if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:
386 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
387 File=self.MetaFile, Line=Record[-1])
388 LanguageCodes = Record[2][1:-1]
389 if not LanguageCodes:
390 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
391 File=self.MetaFile, Line=Record[-1])
392 if len(LanguageCodes) % 3:
393 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'bad ISO639-2 format for ISO_LANGUAGES',
394 File=self.MetaFile, Line=Record[-1])
395 LanguageList = []
396 for i in range(0, len(LanguageCodes), 3):
397 LanguageList.append(LanguageCodes[i:i + 3])
398 self._ISOLanguages = LanguageList
399 elif Name == TAB_DSC_DEFINES_VPD_TOOL_GUID:
400 #
401 # try to convert GUID to a real UUID value to see whether the GUID is format
402 # for VPD_TOOL_GUID is correct.
403 #
404 try:
405 uuid.UUID(Record[2])
406 except:
407 EdkLogger.error("build", FORMAT_INVALID, "Invalid GUID format for VPD_TOOL_GUID", File=self.MetaFile)
408 self._VpdToolGuid = Record[2]
409 elif Name in self:
410 self[Name] = Record[2]
411 # set _Header to non-None in order to avoid database re-querying
412 self._Header = 'DUMMY'
413
414 ## Retrieve platform name
415 @property
416 def PlatformName(self):
417 if self._PlatformName is None:
418 if self._Header is None:
419 self._GetHeaderInfo()
420 if self._PlatformName is None:
421 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_NAME", File=self.MetaFile)
422 return self._PlatformName
423
424 @property
425 def Platform(self):
426 return self.PlatformName
427
428 ## Retrieve file guid
429 @property
430 def Guid(self):
431 if self._Guid is None:
432 if self._Header is None:
433 self._GetHeaderInfo()
434 if self._Guid is None:
435 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_GUID", File=self.MetaFile)
436 return self._Guid
437
438 ## Retrieve platform version
439 @property
440 def Version(self):
441 if self._Version is None:
442 if self._Header is None:
443 self._GetHeaderInfo()
444 if self._Version is None:
445 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_VERSION", File=self.MetaFile)
446 return self._Version
447
448 ## Retrieve platform description file version
449 @property
450 def DscSpecification(self):
451 if self._DscSpecification is None:
452 if self._Header is None:
453 self._GetHeaderInfo()
454 if self._DscSpecification is None:
455 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No DSC_SPECIFICATION", File=self.MetaFile)
456 return self._DscSpecification
457
458 ## Retrieve OUTPUT_DIRECTORY
459 @property
460 def OutputDirectory(self):
461 if self._OutputDirectory is None:
462 if self._Header is None:
463 self._GetHeaderInfo()
464 if self._OutputDirectory is None:
465 self._OutputDirectory = os.path.join("Build", self._PlatformName)
466 return self._OutputDirectory
467
468 ## Retrieve SUPPORTED_ARCHITECTURES
469 @property
470 def SupArchList(self):
471 if self._SupArchList is None:
472 if self._Header is None:
473 self._GetHeaderInfo()
474 if self._SupArchList is None:
475 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No SUPPORTED_ARCHITECTURES", File=self.MetaFile)
476 return self._SupArchList
477
478 ## Retrieve BUILD_TARGETS
479 @property
480 def BuildTargets(self):
481 if self._BuildTargets is None:
482 if self._Header is None:
483 self._GetHeaderInfo()
484 if self._BuildTargets is None:
485 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BUILD_TARGETS", File=self.MetaFile)
486 return self._BuildTargets
487
488 @property
489 def PcdInfoFlag(self):
490 if self._PcdInfoFlag is None or self._PcdInfoFlag.upper() == 'FALSE':
491 return False
492 elif self._PcdInfoFlag.upper() == 'TRUE':
493 return True
494 else:
495 return False
496
497 @property
498 def VarCheckFlag(self):
499 if self._VarCheckFlag is None or self._VarCheckFlag.upper() == 'FALSE':
500 return False
501 elif self._VarCheckFlag.upper() == 'TRUE':
502 return True
503 else:
504 return False
505
506 # # Retrieve SKUID_IDENTIFIER
507 @property
508 def SkuName(self):
509 if self._SkuName is None:
510 if self._Header is None:
511 self._GetHeaderInfo()
512 if self._SkuName is None:
513 self._SkuName = TAB_DEFAULT
514 return self._SkuName
515
516 ## Override SKUID_IDENTIFIER
517 @SkuName.setter
518 def SkuName(self, Value):
519 self._SkuName = Value
520
521 @property
522 def FlashDefinition(self):
523 if self._FlashDefinition is None:
524 if self._Header is None:
525 self._GetHeaderInfo()
526 if self._FlashDefinition is None:
527 self._FlashDefinition = ''
528 return self._FlashDefinition
529
530 @property
531 def Prebuild(self):
532 if self._Prebuild is None:
533 if self._Header is None:
534 self._GetHeaderInfo()
535 if self._Prebuild is None:
536 self._Prebuild = ''
537 return self._Prebuild
538
539 @property
540 def Postbuild(self):
541 if self._Postbuild is None:
542 if self._Header is None:
543 self._GetHeaderInfo()
544 if self._Postbuild is None:
545 self._Postbuild = ''
546 return self._Postbuild
547
548 ## Retrieve FLASH_DEFINITION
549 @property
550 def BuildNumber(self):
551 if self._BuildNumber is None:
552 if self._Header is None:
553 self._GetHeaderInfo()
554 if self._BuildNumber is None:
555 self._BuildNumber = ''
556 return self._BuildNumber
557
558 ## Retrieve MAKEFILE_NAME
559 @property
560 def MakefileName(self):
561 if self._MakefileName is None:
562 if self._Header is None:
563 self._GetHeaderInfo()
564 if self._MakefileName is None:
565 self._MakefileName = ''
566 return self._MakefileName
567
568 ## Retrieve BsBaseAddress
569 @property
570 def BsBaseAddress(self):
571 if self._BsBaseAddress is None:
572 if self._Header is None:
573 self._GetHeaderInfo()
574 if self._BsBaseAddress is None:
575 self._BsBaseAddress = ''
576 return self._BsBaseAddress
577
578 ## Retrieve RtBaseAddress
579 @property
580 def RtBaseAddress(self):
581 if self._RtBaseAddress is None:
582 if self._Header is None:
583 self._GetHeaderInfo()
584 if self._RtBaseAddress is None:
585 self._RtBaseAddress = ''
586 return self._RtBaseAddress
587
588 ## Retrieve the top address for the load fix address
589 @property
590 def LoadFixAddress(self):
591 if self._LoadFixAddress is None:
592 if self._Header is None:
593 self._GetHeaderInfo()
594
595 if self._LoadFixAddress is None:
596 self._LoadFixAddress = self._Macros.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS, '0')
597
598 try:
599 self._LoadFixAddress = int (self._LoadFixAddress, 0)
600 except:
601 EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self._LoadFixAddress))
602
603 #
604 # If command line defined, should override the value in DSC file.
605 #
606 if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData.gCommandLineDefines:
607 try:
608 self._LoadFixAddress = int(GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
609 except:
610 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']))
611
612 if self._LoadFixAddress < 0:
613 EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self._LoadFixAddress))
614 if self._LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self._LoadFixAddress % 0x1000 != 0:
615 EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self._LoadFixAddress))
616
617 return self._LoadFixAddress
618
619 ## Retrieve RFCLanguage filter
620 @property
621 def RFCLanguages(self):
622 if self._RFCLanguages is None:
623 if self._Header is None:
624 self._GetHeaderInfo()
625 if self._RFCLanguages is None:
626 self._RFCLanguages = []
627 return self._RFCLanguages
628
629 ## Retrieve ISOLanguage filter
630 @property
631 def ISOLanguages(self):
632 if self._ISOLanguages is None:
633 if self._Header is None:
634 self._GetHeaderInfo()
635 if self._ISOLanguages is None:
636 self._ISOLanguages = []
637 return self._ISOLanguages
638
639 ## Retrieve the GUID string for VPD tool
640 @property
641 def VpdToolGuid(self):
642 if self._VpdToolGuid is None:
643 if self._Header is None:
644 self._GetHeaderInfo()
645 if self._VpdToolGuid is None:
646 self._VpdToolGuid = ''
647 return self._VpdToolGuid
648
649 ## Retrieve [SkuIds] section information
650 @property
651 def SkuIds(self):
652 if self._SkuIds is None:
653 self._SkuIds = OrderedDict()
654 RecordList = self._RawData[MODEL_EFI_SKU_ID, self._Arch]
655 for Record in RecordList:
656 if not Record[0]:
657 EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID number',
658 File=self.MetaFile, Line=Record[-1])
659 if not Record[1]:
660 EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID name',
661 File=self.MetaFile, Line=Record[-1])
662 if not Pattern.match(Record[0]) and not HexPattern.match(Record[0]):
663 EdkLogger.error('build', FORMAT_INVALID, "The format of the Sku ID number is invalid. It only support Integer and HexNumber",
664 File=self.MetaFile, Line=Record[-1])
665 if not SkuIdPattern.match(Record[1]) or (Record[2] and not SkuIdPattern.match(Record[2])):
666 EdkLogger.error('build', FORMAT_INVALID, "The format of the Sku ID name is invalid. The correct format is '(a-zA-Z_)(a-zA-Z0-9_)*'",
667 File=self.MetaFile, Line=Record[-1])
668 self._SkuIds[Record[1].upper()] = (str(DscBuildData.ToInt(Record[0])), Record[1].upper(), Record[2].upper())
669 if TAB_DEFAULT not in self._SkuIds:
670 self._SkuIds[TAB_DEFAULT] = ("0", TAB_DEFAULT, TAB_DEFAULT)
671 if TAB_COMMON not in self._SkuIds:
672 self._SkuIds[TAB_COMMON] = ("0", TAB_DEFAULT, TAB_DEFAULT)
673 return self._SkuIds
674
675 @staticmethod
676 def ToInt(intstr):
677 return int(intstr, 16) if intstr.upper().startswith("0X") else int(intstr)
678
679 def _GetDefaultStores(self):
680 if self.DefaultStores is None:
681 self.DefaultStores = OrderedDict()
682 RecordList = self._RawData[MODEL_EFI_DEFAULT_STORES, self._Arch]
683 for Record in RecordList:
684 if not Record[0]:
685 EdkLogger.error('build', FORMAT_INVALID, 'No DefaultStores ID number',
686 File=self.MetaFile, Line=Record[-1])
687 if not Record[1]:
688 EdkLogger.error('build', FORMAT_INVALID, 'No DefaultStores ID name',
689 File=self.MetaFile, Line=Record[-1])
690 if not Pattern.match(Record[0]) and not HexPattern.match(Record[0]):
691 EdkLogger.error('build', FORMAT_INVALID, "The format of the DefaultStores ID number is invalid. It only support Integer and HexNumber",
692 File=self.MetaFile, Line=Record[-1])
693 if not IsValidWord(Record[1]):
694 EdkLogger.error('build', FORMAT_INVALID, "The format of the DefaultStores ID name is invalid. The correct format is '(a-zA-Z0-9_)(a-zA-Z0-9_-.)*'",
695 File=self.MetaFile, Line=Record[-1])
696 self.DefaultStores[Record[1].upper()] = (DscBuildData.ToInt(Record[0]), Record[1].upper())
697 if TAB_DEFAULT_STORES_DEFAULT not in self.DefaultStores:
698 self.DefaultStores[TAB_DEFAULT_STORES_DEFAULT] = (0, TAB_DEFAULT_STORES_DEFAULT)
699 GlobalData.gDefaultStores = sorted(self.DefaultStores.keys())
700 return self.DefaultStores
701
702 ## Retrieve [Components] section information
703 @property
704 def Modules(self):
705 if self._Modules is not None:
706 return self._Modules
707
708 self._Modules = OrderedDict()
709 RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]
710 Macros = self._Macros
711 Macros["EDK_SOURCE"] = GlobalData.gEcpSource
712 for Record in RecordList:
713 DuplicatedFile = False
714
715 ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
716 ModuleId = Record[6]
717 LineNo = Record[7]
718
719 # check the file validation
720 ErrorCode, ErrorInfo = ModuleFile.Validate('.inf')
721 if ErrorCode != 0:
722 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
723 ExtraData=ErrorInfo)
724 # Check duplication
725 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
726 if self._Arch != TAB_ARCH_COMMON and ModuleFile in self._Modules:
727 DuplicatedFile = True
728
729 Module = ModuleBuildClassObject()
730 Module.MetaFile = ModuleFile
731
732 # get module private library instance
733 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, ModuleId]
734 for Record in RecordList:
735 LibraryClass = Record[0]
736 LibraryPath = PathClass(NormPath(Record[1], Macros), GlobalData.gWorkspace, Arch=self._Arch)
737 LineNo = Record[-1]
738
739 # check the file validation
740 ErrorCode, ErrorInfo = LibraryPath.Validate('.inf')
741 if ErrorCode != 0:
742 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
743 ExtraData=ErrorInfo)
744
745 if LibraryClass == '' or LibraryClass == 'NULL':
746 self._NullLibraryNumber += 1
747 LibraryClass = 'NULL%d' % self._NullLibraryNumber
748 EdkLogger.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile, LibraryPath, LibraryClass))
749 Module.LibraryClasses[LibraryClass] = LibraryPath
750 if LibraryPath not in self.LibraryInstances:
751 self.LibraryInstances.append(LibraryPath)
752
753 # get module private PCD setting
754 for Type in [MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE, \
755 MODEL_PCD_FEATURE_FLAG, MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]:
756 RecordList = self._RawData[Type, self._Arch, None, ModuleId]
757 for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
758 TokenList = GetSplitValueList(Setting)
759 DefaultValue = TokenList[0]
760 # the format is PcdName| Value | VOID* | MaxDatumSize
761 if len(TokenList) > 2:
762 MaxDatumSize = TokenList[2]
763 else:
764 MaxDatumSize = ''
765 TypeString = self._PCD_TYPE_STRING_[Type]
766 Pcd = PcdClassObject(
767 PcdCName,
768 TokenSpaceGuid,
769 TypeString,
770 '',
771 DefaultValue,
772 '',
773 MaxDatumSize,
774 {},
775 False,
776 None
777 )
778 Module.Pcds[PcdCName, TokenSpaceGuid] = Pcd
779
780 # get module private build options
781 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, None, ModuleId]
782 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
783 if (ToolChainFamily, ToolChain) not in Module.BuildOptions:
784 Module.BuildOptions[ToolChainFamily, ToolChain] = Option
785 else:
786 OptionString = Module.BuildOptions[ToolChainFamily, ToolChain]
787 Module.BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option
788
789 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, None, ModuleId]
790 if DuplicatedFile and not RecordList:
791 EdkLogger.error('build', FILE_DUPLICATED, File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)
792 if RecordList:
793 if len(RecordList) != 1:
794 EdkLogger.error('build', OPTION_UNKNOWN, 'Only FILE_GUID can be listed in <Defines> section.',
795 File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)
796 ModuleFile = ProcessDuplicatedInf(ModuleFile, RecordList[0][2], GlobalData.gWorkspace)
797 ModuleFile.Arch = self._Arch
798
799 self._Modules[ModuleFile] = Module
800 return self._Modules
801
802 ## Retrieve all possible library instances used in this platform
803 @property
804 def LibraryInstances(self):
805 if self._LibraryInstances is None:
806 self.LibraryClasses
807 return self._LibraryInstances
808
809 ## Retrieve [LibraryClasses] information
810 @property
811 def LibraryClasses(self):
812 if self._LibraryClasses is None:
813 self._LibraryInstances = []
814 #
815 # tdict is a special dict kind of type, used for selecting correct
816 # library instance for given library class and module type
817 #
818 LibraryClassDict = tdict(True, 3)
819 # track all library class names
820 LibraryClassSet = set()
821 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, -1]
822 Macros = self._Macros
823 for Record in RecordList:
824 LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy, Dummy, LineNo = Record
825 if LibraryClass == '' or LibraryClass == 'NULL':
826 self._NullLibraryNumber += 1
827 LibraryClass = 'NULL%d' % self._NullLibraryNumber
828 EdkLogger.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch, LibraryInstance, LibraryClass))
829 LibraryClassSet.add(LibraryClass)
830 LibraryInstance = PathClass(NormPath(LibraryInstance, Macros), GlobalData.gWorkspace, Arch=self._Arch)
831 # check the file validation
832 ErrorCode, ErrorInfo = LibraryInstance.Validate('.inf')
833 if ErrorCode != 0:
834 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
835 ExtraData=ErrorInfo)
836
837 if ModuleType != TAB_COMMON and ModuleType not in SUP_MODULE_LIST:
838 EdkLogger.error('build', OPTION_UNKNOWN, "Unknown module type [%s]" % ModuleType,
839 File=self.MetaFile, ExtraData=LibraryInstance, Line=LineNo)
840 LibraryClassDict[Arch, ModuleType, LibraryClass] = LibraryInstance
841 if LibraryInstance not in self._LibraryInstances:
842 self._LibraryInstances.append(LibraryInstance)
843
844 # resolve the specific library instance for each class and each module type
845 self._LibraryClasses = tdict(True)
846 for LibraryClass in LibraryClassSet:
847 # try all possible module types
848 for ModuleType in SUP_MODULE_LIST:
849 LibraryInstance = LibraryClassDict[self._Arch, ModuleType, LibraryClass]
850 if LibraryInstance is None:
851 continue
852 self._LibraryClasses[LibraryClass, ModuleType] = LibraryInstance
853
854 # for Edk style library instances, which are listed in different section
855 Macros["EDK_SOURCE"] = GlobalData.gEcpSource
856 RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch]
857 for Record in RecordList:
858 File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
859 LineNo = Record[-1]
860 # check the file validation
861 ErrorCode, ErrorInfo = File.Validate('.inf')
862 if ErrorCode != 0:
863 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
864 ExtraData=ErrorInfo)
865 if File not in self._LibraryInstances:
866 self._LibraryInstances.append(File)
867 #
868 # we need the module name as the library class name, so we have
869 # to parse it here. (self._Bdb[] will trigger a file parse if it
870 # hasn't been parsed)
871 #
872 Library = self._Bdb[File, self._Arch, self._Target, self._Toolchain]
873 self._LibraryClasses[Library.BaseName, ':dummy:'] = Library
874 return self._LibraryClasses
875
876 def _ValidatePcd(self, PcdCName, TokenSpaceGuid, Setting, PcdType, LineNo):
877 if self._DecPcds is None:
878
879 FdfInfList = []
880 if GlobalData.gFdfParser:
881 FdfInfList = GlobalData.gFdfParser.Profile.InfList
882
883 PkgSet = set()
884 for Inf in FdfInfList:
885 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)
886 if ModuleFile in self._Modules:
887 continue
888 ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
889 PkgSet.update(ModuleData.Packages)
890
891 self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain, PkgSet)
892 self._GuidDict.update(GlobalData.gPlatformPcds)
893
894 if (PcdCName, TokenSpaceGuid) not in self._DecPcds:
895 EdkLogger.error('build', PARSER_ERROR,
896 "Pcd (%s.%s) defined in DSC is not declared in DEC files referenced in INF files in FDF. Arch: ['%s']" % (TokenSpaceGuid, PcdCName, self._Arch),
897 File=self.MetaFile, Line=LineNo)
898 ValueList, IsValid, Index = AnalyzeDscPcd(Setting, PcdType, self._DecPcds[PcdCName, TokenSpaceGuid].DatumType)
899 if not IsValid:
900 if PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:
901 EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,
902 ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))
903 else:
904 if ValueList[2] == '-1':
905 EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,
906 ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))
907 if ValueList[Index]:
908 DatumType = self._DecPcds[PcdCName, TokenSpaceGuid].DatumType
909 try:
910 ValueList[Index] = ValueExpressionEx(ValueList[Index], DatumType, self._GuidDict)(True)
911 except BadExpression as Value:
912 EdkLogger.error('Parser', FORMAT_INVALID, Value, File=self.MetaFile, Line=LineNo,
913 ExtraData="PCD [%s.%s] Value \"%s\" " % (
914 TokenSpaceGuid, PcdCName, ValueList[Index]))
915 except EvaluationException as Excpt:
916 if hasattr(Excpt, 'Pcd'):
917 if Excpt.Pcd in GlobalData.gPlatformOtherPcds:
918 EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"
919 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
920 " of the DSC file" % Excpt.Pcd,
921 File=self.MetaFile, Line=LineNo)
922 else:
923 EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,
924 File=self.MetaFile, Line=LineNo)
925 else:
926 EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),
927 File=self.MetaFile, Line=LineNo)
928
929 if ValueList[Index]:
930 Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName, TokenSpaceGuid].DatumType, ValueList[Index])
931 if not Valid:
932 EdkLogger.error('build', FORMAT_INVALID, ErrStr, File=self.MetaFile, Line=LineNo,
933 ExtraData="%s.%s" % (TokenSpaceGuid, PcdCName))
934 if PcdType in (MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT, MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE):
935 if self._DecPcds[PcdCName, TokenSpaceGuid].DatumType.strip() != ValueList[1].strip():
936 EdkLogger.error('build', FORMAT_INVALID, "Pcd datumtype used in DSC file is not the same as its declaration in DEC file.", File=self.MetaFile, Line=LineNo,
937 ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))
938 if (TokenSpaceGuid + '.' + PcdCName) in GlobalData.gPlatformPcds:
939 if GlobalData.gPlatformPcds[TokenSpaceGuid + '.' + PcdCName] != ValueList[Index]:
940 GlobalData.gPlatformPcds[TokenSpaceGuid + '.' + PcdCName] = ValueList[Index]
941 return ValueList
942
943 def _FilterPcdBySkuUsage(self, Pcds):
944 available_sku = self.SkuIdMgr.AvailableSkuIdSet
945 sku_usage = self.SkuIdMgr.SkuUsageType
946 if sku_usage == SkuClass.SINGLE:
947 for pcdname in Pcds:
948 pcd = Pcds[pcdname]
949 Pcds[pcdname].SkuInfoList = {TAB_DEFAULT:pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}
950 if isinstance(pcd, StructurePcd) and pcd.SkuOverrideValues:
951 Pcds[pcdname].SkuOverrideValues = {TAB_DEFAULT:pcd.SkuOverrideValues[skuid] for skuid in pcd.SkuOverrideValues if skuid in available_sku}
952 else:
953 for pcdname in Pcds:
954 pcd = Pcds[pcdname]
955 Pcds[pcdname].SkuInfoList = {skuid:pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}
956 if isinstance(pcd, StructurePcd) and pcd.SkuOverrideValues:
957 Pcds[pcdname].SkuOverrideValues = {skuid:pcd.SkuOverrideValues[skuid] for skuid in pcd.SkuOverrideValues if skuid in available_sku}
958 return Pcds
959
960 def CompleteHiiPcdsDefaultStores(self, Pcds):
961 HiiPcd = [Pcds[pcd] for pcd in Pcds if Pcds[pcd].Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]]
962 DefaultStoreMgr = DefaultStore(self.DefaultStores)
963 for pcd in HiiPcd:
964 for skuid in pcd.SkuInfoList:
965 skuobj = pcd.SkuInfoList.get(skuid)
966 if TAB_DEFAULT_STORES_DEFAULT not in skuobj.DefaultStoreDict:
967 PcdDefaultStoreSet = set(defaultstorename for defaultstorename in skuobj.DefaultStoreDict)
968 mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)
969 skuobj.DefaultStoreDict[TAB_DEFAULT_STORES_DEFAULT] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])
970 return Pcds
971
972 def RecoverCommandLinePcd(self):
973 def UpdateCommandLineValue(pcd):
974 if pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
975 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
976 pcd.PcdValueFromComm = pcd.DefaultValue
977 elif pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
978 pcd.PcdValueFromComm = pcd.SkuInfoList.get(TAB_DEFAULT).HiiDefaultValue
979 else:
980 pcd.PcdValueFromComm = pcd.SkuInfoList.get(TAB_DEFAULT).DefaultValue
981 for pcd in self._Pcds:
982 if isinstance(self._Pcds[pcd], StructurePcd) and (self._Pcds[pcd].PcdValueFromComm or self._Pcds[pcd].PcdFieldValueFromComm):
983 UpdateCommandLineValue(self._Pcds[pcd])
984
985 def __ParsePcdFromCommandLine(self):
986 if GlobalData.BuildOptionPcd:
987 for i, pcd in enumerate(GlobalData.BuildOptionPcd):
988 if isinstance(pcd, tuple):
989 continue
990 (pcdname, pcdvalue) = pcd.split('=')
991 if not pcdvalue:
992 EdkLogger.error('build', AUTOGEN_ERROR, "No Value specified for the PCD %s." % (pcdname))
993 if '.' in pcdname:
994 (Name1, Name2) = pcdname.split('.', 1)
995 if "." in Name2:
996 (Name3, FieldName) = Name2.split(".", 1)
997 if ((Name3, Name1)) in self.DecPcds:
998 HasTokenSpace = True
999 TokenCName = Name3
1000 TokenSpaceGuidCName = Name1
1001 else:
1002 FieldName = Name2
1003 TokenCName = Name1
1004 TokenSpaceGuidCName = ''
1005 HasTokenSpace = False
1006 else:
1007 if ((Name2, Name1)) in self.DecPcds:
1008 HasTokenSpace = True
1009 TokenCName = Name2
1010 TokenSpaceGuidCName = Name1
1011 FieldName =""
1012 else:
1013 FieldName = Name2
1014 TokenCName = Name1
1015 TokenSpaceGuidCName = ''
1016 HasTokenSpace = False
1017 else:
1018 FieldName = ""
1019 TokenCName = pcdname
1020 TokenSpaceGuidCName = ''
1021 HasTokenSpace = False
1022 TokenSpaceGuidCNameList = []
1023 FoundFlag = False
1024 PcdDatumType = ''
1025 DisplayName = TokenCName
1026 if FieldName:
1027 DisplayName = TokenCName + '.' + FieldName
1028 if not HasTokenSpace:
1029 for key in self.DecPcds:
1030 PcdItem = self.DecPcds[key]
1031 if TokenCName == PcdItem.TokenCName:
1032 if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:
1033 if len (TokenSpaceGuidCNameList) < 1:
1034 TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)
1035 TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName
1036 PcdDatumType = PcdItem.DatumType
1037 FoundFlag = True
1038 else:
1039 EdkLogger.error(
1040 'build',
1041 AUTOGEN_ERROR,
1042 "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (DisplayName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])
1043 )
1044 else:
1045 if (TokenCName, TokenSpaceGuidCName) in self.DecPcds:
1046 PcdDatumType = self.DecPcds[(TokenCName, TokenSpaceGuidCName)].DatumType
1047 FoundFlag = True
1048 if not FoundFlag:
1049 if HasTokenSpace:
1050 EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s.%s is not found in the DEC file." % (TokenSpaceGuidCName, DisplayName))
1051 else:
1052 EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s is not found in the DEC file." % (DisplayName))
1053 pcdvalue = pcdvalue.replace("\\\\\\'", '\\\\\\"').replace('\\\'', '\'').replace('\\\\\\"', "\\'")
1054 if FieldName:
1055 pcdvalue = DscBuildData.HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, pcdvalue, PcdDatumType, self._GuidDict, FieldName)
1056 else:
1057 pcdvalue = DscBuildData.HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, pcdvalue, PcdDatumType, self._GuidDict)
1058 IsValid, Cause = CheckPcdDatum(PcdDatumType, pcdvalue)
1059 if not IsValid:
1060 EdkLogger.error("build", FORMAT_INVALID, Cause, ExtraData="%s.%s" % (TokenSpaceGuidCName, TokenCName))
1061 GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, FieldName, pcdvalue, ("build command options", 1))
1062
1063 for BuildData in self._Bdb._CACHE_.values():
1064 if BuildData.MetaFile.Ext == '.dec' or BuildData.MetaFile.Ext == '.dsc':
1065 continue
1066 for key in BuildData.Pcds:
1067 PcdItem = BuildData.Pcds[key]
1068 if (TokenSpaceGuidCName, TokenCName) == (PcdItem.TokenSpaceGuidCName, PcdItem.TokenCName) and FieldName =="":
1069 PcdItem.DefaultValue = pcdvalue
1070
1071 @staticmethod
1072 def HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, PcdValue, PcdDatumType, GuidDict, FieldName=''):
1073 if FieldName:
1074 IsArray = False
1075 TokenCName += '.' + FieldName
1076 if PcdValue.startswith('H'):
1077 if FieldName and IsFieldValueAnArray(PcdValue[1:]):
1078 PcdDatumType = TAB_VOID
1079 IsArray = True
1080 if FieldName and not IsArray:
1081 return PcdValue
1082 try:
1083 PcdValue = ValueExpressionEx(PcdValue[1:], PcdDatumType, GuidDict)(True)
1084 except BadExpression as Value:
1085 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
1086 (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
1087 elif PcdValue.startswith("L'") or PcdValue.startswith("'"):
1088 if FieldName and IsFieldValueAnArray(PcdValue):
1089 PcdDatumType = TAB_VOID
1090 IsArray = True
1091 if FieldName and not IsArray:
1092 return PcdValue
1093 try:
1094 PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)
1095 except BadExpression as Value:
1096 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
1097 (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
1098 elif PcdValue.startswith('L'):
1099 PcdValue = 'L"' + PcdValue[1:] + '"'
1100 if FieldName and IsFieldValueAnArray(PcdValue):
1101 PcdDatumType = TAB_VOID
1102 IsArray = True
1103 if FieldName and not IsArray:
1104 return PcdValue
1105 try:
1106 PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)
1107 except BadExpression as Value:
1108 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
1109 (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
1110 else:
1111 if PcdValue.upper() == 'FALSE':
1112 PcdValue = str(0)
1113 if PcdValue.upper() == 'TRUE':
1114 PcdValue = str(1)
1115 if not FieldName:
1116 if PcdDatumType not in TAB_PCD_NUMERIC_TYPES:
1117 PcdValue = '"' + PcdValue + '"'
1118 else:
1119 IsArray = False
1120 Base = 10
1121 if PcdValue.upper().startswith('0X'):
1122 Base = 16
1123 try:
1124 Num = int(PcdValue, Base)
1125 except:
1126 PcdValue = '"' + PcdValue + '"'
1127 if IsFieldValueAnArray(PcdValue):
1128 PcdDatumType = TAB_VOID
1129 IsArray = True
1130 if not IsArray:
1131 return PcdValue
1132 try:
1133 PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)
1134 except BadExpression as Value:
1135 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
1136 (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
1137 return PcdValue
1138
1139 ## Retrieve all PCD settings in platform
1140 @property
1141 def Pcds(self):
1142 if self._Pcds is None:
1143 self._Pcds = OrderedDict()
1144 self.__ParsePcdFromCommandLine()
1145 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))
1146 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))
1147 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))
1148 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT))
1149 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII))
1150 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD))
1151 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT))
1152 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII))
1153 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD))
1154
1155 self._Pcds = self.CompletePcdValues(self._Pcds)
1156 self._Pcds = self.OverrideByFdfOverAll(self._Pcds)
1157 self._Pcds = self.OverrideByCommOverAll(self._Pcds)
1158 self._Pcds = self.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST, self._Pcds)
1159 self._Pcds = self.CompleteHiiPcdsDefaultStores(self._Pcds)
1160 self._Pcds = self._FilterPcdBySkuUsage(self._Pcds)
1161
1162 self.RecoverCommandLinePcd()
1163 return self._Pcds
1164
1165 ## Retrieve [BuildOptions]
1166 @property
1167 def BuildOptions(self):
1168 if self._BuildOptions is None:
1169 self._BuildOptions = OrderedDict()
1170 #
1171 # Retrieve build option for EDKII and EDK style module
1172 #
1173 for CodeBase in (EDKII_NAME, EDK_NAME):
1174 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, CodeBase]
1175 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
1176 if Dummy3.upper() != TAB_COMMON:
1177 continue
1178 CurKey = (ToolChainFamily, ToolChain, CodeBase)
1179 #
1180 # Only flags can be appended
1181 #
1182 if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
1183 self._BuildOptions[CurKey] = Option
1184 else:
1185 if ' ' + Option not in self._BuildOptions[CurKey]:
1186 self._BuildOptions[CurKey] += ' ' + Option
1187 return self._BuildOptions
1188
1189 def GetBuildOptionsByModuleType(self, Edk, ModuleType):
1190 if self._ModuleTypeOptions is None:
1191 self._ModuleTypeOptions = OrderedDict()
1192 if (Edk, ModuleType) not in self._ModuleTypeOptions:
1193 options = OrderedDict()
1194 self._ModuleTypeOptions[Edk, ModuleType] = options
1195 DriverType = '%s.%s' % (Edk, ModuleType)
1196 CommonDriverType = '%s.%s' % (TAB_COMMON, ModuleType)
1197 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch]
1198 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
1199 Type = Dummy2 + '.' + Dummy3
1200 if Type.upper() == DriverType.upper() or Type.upper() == CommonDriverType.upper():
1201 Key = (ToolChainFamily, ToolChain, Edk)
1202 if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
1203 options[Key] = Option
1204 else:
1205 if ' ' + Option not in options[Key]:
1206 options[Key] += ' ' + Option
1207 return self._ModuleTypeOptions[Edk, ModuleType]
1208
1209 @staticmethod
1210 def GetStructurePcdInfo(PcdSet):
1211 structure_pcd_data = defaultdict(list)
1212 for item in PcdSet:
1213 structure_pcd_data[(item[0], item[1])].append(item)
1214
1215 return structure_pcd_data
1216
1217 @staticmethod
1218 def OverrideByFdf(StruPcds,workspace):
1219 if GlobalData.gFdfParser is None:
1220 return StruPcds
1221 StructurePcdInFdf = OrderedDict()
1222 fdfpcd = GlobalData.gFdfParser.Profile.PcdDict
1223 fdfpcdlocation = GlobalData.gFdfParser.Profile.PcdLocalDict
1224 for item in fdfpcd :
1225 if len(item[2]) and (item[0],item[1]) in StruPcds:
1226 StructurePcdInFdf[(item[1],item[0],item[2] )] = fdfpcd[item]
1227 GlobalPcds = {(item[0],item[1]) for item in StructurePcdInFdf}
1228 for Pcd in StruPcds.values():
1229 if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) not in GlobalPcds:
1230 continue
1231 FieldValues = OrderedDict()
1232 for item in StructurePcdInFdf:
1233 if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) == (item[0],item[1]) and item[2]:
1234 FieldValues[item[2]] = StructurePcdInFdf[item]
1235 for field in FieldValues:
1236 if field not in Pcd.PcdFieldValueFromFdf:
1237 Pcd.PcdFieldValueFromFdf[field] = ["","",""]
1238 Pcd.PcdFieldValueFromFdf[field][0] = FieldValues[field]
1239 Pcd.PcdFieldValueFromFdf[field][1] = os.path.relpath(fdfpcdlocation[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName,field)][0],workspace)
1240 Pcd.PcdFieldValueFromFdf[field][2] = fdfpcdlocation[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName,field)][1]
1241
1242 return StruPcds
1243
1244 @staticmethod
1245 def OverrideByComm(StruPcds):
1246 StructurePcdInCom = OrderedDict()
1247 for item in GlobalData.BuildOptionPcd:
1248 if len(item) == 5 and (item[1], item[0]) in StruPcds:
1249 StructurePcdInCom[(item[0], item[1], item[2] )] = (item[3], item[4])
1250 GlobalPcds = {(item[0], item[1]) for item in StructurePcdInCom}
1251 for Pcd in StruPcds.values():
1252 if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) not in GlobalPcds:
1253 continue
1254 FieldValues = OrderedDict()
1255 for item in StructurePcdInCom:
1256 if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) == (item[0], item[1]) and item[2]:
1257 FieldValues[item[2]] = StructurePcdInCom[item]
1258 for field in FieldValues:
1259 if field not in Pcd.PcdFieldValueFromComm:
1260 Pcd.PcdFieldValueFromComm[field] = ["", "", ""]
1261 Pcd.PcdFieldValueFromComm[field][0] = FieldValues[field][0]
1262 Pcd.PcdFieldValueFromComm[field][1] = FieldValues[field][1][0]
1263 Pcd.PcdFieldValueFromComm[field][2] = FieldValues[field][1][1]
1264 return StruPcds
1265
1266 def OverrideByCommOverAll(self,AllPcds):
1267 def CheckStructureInComm(commpcds):
1268 if not commpcds:
1269 return False
1270 if len(commpcds[0]) == 5:
1271 return True
1272 return False
1273
1274 if CheckStructureInComm(GlobalData.BuildOptionPcd):
1275 StructurePcdInCom = {(item[0], item[1], item[2] ):(item[3], item[4]) for item in GlobalData.BuildOptionPcd } if GlobalData.BuildOptionPcd else {}
1276 NoFiledValues = {(item[0], item[1]):StructurePcdInCom[item] for item in StructurePcdInCom if not item[2]}
1277 else:
1278 NoFiledValues = {(item[0], item[1]):[item[2]] for item in GlobalData.BuildOptionPcd}
1279 for Guid, Name in NoFiledValues:
1280 if (Name, Guid) in AllPcds:
1281 Pcd = AllPcds.get((Name, Guid))
1282 if isinstance(self._DecPcds.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName), None), StructurePcd):
1283 self._DecPcds.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName)).PcdValueFromComm = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
1284 else:
1285 Pcd.PcdValueFromComm = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
1286 Pcd.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
1287 for sku in Pcd.SkuInfoList:
1288 SkuInfo = Pcd.SkuInfoList[sku]
1289 if SkuInfo.DefaultValue:
1290 SkuInfo.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
1291 else:
1292 SkuInfo.HiiDefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
1293 for defaultstore in SkuInfo.DefaultStoreDict:
1294 SkuInfo.DefaultStoreDict[defaultstore] = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
1295 if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII]]:
1296 if Pcd.DatumType == TAB_VOID:
1297 if not Pcd.MaxDatumSize:
1298 Pcd.MaxDatumSize = '0'
1299 CurrentSize = int(Pcd.MaxDatumSize, 16) if Pcd.MaxDatumSize.upper().startswith("0X") else int(Pcd.MaxDatumSize)
1300 OptionSize = len((StringToArray(Pcd.PcdValueFromComm)).split(","))
1301 MaxSize = max(CurrentSize, OptionSize)
1302 Pcd.MaxDatumSize = str(MaxSize)
1303 else:
1304 PcdInDec = self.DecPcds.get((Name, Guid))
1305 if PcdInDec:
1306 PcdInDec.PcdValueFromComm = NoFiledValues[(Guid, Name)][0]
1307 if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
1308 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE],
1309 self._PCD_TYPE_STRING_[MODEL_PCD_FEATURE_FLAG],
1310 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC],
1311 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX]]:
1312 self.Pcds[Name, Guid] = copy.deepcopy(PcdInDec)
1313 self.Pcds[Name, Guid].DefaultValue = NoFiledValues[( Guid, Name)][0]
1314 if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC],
1315 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX]]:
1316 self.Pcds[Name, Guid].SkuInfoList = {TAB_DEFAULT:SkuInfoClass(TAB_DEFAULT, self.SkuIds[TAB_DEFAULT][0], '', '', '', '', '', NoFiledValues[( Guid, Name)][0])}
1317 return AllPcds
1318
1319 def OverrideByFdfOverAll(self,AllPcds):
1320
1321 if GlobalData.gFdfParser is None:
1322 return AllPcds
1323 NoFiledValues = GlobalData.gFdfParser.Profile.PcdDict
1324 for Name,Guid,Field in NoFiledValues:
1325 if len(Field):
1326 continue
1327 Value = NoFiledValues[(Name,Guid,Field)]
1328 if (Name,Guid) in AllPcds:
1329 Pcd = AllPcds.get((Name,Guid))
1330 if isinstance(self._DecPcds.get((Pcd.TokenCName,Pcd.TokenSpaceGuidCName), None),StructurePcd):
1331 self._DecPcds.get((Pcd.TokenCName,Pcd.TokenSpaceGuidCName)).PcdValueFromComm = Value
1332 else:
1333 Pcd.PcdValueFromComm = Value
1334 Pcd.DefaultValue = Value
1335 for sku in Pcd.SkuInfoList:
1336 SkuInfo = Pcd.SkuInfoList[sku]
1337 if SkuInfo.DefaultValue:
1338 SkuInfo.DefaultValue = Value
1339 else:
1340 SkuInfo.HiiDefaultValue = Value
1341 for defaultstore in SkuInfo.DefaultStoreDict:
1342 SkuInfo.DefaultStoreDict[defaultstore] = Value
1343 if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII]]:
1344 if Pcd.DatumType == TAB_VOID:
1345 if not Pcd.MaxDatumSize:
1346 Pcd.MaxDatumSize = '0'
1347 CurrentSize = int(Pcd.MaxDatumSize,16) if Pcd.MaxDatumSize.upper().startswith("0X") else int(Pcd.MaxDatumSize)
1348 OptionSize = len((StringToArray(Pcd.PcdValueFromComm)).split(","))
1349 MaxSize = max(CurrentSize, OptionSize)
1350 Pcd.MaxDatumSize = str(MaxSize)
1351 else:
1352 PcdInDec = self.DecPcds.get((Name,Guid))
1353 if PcdInDec:
1354 PcdInDec.PcdValueFromFdf = Value
1355 if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
1356 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE],
1357 self._PCD_TYPE_STRING_[MODEL_PCD_FEATURE_FLAG]]:
1358 self.Pcds[Name, Guid] = copy.deepcopy(PcdInDec)
1359 self.Pcds[Name, Guid].DefaultValue = Value
1360 return AllPcds
1361
1362 def UpdateStructuredPcds(self, TypeList, AllPcds):
1363
1364 DynamicPcdType = [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
1365 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
1366 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],
1367 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],
1368 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],
1369 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]
1370
1371 Pcds = AllPcds
1372 DefaultStoreMgr = DefaultStore(self.DefaultStores)
1373 SkuIds = self.SkuIds
1374 DefaultStores = {storename for pcdobj in AllPcds.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict}
1375
1376 S_PcdSet = []
1377 # Find out all possible PCD candidates for self._Arch
1378 RecordList = []
1379
1380 for Type in TypeList:
1381 RecordList.extend(self._RawData[Type, self._Arch])
1382
1383 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, default_store, Dummy4, Dummy5 in RecordList:
1384 SkuName = SkuName.upper()
1385 default_store = default_store.upper()
1386 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
1387 if SkuName not in SkuIds:
1388 continue
1389
1390 if SkuName in SkuIds and "." in TokenSpaceGuid:
1391 S_PcdSet.append([ TokenSpaceGuid.split(".")[0], TokenSpaceGuid.split(".")[1], PcdCName, SkuName, default_store, Dummy5, AnalyzePcdExpression(Setting)[0]])
1392
1393 # handle pcd value override
1394 StrPcdSet = DscBuildData.GetStructurePcdInfo(S_PcdSet)
1395 S_pcd_set = OrderedDict()
1396 for str_pcd in StrPcdSet:
1397 str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None)
1398 str_pcd_dec = self._DecPcds.get((str_pcd[1], str_pcd[0]), None)
1399 if not isinstance (str_pcd_dec, StructurePcd):
1400 EdkLogger.error('build', PARSER_ERROR,
1401 "Pcd (%s.%s) is not declared as Structure PCD in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),
1402 File=self.MetaFile, Line = StrPcdSet[str_pcd][0][5])
1403 if str_pcd_dec:
1404 str_pcd_obj_str = StructurePcd()
1405 str_pcd_obj_str.copy(str_pcd_dec)
1406 if str_pcd_obj:
1407 str_pcd_obj_str.copy(str_pcd_obj)
1408 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1409 str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
1410 else:
1411 str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
1412 for str_pcd_data in StrPcdSet[str_pcd]:
1413 if str_pcd_data[3] in SkuIds:
1414 str_pcd_obj_str.AddOverrideValue(str_pcd_data[2], str(str_pcd_data[6]), TAB_DEFAULT if str_pcd_data[3] == TAB_COMMON else str_pcd_data[3], TAB_DEFAULT_STORES_DEFAULT if str_pcd_data[4] == TAB_COMMON else str_pcd_data[4], self.MetaFile.File if self.WorkspaceDir not in self.MetaFile.File else self.MetaFile.File[len(self.WorkspaceDir) if self.WorkspaceDir.endswith(os.path.sep) else len(self.WorkspaceDir)+1:], LineNo=str_pcd_data[5])
1415 S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str
1416 else:
1417 EdkLogger.error('build', PARSER_ERROR,
1418 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),
1419 File=self.MetaFile, Line = StrPcdSet[str_pcd][0][5])
1420 # Add the Structure PCD that only defined in DEC, don't have override in DSC file
1421 for Pcd in self.DecPcds:
1422 if isinstance(self._DecPcds[Pcd], StructurePcd):
1423 if Pcd not in S_pcd_set:
1424 str_pcd_obj_str = StructurePcd()
1425 str_pcd_obj_str.copy(self._DecPcds[Pcd])
1426 str_pcd_obj = Pcds.get(Pcd, None)
1427 if str_pcd_obj:
1428 str_pcd_obj_str.copy(str_pcd_obj)
1429 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1430 str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
1431 else:
1432 str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
1433 S_pcd_set[Pcd] = str_pcd_obj_str
1434 if S_pcd_set:
1435 GlobalData.gStructurePcd[self.Arch] = S_pcd_set
1436 for stru_pcd in S_pcd_set.values():
1437 for skuid in SkuIds:
1438 if skuid in stru_pcd.SkuOverrideValues:
1439 continue
1440 nextskuid = self.SkuIdMgr.GetNextSkuId(skuid)
1441 NoDefault = False
1442 if skuid not in stru_pcd.SkuOverrideValues:
1443 while nextskuid not in stru_pcd.SkuOverrideValues:
1444 if nextskuid == TAB_DEFAULT:
1445 NoDefault = True
1446 break
1447 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
1448 stru_pcd.SkuOverrideValues[skuid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid]) if not NoDefault else copy.deepcopy({defaultstorename: stru_pcd.DefaultValues for defaultstorename in DefaultStores} if DefaultStores else {}) #{TAB_DEFAULT_STORES_DEFAULT:stru_pcd.DefaultValues})
1449 if not NoDefault:
1450 stru_pcd.ValueChain.add((skuid, ''))
1451 if stru_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1452 for skuid in SkuIds:
1453 nextskuid = skuid
1454 NoDefault = False
1455 if skuid not in stru_pcd.SkuOverrideValues:
1456 while nextskuid not in stru_pcd.SkuOverrideValues:
1457 if nextskuid == TAB_DEFAULT:
1458 NoDefault = True
1459 break
1460 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
1461 if NoDefault:
1462 continue
1463 PcdDefaultStoreSet = set(defaultstorename for defaultstorename in stru_pcd.SkuOverrideValues[nextskuid])
1464 mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)
1465
1466 for defaultstoreid in DefaultStores:
1467 if defaultstoreid not in stru_pcd.SkuOverrideValues[skuid]:
1468 stru_pcd.SkuOverrideValues[skuid][defaultstoreid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])
1469 stru_pcd.ValueChain.add((skuid, defaultstoreid))
1470 S_pcd_set = DscBuildData.OverrideByFdf(S_pcd_set,self.WorkspaceDir)
1471 S_pcd_set = DscBuildData.OverrideByComm(S_pcd_set)
1472 Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set)
1473 if Str_Pcd_Values:
1474 for (skuname, StoreName, PcdGuid, PcdName, PcdValue) in Str_Pcd_Values:
1475 str_pcd_obj = S_pcd_set.get((PcdName, PcdGuid))
1476 if str_pcd_obj is None:
1477 print(PcdName, PcdGuid)
1478 raise
1479 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
1480 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1481 if skuname not in str_pcd_obj.SkuInfoList:
1482 str_pcd_obj.SkuInfoList[skuname] = SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], HiiDefaultValue=PcdValue, DefaultStore = {StoreName:PcdValue})
1483 else:
1484 str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue = PcdValue
1485 str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.update({StoreName:PcdValue})
1486 elif str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
1487 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
1488 if skuname in (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT, TAB_COMMON):
1489 str_pcd_obj.DefaultValue = PcdValue
1490 else:
1491 if skuname not in str_pcd_obj.SkuInfoList:
1492 nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
1493 NoDefault = False
1494 while nextskuid not in str_pcd_obj.SkuInfoList:
1495 if nextskuid == TAB_DEFAULT:
1496 NoDefault = True
1497 break
1498 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
1499 str_pcd_obj.SkuInfoList[skuname] = copy.deepcopy(str_pcd_obj.SkuInfoList[nextskuid]) if not NoDefault else SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], DefaultValue=PcdValue)
1500 str_pcd_obj.SkuInfoList[skuname].SkuId = self.SkuIds[skuname][0]
1501 str_pcd_obj.SkuInfoList[skuname].SkuIdName = skuname
1502 else:
1503 str_pcd_obj.SkuInfoList[skuname].DefaultValue = PcdValue
1504 for str_pcd_obj in S_pcd_set.values():
1505 if str_pcd_obj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
1506 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1507 continue
1508 PcdDefaultStoreSet = set(defaultstorename for skuobj in str_pcd_obj.SkuInfoList.values() for defaultstorename in skuobj.DefaultStoreDict)
1509 DefaultStoreObj = DefaultStore(self._GetDefaultStores())
1510 mindefaultstorename = DefaultStoreObj.GetMin(PcdDefaultStoreSet)
1511 str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].HiiDefaultValue = str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].DefaultStoreDict[mindefaultstorename]
1512
1513 for str_pcd_obj in S_pcd_set.values():
1514
1515 str_pcd_obj.MaxDatumSize = self.GetStructurePcdMaxSize(str_pcd_obj)
1516 Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName] = str_pcd_obj
1517
1518 for pcdkey in Pcds:
1519 pcd = Pcds[pcdkey]
1520 if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
1521 pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
1522 del pcd.SkuInfoList[TAB_COMMON]
1523 elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
1524 del pcd.SkuInfoList[TAB_COMMON]
1525
1526 map(self.FilterSkuSettings, [Pcds[pcdkey] for pcdkey in Pcds if Pcds[pcdkey].Type in DynamicPcdType])
1527 return Pcds
1528
1529 ## Retrieve non-dynamic PCD settings
1530 #
1531 # @param Type PCD type
1532 #
1533 # @retval a dict object contains settings of given PCD type
1534 #
1535 def _GetPcd(self, Type):
1536 Pcds = OrderedDict()
1537 #
1538 # tdict is a special dict kind of type, used for selecting correct
1539 # PCD settings for certain ARCH
1540 #
1541 AvailableSkuIdSet = copy.copy(self.SkuIds)
1542
1543 PcdDict = tdict(True, 3)
1544 PcdSet = set()
1545 # Find out all possible PCD candidates for self._Arch
1546 RecordList = self._RawData[Type, self._Arch]
1547 PcdValueDict = OrderedDict()
1548 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:
1549 SkuName = SkuName.upper()
1550 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
1551 if SkuName not in AvailableSkuIdSet:
1552 EdkLogger.error('build ', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
1553 File=self.MetaFile, Line=Dummy5)
1554 if SkuName in (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT, TAB_COMMON):
1555 if "." not in TokenSpaceGuid:
1556 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
1557 PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting
1558
1559 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdSet:
1560 Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid, SkuName]
1561 if Setting is None:
1562 continue
1563 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
1564 if MaxDatumSize:
1565 if int(MaxDatumSize, 0) > 0xFFFF:
1566 EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),
1567 File=self.MetaFile, Line=Dummy4)
1568 if int(MaxDatumSize, 0) < 0:
1569 EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),
1570 File=self.MetaFile, Line=Dummy4)
1571 if (PcdCName, TokenSpaceGuid) in PcdValueDict:
1572 PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue, DatumType, MaxDatumSize)
1573 else:
1574 PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue, DatumType, MaxDatumSize)}
1575
1576 for ((PcdCName, TokenSpaceGuid), PcdSetting) in PcdValueDict.iteritems():
1577 if self.SkuIdMgr.SystemSkuId in PcdSetting:
1578 PcdValue, DatumType, MaxDatumSize = PcdSetting[self.SkuIdMgr.SystemSkuId]
1579 elif TAB_DEFAULT in PcdSetting:
1580 PcdValue, DatumType, MaxDatumSize = PcdSetting[TAB_DEFAULT]
1581 elif TAB_COMMON in PcdSetting:
1582 PcdValue, DatumType, MaxDatumSize = PcdSetting[TAB_COMMON]
1583 else:
1584 PcdValue = None
1585 DatumType = None
1586 MaxDatumSize = None
1587
1588 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
1589 PcdCName,
1590 TokenSpaceGuid,
1591 self._PCD_TYPE_STRING_[Type],
1592 DatumType,
1593 PcdValue,
1594 '',
1595 MaxDatumSize,
1596 {},
1597 False,
1598 None,
1599 IsDsc=True)
1600
1601 if self.SkuIdMgr.SystemSkuId not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
1602 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[self.SkuIdMgr.SystemSkuId] = {}
1603 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[self.SkuIdMgr.SystemSkuId][TAB_DEFAULT_STORES_DEFAULT] = PcdValue
1604 return Pcds
1605
1606 def GetStructurePcdMaxSize(self, str_pcd):
1607 pcd_default_value = str_pcd.DefaultValue
1608 sku_values = [skuobj.HiiDefaultValue if str_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]] else skuobj.DefaultValue for skuobj in str_pcd.SkuInfoList.values()]
1609 sku_values.append(pcd_default_value)
1610
1611 def get_length(value):
1612 Value = value.strip()
1613 if len(value) > 1:
1614 if Value.startswith(TAB_GUID) and Value.endswith(')'):
1615 return 16
1616 if Value.startswith('L"') and Value.endswith('"'):
1617 return len(Value[2:-1])
1618 if Value[0] == '"' and Value[-1] == '"':
1619 return len(Value) - 2
1620 if Value[0] == '{' and Value[-1] == '}':
1621 return len(Value.split(","))
1622 if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:
1623 return len(list(Value[2:-1]))
1624 if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:
1625 return len(Value) - 2
1626 return len(Value)
1627
1628 return str(max(get_length(item) for item in sku_values))
1629
1630 @staticmethod
1631 def ExecuteCommand (Command):
1632 try:
1633 Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
1634 except:
1635 EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % Command)
1636 Result = Process.communicate()
1637 return Process.returncode, Result[0], Result[1]
1638
1639 @staticmethod
1640 def IntToCString(Value, ValueSize):
1641 Result = '"'
1642 if not isinstance (Value, str):
1643 for Index in range(0, ValueSize):
1644 Result = Result + '\\x%02x' % (Value & 0xff)
1645 Value = Value >> 8
1646 Result = Result + '"'
1647 return Result
1648
1649 def GenerateSizeFunction(self, Pcd):
1650 CApp = "// Default Value in Dec \n"
1651 CApp = CApp + "void Cal_%s_%s_Size(UINT32 *Size){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1652 for FieldList in [Pcd.DefaultValues]:
1653 if not FieldList:
1654 continue
1655 for FieldName in FieldList:
1656 FieldName = "." + FieldName
1657 IsArray = IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
1658 if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):
1659 try:
1660 Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
1661 except BadExpression:
1662 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1663 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))
1664 Value, ValueSize = ParseFieldValue(Value)
1665 CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]);
1666 else:
1667 NewFieldName = ''
1668 FieldName_ori = FieldName.strip('.')
1669 while '[' in FieldName:
1670 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
1671 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
1672 FieldName = FieldName.split(']', 1)[1]
1673 FieldName = NewFieldName + FieldName
1674 while '[' in FieldName:
1675 FieldName = FieldName.rsplit('[', 1)[0]
1676 CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
1677 for skuname in Pcd.SkuOverrideValues:
1678 if skuname == TAB_COMMON:
1679 continue
1680 for defaultstorenameitem in Pcd.SkuOverrideValues[skuname]:
1681 CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
1682 for FieldList in [Pcd.SkuOverrideValues[skuname].get(defaultstorenameitem)]:
1683 if not FieldList:
1684 continue
1685 for FieldName in FieldList:
1686 FieldName = "." + FieldName
1687 IsArray = IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
1688 if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):
1689 try:
1690 Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
1691 except BadExpression:
1692 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1693 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))
1694 Value, ValueSize = ParseFieldValue(Value)
1695 CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]);
1696 else:
1697 NewFieldName = ''
1698 FieldName_ori = FieldName.strip('.')
1699 while '[' in FieldName:
1700 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
1701 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
1702 FieldName = FieldName.split(']', 1)[1]
1703 FieldName = NewFieldName + FieldName
1704 while '[' in FieldName:
1705 FieldName = FieldName.rsplit('[', 1)[0]
1706 CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
1707 if Pcd.PcdFieldValueFromFdf:
1708 CApp = CApp + "// From fdf \n"
1709 for FieldName in Pcd.PcdFieldValueFromFdf:
1710 FieldName = "." + FieldName
1711 IsArray = IsFieldValueAnArray(Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0])
1712 if IsArray and not (Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0].startswith('{GUID') and Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0].endswith('}')):
1713 try:
1714 Value = ValueExpressionEx(Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
1715 except BadExpression:
1716 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1717 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][1], Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][2]))
1718 Value, ValueSize = ParseFieldValue(Value)
1719 CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][1], Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][2], Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0]);
1720 else:
1721 NewFieldName = ''
1722 FieldName_ori = FieldName.strip('.')
1723 while '[' in FieldName:
1724 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
1725 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
1726 FieldName = FieldName.split(']', 1)[1]
1727 FieldName = NewFieldName + FieldName
1728 while '[' in FieldName:
1729 FieldName = FieldName.rsplit('[', 1)[0]
1730 CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %s Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, Pcd.PcdFieldValueFromFdf[FieldName_ori][1], Pcd.PcdFieldValueFromFdf[FieldName_ori][2], Pcd.PcdFieldValueFromFdf[FieldName_ori][0])
1731 if Pcd.PcdFieldValueFromComm:
1732 CApp = CApp + "// From Command Line \n"
1733 for FieldName in Pcd.PcdFieldValueFromComm:
1734 FieldName = "." + FieldName
1735 IsArray = IsFieldValueAnArray(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0])
1736 if IsArray and not (Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].startswith('{GUID') and Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].endswith('}')):
1737 try:
1738 Value = ValueExpressionEx(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
1739 except BadExpression:
1740 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1741 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), Pcd.PcdFieldValueFromComm[FieldName.strip(".")][1], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][2]))
1742 Value, ValueSize = ParseFieldValue(Value)
1743 CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), Pcd.PcdFieldValueFromComm[FieldName.strip(".")][1], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][2], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0]);
1744 else:
1745 NewFieldName = ''
1746 FieldName_ori = FieldName.strip('.')
1747 while '[' in FieldName:
1748 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
1749 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
1750 FieldName = FieldName.split(']', 1)[1]
1751 FieldName = NewFieldName + FieldName
1752 while '[' in FieldName:
1753 FieldName = FieldName.rsplit('[', 1)[0]
1754 CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, Pcd.PcdFieldValueFromComm[FieldName_ori][1], Pcd.PcdFieldValueFromComm[FieldName_ori][2], Pcd.PcdFieldValueFromComm[FieldName_ori][0])
1755 CApp = CApp + " *Size = (%d > *Size ? %d : *Size); // The Pcd maxsize is %d \n" % (Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize())
1756 CApp = CApp + "}\n"
1757 return CApp
1758
1759 @staticmethod
1760 def GenerateSizeStatments(Pcd):
1761 CApp = ' Size = sizeof(%s);\n' % (Pcd.DatumType)
1762 CApp = CApp + ' Cal_%s_%s_Size(&Size);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1763 return CApp
1764
1765 def GenerateDefaultValueAssignFunction(self, Pcd):
1766 CApp = "// Default value in Dec \n"
1767 CApp = CApp + "void Assign_%s_%s_Default_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType)
1768 CApp = CApp + ' UINT32 FieldSize;\n'
1769 CApp = CApp + ' CHAR8 *Value;\n'
1770 DefaultValueFromDec = Pcd.DefaultValueFromDec
1771 IsArray = IsFieldValueAnArray(Pcd.DefaultValueFromDec)
1772 if IsArray:
1773 try:
1774 DefaultValueFromDec = ValueExpressionEx(Pcd.DefaultValueFromDec, TAB_VOID)(True)
1775 except BadExpression:
1776 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DEC: %s" %
1777 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, DefaultValueFromDec))
1778 DefaultValueFromDec = StringToArray(DefaultValueFromDec)
1779 Value, ValueSize = ParseFieldValue (DefaultValueFromDec)
1780 if isinstance(Value, str):
1781 CApp = CApp + ' Pcd = %s; // From DEC Default Value %s\n' % (Value, Pcd.DefaultValueFromDec)
1782 elif IsArray:
1783 #
1784 # Use memcpy() to copy value into field
1785 #
1786 CApp = CApp + ' Value = %s; // From DEC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec)
1787 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
1788 for FieldList in [Pcd.DefaultValues]:
1789 if not FieldList:
1790 continue
1791 for FieldName in FieldList:
1792 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
1793 if IsArray:
1794 try:
1795 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
1796 except BadExpression:
1797 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1798 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
1799
1800 try:
1801 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
1802 except Exception:
1803 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
1804 if isinstance(Value, str):
1805 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1806 elif IsArray:
1807 #
1808 # Use memcpy() to copy value into field
1809 #
1810 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
1811 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1812 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
1813 else:
1814 if ValueSize > 4:
1815 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1816 else:
1817 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1818 CApp = CApp + "}\n"
1819 return CApp
1820
1821 @staticmethod
1822 def GenerateDefaultValueAssignStatement(Pcd):
1823 CApp = ' Assign_%s_%s_Default_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1824 return CApp
1825
1826 def GenerateInitValueFunction(self, Pcd, SkuName, DefaultStoreName):
1827 CApp = "// Value in Dsc for Sku: %s, DefaultStore %s\n" % (SkuName, DefaultStoreName)
1828 CApp = CApp + "void Assign_%s_%s_%s_%s_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, SkuName, DefaultStoreName, Pcd.DatumType)
1829 CApp = CApp + ' UINT32 FieldSize;\n'
1830 CApp = CApp + ' CHAR8 *Value;\n'
1831
1832 CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT)
1833 inherit_OverrideValues = Pcd.SkuOverrideValues[SkuName]
1834 if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT):
1835 pcddefaultvalue = Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT) if Pcd.DefaultFromDSC else None
1836 else:
1837 pcddefaultvalue = Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName)
1838 for FieldList in [pcddefaultvalue, inherit_OverrideValues.get(DefaultStoreName)]:
1839 if not FieldList:
1840 continue
1841 if pcddefaultvalue and FieldList == pcddefaultvalue:
1842 IsArray = IsFieldValueAnArray(FieldList)
1843 if IsArray:
1844 try:
1845 FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
1846 except BadExpression:
1847 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DSC: %s" %
1848 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
1849 Value, ValueSize = ParseFieldValue (FieldList)
1850
1851 if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT):
1852 if isinstance(Value, str):
1853 CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)
1854 elif IsArray:
1855 #
1856 # Use memcpy() to copy value into field
1857 #
1858 CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)
1859 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
1860 else:
1861 if isinstance(Value, str):
1862 CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName))
1863 elif IsArray:
1864 #
1865 # Use memcpy() to copy value into field
1866 #
1867 CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName))
1868 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
1869 continue
1870 if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT) or (( (SkuName, '') not in Pcd.ValueChain) and ( (SkuName, DefaultStoreName) not in Pcd.ValueChain )):
1871 for FieldName in FieldList:
1872 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
1873 if IsArray:
1874 try:
1875 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
1876 except BadExpression:
1877 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1878 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
1879 try:
1880 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
1881 except Exception:
1882 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
1883 if isinstance(Value, str):
1884 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1885 elif IsArray:
1886 #
1887 # Use memcpy() to copy value into field
1888 #
1889 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
1890 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1891 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
1892 else:
1893 if ValueSize > 4:
1894 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1895 else:
1896 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1897 CApp = CApp + "}\n"
1898 return CApp
1899
1900 @staticmethod
1901 def GenerateInitValueStatement(Pcd, SkuName, DefaultStoreName):
1902 CApp = ' Assign_%s_%s_%s_%s_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, SkuName, DefaultStoreName)
1903 return CApp
1904
1905 def GenerateCommandLineValue(self, Pcd):
1906 CApp = "// Value in CommandLine\n"
1907 CApp = CApp + "void Assign_%s_%s_CommandLine_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType)
1908 CApp = CApp + ' UINT32 FieldSize;\n'
1909 CApp = CApp + ' CHAR8 *Value;\n'
1910
1911 pcddefaultvalue = Pcd.PcdValueFromComm
1912 for FieldList in [pcddefaultvalue, Pcd.PcdFieldValueFromComm]:
1913 if not FieldList:
1914 continue
1915 if pcddefaultvalue and FieldList == pcddefaultvalue:
1916 IsArray = IsFieldValueAnArray(FieldList)
1917 if IsArray:
1918 try:
1919 FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
1920 except BadExpression:
1921 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from Command: %s" %
1922 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
1923 Value, ValueSize = ParseFieldValue (FieldList)
1924
1925 if isinstance(Value, str):
1926 CApp = CApp + ' Pcd = %s; // From Command Line \n' % (Value)
1927 elif IsArray:
1928 #
1929 # Use memcpy() to copy value into field
1930 #
1931 CApp = CApp + ' Value = %s; // From Command Line.\n' % (DscBuildData.IntToCString(Value, ValueSize))
1932 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
1933 continue
1934 for FieldName in FieldList:
1935 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
1936 if IsArray:
1937 try:
1938 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
1939 except BadExpression:
1940 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1941 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
1942 except:
1943 print("error")
1944 try:
1945 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
1946 except Exception:
1947 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
1948 if isinstance(Value, str):
1949 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1950 elif IsArray:
1951 #
1952 # Use memcpy() to copy value into field
1953 #
1954 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
1955 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1956 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
1957 else:
1958 if ValueSize > 4:
1959 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1960 else:
1961 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1962 CApp = CApp + "}\n"
1963 return CApp
1964
1965 @staticmethod
1966 def GenerateCommandLineValueStatement(Pcd):
1967 CApp = ' Assign_%s_%s_CommandLine_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1968 return CApp
1969 def GenerateFdfValue(self,Pcd):
1970 CApp = "// Value in Fdf\n"
1971 CApp = CApp + "void Assign_%s_%s_Fdf_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType)
1972 CApp = CApp + ' UINT32 FieldSize;\n'
1973 CApp = CApp + ' CHAR8 *Value;\n'
1974
1975 pcddefaultvalue = Pcd.PcdValueFromFdf
1976 for FieldList in [pcddefaultvalue,Pcd.PcdFieldValueFromFdf]:
1977 if not FieldList:
1978 continue
1979 if pcddefaultvalue and FieldList == pcddefaultvalue:
1980 IsArray = IsFieldValueAnArray(FieldList)
1981 if IsArray:
1982 try:
1983 FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
1984 except BadExpression:
1985 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from Fdf: %s" %
1986 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
1987 Value, ValueSize = ParseFieldValue (FieldList)
1988
1989 if isinstance(Value, str):
1990 CApp = CApp + ' Pcd = %s; // From Fdf \n' % (Value)
1991 elif IsArray:
1992 #
1993 # Use memcpy() to copy value into field
1994 #
1995 CApp = CApp + ' Value = %s; // From Fdf .\n' % (DscBuildData.IntToCString(Value, ValueSize))
1996 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
1997 continue
1998 for FieldName in FieldList:
1999 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
2000 if IsArray:
2001 try:
2002 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
2003 except BadExpression:
2004 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
2005 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
2006 except:
2007 print("error")
2008 try:
2009 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
2010 except Exception:
2011 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName,FieldName)),FieldList[FieldName][1], FieldList[FieldName][2]))
2012 if isinstance(Value, str):
2013 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2014 elif IsArray:
2015 #
2016 # Use memcpy() to copy value into field
2017 #
2018 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
2019 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2020 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
2021 else:
2022 if ValueSize > 4:
2023 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2024 else:
2025 CApp = CApp + ' Pcd->%s = %d; // From %s Line %s Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2026 CApp = CApp + "}\n"
2027 return CApp
2028
2029 @staticmethod
2030 def GenerateFdfValueStatement(Pcd):
2031 CApp = ' Assign_%s_%s_Fdf_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2032 return CApp
2033
2034 def GenerateInitializeFunc(self, SkuName, DefaultStore, Pcd, InitByteValue, CApp):
2035 OverrideValues = {DefaultStore:""}
2036 if Pcd.SkuOverrideValues:
2037 OverrideValues = Pcd.SkuOverrideValues[SkuName]
2038 if not OverrideValues:
2039 OverrideValues = {TAB_DEFAULT_STORES_DEFAULT:Pcd.DefaultValues}
2040 for DefaultStoreName in OverrideValues:
2041 CApp = CApp + 'void\n'
2042 CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2043 CApp = CApp + ' void\n'
2044 CApp = CApp + ' )\n'
2045 CApp = CApp + '{\n'
2046 CApp = CApp + ' UINT32 Size;\n'
2047 CApp = CApp + ' UINT32 FieldSize;\n'
2048 CApp = CApp + ' CHAR8 *Value;\n'
2049 CApp = CApp + ' UINT32 OriginalSize;\n'
2050 CApp = CApp + ' VOID *OriginalPcd;\n'
2051 CApp = CApp + ' %s *Pcd; // From %s Line %d \n' % (Pcd.DatumType, Pcd.PkgPath, Pcd.PcdDefineLineNo)
2052 CApp = CApp + '\n'
2053
2054 if SkuName in Pcd.SkuInfoList:
2055 DefaultValue = Pcd.SkuInfoList[SkuName].DefaultStoreDict.get(DefaultStoreName, Pcd.SkuInfoList[SkuName].HiiDefaultValue if Pcd.SkuInfoList[SkuName].HiiDefaultValue else Pcd.SkuInfoList[SkuName].DefaultValue)
2056 else:
2057 DefaultValue = Pcd.DefaultValue
2058 PcdDefaultValue = StringToArray(DefaultValue.strip())
2059
2060 InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)
2061
2062 #
2063 # Get current PCD value and size
2064 #
2065 CApp = CApp + ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2066
2067 #
2068 # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides
2069 # the correct value. For structures with a flexible array member, the flexible
2070 # array member is detected, and the size is based on the highest index used with
2071 # the flexible array member. The flexible array member must be the last field
2072 # in a structure. The size formula for this case is:
2073 # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
2074 #
2075 CApp = CApp + DscBuildData.GenerateSizeStatments(Pcd)
2076
2077 #
2078 # Allocate and zero buffer for the PCD
2079 # Must handle cases where current value is smaller, larger, or same size
2080 # Always keep that larger one as the current size
2081 #
2082 CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'
2083 CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.DatumType)
2084 CApp = CApp + ' memset (Pcd, 0, Size);\n'
2085
2086 #
2087 # Copy current PCD value into allocated buffer.
2088 #
2089 CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'
2090
2091 #
2092 # Assign field values in PCD
2093 #
2094 CApp = CApp + DscBuildData.GenerateDefaultValueAssignStatement(Pcd)
2095 if Pcd.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
2096 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
2097 for skuname in self.SkuIdMgr.GetSkuChain(SkuName):
2098 storeset = [DefaultStoreName] if DefaultStoreName == TAB_DEFAULT_STORES_DEFAULT else [TAB_DEFAULT_STORES_DEFAULT, DefaultStoreName]
2099 for defaultstorenameitem in storeset:
2100 CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
2101 CApp = CApp + DscBuildData.GenerateInitValueStatement(Pcd, skuname, defaultstorenameitem)
2102 if skuname == SkuName:
2103 break
2104 else:
2105 CApp = CApp + "// SkuName: %s, DefaultStoreName: STANDARD \n" % self.SkuIdMgr.SystemSkuId
2106 CApp = CApp + DscBuildData.GenerateInitValueStatement(Pcd, self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT)
2107 CApp = CApp + DscBuildData.GenerateFdfValueStatement(Pcd)
2108 CApp = CApp + DscBuildData.GenerateCommandLineValueStatement(Pcd)
2109 #
2110 # Set new PCD value and size
2111 #
2112 CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2113
2114 #
2115 # Free PCD
2116 #
2117 CApp = CApp + ' free (Pcd);\n'
2118 CApp = CApp + '}\n'
2119 CApp = CApp + '\n'
2120 return InitByteValue, CApp
2121 def SkuOverrideValuesEmpty(self,OverrideValues):
2122 if not OverrideValues:
2123 return True
2124 for key in OverrideValues:
2125 if OverrideValues[key]:
2126 return False
2127 return True
2128
2129 def GenerateByteArrayValue (self, StructuredPcds):
2130 #
2131 # Generate/Compile/Run C application to determine if there are any flexible array members
2132 #
2133 if not StructuredPcds:
2134 return
2135
2136 InitByteValue = ""
2137 CApp = PcdMainCHeader
2138
2139 IncludeFiles = set()
2140 for PcdName in StructuredPcds:
2141 Pcd = StructuredPcds[PcdName]
2142 for IncludeFile in Pcd.StructuredPcdIncludeFile:
2143 if IncludeFile not in IncludeFiles:
2144 IncludeFiles.add(IncludeFile)
2145 CApp = CApp + '#include <%s>\n' % (IncludeFile)
2146 CApp = CApp + '\n'
2147 for PcdName in StructuredPcds:
2148 Pcd = StructuredPcds[PcdName]
2149 CApp = CApp + self.GenerateSizeFunction(Pcd)
2150 CApp = CApp + self.GenerateDefaultValueAssignFunction(Pcd)
2151 CApp = CApp + self.GenerateFdfValue(Pcd)
2152 CApp = CApp + self.GenerateCommandLineValue(Pcd)
2153 if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
2154 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
2155 CApp = CApp + self.GenerateInitValueFunction(Pcd, self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT)
2156 else:
2157 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
2158 if SkuName not in Pcd.SkuOverrideValues:
2159 continue
2160 for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:
2161 CApp = CApp + self.GenerateInitValueFunction(Pcd, SkuName, DefaultStoreName)
2162 if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
2163 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
2164 InitByteValue, CApp = self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT, Pcd, InitByteValue, CApp)
2165 else:
2166 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
2167 if SkuName not in Pcd.SkuOverrideValues:
2168 continue
2169 for DefaultStoreName in Pcd.DefaultStoreName:
2170 Pcd = StructuredPcds[PcdName]
2171 InitByteValue, CApp = self.GenerateInitializeFunc(SkuName, DefaultStoreName, Pcd, InitByteValue, CApp)
2172
2173 CApp = CApp + 'VOID\n'
2174 CApp = CApp + 'PcdEntryPoint(\n'
2175 CApp = CApp + ' VOID\n'
2176 CApp = CApp + ' )\n'
2177 CApp = CApp + '{\n'
2178 for Pcd in StructuredPcds.values():
2179 if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD], self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
2180 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2181 else:
2182 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
2183 if SkuName not in self.SkuIdMgr.AvailableSkuIdSet:
2184 continue
2185 for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:
2186 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2187 CApp = CApp + '}\n'
2188
2189 CApp = CApp + PcdMainCEntry + '\n'
2190
2191 if not os.path.exists(self.OutputPath):
2192 os.makedirs(self.OutputPath)
2193 CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
2194 SaveFileOnChange(CAppBaseFileName + '.c', CApp, False)
2195
2196 MakeApp = PcdMakefileHeader
2197 if sys.platform == "win32":
2198 MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + 'INC = '
2199 else:
2200 MakeApp = MakeApp + PcdGccMakefile
2201 MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s/%s.o\n' % (self.OutputPath, PcdValueInitName) + \
2202 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'INCLUDE +='
2203
2204 IncSearchList = []
2205 PlatformInc = {}
2206 for Cache in self._Bdb._CACHE_.values():
2207 if Cache.MetaFile.Ext.lower() != '.dec':
2208 continue
2209 if Cache.Includes:
2210 if str(Cache.MetaFile.Path) not in PlatformInc:
2211 PlatformInc[str(Cache.MetaFile.Path)] = []
2212 PlatformInc[str(Cache.MetaFile.Path)].append (os.path.dirname(Cache.MetaFile.Path))
2213 PlatformInc[str(Cache.MetaFile.Path)].extend (Cache.CommonIncludes)
2214
2215 PcdDependDEC = []
2216 for Pcd in StructuredPcds.values():
2217 for PackageDec in Pcd.PackageDecs:
2218 Package = os.path.normpath(mws.join(GlobalData.gWorkspace, PackageDec))
2219 if not os.path.exists(Package):
2220 EdkLogger.error('Build', RESOURCE_NOT_AVAILABLE, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
2221 if Package not in PcdDependDEC:
2222 PcdDependDEC.append(Package)
2223
2224 if PlatformInc and PcdDependDEC:
2225 for pkg in PcdDependDEC:
2226 if pkg in PlatformInc:
2227 for inc in PlatformInc[pkg]:
2228 MakeApp += '-I' + str(inc) + ' '
2229 IncSearchList.append(inc)
2230 MakeApp = MakeApp + '\n'
2231
2232 CC_FLAGS = LinuxCFLAGS
2233 if sys.platform == "win32":
2234 CC_FLAGS = WindowsCFLAGS
2235 BuildOptions = {}
2236 for Options in self.BuildOptions:
2237 if Options[2] != EDKII_NAME:
2238 continue
2239 Family = Options[0]
2240 if Family and Family != self.ToolChainFamily:
2241 continue
2242 Target, Tag, Arch, Tool, Attr = Options[1].split("_")
2243 if Tool != 'CC':
2244 continue
2245
2246 if Target == "*" or Target == self._Target:
2247 if Tag == "*" or Tag == self._Toolchain:
2248 if Arch == "*" or Arch == self.Arch:
2249 if Tool not in BuildOptions:
2250 BuildOptions[Tool] = {}
2251 if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or self.BuildOptions[Options].startswith('='):
2252 BuildOptions[Tool][Attr] = self.BuildOptions[Options]
2253 else:
2254 # append options for the same tool except PATH
2255 if Attr != 'PATH':
2256 BuildOptions[Tool][Attr] += " " + self.BuildOptions[Options]
2257 else:
2258 BuildOptions[Tool][Attr] = self.BuildOptions[Options]
2259 if BuildOptions:
2260 for Tool in BuildOptions:
2261 for Attr in BuildOptions[Tool]:
2262 if Attr == "FLAGS":
2263 Value = BuildOptions[Tool][Attr]
2264 ValueList = Value.split()
2265 if ValueList:
2266 for Id, Item in enumerate(ValueList):
2267 if Item in ['-D', '/D', '-U', '/U']:
2268 CC_FLAGS += ' ' + Item
2269 if Id + 1 < len(ValueList):
2270 CC_FLAGS += ' ' + ValueList[Id + 1]
2271 elif Item.startswith(('-D', '/D', '-U', '/U')):
2272 CC_FLAGS += ' ' + Item
2273 MakeApp += CC_FLAGS
2274
2275 if sys.platform == "win32":
2276 MakeApp = MakeApp + PcdMakefileEnd
2277 MakeApp = MakeApp + '\n'
2278 IncludeFileFullPaths = []
2279 for includefile in IncludeFiles:
2280 for includepath in IncSearchList:
2281 includefullpath = os.path.join(str(includepath), includefile)
2282 if os.path.exists(includefullpath):
2283 IncludeFileFullPaths.append(os.path.normpath(includefullpath))
2284 break
2285 SearchPathList = []
2286 SearchPathList.append(os.path.normpath(mws.join(GlobalData.gWorkspace, "BaseTools/Source/C/Include")))
2287 SearchPathList.append(os.path.normpath(mws.join(GlobalData.gWorkspace, "BaseTools/Source/C/Common")))
2288 SearchPathList.extend(str(item) for item in IncSearchList)
2289 IncFileList = GetDependencyList(IncludeFileFullPaths, SearchPathList)
2290 for include_file in IncFileList:
2291 MakeApp += "$(OBJECTS) : %s\n" % include_file
2292 MakeFileName = os.path.join(self.OutputPath, 'Makefile')
2293 MakeApp += "$(OBJECTS) : %s\n" % MakeFileName
2294 SaveFileOnChange(MakeFileName, MakeApp, False)
2295
2296 InputValueFile = os.path.join(self.OutputPath, 'Input.txt')
2297 OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')
2298 SaveFileOnChange(InputValueFile, InitByteValue, False)
2299
2300 PcdValueInitExe = PcdValueInitName
2301 if not sys.platform == "win32":
2302 PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName)
2303 else:
2304 PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Bin', 'Win32', PcdValueInitName) +".exe"
2305
2306 Messages = ''
2307 if sys.platform == "win32":
2308 MakeCommand = 'nmake -f %s' % (MakeFileName)
2309 returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (MakeCommand)
2310 Messages = StdOut
2311 else:
2312 MakeCommand = 'make -f %s' % (MakeFileName)
2313 returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (MakeCommand)
2314 Messages = StdErr
2315 Messages = Messages.split('\n')
2316 MessageGroup = []
2317 if returncode != 0:
2318 CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
2319 File = open (CAppBaseFileName + '.c', 'r')
2320 FileData = File.readlines()
2321 File.close()
2322 for Message in Messages:
2323 if " error" in Message or "warning" in Message:
2324 FileInfo = Message.strip().split('(')
2325 if len (FileInfo) > 1:
2326 FileName = FileInfo [0]
2327 FileLine = FileInfo [1].split (')')[0]
2328 else:
2329 FileInfo = Message.strip().split(':')
2330 FileName = FileInfo [0]
2331 FileLine = FileInfo [1]
2332 if FileLine.isdigit():
2333 error_line = FileData[int (FileLine) - 1]
2334 if r"//" in error_line:
2335 c_line, dsc_line = error_line.split(r"//")
2336 else:
2337 dsc_line = error_line
2338 message_itmes = Message.split(":")
2339 Index = 0
2340 if "PcdValueInit.c" not in Message:
2341 if not MessageGroup:
2342 MessageGroup.append(Message)
2343 break
2344 else:
2345 for item in message_itmes:
2346 if "PcdValueInit.c" in item:
2347 Index = message_itmes.index(item)
2348 message_itmes[Index] = dsc_line.strip()
2349 break
2350 MessageGroup.append(":".join(message_itmes[Index:]).strip())
2351 continue
2352 else:
2353 MessageGroup.append(Message)
2354 if MessageGroup:
2355 EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "\n".join(MessageGroup) )
2356 else:
2357 EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % MakeCommand)
2358
2359 if DscBuildData.NeedUpdateOutput(OutputValueFile, PcdValueInitExe, InputValueFile):
2360 Command = PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile)
2361 returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (Command)
2362 if returncode != 0:
2363 EdkLogger.warn('Build', COMMAND_FAILURE, 'Can not collect output from command: %s' % Command)
2364
2365 File = open (OutputValueFile, 'r')
2366 FileBuffer = File.readlines()
2367 File.close()
2368
2369 StructurePcdSet = []
2370 for Pcd in FileBuffer:
2371 PcdValue = Pcd.split ('|')
2372 PcdInfo = PcdValue[0].split ('.')
2373 StructurePcdSet.append((PcdInfo[0], PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip()))
2374 return StructurePcdSet
2375
2376 @staticmethod
2377 def NeedUpdateOutput(OutputFile, ValueCFile, StructureInput):
2378 if not os.path.exists(OutputFile):
2379 return True
2380 if os.stat(OutputFile).st_mtime <= os.stat(ValueCFile).st_mtime:
2381 return True
2382 if os.stat(OutputFile).st_mtime <= os.stat(StructureInput).st_mtime:
2383 return True
2384 return False
2385
2386 ## Retrieve dynamic PCD settings
2387 #
2388 # @param Type PCD type
2389 #
2390 # @retval a dict object contains settings of given PCD type
2391 #
2392 def _GetDynamicPcd(self, Type):
2393
2394
2395 Pcds = OrderedDict()
2396 #
2397 # tdict is a special dict kind of type, used for selecting correct
2398 # PCD settings for certain ARCH and SKU
2399 #
2400 PcdDict = tdict(True, 4)
2401 PcdList = []
2402 # Find out all possible PCD candidates for self._Arch
2403 RecordList = self._RawData[Type, self._Arch]
2404 AvailableSkuIdSet = copy.copy(self.SkuIds)
2405
2406
2407 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:
2408 SkuName = SkuName.upper()
2409 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
2410 if SkuName not in AvailableSkuIdSet:
2411 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
2412 File=self.MetaFile, Line=Dummy5)
2413 if "." not in TokenSpaceGuid:
2414 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
2415 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
2416
2417 # Remove redundant PCD candidates, per the ARCH and SKU
2418 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
2419
2420 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
2421 if Setting is None:
2422 continue
2423
2424 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
2425 if MaxDatumSize:
2426 if int(MaxDatumSize, 0) > 0xFFFF:
2427 EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),
2428 File=self.MetaFile, Line=Dummy4)
2429 if int(MaxDatumSize, 0) < 0:
2430 EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),
2431 File=self.MetaFile, Line=Dummy4)
2432 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', '', PcdValue)
2433 if (PcdCName, TokenSpaceGuid) in Pcds:
2434 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
2435 pcdObject.SkuInfoList[SkuName] = SkuInfo
2436 if MaxDatumSize.strip():
2437 CurrentMaxSize = int(MaxDatumSize.strip(), 0)
2438 else:
2439 CurrentMaxSize = 0
2440 if pcdObject.MaxDatumSize:
2441 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
2442 else:
2443 PcdMaxSize = 0
2444 if CurrentMaxSize > PcdMaxSize:
2445 pcdObject.MaxDatumSize = str(CurrentMaxSize)
2446 else:
2447 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
2448 PcdCName,
2449 TokenSpaceGuid,
2450 self._PCD_TYPE_STRING_[Type],
2451 DatumType,
2452 PcdValue,
2453 '',
2454 MaxDatumSize,
2455 {SkuName : SkuInfo},
2456 False,
2457 None,
2458 IsDsc=True)
2459
2460 if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
2461 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
2462 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = PcdValue
2463
2464 for pcd in Pcds.values():
2465 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
2466 # Only fix the value while no value provided in DSC file.
2467 for sku in pcd.SkuInfoList.values():
2468 if not sku.DefaultValue:
2469 sku.DefaultValue = pcdDecObject.DefaultValue
2470 if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:
2471 valuefromDec = pcdDecObject.DefaultValue
2472 SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', '', '', '', '', '', valuefromDec)
2473 pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo
2474 elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2475 pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
2476 del pcd.SkuInfoList[TAB_COMMON]
2477 elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2478 del pcd.SkuInfoList[TAB_COMMON]
2479
2480 map(self.FilterSkuSettings, Pcds.values())
2481
2482 return Pcds
2483
2484 def FilterSkuSettings(self, PcdObj):
2485
2486 if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE:
2487 if TAB_DEFAULT in PcdObj.SkuInfoList and self.SkuIdMgr.SystemSkuId not in PcdObj.SkuInfoList:
2488 PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId] = PcdObj.SkuInfoList[TAB_DEFAULT]
2489 PcdObj.SkuInfoList = {TAB_DEFAULT:PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId]}
2490 PcdObj.SkuInfoList[TAB_DEFAULT].SkuIdName = TAB_DEFAULT
2491 PcdObj.SkuInfoList[TAB_DEFAULT].SkuId = '0'
2492
2493 elif self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.DEFAULT:
2494 PcdObj.SkuInfoList = {TAB_DEFAULT:PcdObj.SkuInfoList[TAB_DEFAULT]}
2495
2496 return PcdObj
2497
2498 @staticmethod
2499 def CompareVarAttr(Attr1, Attr2):
2500 if not Attr1 or not Attr2: # for empty string
2501 return True
2502 Attr1s = [attr.strip() for attr in Attr1.split(",")]
2503 Attr1Set = set(Attr1s)
2504 Attr2s = [attr.strip() for attr in Attr2.split(",")]
2505 Attr2Set = set(Attr2s)
2506 if Attr2Set == Attr1Set:
2507 return True
2508 else:
2509 return False
2510
2511 def CompletePcdValues(self, PcdSet):
2512 Pcds = {}
2513 DefaultStoreObj = DefaultStore(self._GetDefaultStores())
2514 SkuIds = {skuname:skuid for skuname, skuid in self.SkuIdMgr.AvailableSkuIdSet.items() if skuname != TAB_COMMON}
2515 DefaultStores = set(storename for pcdobj in PcdSet.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict)
2516 for PcdCName, TokenSpaceGuid in PcdSet:
2517 PcdObj = PcdSet[(PcdCName, TokenSpaceGuid)]
2518
2519 if PcdObj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
2520 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
2521 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],
2522 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],
2523 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],
2524 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]:
2525 Pcds[PcdCName, TokenSpaceGuid]= PcdObj
2526 continue
2527 PcdType = PcdObj.Type
2528 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
2529 for skuid in PcdObj.SkuInfoList:
2530 skuobj = PcdObj.SkuInfoList[skuid]
2531 mindefaultstorename = DefaultStoreObj.GetMin(set(defaultstorename for defaultstorename in skuobj.DefaultStoreDict))
2532 for defaultstorename in DefaultStores:
2533 if defaultstorename not in skuobj.DefaultStoreDict:
2534 skuobj.DefaultStoreDict[defaultstorename] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])
2535 skuobj.HiiDefaultValue = skuobj.DefaultStoreDict[mindefaultstorename]
2536 for skuname, skuid in SkuIds.items():
2537 if skuname not in PcdObj.SkuInfoList:
2538 nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
2539 while nextskuid not in PcdObj.SkuInfoList:
2540 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
2541 PcdObj.SkuInfoList[skuname] = copy.deepcopy(PcdObj.SkuInfoList[nextskuid])
2542 PcdObj.SkuInfoList[skuname].SkuId = skuid
2543 PcdObj.SkuInfoList[skuname].SkuIdName = skuname
2544 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
2545 PcdObj.DefaultValue = PcdObj.SkuInfoList.values()[0].HiiDefaultValue if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE else PcdObj.SkuInfoList[TAB_DEFAULT].HiiDefaultValue
2546 Pcds[PcdCName, TokenSpaceGuid]= PcdObj
2547 return Pcds
2548 ## Retrieve dynamic HII PCD settings
2549 #
2550 # @param Type PCD type
2551 #
2552 # @retval a dict object contains settings of given PCD type
2553 #
2554 def _GetDynamicHiiPcd(self, Type):
2555
2556 VariableAttrs = {}
2557
2558 Pcds = OrderedDict()
2559 UserDefinedDefaultStores = []
2560 #
2561 # tdict is a special dict kind of type, used for selecting correct
2562 # PCD settings for certain ARCH and SKU
2563 #
2564 PcdDict = tdict(True, 5)
2565 PcdSet = set()
2566 RecordList = self._RawData[Type, self._Arch]
2567 # Find out all possible PCD candidates for self._Arch
2568 AvailableSkuIdSet = copy.copy(self.SkuIds)
2569 DefaultStoresDefine = self._GetDefaultStores()
2570
2571 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, DefaultStore, Dummy4, Dummy5 in RecordList:
2572 SkuName = SkuName.upper()
2573 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
2574 DefaultStore = DefaultStore.upper()
2575 if DefaultStore == TAB_COMMON:
2576 DefaultStore = TAB_DEFAULT_STORES_DEFAULT
2577 else:
2578 #The end user define [DefaultStores] and [SKUID_IDENTIFIER.Menufacturing] in DSC
2579 UserDefinedDefaultStores.append((PcdCName, TokenSpaceGuid))
2580 if SkuName not in AvailableSkuIdSet:
2581 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
2582 File=self.MetaFile, Line=Dummy5)
2583 if DefaultStore not in DefaultStoresDefine:
2584 EdkLogger.error('build', PARAMETER_INVALID, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore,
2585 File=self.MetaFile, Line=Dummy5)
2586 if "." not in TokenSpaceGuid:
2587 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, DefaultStore, Dummy5))
2588 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid, DefaultStore] = Setting
2589
2590
2591 # Remove redundant PCD candidates, per the ARCH and SKU
2592 for PcdCName, TokenSpaceGuid, SkuName, DefaultStore, Dummy4 in PcdSet:
2593
2594 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid, DefaultStore]
2595 if Setting is None:
2596 continue
2597 VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
2598
2599 rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)
2600 if not rt:
2601 EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),
2602 ExtraData="[%s]" % VarAttribute)
2603 ExceedMax = False
2604 FormatCorrect = True
2605 if VariableOffset.isdigit():
2606 if int(VariableOffset, 10) > 0xFFFF:
2607 ExceedMax = True
2608 elif variablePattern.match(VariableOffset):
2609 if int(VariableOffset, 16) > 0xFFFF:
2610 ExceedMax = True
2611 # For Offset written in "A.B"
2612 elif VariableOffset.find('.') > -1:
2613 VariableOffsetList = VariableOffset.split(".")
2614 if not (len(VariableOffsetList) == 2
2615 and IsValidWord(VariableOffsetList[0])
2616 and IsValidWord(VariableOffsetList[1])):
2617 FormatCorrect = False
2618 else:
2619 FormatCorrect = False
2620 if not FormatCorrect:
2621 EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid, PcdCName)))
2622
2623 if ExceedMax:
2624 EdkLogger.error('Build', OPTION_VALUE_INVALID, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)))
2625 if (VariableName, VariableGuid) not in VariableAttrs:
2626 VariableAttrs[(VariableName, VariableGuid)] = VarAttribute
2627 else:
2628 if not DscBuildData.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):
2629 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)]))
2630
2631 pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]
2632 if (PcdCName, TokenSpaceGuid) in Pcds:
2633 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
2634 if SkuName in pcdObject.SkuInfoList:
2635 Skuitem = pcdObject.SkuInfoList[SkuName]
2636 Skuitem.DefaultStoreDict.update({DefaultStore:DefaultValue})
2637 else:
2638 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute, DefaultStore={DefaultStore:DefaultValue})
2639 pcdObject.SkuInfoList[SkuName] = SkuInfo
2640 else:
2641 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute, DefaultStore={DefaultStore:DefaultValue})
2642 PcdClassObj = PcdClassObject(
2643 PcdCName,
2644 TokenSpaceGuid,
2645 self._PCD_TYPE_STRING_[Type],
2646 '',
2647 DefaultValue,
2648 '',
2649 '',
2650 {SkuName : SkuInfo},
2651 False,
2652 None,
2653 pcdDecObject.validateranges,
2654 pcdDecObject.validlists,
2655 pcdDecObject.expressions,
2656 IsDsc=True)
2657 if (PcdCName, TokenSpaceGuid) in UserDefinedDefaultStores:
2658 PcdClassObj.UserDefinedDefaultStoresFlag = True
2659 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObj
2660
2661 if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
2662 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
2663 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][DefaultStore] = DefaultValue
2664 for pcd in Pcds.values():
2665 SkuInfoObj = pcd.SkuInfoList.values()[0]
2666 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
2667 pcd.DatumType = pcdDecObject.DatumType
2668 # Only fix the value while no value provided in DSC file.
2669 for sku in pcd.SkuInfoList.values():
2670 if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue is None):
2671 sku.HiiDefaultValue = pcdDecObject.DefaultValue
2672 for default_store in sku.DefaultStoreDict:
2673 sku.DefaultStoreDict[default_store]=pcdDecObject.DefaultValue
2674 pcd.DefaultValue = pcdDecObject.DefaultValue
2675 if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:
2676 valuefromDec = pcdDecObject.DefaultValue
2677 SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec, VariableAttribute=SkuInfoObj.VariableAttribute, DefaultStore={DefaultStore:valuefromDec})
2678 pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo
2679 elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2680 pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
2681 del pcd.SkuInfoList[TAB_COMMON]
2682 elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2683 del pcd.SkuInfoList[TAB_COMMON]
2684
2685 if pcd.MaxDatumSize.strip():
2686 MaxSize = int(pcd.MaxDatumSize, 0)
2687 else:
2688 MaxSize = 0
2689 if pcd.DatumType not in TAB_PCD_NUMERIC_TYPES:
2690 for (_, skuobj) in pcd.SkuInfoList.items():
2691 datalen = 0
2692 skuobj.HiiDefaultValue = StringToArray(skuobj.HiiDefaultValue)
2693 datalen = len(skuobj.HiiDefaultValue.split(","))
2694 if datalen > MaxSize:
2695 MaxSize = datalen
2696 for defaultst in skuobj.DefaultStoreDict:
2697 skuobj.DefaultStoreDict[defaultst] = StringToArray(skuobj.DefaultStoreDict[defaultst])
2698 pcd.DefaultValue = StringToArray(pcd.DefaultValue)
2699 pcd.MaxDatumSize = str(MaxSize)
2700 rt, invalidhii = DscBuildData.CheckVariableNameAssignment(Pcds)
2701 if not rt:
2702 invalidpcd = ",".join(invalidhii)
2703 EdkLogger.error('build', PCD_VARIABLE_INFO_ERROR, Message='The same HII PCD must map to the same EFI variable for all SKUs', File=self.MetaFile, ExtraData=invalidpcd)
2704
2705 map(self.FilterSkuSettings, Pcds.values())
2706
2707 return Pcds
2708
2709 @staticmethod
2710 def CheckVariableNameAssignment(Pcds):
2711 invalidhii = []
2712 for pcdname in Pcds:
2713 pcd = Pcds[pcdname]
2714 varnameset = set(sku.VariableName for (skuid, sku) in pcd.SkuInfoList.items())
2715 if len(varnameset) > 1:
2716 invalidhii.append(".".join((pcdname[1], pcdname[0])))
2717 if len(invalidhii):
2718 return False, invalidhii
2719 else:
2720 return True, []
2721 ## Retrieve dynamic VPD PCD settings
2722 #
2723 # @param Type PCD type
2724 #
2725 # @retval a dict object contains settings of given PCD type
2726 #
2727 def _GetDynamicVpdPcd(self, Type):
2728
2729
2730 Pcds = OrderedDict()
2731 #
2732 # tdict is a special dict kind of type, used for selecting correct
2733 # PCD settings for certain ARCH and SKU
2734 #
2735 PcdDict = tdict(True, 4)
2736 PcdList = []
2737
2738 # Find out all possible PCD candidates for self._Arch
2739 RecordList = self._RawData[Type, self._Arch]
2740 AvailableSkuIdSet = copy.copy(self.SkuIds)
2741
2742 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:
2743 SkuName = SkuName.upper()
2744 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
2745 if SkuName not in AvailableSkuIdSet:
2746 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
2747 File=self.MetaFile, Line=Dummy5)
2748 if "." not in TokenSpaceGuid:
2749 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
2750 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
2751
2752 # Remove redundant PCD candidates, per the ARCH and SKU
2753 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
2754 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
2755 if Setting is None:
2756 continue
2757 #
2758 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
2759 # For the Integer & Boolean type, the optional data can only be InitialValue.
2760 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
2761 # until the DEC parser has been called.
2762 #
2763 VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
2764 if MaxDatumSize:
2765 if int(MaxDatumSize, 0) > 0xFFFF:
2766 EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),
2767 File=self.MetaFile, Line=Dummy4)
2768 if int(MaxDatumSize, 0) < 0:
2769 EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),
2770 File=self.MetaFile, Line=Dummy4)
2771 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', VpdOffset, InitialValue)
2772 if (PcdCName, TokenSpaceGuid) in Pcds:
2773 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
2774 pcdObject.SkuInfoList[SkuName] = SkuInfo
2775 if MaxDatumSize.strip():
2776 CurrentMaxSize = int(MaxDatumSize.strip(), 0)
2777 else:
2778 CurrentMaxSize = 0
2779 if pcdObject.MaxDatumSize:
2780 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
2781 else:
2782 PcdMaxSize = 0
2783 if CurrentMaxSize > PcdMaxSize:
2784 pcdObject.MaxDatumSize = str(CurrentMaxSize)
2785 else:
2786 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
2787 PcdCName,
2788 TokenSpaceGuid,
2789 self._PCD_TYPE_STRING_[Type],
2790 '',
2791 InitialValue,
2792 '',
2793 MaxDatumSize,
2794 {SkuName : SkuInfo},
2795 False,
2796 None,
2797 IsDsc=True)
2798
2799 if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
2800 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
2801 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = InitialValue
2802 for pcd in Pcds.values():
2803 SkuInfoObj = pcd.SkuInfoList.values()[0]
2804 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
2805 pcd.DatumType = pcdDecObject.DatumType
2806 # Only fix the value while no value provided in DSC file.
2807 for sku in pcd.SkuInfoList.values():
2808 if not sku.DefaultValue:
2809 sku.DefaultValue = pcdDecObject.DefaultValue
2810 if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:
2811 valuefromDec = pcdDecObject.DefaultValue
2812 SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', '', '', '', '', SkuInfoObj.VpdOffset, valuefromDec)
2813 pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo
2814 elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2815 pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
2816 del pcd.SkuInfoList[TAB_COMMON]
2817 elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2818 del pcd.SkuInfoList[TAB_COMMON]
2819
2820
2821 map(self.FilterSkuSettings, Pcds.values())
2822 return Pcds
2823
2824 ## Add external modules
2825 #
2826 # The external modules are mostly those listed in FDF file, which don't
2827 # need "build".
2828 #
2829 # @param FilePath The path of module description file
2830 #
2831 def AddModule(self, FilePath):
2832 FilePath = NormPath(FilePath)
2833 if FilePath not in self.Modules:
2834 Module = ModuleBuildClassObject()
2835 Module.MetaFile = FilePath
2836 self.Modules.append(Module)
2837
2838 @property
2839 def ToolChainFamily(self):
2840 self._ToolChainFamily = TAB_COMPILER_MSFT
2841 BuildConfigurationFile = os.path.normpath(os.path.join(GlobalData.gConfDirectory, "target.txt"))
2842 if os.path.isfile(BuildConfigurationFile) == True:
2843 TargetTxt = TargetTxtClassObject()
2844 TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)
2845 ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
2846 if ToolDefinitionFile == '':
2847 ToolDefinitionFile = "tools_def.txt"
2848 ToolDefinitionFile = os.path.normpath(mws.join(self.WorkspaceDir, 'Conf', ToolDefinitionFile))
2849 if os.path.isfile(ToolDefinitionFile) == True:
2850 ToolDef = ToolDefClassObject()
2851 ToolDef.LoadToolDefFile(ToolDefinitionFile)
2852 ToolDefinition = ToolDef.ToolsDefTxtDatabase
2853 if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \
2854 or self._Toolchain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \
2855 or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]:
2856 self._ToolChainFamily = TAB_COMPILER_MSFT
2857 else:
2858 self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]
2859 return self._ToolChainFamily
2860
2861 ## Add external PCDs
2862 #
2863 # The external PCDs are mostly those listed in FDF file to specify address
2864 # or offset information.
2865 #
2866 # @param Name Name of the PCD
2867 # @param Guid Token space guid of the PCD
2868 # @param Value Value of the PCD
2869 #
2870 def AddPcd(self, Name, Guid, Value):
2871 if (Name, Guid) not in self.Pcds:
2872 self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)
2873 self.Pcds[Name, Guid].DefaultValue = Value
2874
2875 @property
2876 def DecPcds(self):
2877 if self._DecPcds is None:
2878 FdfInfList = []
2879 if GlobalData.gFdfParser:
2880 FdfInfList = GlobalData.gFdfParser.Profile.InfList
2881 PkgSet = set()
2882 for Inf in FdfInfList:
2883 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)
2884 if ModuleFile in self._Modules:
2885 continue
2886 ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
2887 PkgSet.update(ModuleData.Packages)
2888 self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain, PkgSet)
2889 return self._DecPcds