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