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