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