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