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