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