2 # This file is used to create a database used by build tool
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
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.
15 ## Platform build information from DSC file
17 # This class is used to retrieve information stored in database and convert them
18 # into PlatformBuildClassObject form for easier use for AutoGen.
20 from __future__
import print_function
21 from Common
.StringUtils
import *
22 from Common
.DataType
import *
23 from Common
.Misc
import *
25 from Common
.Expression
import *
26 from CommonDataClass
.CommonClass
import SkuInfoClass
27 from Common
.TargetTxtClassObject
import *
28 from Common
.ToolDefClassObject
import *
29 from MetaDataTable
import *
30 from MetaFileTable
import *
31 from MetaFileParser
import *
33 from WorkspaceCommon
import GetDeclaredPcd
34 from Common
.Misc
import AnalyzeDscPcd
35 from Common
.Misc
import ProcessDuplicatedInf
37 from Common
.Parsing
import IsValidWord
38 from Common
.VariableAttributes
import VariableAttributes
39 import Common
.GlobalData
as GlobalData
41 from Common
.Misc
import SaveFileOnChange
42 from Workspace
.BuildClassObject
import PlatformBuildClassObject
, StructurePcd
, PcdClassObject
, ModuleBuildClassObject
43 from collections
import OrderedDict
,defaultdict
45 PcdValueInitName
= 'PcdValueInit'
56 #include <PcdValueCommon.h>
66 return PcdValueMain (argc, argv);
70 PcdMakefileHeader
= '''
73 # This file is auto-generated by build utility
78 WindowsCFLAGS
= 'CFLAGS = $(CFLAGS) /wd4200 /wd4034 /wd4101 '
79 LinuxCFLAGS
= 'BUILD_CFLAGS += -Wno-pointer-to-int-cast -Wno-unused-variable '
81 !INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.common
83 LIBS = $(LIB_PATH)\Common.lib
85 !INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.app
89 MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C
93 variablePattern
= re
.compile(r
'[\t\s]*0[xX][a-fA-F0-9]+$')
95 ## regular expressions for finding decimal and hex numbers
96 Pattern
= re
.compile('^[1-9]\d*|0$')
97 HexPattern
= re
.compile(r
'0[xX][0-9a-fA-F]+$')
98 ## Regular expression for finding header file inclusions
99 from AutoGen
.GenMake
import gIncludePattern
101 ## Find dependencies for one source file
103 # By searching recursively "#include" directive in file, find out all the
104 # files needed by given source file. The dependecies will be only searched
105 # in given search path list.
107 # @param SearchPathList The list of search path
109 # @retval list The list of files the given source file depends on
111 def GetDependencyList(FileStack
,SearchPathList
):
113 DependencySet
= set(FileStack
)
114 while len(FileStack
) > 0:
116 FullPathDependList
= []
117 CurrentFileDependencyList
= []
119 CurrentFileDependencyList
= DepDb
[F
]
123 FileContent
= Fd
.read()
124 except BaseException
as X
:
125 EdkLogger
.error("build", FILE_OPEN_FAILURE
, ExtraData
=F
+ "\n\t" + str(X
))
127 if "Fd" in dir(locals()):
130 if len(FileContent
) == 0:
133 if FileContent
[0] == 0xff or FileContent
[0] == 0xfe:
134 FileContent
= unicode(FileContent
, "utf-16")
135 IncludedFileList
= gIncludePattern
.findall(FileContent
)
137 for Inc
in IncludedFileList
:
139 Inc
= os
.path
.normpath(Inc
)
140 CurrentFileDependencyList
.append(Inc
)
141 DepDb
[F
] = CurrentFileDependencyList
143 CurrentFilePath
= os
.path
.dirname(F
)
144 PathList
= [CurrentFilePath
] + SearchPathList
145 for Inc
in CurrentFileDependencyList
:
146 for SearchPath
in PathList
:
147 FilePath
= os
.path
.join(SearchPath
, Inc
)
148 if not os
.path
.exists(FilePath
):
150 if FilePath
not in DependencySet
:
151 FileStack
.append(FilePath
)
152 FullPathDependList
.append(FilePath
)
154 DependencySet
.update(FullPathDependList
)
155 DependencyList
= list(DependencySet
) # remove duplicate ones
157 return DependencyList
159 class DscBuildData(PlatformBuildClassObject
):
160 # dict used to convert PCD type in database to string used by build tool
161 _PCD_TYPE_STRING_
= {
162 MODEL_PCD_FIXED_AT_BUILD
: TAB_PCDS_FIXED_AT_BUILD
,
163 MODEL_PCD_PATCHABLE_IN_MODULE
: TAB_PCDS_PATCHABLE_IN_MODULE
,
164 MODEL_PCD_FEATURE_FLAG
: TAB_PCDS_FEATURE_FLAG
,
165 MODEL_PCD_DYNAMIC
: TAB_PCDS_DYNAMIC
,
166 MODEL_PCD_DYNAMIC_DEFAULT
: TAB_PCDS_DYNAMIC
,
167 MODEL_PCD_DYNAMIC_HII
: TAB_PCDS_DYNAMIC_HII
,
168 MODEL_PCD_DYNAMIC_VPD
: TAB_PCDS_DYNAMIC_VPD
,
169 MODEL_PCD_DYNAMIC_EX
: TAB_PCDS_DYNAMIC_EX
,
170 MODEL_PCD_DYNAMIC_EX_DEFAULT
: TAB_PCDS_DYNAMIC_EX
,
171 MODEL_PCD_DYNAMIC_EX_HII
: TAB_PCDS_DYNAMIC_EX_HII
,
172 MODEL_PCD_DYNAMIC_EX_VPD
: TAB_PCDS_DYNAMIC_EX_VPD
,
175 # dict used to convert part of [Defines] to members of DscBuildData directly
180 TAB_DSC_DEFINES_PLATFORM_NAME
: "_PlatformName",
181 TAB_DSC_DEFINES_PLATFORM_GUID
: "_Guid",
182 TAB_DSC_DEFINES_PLATFORM_VERSION
: "_Version",
183 TAB_DSC_DEFINES_DSC_SPECIFICATION
: "_DscSpecification",
184 # TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
185 # TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
186 # TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
187 TAB_DSC_DEFINES_SKUID_IDENTIFIER
: "_SkuName",
188 # TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
189 TAB_DSC_DEFINES_BUILD_NUMBER
: "_BuildNumber",
190 TAB_DSC_DEFINES_MAKEFILE_NAME
: "_MakefileName",
191 TAB_DSC_DEFINES_BS_BASE_ADDRESS
: "_BsBaseAddress",
192 TAB_DSC_DEFINES_RT_BASE_ADDRESS
: "_RtBaseAddress",
193 # TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
194 # TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
197 # used to compose dummy library class name for those forced library instances
198 _NullLibraryNumber
= 0
200 ## Constructor of DscBuildData
202 # Initialize object of DscBuildData
204 # @param FilePath The path of platform description file
205 # @param RawData The raw data of DSC file
206 # @param BuildDataBase Database used to retrieve module/package information
207 # @param Arch The target architecture
208 # @param Platform (not used for DscBuildData)
209 # @param Macros Macros used for replacement in DSC file
211 def __init__(self
, FilePath
, RawData
, BuildDataBase
, Arch
=TAB_ARCH_COMMON
, Target
=None, Toolchain
=None):
212 self
.MetaFile
= FilePath
213 self
._RawData
= RawData
214 self
._Bdb
= BuildDataBase
216 self
._Target
= Target
217 self
._Toolchain
= Toolchain
218 self
._ToolChainFamily
= None
220 self
._HandleOverridePath
()
221 self
.WorkspaceDir
= os
.getenv("WORKSPACE") if os
.getenv("WORKSPACE") else ""
222 self
.DefaultStores
= None
223 self
.SkuIdMgr
= SkuClass(self
.SkuName
, self
.SkuIds
)
225 def OutputPath(self
):
226 if os
.getenv("WORKSPACE"):
227 return os
.path
.join(os
.getenv("WORKSPACE"), self
.OutputDirectory
, self
._Target
+ "_" + self
._Toolchain
,PcdValueInitName
)
229 return os
.path
.dirname(self
.DscFile
)
232 def __setitem__(self
, key
, value
):
233 self
.__dict
__[self
._PROPERTY
_[key
]] = value
236 def __getitem__(self
, key
):
237 return self
.__dict
__[self
._PROPERTY
_[key
]]
240 def __contains__(self
, key
):
241 return key
in self
._PROPERTY
_
243 ## Set all internal used members of DscBuildData to None
246 self
._PlatformName
= None
249 self
._DscSpecification
= None
250 self
._OutputDirectory
= None
251 self
._SupArchList
= None
252 self
._BuildTargets
= None
254 self
._PcdInfoFlag
= None
255 self
._VarCheckFlag
= None
256 self
._FlashDefinition
= None
257 self
._Prebuild
= None
258 self
._Postbuild
= None
259 self
._BuildNumber
= None
260 self
._MakefileName
= None
261 self
._BsBaseAddress
= None
262 self
._RtBaseAddress
= None
265 self
._LibraryInstances
= None
266 self
._LibraryClasses
= None
269 self
._BuildOptions
= None
270 self
._ModuleTypeOptions
= None
271 self
._LoadFixAddress
= None
272 self
._RFCLanguages
= None
273 self
._ISOLanguages
= None
274 self
._VpdToolGuid
= None
276 self
.DefaultStores
= None
279 ## handle Override Path of Module
280 def _HandleOverridePath(self
):
281 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
282 for Record
in RecordList
:
285 ModuleFile
= PathClass(NormPath(Record
[0]), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
286 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
, self
._Arch
, None, ModuleId
]
288 SourceOverridePath
= mws
.join(GlobalData
.gWorkspace
, NormPath(RecordList
[0][0]))
290 # Check if the source override path exists
291 if not os
.path
.isdir(SourceOverridePath
):
292 EdkLogger
.error('build', FILE_NOT_FOUND
, Message
='Source override path does not exist:', File
=self
.MetaFile
, ExtraData
=SourceOverridePath
, Line
=LineNo
)
294 # Add to GlobalData Variables
295 GlobalData
.gOverrideDir
[ModuleFile
.Key
] = SourceOverridePath
297 ## Get current effective macros
298 def _GetMacros(self
):
299 if self
.__Macros
is None:
301 self
.__Macros
.update(GlobalData
.gPlatformDefines
)
302 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
303 self
.__Macros
.update(GlobalData
.gCommandLineDefines
)
312 # Changing the default ARCH to another may affect all other information
313 # because all information in a platform may be ARCH-related. That's
314 # why we need to clear all internal used members, in order to cause all
315 # information to be re-retrieved.
317 # @param Value The value of ARCH
319 def _SetArch(self
, Value
):
320 if self
._Arch
== Value
:
325 ## Retrieve all information in [Defines] section
327 # (Retriving all [Defines] information in one-shot is just to save time.)
329 def _GetHeaderInfo(self
):
330 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
331 for Record
in RecordList
:
333 # items defined _PROPERTY_ don't need additional processing
335 # some special items in [Defines] section need special treatment
336 if Name
== TAB_DSC_DEFINES_OUTPUT_DIRECTORY
:
337 self
._OutputDirectory
= NormPath(Record
[2], self
._Macros
)
338 if ' ' in self
._OutputDirectory
:
339 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "No space is allowed in OUTPUT_DIRECTORY",
340 File
=self
.MetaFile
, Line
=Record
[-1],
341 ExtraData
=self
._OutputDirectory
)
342 elif Name
== TAB_DSC_DEFINES_FLASH_DEFINITION
:
343 self
._FlashDefinition
= PathClass(NormPath(Record
[2], self
._Macros
), GlobalData
.gWorkspace
)
344 ErrorCode
, ErrorInfo
= self
._FlashDefinition
.Validate('.fdf')
346 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=Record
[-1],
348 elif Name
== TAB_DSC_PREBUILD
:
349 PrebuildValue
= Record
[2]
350 if Record
[2][0] == '"':
351 if Record
[2][-1] != '"':
352 EdkLogger
.error('build', FORMAT_INVALID
, 'Missing double quotes in the end of %s statement.' % TAB_DSC_PREBUILD
,
353 File
=self
.MetaFile
, Line
=Record
[-1])
354 PrebuildValue
= Record
[2][1:-1]
355 self
._Prebuild
= PrebuildValue
356 elif Name
== TAB_DSC_POSTBUILD
:
357 PostbuildValue
= Record
[2]
358 if Record
[2][0] == '"':
359 if Record
[2][-1] != '"':
360 EdkLogger
.error('build', FORMAT_INVALID
, 'Missing double quotes in the end of %s statement.' % TAB_DSC_POSTBUILD
,
361 File
=self
.MetaFile
, Line
=Record
[-1])
362 PostbuildValue
= Record
[2][1:-1]
363 self
._Postbuild
= PostbuildValue
364 elif Name
== TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES
:
365 self
._SupArchList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
366 elif Name
== TAB_DSC_DEFINES_BUILD_TARGETS
:
367 self
._BuildTargets
= GetSplitValueList(Record
[2])
368 elif Name
== TAB_DSC_DEFINES_SKUID_IDENTIFIER
:
369 if self
._SkuName
is None:
370 self
._SkuName
= Record
[2]
371 if GlobalData
.gSKUID_CMD
:
372 self
._SkuName
= GlobalData
.gSKUID_CMD
373 elif Name
== TAB_DSC_DEFINES_PCD_INFO_GENERATION
:
374 self
._PcdInfoFlag
= Record
[2]
375 elif Name
== TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION
:
376 self
._VarCheckFlag
= Record
[2]
377 elif Name
== TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
:
379 self
._LoadFixAddress
= int (Record
[2], 0)
381 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record
[2]))
382 elif Name
== TAB_DSC_DEFINES_RFC_LANGUAGES
:
383 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
384 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for RFC_LANGUAGES must have double quotes around it, for example: RFC_LANGUAGES = "en-us;zh-hans"',
385 File
=self
.MetaFile
, Line
=Record
[-1])
386 LanguageCodes
= Record
[2][1:-1]
387 if not LanguageCodes
:
388 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
389 File
=self
.MetaFile
, Line
=Record
[-1])
390 LanguageList
= GetSplitValueList(LanguageCodes
, TAB_SEMI_COLON_SPLIT
)
391 # check whether there is empty entries in the list
392 if None in LanguageList
:
393 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more empty language code is in RFC_LANGUAGES statement',
394 File
=self
.MetaFile
, Line
=Record
[-1])
395 self
._RFCLanguages
= LanguageList
396 elif Name
== TAB_DSC_DEFINES_ISO_LANGUAGES
:
397 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
398 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
399 File
=self
.MetaFile
, Line
=Record
[-1])
400 LanguageCodes
= Record
[2][1:-1]
401 if not LanguageCodes
:
402 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
403 File
=self
.MetaFile
, Line
=Record
[-1])
404 if len(LanguageCodes
) % 3:
405 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'bad ISO639-2 format for ISO_LANGUAGES',
406 File
=self
.MetaFile
, Line
=Record
[-1])
408 for i
in range(0, len(LanguageCodes
), 3):
409 LanguageList
.append(LanguageCodes
[i
:i
+ 3])
410 self
._ISOLanguages
= LanguageList
411 elif Name
== TAB_DSC_DEFINES_VPD_TOOL_GUID
:
413 # try to convert GUID to a real UUID value to see whether the GUID is format
414 # for VPD_TOOL_GUID is correct.
419 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid GUID format for VPD_TOOL_GUID", File
=self
.MetaFile
)
420 self
._VpdToolGuid
= Record
[2]
422 self
[Name
] = Record
[2]
423 # set _Header to non-None in order to avoid database re-querying
424 self
._Header
= 'DUMMY'
426 ## Retrieve platform name
427 def _GetPlatformName(self
):
428 if self
._PlatformName
is None:
429 if self
._Header
is None:
430 self
._GetHeaderInfo
()
431 if self
._PlatformName
is None:
432 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_NAME", File
=self
.MetaFile
)
433 return self
._PlatformName
435 ## Retrieve file guid
436 def _GetFileGuid(self
):
437 if self
._Guid
is None:
438 if self
._Header
is None:
439 self
._GetHeaderInfo
()
440 if self
._Guid
is None:
441 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_GUID", File
=self
.MetaFile
)
444 ## Retrieve platform version
445 def _GetVersion(self
):
446 if self
._Version
is None:
447 if self
._Header
is None:
448 self
._GetHeaderInfo
()
449 if self
._Version
is None:
450 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_VERSION", File
=self
.MetaFile
)
453 ## Retrieve platform description file version
454 def _GetDscSpec(self
):
455 if self
._DscSpecification
is None:
456 if self
._Header
is None:
457 self
._GetHeaderInfo
()
458 if self
._DscSpecification
is None:
459 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No DSC_SPECIFICATION", File
=self
.MetaFile
)
460 return self
._DscSpecification
462 ## Retrieve OUTPUT_DIRECTORY
463 def _GetOutpuDir(self
):
464 if self
._OutputDirectory
is None:
465 if self
._Header
is None:
466 self
._GetHeaderInfo
()
467 if self
._OutputDirectory
is None:
468 self
._OutputDirectory
= os
.path
.join("Build", self
._PlatformName
)
469 return self
._OutputDirectory
471 ## Retrieve SUPPORTED_ARCHITECTURES
472 def _GetSupArch(self
):
473 if self
._SupArchList
is None:
474 if self
._Header
is None:
475 self
._GetHeaderInfo
()
476 if self
._SupArchList
is None:
477 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No SUPPORTED_ARCHITECTURES", File
=self
.MetaFile
)
478 return self
._SupArchList
480 ## Retrieve BUILD_TARGETS
481 def _GetBuildTarget(self
):
482 if self
._BuildTargets
is None:
483 if self
._Header
is None:
484 self
._GetHeaderInfo
()
485 if self
._BuildTargets
is None:
486 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BUILD_TARGETS", File
=self
.MetaFile
)
487 return self
._BuildTargets
489 def _GetPcdInfoFlag(self
):
490 if self
._PcdInfoFlag
is None or self
._PcdInfoFlag
.upper() == 'FALSE':
492 elif self
._PcdInfoFlag
.upper() == 'TRUE':
496 def _GetVarCheckFlag(self
):
497 if self
._VarCheckFlag
is None or self
._VarCheckFlag
.upper() == 'FALSE':
499 elif self
._VarCheckFlag
.upper() == 'TRUE':
504 # # Retrieve SKUID_IDENTIFIER
505 def _GetSkuName(self
):
506 if self
._SkuName
is None:
507 if self
._Header
is None:
508 self
._GetHeaderInfo
()
509 if self
._SkuName
is None:
510 self
._SkuName
= TAB_DEFAULT
513 ## Override SKUID_IDENTIFIER
514 def _SetSkuName(self
, Value
):
515 self
._SkuName
= Value
517 def _GetFdfFile(self
):
518 if self
._FlashDefinition
is None:
519 if self
._Header
is None:
520 self
._GetHeaderInfo
()
521 if self
._FlashDefinition
is None:
522 self
._FlashDefinition
= ''
523 return self
._FlashDefinition
525 def _GetPrebuild(self
):
526 if self
._Prebuild
is None:
527 if self
._Header
is None:
528 self
._GetHeaderInfo
()
529 if self
._Prebuild
is None:
531 return self
._Prebuild
533 def _GetPostbuild(self
):
534 if self
._Postbuild
is None:
535 if self
._Header
is None:
536 self
._GetHeaderInfo
()
537 if self
._Postbuild
is None:
539 return self
._Postbuild
541 ## Retrieve FLASH_DEFINITION
542 def _GetBuildNumber(self
):
543 if self
._BuildNumber
is None:
544 if self
._Header
is None:
545 self
._GetHeaderInfo
()
546 if self
._BuildNumber
is None:
547 self
._BuildNumber
= ''
548 return self
._BuildNumber
550 ## Retrieve MAKEFILE_NAME
551 def _GetMakefileName(self
):
552 if self
._MakefileName
is None:
553 if self
._Header
is None:
554 self
._GetHeaderInfo
()
555 if self
._MakefileName
is None:
556 self
._MakefileName
= ''
557 return self
._MakefileName
559 ## Retrieve BsBaseAddress
560 def _GetBsBaseAddress(self
):
561 if self
._BsBaseAddress
is None:
562 if self
._Header
is None:
563 self
._GetHeaderInfo
()
564 if self
._BsBaseAddress
is None:
565 self
._BsBaseAddress
= ''
566 return self
._BsBaseAddress
568 ## Retrieve RtBaseAddress
569 def _GetRtBaseAddress(self
):
570 if self
._RtBaseAddress
is None:
571 if self
._Header
is None:
572 self
._GetHeaderInfo
()
573 if self
._RtBaseAddress
is None:
574 self
._RtBaseAddress
= ''
575 return self
._RtBaseAddress
577 ## Retrieve the top address for the load fix address
578 def _GetLoadFixAddress(self
):
579 if self
._LoadFixAddress
is None:
580 if self
._Header
is None:
581 self
._GetHeaderInfo
()
583 if self
._LoadFixAddress
is None:
584 self
._LoadFixAddress
= self
._Macros
.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
, '0')
587 self
._LoadFixAddress
= int (self
._LoadFixAddress
, 0)
589 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self
._LoadFixAddress
))
592 # If command line defined, should override the value in DSC file.
594 if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData
.gCommandLineDefines
:
596 self
._LoadFixAddress
= int(GlobalData
.gCommandLineDefines
['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
598 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (GlobalData
.gCommandLineDefines
['FIX_LOAD_TOP_MEMORY_ADDRESS']))
600 if self
._LoadFixAddress
< 0:
601 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self
._LoadFixAddress
))
602 if self
._LoadFixAddress
!= 0xFFFFFFFFFFFFFFFF and self
._LoadFixAddress
% 0x1000 != 0:
603 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self
._LoadFixAddress
))
605 return self
._LoadFixAddress
607 ## Retrieve RFCLanguage filter
608 def _GetRFCLanguages(self
):
609 if self
._RFCLanguages
is None:
610 if self
._Header
is None:
611 self
._GetHeaderInfo
()
612 if self
._RFCLanguages
is None:
613 self
._RFCLanguages
= []
614 return self
._RFCLanguages
616 ## Retrieve ISOLanguage filter
617 def _GetISOLanguages(self
):
618 if self
._ISOLanguages
is None:
619 if self
._Header
is None:
620 self
._GetHeaderInfo
()
621 if self
._ISOLanguages
is None:
622 self
._ISOLanguages
= []
623 return self
._ISOLanguages
624 ## Retrieve the GUID string for VPD tool
625 def _GetVpdToolGuid(self
):
626 if self
._VpdToolGuid
is None:
627 if self
._Header
is None:
628 self
._GetHeaderInfo
()
629 if self
._VpdToolGuid
is None:
630 self
._VpdToolGuid
= ''
631 return self
._VpdToolGuid
633 ## Retrieve [SkuIds] section information
634 def _GetSkuIds(self
):
635 if self
._SkuIds
is None:
636 self
._SkuIds
= OrderedDict()
637 RecordList
= self
._RawData
[MODEL_EFI_SKU_ID
, self
._Arch
]
638 for Record
in RecordList
:
640 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID number',
641 File
=self
.MetaFile
, Line
=Record
[-1])
643 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID name',
644 File
=self
.MetaFile
, Line
=Record
[-1])
645 if not Pattern
.match(Record
[0]) and not HexPattern
.match(Record
[0]):
646 EdkLogger
.error('build', FORMAT_INVALID
, "The format of the Sku ID number is invalid. It only support Integer and HexNumber",
647 File
=self
.MetaFile
, Line
=Record
[-1])
648 if not IsValidWord(Record
[1]):
649 EdkLogger
.error('build', FORMAT_INVALID
, "The format of the Sku ID name is invalid. The correct format is '(a-zA-Z0-9_)(a-zA-Z0-9_-.)*'",
650 File
=self
.MetaFile
, Line
=Record
[-1])
651 self
._SkuIds
[Record
[1].upper()] = (str(DscBuildData
.ToInt(Record
[0])), Record
[1].upper(), Record
[2].upper())
652 if TAB_DEFAULT
not in self
._SkuIds
:
653 self
._SkuIds
[TAB_DEFAULT
] = ("0", TAB_DEFAULT
, TAB_DEFAULT
)
654 if TAB_COMMON
not in self
._SkuIds
:
655 self
._SkuIds
[TAB_COMMON
] = ("0", TAB_DEFAULT
, TAB_DEFAULT
)
660 return int(intstr
,16) if intstr
.upper().startswith("0X") else int(intstr
)
662 def _GetDefaultStores(self
):
663 if self
.DefaultStores
is None:
664 self
.DefaultStores
= OrderedDict()
665 RecordList
= self
._RawData
[MODEL_EFI_DEFAULT_STORES
, self
._Arch
]
666 for Record
in RecordList
:
668 EdkLogger
.error('build', FORMAT_INVALID
, 'No DefaultStores ID number',
669 File
=self
.MetaFile
, Line
=Record
[-1])
671 EdkLogger
.error('build', FORMAT_INVALID
, 'No DefaultStores ID name',
672 File
=self
.MetaFile
, Line
=Record
[-1])
673 if not Pattern
.match(Record
[0]) and not HexPattern
.match(Record
[0]):
674 EdkLogger
.error('build', FORMAT_INVALID
, "The format of the DefaultStores ID number is invalid. It only support Integer and HexNumber",
675 File
=self
.MetaFile
, Line
=Record
[-1])
676 if not IsValidWord(Record
[1]):
677 EdkLogger
.error('build', FORMAT_INVALID
, "The format of the DefaultStores ID name is invalid. The correct format is '(a-zA-Z0-9_)(a-zA-Z0-9_-.)*'",
678 File
=self
.MetaFile
, Line
=Record
[-1])
679 self
.DefaultStores
[Record
[1].upper()] = (DscBuildData
.ToInt(Record
[0]),Record
[1].upper())
680 if TAB_DEFAULT_STORES_DEFAULT
not in self
.DefaultStores
:
681 self
.DefaultStores
[TAB_DEFAULT_STORES_DEFAULT
] = (0,TAB_DEFAULT_STORES_DEFAULT
)
682 GlobalData
.gDefaultStores
= sorted(self
.DefaultStores
.keys())
683 return self
.DefaultStores
685 ## Retrieve [Components] section information
686 def _GetModules(self
):
687 if self
._Modules
is not None:
690 self
._Modules
= OrderedDict()
691 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
692 Macros
= self
._Macros
693 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
694 for Record
in RecordList
:
695 DuplicatedFile
= False
697 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
701 # check the file validation
702 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
704 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
707 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
708 if self
._Arch
!= TAB_ARCH_COMMON
and ModuleFile
in self
._Modules
:
709 DuplicatedFile
= True
711 Module
= ModuleBuildClassObject()
712 Module
.MetaFile
= ModuleFile
714 # get module private library instance
715 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
716 for Record
in RecordList
:
717 LibraryClass
= Record
[0]
718 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
721 # check the file validation
722 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
724 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
727 if LibraryClass
== '' or LibraryClass
== 'NULL':
728 self
._NullLibraryNumber
+= 1
729 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
730 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
731 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
732 if LibraryPath
not in self
.LibraryInstances
:
733 self
.LibraryInstances
.append(LibraryPath
)
735 # get module private PCD setting
736 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
737 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
738 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
739 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
740 TokenList
= GetSplitValueList(Setting
)
741 DefaultValue
= TokenList
[0]
742 # the format is PcdName| Value | VOID* | MaxDatumSize
743 if len(TokenList
) > 2:
744 MaxDatumSize
= TokenList
[2]
747 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
748 Pcd
= PcdClassObject(
760 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
762 # get module private build options
763 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
764 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
765 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
766 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
768 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
769 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
771 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, None, ModuleId
]
772 if DuplicatedFile
and not RecordList
:
773 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
775 if len(RecordList
) != 1:
776 EdkLogger
.error('build', OPTION_UNKNOWN
, 'Only FILE_GUID can be listed in <Defines> section.',
777 File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
778 ModuleFile
= ProcessDuplicatedInf(ModuleFile
, RecordList
[0][2], GlobalData
.gWorkspace
)
779 ModuleFile
.Arch
= self
._Arch
781 self
._Modules
[ModuleFile
] = Module
784 ## Retrieve all possible library instances used in this platform
785 def _GetLibraryInstances(self
):
786 if self
._LibraryInstances
is None:
787 self
._GetLibraryClasses
()
788 return self
._LibraryInstances
790 ## Retrieve [LibraryClasses] information
791 def _GetLibraryClasses(self
):
792 if self
._LibraryClasses
is None:
793 self
._LibraryInstances
= []
795 # tdict is a special dict kind of type, used for selecting correct
796 # library instance for given library class and module type
798 LibraryClassDict
= tdict(True, 3)
799 # track all library class names
800 LibraryClassSet
= set()
801 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, -1]
802 Macros
= self
._Macros
803 for Record
in RecordList
:
804 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
,Dummy
, LineNo
= Record
805 if LibraryClass
== '' or LibraryClass
== 'NULL':
806 self
._NullLibraryNumber
+= 1
807 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
808 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
809 LibraryClassSet
.add(LibraryClass
)
810 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
811 # check the file validation
812 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
814 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
817 if ModuleType
!= TAB_COMMON
and ModuleType
not in SUP_MODULE_LIST
:
818 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
819 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
820 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
821 if LibraryInstance
not in self
._LibraryInstances
:
822 self
._LibraryInstances
.append(LibraryInstance
)
824 # resolve the specific library instance for each class and each module type
825 self
._LibraryClasses
= tdict(True)
826 for LibraryClass
in LibraryClassSet
:
827 # try all possible module types
828 for ModuleType
in SUP_MODULE_LIST
:
829 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
830 if LibraryInstance
is None:
832 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
834 # for Edk style library instances, which are listed in different section
835 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
836 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
837 for Record
in RecordList
:
838 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
840 # check the file validation
841 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
843 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
845 if File
not in self
._LibraryInstances
:
846 self
._LibraryInstances
.append(File
)
848 # we need the module name as the library class name, so we have
849 # to parse it here. (self._Bdb[] will trigger a file parse if it
850 # hasn't been parsed)
852 Library
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
853 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
854 return self
._LibraryClasses
856 def _ValidatePcd(self
, PcdCName
, TokenSpaceGuid
, Setting
, PcdType
, LineNo
):
857 if self
._DecPcds
is None:
860 if GlobalData
.gFdfParser
:
861 FdfInfList
= GlobalData
.gFdfParser
.Profile
.InfList
864 for Inf
in FdfInfList
:
865 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
866 if ModuleFile
in self
._Modules
:
868 ModuleData
= self
._Bdb
[ModuleFile
, self
._Arch
, self
._Target
, self
._Toolchain
]
869 PkgSet
.update(ModuleData
.Packages
)
871 self
._DecPcds
, self
._GuidDict
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
,PkgSet
)
872 self
._GuidDict
.update(GlobalData
.gPlatformPcds
)
874 if (PcdCName
, TokenSpaceGuid
) not in self
._DecPcds
:
875 EdkLogger
.error('build', PARSER_ERROR
,
876 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid
, PcdCName
, self
._Arch
),
877 File
=self
.MetaFile
, Line
=LineNo
)
878 ValueList
, IsValid
, Index
= AnalyzeDscPcd(Setting
, PcdType
, self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
)
880 if PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
881 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
882 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
884 if ValueList
[2] == '-1':
885 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
886 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
888 DatumType
= self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
890 ValueList
[Index
] = ValueExpressionEx(ValueList
[Index
], DatumType
, self
._GuidDict
)(True)
891 except BadExpression
as Value
:
892 EdkLogger
.error('Parser', FORMAT_INVALID
, Value
, File
=self
.MetaFile
, Line
=LineNo
,
893 ExtraData
="PCD [%s.%s] Value \"%s\" " % (
894 TokenSpaceGuid
, PcdCName
, ValueList
[Index
]))
895 except EvaluationException
as Excpt
:
896 if hasattr(Excpt
, 'Pcd'):
897 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
898 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
899 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
900 " of the DSC file" % Excpt
.Pcd
,
901 File
=self
.MetaFile
, Line
=LineNo
)
903 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
904 File
=self
.MetaFile
, Line
=LineNo
)
906 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
907 File
=self
.MetaFile
, Line
=LineNo
)
910 Valid
, ErrStr
= CheckPcdDatum(self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
, ValueList
[Index
])
912 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
913 ExtraData
="%s.%s" % (TokenSpaceGuid
, PcdCName
))
914 if PcdType
in (MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
):
915 if self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
.strip() != ValueList
[1].strip():
916 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd datumtype used in DSC file is not the same as its declaration in DEC file." , File
=self
.MetaFile
, Line
=LineNo
,
917 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
918 if (TokenSpaceGuid
+ '.' + PcdCName
) in GlobalData
.gPlatformPcds
:
919 if GlobalData
.gPlatformPcds
[TokenSpaceGuid
+ '.' + PcdCName
] != ValueList
[Index
]:
920 GlobalData
.gPlatformPcds
[TokenSpaceGuid
+ '.' + PcdCName
] = ValueList
[Index
]
923 def _FilterPcdBySkuUsage(self
,Pcds
):
924 available_sku
= self
.SkuIdMgr
.AvailableSkuIdSet
925 sku_usage
= self
.SkuIdMgr
.SkuUsageType
926 if sku_usage
== SkuClass
.SINGLE
:
929 Pcds
[pcdname
].SkuInfoList
= {TAB_DEFAULT
:pcd
.SkuInfoList
[skuid
] for skuid
in pcd
.SkuInfoList
if skuid
in available_sku
}
930 if type(pcd
) is StructurePcd
and pcd
.SkuOverrideValues
:
931 Pcds
[pcdname
].SkuOverrideValues
= {TAB_DEFAULT
:pcd
.SkuOverrideValues
[skuid
] for skuid
in pcd
.SkuOverrideValues
if skuid
in available_sku
}
935 Pcds
[pcdname
].SkuInfoList
= {skuid
:pcd
.SkuInfoList
[skuid
] for skuid
in pcd
.SkuInfoList
if skuid
in available_sku
}
936 if type(pcd
) is StructurePcd
and pcd
.SkuOverrideValues
:
937 Pcds
[pcdname
].SkuOverrideValues
= {skuid
:pcd
.SkuOverrideValues
[skuid
] for skuid
in pcd
.SkuOverrideValues
if skuid
in available_sku
}
939 def CompleteHiiPcdsDefaultStores(self
,Pcds
):
940 HiiPcd
= [Pcds
[pcd
] for pcd
in Pcds
if Pcds
[pcd
].Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]]
941 DefaultStoreMgr
= DefaultStore(self
.DefaultStores
)
943 for skuid
in pcd
.SkuInfoList
:
944 skuobj
= pcd
.SkuInfoList
.get(skuid
)
945 if TAB_DEFAULT_STORES_DEFAULT
not in skuobj
.DefaultStoreDict
:
946 PcdDefaultStoreSet
= set(defaultstorename
for defaultstorename
in skuobj
.DefaultStoreDict
)
947 mindefaultstorename
= DefaultStoreMgr
.GetMin(PcdDefaultStoreSet
)
948 skuobj
.DefaultStoreDict
[TAB_DEFAULT_STORES_DEFAULT
] = copy
.deepcopy(skuobj
.DefaultStoreDict
[mindefaultstorename
])
951 def RecoverCommandLinePcd(self
):
952 def UpdateCommandLineValue(pcd
):
953 if pcd
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_FIXED_AT_BUILD
],
954 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_PATCHABLE_IN_MODULE
]]:
955 pcd
.PcdValueFromComm
= pcd
.DefaultValue
956 elif pcd
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
957 pcd
.PcdValueFromComm
= pcd
.SkuInfoList
.get(TAB_DEFAULT
).HiiDefaultValue
959 pcd
.PcdValueFromComm
= pcd
.SkuInfoList
.get(TAB_DEFAULT
).DefaultValue
960 for pcd
in self
._Pcds
:
961 if isinstance(self
._Pcds
[pcd
],StructurePcd
) and (self
._Pcds
[pcd
].PcdValueFromComm
or self
._Pcds
[pcd
].PcdFieldValueFromComm
):
962 UpdateCommandLineValue(self
._Pcds
[pcd
])
964 def __ParsePcdFromCommandLine(self
):
965 if GlobalData
.BuildOptionPcd
:
966 for i
, pcd
in enumerate(GlobalData
.BuildOptionPcd
):
967 if type(pcd
) is tuple:
969 (pcdname
, pcdvalue
) = pcd
.split('=')
971 EdkLogger
.error('build', AUTOGEN_ERROR
, "No Value specified for the PCD %s." % (pcdname
))
973 (Name1
, Name2
) = pcdname
.split('.',1)
975 (Name3
, FieldName
) = Name2
.split(".",1)
976 if ((Name3
,Name1
)) in self
.DecPcds
:
979 TokenSpaceGuidCName
= Name1
983 TokenSpaceGuidCName
= ''
984 HasTokenSpace
= False
986 if ((Name2
,Name1
)) in self
.DecPcds
:
989 TokenSpaceGuidCName
= Name1
994 TokenSpaceGuidCName
= ''
995 HasTokenSpace
= False
999 TokenSpaceGuidCName
= ''
1000 HasTokenSpace
= False
1001 TokenSpaceGuidCNameList
= []
1004 DisplayName
= TokenCName
1006 DisplayName
= TokenCName
+ '.' + FieldName
1007 if not HasTokenSpace
:
1008 for key
in self
.DecPcds
:
1009 PcdItem
= self
.DecPcds
[key
]
1010 if TokenCName
== PcdItem
.TokenCName
:
1011 if not PcdItem
.TokenSpaceGuidCName
in TokenSpaceGuidCNameList
:
1012 if len (TokenSpaceGuidCNameList
) < 1:
1013 TokenSpaceGuidCNameList
.append(PcdItem
.TokenSpaceGuidCName
)
1014 TokenSpaceGuidCName
= PcdItem
.TokenSpaceGuidCName
1015 PcdDatumType
= PcdItem
.DatumType
1021 "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (DisplayName
, PcdItem
.TokenSpaceGuidCName
, TokenSpaceGuidCNameList
[0])
1024 if (TokenCName
, TokenSpaceGuidCName
) in self
.DecPcds
:
1025 PcdDatumType
= self
.DecPcds
[(TokenCName
, TokenSpaceGuidCName
)].DatumType
1029 EdkLogger
.error('build', AUTOGEN_ERROR
, "The Pcd %s.%s is not found in the DEC file." % (TokenSpaceGuidCName
, DisplayName
))
1031 EdkLogger
.error('build', AUTOGEN_ERROR
, "The Pcd %s is not found in the DEC file." % (DisplayName
))
1032 pcdvalue
= pcdvalue
.replace("\\\\\\'", '\\\\\\"').replace('\\\'', '\'').replace('\\\\\\"', "\\'")
1034 pcdvalue
= DscBuildData
.HandleFlexiblePcd(TokenSpaceGuidCName
, TokenCName
, pcdvalue
, PcdDatumType
, self
._GuidDict
, FieldName
)
1036 pcdvalue
= DscBuildData
.HandleFlexiblePcd(TokenSpaceGuidCName
, TokenCName
, pcdvalue
, PcdDatumType
, self
._GuidDict
)
1037 IsValid
, Cause
= CheckPcdDatum(PcdDatumType
, pcdvalue
)
1039 EdkLogger
.error("build", FORMAT_INVALID
, Cause
, ExtraData
="%s.%s" % (TokenSpaceGuidCName
, TokenCName
))
1040 GlobalData
.BuildOptionPcd
[i
] = (TokenSpaceGuidCName
, TokenCName
, FieldName
, pcdvalue
,("build command options",1))
1042 for BuildData
in self
._Bdb
._CACHE
_.values():
1043 if BuildData
.MetaFile
.Ext
== '.dec' or BuildData
.MetaFile
.Ext
== '.dsc':
1045 for key
in BuildData
.Pcds
:
1046 PcdItem
= BuildData
.Pcds
[key
]
1047 if (TokenSpaceGuidCName
, TokenCName
) == (PcdItem
.TokenSpaceGuidCName
, PcdItem
.TokenCName
) and FieldName
=="":
1048 PcdItem
.DefaultValue
= pcdvalue
1051 def HandleFlexiblePcd(TokenSpaceGuidCName
, TokenCName
, PcdValue
, PcdDatumType
, GuidDict
, FieldName
=''):
1054 TokenCName
+= '.' + FieldName
1055 if PcdValue
.startswith('H'):
1056 if FieldName
and IsFieldValueAnArray(PcdValue
[1:]):
1057 PcdDatumType
= TAB_VOID
1059 if FieldName
and not IsArray
:
1062 PcdValue
= ValueExpressionEx(PcdValue
[1:], PcdDatumType
, GuidDict
)(True)
1063 except BadExpression
as Value
:
1064 EdkLogger
.error('Parser', FORMAT_INVALID
, 'PCD [%s.%s] Value "%s", %s' %
1065 (TokenSpaceGuidCName
, TokenCName
, PcdValue
, Value
))
1066 elif PcdValue
.startswith("L'") or PcdValue
.startswith("'"):
1067 if FieldName
and IsFieldValueAnArray(PcdValue
):
1068 PcdDatumType
= TAB_VOID
1070 if FieldName
and not IsArray
:
1073 PcdValue
= ValueExpressionEx(PcdValue
, PcdDatumType
, GuidDict
)(True)
1074 except BadExpression
as Value
:
1075 EdkLogger
.error('Parser', FORMAT_INVALID
, 'PCD [%s.%s] Value "%s", %s' %
1076 (TokenSpaceGuidCName
, TokenCName
, PcdValue
, Value
))
1077 elif PcdValue
.startswith('L'):
1078 PcdValue
= 'L"' + PcdValue
[1:] + '"'
1079 if FieldName
and IsFieldValueAnArray(PcdValue
):
1080 PcdDatumType
= TAB_VOID
1082 if FieldName
and not IsArray
:
1085 PcdValue
= ValueExpressionEx(PcdValue
, PcdDatumType
, GuidDict
)(True)
1086 except BadExpression
as Value
:
1087 EdkLogger
.error('Parser', FORMAT_INVALID
, 'PCD [%s.%s] Value "%s", %s' %
1088 (TokenSpaceGuidCName
, TokenCName
, PcdValue
, Value
))
1090 if PcdValue
.upper() == 'FALSE':
1092 if PcdValue
.upper() == 'TRUE':
1095 if PcdDatumType
not in TAB_PCD_NUMERIC_TYPES
:
1096 PcdValue
= '"' + PcdValue
+ '"'
1100 if PcdValue
.upper().startswith('0X'):
1103 Num
= int(PcdValue
, Base
)
1105 PcdValue
= '"' + PcdValue
+ '"'
1106 if IsFieldValueAnArray(PcdValue
):
1107 PcdDatumType
= TAB_VOID
1112 PcdValue
= ValueExpressionEx(PcdValue
, PcdDatumType
, GuidDict
)(True)
1113 except BadExpression
as Value
:
1114 EdkLogger
.error('Parser', FORMAT_INVALID
, 'PCD [%s.%s] Value "%s", %s' %
1115 (TokenSpaceGuidCName
, TokenCName
, PcdValue
, Value
))
1118 ## Retrieve all PCD settings in platform
1120 if self
._Pcds
is None:
1121 self
._Pcds
= OrderedDict()
1122 self
.__ParsePcdFromCommandLine
()
1123 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1124 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1125 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1126 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
1127 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
1128 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
1129 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
1130 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
1131 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
1133 self
._Pcds
= self
.CompletePcdValues(self
._Pcds
)
1134 self
._Pcds
= self
.OverrideByFdfCommOverAll(self
._Pcds
)
1135 self
._Pcds
= self
.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST
, self
._Pcds
)
1136 self
._Pcds
= self
.CompleteHiiPcdsDefaultStores(self
._Pcds
)
1137 self
._Pcds
= self
._FilterPcdBySkuUsage
(self
._Pcds
)
1139 self
.RecoverCommandLinePcd()
1142 ## Retrieve [BuildOptions]
1143 def _GetBuildOptions(self
):
1144 if self
._BuildOptions
is None:
1145 self
._BuildOptions
= OrderedDict()
1147 # Retrieve build option for EDKII and EDK style module
1149 for CodeBase
in (EDKII_NAME
, EDK_NAME
):
1150 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, CodeBase
]
1151 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
1152 if Dummy3
.upper() != TAB_COMMON
:
1154 CurKey
= (ToolChainFamily
, ToolChain
, CodeBase
)
1156 # Only flags can be appended
1158 if CurKey
not in self
._BuildOptions
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
1159 self
._BuildOptions
[CurKey
] = Option
1161 if ' ' + Option
not in self
._BuildOptions
[CurKey
]:
1162 self
._BuildOptions
[CurKey
] += ' ' + Option
1163 return self
._BuildOptions
1165 def GetBuildOptionsByModuleType(self
, Edk
, ModuleType
):
1166 if self
._ModuleTypeOptions
is None:
1167 self
._ModuleTypeOptions
= OrderedDict()
1168 if (Edk
, ModuleType
) not in self
._ModuleTypeOptions
:
1169 options
= OrderedDict()
1170 self
._ModuleTypeOptions
[Edk
, ModuleType
] = options
1171 DriverType
= '%s.%s' % (Edk
, ModuleType
)
1172 CommonDriverType
= '%s.%s' % (TAB_COMMON
, ModuleType
)
1173 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
]
1174 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
1175 Type
= Dummy2
+ '.' + Dummy3
1176 if Type
.upper() == DriverType
.upper() or Type
.upper() == CommonDriverType
.upper():
1177 Key
= (ToolChainFamily
, ToolChain
, Edk
)
1178 if Key
not in options
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
1179 options
[Key
] = Option
1181 if ' ' + Option
not in options
[Key
]:
1182 options
[Key
] += ' ' + Option
1183 return self
._ModuleTypeOptions
[Edk
, ModuleType
]
1186 def GetStructurePcdInfo(PcdSet
):
1187 structure_pcd_data
= defaultdict(list)
1189 structure_pcd_data
[(item
[0],item
[1])].append(item
)
1191 return structure_pcd_data
1194 def OverrideByFdfComm(StruPcds
):
1195 StructurePcdInCom
= OrderedDict()
1196 for item
in GlobalData
.BuildOptionPcd
:
1197 if len(item
) == 5 and (item
[1],item
[0]) in StruPcds
:
1198 StructurePcdInCom
[(item
[0],item
[1],item
[2] )] = (item
[3],item
[4])
1199 GlobalPcds
= {(item
[0],item
[1]) for item
in StructurePcdInCom
}
1200 for Pcd
in StruPcds
.values():
1201 if (Pcd
.TokenSpaceGuidCName
,Pcd
.TokenCName
) not in GlobalPcds
:
1203 FieldValues
= OrderedDict()
1204 for item
in StructurePcdInCom
:
1205 if (Pcd
.TokenSpaceGuidCName
,Pcd
.TokenCName
) == (item
[0],item
[1]) and item
[2]:
1206 FieldValues
[item
[2]] = StructurePcdInCom
[item
]
1207 for field
in FieldValues
:
1208 if field
not in Pcd
.PcdFieldValueFromComm
:
1209 Pcd
.PcdFieldValueFromComm
[field
] = ["","",""]
1210 Pcd
.PcdFieldValueFromComm
[field
][0] = FieldValues
[field
][0]
1211 Pcd
.PcdFieldValueFromComm
[field
][1] = FieldValues
[field
][1][0]
1212 Pcd
.PcdFieldValueFromComm
[field
][2] = FieldValues
[field
][1][1]
1215 def OverrideByFdfCommOverAll(self
,AllPcds
):
1216 def CheckStructureInComm(commpcds
):
1219 if len(commpcds
[0]) == 5:
1223 if CheckStructureInComm(GlobalData
.BuildOptionPcd
):
1224 StructurePcdInCom
= {(item
[0],item
[1],item
[2] ):(item
[3],item
[4]) for item
in GlobalData
.BuildOptionPcd
} if GlobalData
.BuildOptionPcd
else {}
1225 NoFiledValues
= {(item
[0],item
[1]):StructurePcdInCom
[item
] for item
in StructurePcdInCom
if not item
[2]}
1227 NoFiledValues
= {(item
[0],item
[1]):[item
[2]] for item
in GlobalData
.BuildOptionPcd
}
1228 for Guid
,Name
in NoFiledValues
:
1229 if (Name
,Guid
) in AllPcds
:
1230 Pcd
= AllPcds
.get((Name
,Guid
))
1231 if isinstance(self
._DecPcds
.get((Pcd
.TokenCName
,Pcd
.TokenSpaceGuidCName
), None),StructurePcd
):
1232 self
._DecPcds
.get((Pcd
.TokenCName
,Pcd
.TokenSpaceGuidCName
)).PcdValueFromComm
= NoFiledValues
[(Pcd
.TokenSpaceGuidCName
,Pcd
.TokenCName
)][0]
1234 Pcd
.PcdValueFromComm
= NoFiledValues
[(Pcd
.TokenSpaceGuidCName
,Pcd
.TokenCName
)][0]
1235 Pcd
.DefaultValue
= NoFiledValues
[(Pcd
.TokenSpaceGuidCName
,Pcd
.TokenCName
)][0]
1236 for sku
in Pcd
.SkuInfoList
:
1237 SkuInfo
= Pcd
.SkuInfoList
[sku
]
1238 if SkuInfo
.DefaultValue
:
1239 SkuInfo
.DefaultValue
= NoFiledValues
[(Pcd
.TokenSpaceGuidCName
,Pcd
.TokenCName
)][0]
1241 SkuInfo
.HiiDefaultValue
= NoFiledValues
[(Pcd
.TokenSpaceGuidCName
,Pcd
.TokenCName
)][0]
1242 for defaultstore
in SkuInfo
.DefaultStoreDict
:
1243 SkuInfo
.DefaultStoreDict
[defaultstore
] = NoFiledValues
[(Pcd
.TokenSpaceGuidCName
,Pcd
.TokenCName
)][0]
1244 if Pcd
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
]]:
1245 if Pcd
.DatumType
== TAB_VOID
:
1246 if not Pcd
.MaxDatumSize
:
1247 Pcd
.MaxDatumSize
= '0'
1248 CurrentSize
= int(Pcd
.MaxDatumSize
,16) if Pcd
.MaxDatumSize
.upper().startswith("0X") else int(Pcd
.MaxDatumSize
)
1249 OptionSize
= len((StringToArray(Pcd
.PcdValueFromComm
)).split(","))
1250 MaxSize
= max(CurrentSize
, OptionSize
)
1251 Pcd
.MaxDatumSize
= str(MaxSize
)
1253 PcdInDec
= self
.DecPcds
.get((Name
,Guid
))
1255 PcdInDec
.PcdValueFromComm
= NoFiledValues
[(Guid
,Name
)][0]
1256 if PcdInDec
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_FIXED_AT_BUILD
],
1257 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_PATCHABLE_IN_MODULE
],
1258 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_FEATURE_FLAG
]]:
1259 self
.Pcds
[Name
, Guid
] = copy
.deepcopy(PcdInDec
)
1260 self
.Pcds
[Name
, Guid
].DefaultValue
= NoFiledValues
[( Guid
,Name
)][0]
1262 def UpdateStructuredPcds(self
, TypeList
, AllPcds
):
1264 DynamicPcdType
= [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_DEFAULT
],
1265 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
1266 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_VPD
],
1267 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_DEFAULT
],
1268 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
],
1269 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_VPD
]]
1272 DefaultStoreMgr
= DefaultStore(self
.DefaultStores
)
1273 SkuIds
= self
.SkuIdMgr
.AvailableSkuIdSet
1274 SkuIds
.update({TAB_DEFAULT
:0})
1275 DefaultStores
= {storename
for pcdobj
in AllPcds
.values() for skuobj
in pcdobj
.SkuInfoList
.values() for storename
in skuobj
.DefaultStoreDict
}
1278 # Find out all possible PCD candidates for self._Arch
1281 for Type
in TypeList
:
1282 RecordList
.extend(self
._RawData
[Type
, self
._Arch
])
1284 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, default_store
, Dummy4
,Dummy5
in RecordList
:
1285 SkuName
= SkuName
.upper()
1286 default_store
= default_store
.upper()
1287 SkuName
= TAB_DEFAULT
if SkuName
== TAB_COMMON
else SkuName
1288 if SkuName
not in SkuIds
:
1291 if SkuName
in SkuIds
and "." in TokenSpaceGuid
:
1292 S_PcdSet
.append([ TokenSpaceGuid
.split(".")[0],TokenSpaceGuid
.split(".")[1], PcdCName
,SkuName
, default_store
,Dummy5
, AnalyzePcdExpression(Setting
)[0]])
1294 # handle pcd value override
1295 StrPcdSet
= DscBuildData
.GetStructurePcdInfo(S_PcdSet
)
1296 S_pcd_set
= OrderedDict()
1297 for str_pcd
in StrPcdSet
:
1298 str_pcd_obj
= Pcds
.get((str_pcd
[1], str_pcd
[0]), None)
1299 str_pcd_dec
= self
._DecPcds
.get((str_pcd
[1], str_pcd
[0]), None)
1300 if not isinstance (str_pcd_dec
, StructurePcd
):
1301 EdkLogger
.error('build', PARSER_ERROR
,
1302 "Pcd (%s.%s) is not declared as Structure PCD in DEC files. Arch: ['%s']" % (str_pcd
[0], str_pcd
[1], self
._Arch
),
1303 File
=self
.MetaFile
,Line
= StrPcdSet
[str_pcd
][0][5])
1305 str_pcd_obj_str
= StructurePcd()
1306 str_pcd_obj_str
.copy(str_pcd_dec
)
1308 str_pcd_obj_str
.copy(str_pcd_obj
)
1309 if str_pcd_obj
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1310 str_pcd_obj_str
.DefaultFromDSC
= {skuname
:{defaultstore
: str_pcd_obj
.SkuInfoList
[skuname
].DefaultStoreDict
.get(defaultstore
, str_pcd_obj
.SkuInfoList
[skuname
].HiiDefaultValue
) for defaultstore
in DefaultStores
} for skuname
in str_pcd_obj
.SkuInfoList
}
1312 str_pcd_obj_str
.DefaultFromDSC
= {skuname
:{defaultstore
: str_pcd_obj
.SkuInfoList
[skuname
].DefaultStoreDict
.get(defaultstore
, str_pcd_obj
.SkuInfoList
[skuname
].DefaultValue
) for defaultstore
in DefaultStores
} for skuname
in str_pcd_obj
.SkuInfoList
}
1313 for str_pcd_data
in StrPcdSet
[str_pcd
]:
1314 if str_pcd_data
[3] in SkuIds
:
1315 str_pcd_obj_str
.AddOverrideValue(str_pcd_data
[2], str(str_pcd_data
[6]), TAB_DEFAULT
if str_pcd_data
[3] == TAB_COMMON
else str_pcd_data
[3],TAB_DEFAULT_STORES_DEFAULT
if str_pcd_data
[4] == TAB_COMMON
else str_pcd_data
[4], self
.MetaFile
.File
if self
.WorkspaceDir
not in self
.MetaFile
.File
else self
.MetaFile
.File
[len(self
.WorkspaceDir
) if self
.WorkspaceDir
.endswith(os
.path
.sep
) else len(self
.WorkspaceDir
)+1:],LineNo
=str_pcd_data
[5])
1316 S_pcd_set
[str_pcd
[1], str_pcd
[0]] = str_pcd_obj_str
1318 EdkLogger
.error('build', PARSER_ERROR
,
1319 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd
[0], str_pcd
[1], self
._Arch
),
1320 File
=self
.MetaFile
,Line
= StrPcdSet
[str_pcd
][0][5])
1321 # Add the Structure PCD that only defined in DEC, don't have override in DSC file
1322 for Pcd
in self
.DecPcds
:
1323 if type (self
._DecPcds
[Pcd
]) is StructurePcd
:
1324 if Pcd
not in S_pcd_set
:
1325 str_pcd_obj_str
= StructurePcd()
1326 str_pcd_obj_str
.copy(self
._DecPcds
[Pcd
])
1327 str_pcd_obj
= Pcds
.get(Pcd
, None)
1329 str_pcd_obj_str
.copy(str_pcd_obj
)
1330 if str_pcd_obj
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1331 str_pcd_obj_str
.DefaultFromDSC
= {skuname
:{defaultstore
: str_pcd_obj
.SkuInfoList
[skuname
].DefaultStoreDict
.get(defaultstore
, str_pcd_obj
.SkuInfoList
[skuname
].HiiDefaultValue
) for defaultstore
in DefaultStores
} for skuname
in str_pcd_obj
.SkuInfoList
}
1333 str_pcd_obj_str
.DefaultFromDSC
= {skuname
:{defaultstore
: str_pcd_obj
.SkuInfoList
[skuname
].DefaultStoreDict
.get(defaultstore
, str_pcd_obj
.SkuInfoList
[skuname
].DefaultValue
) for defaultstore
in DefaultStores
} for skuname
in str_pcd_obj
.SkuInfoList
}
1334 S_pcd_set
[Pcd
] = str_pcd_obj_str
1336 GlobalData
.gStructurePcd
[self
.Arch
] = S_pcd_set
1337 for stru_pcd
in S_pcd_set
.values():
1338 for skuid
in SkuIds
:
1339 if skuid
in stru_pcd
.SkuOverrideValues
:
1341 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(skuid
)
1343 if skuid
not in stru_pcd
.SkuOverrideValues
:
1344 while nextskuid
not in stru_pcd
.SkuOverrideValues
:
1345 if nextskuid
== TAB_DEFAULT
:
1348 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1349 stru_pcd
.SkuOverrideValues
[skuid
] = copy
.deepcopy(stru_pcd
.SkuOverrideValues
[nextskuid
]) if not NoDefault
else copy
.deepcopy({defaultstorename
: stru_pcd
.DefaultValues
for defaultstorename
in DefaultStores
} if DefaultStores
else {TAB_DEFAULT_STORES_DEFAULT
:stru_pcd
.DefaultValues
})
1351 stru_pcd
.ValueChain
.add((skuid
,''))
1352 if stru_pcd
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1353 for skuid
in SkuIds
:
1356 if skuid
not in stru_pcd
.SkuOverrideValues
:
1357 while nextskuid
not in stru_pcd
.SkuOverrideValues
:
1358 if nextskuid
== TAB_DEFAULT
:
1361 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1364 PcdDefaultStoreSet
= set(defaultstorename
for defaultstorename
in stru_pcd
.SkuOverrideValues
[nextskuid
])
1365 mindefaultstorename
= DefaultStoreMgr
.GetMin(PcdDefaultStoreSet
)
1367 for defaultstoreid
in DefaultStores
:
1368 if defaultstoreid
not in stru_pcd
.SkuOverrideValues
[skuid
]:
1369 stru_pcd
.SkuOverrideValues
[skuid
][defaultstoreid
] = copy
.deepcopy(stru_pcd
.SkuOverrideValues
[nextskuid
][mindefaultstorename
])
1370 stru_pcd
.ValueChain
.add((skuid
,defaultstoreid
))
1371 S_pcd_set
= DscBuildData
.OverrideByFdfComm(S_pcd_set
)
1372 Str_Pcd_Values
= self
.GenerateByteArrayValue(S_pcd_set
)
1374 for (skuname
,StoreName
,PcdGuid
,PcdName
,PcdValue
) in Str_Pcd_Values
:
1375 str_pcd_obj
= S_pcd_set
.get((PcdName
, PcdGuid
))
1376 if str_pcd_obj
is None:
1377 print(PcdName
, PcdGuid
)
1379 if str_pcd_obj
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
1380 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1381 if skuname
not in str_pcd_obj
.SkuInfoList
:
1382 str_pcd_obj
.SkuInfoList
[skuname
] = SkuInfoClass(SkuIdName
=skuname
, SkuId
=self
.SkuIds
[skuname
][0], HiiDefaultValue
=PcdValue
, DefaultStore
= {StoreName
:PcdValue
})
1384 str_pcd_obj
.SkuInfoList
[skuname
].HiiDefaultValue
= PcdValue
1385 str_pcd_obj
.SkuInfoList
[skuname
].DefaultStoreDict
.update({StoreName
:PcdValue
})
1386 elif str_pcd_obj
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_FIXED_AT_BUILD
],
1387 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_PATCHABLE_IN_MODULE
]]:
1388 if skuname
in (self
.SkuIdMgr
.SystemSkuId
, TAB_DEFAULT
, TAB_COMMON
):
1389 str_pcd_obj
.DefaultValue
= PcdValue
1391 if skuname
not in str_pcd_obj
.SkuInfoList
:
1392 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(skuname
)
1394 while nextskuid
not in str_pcd_obj
.SkuInfoList
:
1395 if nextskuid
== TAB_DEFAULT
:
1398 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1399 str_pcd_obj
.SkuInfoList
[skuname
] = copy
.deepcopy(str_pcd_obj
.SkuInfoList
[nextskuid
]) if not NoDefault
else SkuInfoClass(SkuIdName
=skuname
, SkuId
=self
.SkuIds
[skuname
][0], DefaultValue
=PcdValue
)
1400 str_pcd_obj
.SkuInfoList
[skuname
].SkuId
= self
.SkuIds
[skuname
][0]
1401 str_pcd_obj
.SkuInfoList
[skuname
].SkuIdName
= skuname
1403 str_pcd_obj
.SkuInfoList
[skuname
].DefaultValue
= PcdValue
1404 for str_pcd_obj
in S_pcd_set
.values():
1405 if str_pcd_obj
.Type
not in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
1406 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1408 PcdDefaultStoreSet
= set(defaultstorename
for skuobj
in str_pcd_obj
.SkuInfoList
.values() for defaultstorename
in skuobj
.DefaultStoreDict
)
1409 DefaultStoreObj
= DefaultStore(self
._GetDefaultStores
())
1410 mindefaultstorename
= DefaultStoreObj
.GetMin(PcdDefaultStoreSet
)
1411 str_pcd_obj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
].HiiDefaultValue
= str_pcd_obj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
].DefaultStoreDict
[mindefaultstorename
]
1413 for str_pcd_obj
in S_pcd_set
.values():
1415 str_pcd_obj
.MaxDatumSize
= self
.GetStructurePcdMaxSize(str_pcd_obj
)
1416 Pcds
[str_pcd_obj
.TokenCName
, str_pcd_obj
.TokenSpaceGuidCName
] = str_pcd_obj
1420 if TAB_DEFAULT
not in pcd
.SkuInfoList
and TAB_COMMON
in pcd
.SkuInfoList
:
1421 pcd
.SkuInfoList
[TAB_DEFAULT
] = pcd
.SkuInfoList
[TAB_COMMON
]
1422 del pcd
.SkuInfoList
[TAB_COMMON
]
1423 elif TAB_DEFAULT
in pcd
.SkuInfoList
and TAB_COMMON
in pcd
.SkuInfoList
:
1424 del pcd
.SkuInfoList
[TAB_COMMON
]
1426 map(self
.FilterSkuSettings
,[Pcds
[pcdkey
] for pcdkey
in Pcds
if Pcds
[pcdkey
].Type
in DynamicPcdType
])
1429 ## Retrieve non-dynamic PCD settings
1431 # @param Type PCD type
1433 # @retval a dict object contains settings of given PCD type
1435 def _GetPcd(self
, Type
):
1436 Pcds
= OrderedDict()
1438 # tdict is a special dict kind of type, used for selecting correct
1439 # PCD settings for certain ARCH
1441 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1443 PcdDict
= tdict(True, 3)
1445 # Find out all possible PCD candidates for self._Arch
1446 RecordList
= self
._RawData
[Type
, self
._Arch
]
1447 PcdValueDict
= OrderedDict()
1448 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
1449 SkuName
= SkuName
.upper()
1450 SkuName
= TAB_DEFAULT
if SkuName
== TAB_COMMON
else SkuName
1451 if SkuName
not in AvailableSkuIdSet
:
1452 EdkLogger
.error('build ', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1453 File
=self
.MetaFile
, Line
=Dummy5
)
1454 if SkuName
in (self
.SkuIdMgr
.SystemSkuId
, TAB_DEFAULT
, TAB_COMMON
):
1455 if "." not in TokenSpaceGuid
:
1456 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy5
))
1457 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
, SkuName
] = Setting
1459 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdSet
:
1460 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
, SkuName
]
1463 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1464 if (PcdCName
, TokenSpaceGuid
) in PcdValueDict
:
1465 PcdValueDict
[PcdCName
, TokenSpaceGuid
][SkuName
] = (PcdValue
, DatumType
, MaxDatumSize
)
1467 PcdValueDict
[PcdCName
, TokenSpaceGuid
] = {SkuName
:(PcdValue
, DatumType
, MaxDatumSize
)}
1469 for ((PcdCName
,TokenSpaceGuid
),PcdSetting
) in PcdValueDict
.iteritems():
1473 if TAB_COMMON
in PcdSetting
:
1474 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
[TAB_COMMON
]
1475 if TAB_DEFAULT
in PcdSetting
:
1476 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
[TAB_DEFAULT
]
1477 if self
.SkuIdMgr
.SystemSkuId
in PcdSetting
:
1478 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
[self
.SkuIdMgr
.SystemSkuId
]
1480 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1483 self
._PCD
_TYPE
_STRING
_[Type
],
1496 def GetStructurePcdMaxSize(self
, str_pcd
):
1497 pcd_default_value
= str_pcd
.DefaultValue
1498 sku_values
= [skuobj
.HiiDefaultValue
if str_pcd
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]] else skuobj
.DefaultValue
for skuobj
in str_pcd
.SkuInfoList
.values()]
1499 sku_values
.append(pcd_default_value
)
1501 def get_length(value
):
1502 Value
= value
.strip()
1504 if Value
.startswith(TAB_GUID
) and Value
.endswith(')'):
1506 if Value
.startswith('L"') and Value
.endswith('"'):
1507 return len(Value
[2:-1])
1508 if Value
[0] == '"' and Value
[-1] == '"':
1509 return len(Value
) - 2
1510 if Value
[0] == '{' and Value
[-1] == '}':
1511 return len(Value
.split(","))
1512 if Value
.startswith("L'") and Value
.endswith("'") and len(list(Value
[2:-1])) > 1:
1513 return len(list(Value
[2:-1]))
1514 if Value
[0] == "'" and Value
[-1] == "'" and len(list(Value
[1:-1])) > 1:
1515 return len(Value
) - 2
1518 return str(max(get_length(item
) for item
in sku_values
))
1521 def ExecuteCommand (Command
):
1523 Process
= subprocess
.Popen(Command
, stdout
=subprocess
.PIPE
, stderr
=subprocess
.PIPE
, shell
=True)
1525 EdkLogger
.error('Build', COMMAND_FAILURE
, 'Can not execute command: %s' % Command
)
1526 Result
= Process
.communicate()
1527 return Process
.returncode
, Result
[0], Result
[1]
1530 def IntToCString(Value
, ValueSize
):
1532 if not isinstance (Value
, str):
1533 for Index
in range(0, ValueSize
):
1534 Result
= Result
+ '\\x%02x' % (Value
& 0xff)
1536 Result
= Result
+ '"'
1539 def GenerateSizeFunction(self
,Pcd
):
1540 CApp
= "// Default Value in Dec \n"
1541 CApp
= CApp
+ "void Cal_%s_%s_Size(UINT32 *Size){\n" % (Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1542 for FieldList
in [Pcd
.DefaultValues
]:
1545 for FieldName
in FieldList
:
1546 FieldName
= "." + FieldName
1547 IsArray
= IsFieldValueAnArray(FieldList
[FieldName
.strip(".")][0])
1548 if IsArray
and not (FieldList
[FieldName
.strip(".")][0].startswith('{GUID') and FieldList
[FieldName
.strip(".")][0].endswith('}')):
1550 Value
= ValueExpressionEx(FieldList
[FieldName
.strip(".")][0], TAB_VOID
, self
._GuidDict
)(True)
1551 except BadExpression
:
1552 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid value format for %s. From %s Line %d " %
1553 (".".join((Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, FieldName
.strip('.'))), FieldList
[FieldName
.strip(".")][1], FieldList
[FieldName
.strip(".")][2]))
1554 Value
, ValueSize
= ParseFieldValue(Value
)
1555 CApp
= CApp
+ ' __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s \n' % (Pcd
.DatumType
, FieldName
.strip("."), ValueSize
, Pcd
.DatumType
, FieldName
.strip("."), ValueSize
, Pcd
.DatumType
, FieldName
.strip("."), FieldList
[FieldName
.strip(".")][1], FieldList
[FieldName
.strip(".")][2], FieldList
[FieldName
.strip(".")][0]);
1558 FieldName_ori
= FieldName
.strip('.')
1559 while '[' in FieldName
:
1560 NewFieldName
= NewFieldName
+ FieldName
.split('[', 1)[0] + '[0]'
1561 ArrayIndex
= int(FieldName
.split('[', 1)[1].split(']', 1)[0])
1562 FieldName
= FieldName
.split(']', 1)[1]
1563 FieldName
= NewFieldName
+ FieldName
1564 while '[' in FieldName
:
1565 FieldName
= FieldName
.rsplit('[', 1)[0]
1566 CApp
= CApp
+ ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s\n' % (Pcd
.DatumType
, FieldName
.strip("."), ArrayIndex
+ 1, FieldList
[FieldName_ori
][1], FieldList
[FieldName_ori
][2], FieldList
[FieldName_ori
][0])
1567 for skuname
in Pcd
.SkuOverrideValues
:
1568 if skuname
== TAB_COMMON
:
1570 for defaultstorenameitem
in Pcd
.SkuOverrideValues
[skuname
]:
1571 CApp
= CApp
+ "// SkuName: %s, DefaultStoreName: %s \n" % (skuname
, defaultstorenameitem
)
1572 for FieldList
in [Pcd
.SkuOverrideValues
[skuname
].get(defaultstorenameitem
)]:
1575 for FieldName
in FieldList
:
1576 FieldName
= "." + FieldName
1577 IsArray
= IsFieldValueAnArray(FieldList
[FieldName
.strip(".")][0])
1578 if IsArray
and not (FieldList
[FieldName
.strip(".")][0].startswith('{GUID') and FieldList
[FieldName
.strip(".")][0].endswith('}')):
1580 Value
= ValueExpressionEx(FieldList
[FieldName
.strip(".")][0], TAB_VOID
, self
._GuidDict
)(True)
1581 except BadExpression
:
1582 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid value format for %s. From %s Line %d " %
1583 (".".join((Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, FieldName
.strip('.'))), FieldList
[FieldName
.strip(".")][1], FieldList
[FieldName
.strip(".")][2]))
1584 Value
, ValueSize
= ParseFieldValue(Value
)
1585 CApp
= CApp
+ ' __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd
.DatumType
, FieldName
.strip("."), ValueSize
, Pcd
.DatumType
, FieldName
.strip("."), ValueSize
, Pcd
.DatumType
, FieldName
.strip("."), FieldList
[FieldName
.strip(".")][1], FieldList
[FieldName
.strip(".")][2], FieldList
[FieldName
.strip(".")][0]);
1588 FieldName_ori
= FieldName
.strip('.')
1589 while '[' in FieldName
:
1590 NewFieldName
= NewFieldName
+ FieldName
.split('[', 1)[0] + '[0]'
1591 ArrayIndex
= int(FieldName
.split('[', 1)[1].split(']', 1)[0])
1592 FieldName
= FieldName
.split(']', 1)[1]
1593 FieldName
= NewFieldName
+ FieldName
1594 while '[' in FieldName
:
1595 FieldName
= FieldName
.rsplit('[', 1)[0]
1596 CApp
= CApp
+ ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd
.DatumType
, FieldName
.strip("."), ArrayIndex
+ 1, FieldList
[FieldName_ori
][1], FieldList
[FieldName_ori
][2], FieldList
[FieldName_ori
][0])
1597 if Pcd
.PcdFieldValueFromComm
:
1598 CApp
= CApp
+ "// From Command Line \n"
1599 for FieldName
in Pcd
.PcdFieldValueFromComm
:
1600 FieldName
= "." + FieldName
1601 IsArray
= IsFieldValueAnArray(Pcd
.PcdFieldValueFromComm
[FieldName
.strip(".")][0])
1602 if IsArray
and not (Pcd
.PcdFieldValueFromComm
[FieldName
.strip(".")][0].startswith('{GUID') and Pcd
.PcdFieldValueFromComm
[FieldName
.strip(".")][0].endswith('}')):
1604 Value
= ValueExpressionEx(Pcd
.PcdFieldValueFromComm
[FieldName
.strip(".")][0], TAB_VOID
, self
._GuidDict
)(True)
1605 except BadExpression
:
1606 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid value format for %s. From %s Line %d " %
1607 (".".join((Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, FieldName
.strip('.'))), Pcd
.PcdFieldValueFromComm
[FieldName
.strip(".")][1], Pcd
.PcdFieldValueFromComm
[FieldName
.strip(".")][2]))
1608 Value
, ValueSize
= ParseFieldValue(Value
)
1609 CApp
= CApp
+ ' __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd
.DatumType
, FieldName
.strip("."), ValueSize
, Pcd
.DatumType
, FieldName
.strip("."), ValueSize
, Pcd
.DatumType
, FieldName
.strip("."), Pcd
.PcdFieldValueFromComm
[FieldName
.strip(".")][1], Pcd
.PcdFieldValueFromComm
[FieldName
.strip(".")][2], Pcd
.PcdFieldValueFromComm
[FieldName
.strip(".")][0]);
1612 FieldName_ori
= FieldName
.strip('.')
1613 while '[' in FieldName
:
1614 NewFieldName
= NewFieldName
+ FieldName
.split('[', 1)[0] + '[0]'
1615 ArrayIndex
= int(FieldName
.split('[', 1)[1].split(']', 1)[0])
1616 FieldName
= FieldName
.split(']', 1)[1]
1617 FieldName
= NewFieldName
+ FieldName
1618 while '[' in FieldName
:
1619 FieldName
= FieldName
.rsplit('[', 1)[0]
1620 CApp
= CApp
+ ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd
.DatumType
, FieldName
.strip("."), ArrayIndex
+ 1, Pcd
.PcdFieldValueFromComm
[FieldName_ori
][1], Pcd
.PcdFieldValueFromComm
[FieldName_ori
][2], Pcd
.PcdFieldValueFromComm
[FieldName_ori
][0])
1621 CApp
= CApp
+ " *Size = (%d > *Size ? %d : *Size); // The Pcd maxsize is %d \n" % (Pcd
.GetPcdMaxSize(),Pcd
.GetPcdMaxSize(),Pcd
.GetPcdMaxSize())
1626 def GenerateSizeStatments(Pcd
):
1627 CApp
= ' Size = sizeof(%s);\n' % (Pcd
.DatumType
)
1628 CApp
= CApp
+ ' Cal_%s_%s_Size(&Size);\n' % (Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1631 def GenerateDefaultValueAssignFunction(self
,Pcd
):
1632 CApp
= "// Default value in Dec \n"
1633 CApp
= CApp
+ "void Assign_%s_%s_Default_Value(%s *Pcd){\n" % (Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
,Pcd
.DatumType
)
1634 CApp
= CApp
+ ' UINT32 FieldSize;\n'
1635 CApp
= CApp
+ ' CHAR8 *Value;\n'
1636 DefaultValueFromDec
= Pcd
.DefaultValueFromDec
1637 IsArray
= IsFieldValueAnArray(Pcd
.DefaultValueFromDec
)
1640 DefaultValueFromDec
= ValueExpressionEx(Pcd
.DefaultValueFromDec
, TAB_VOID
)(True)
1641 except BadExpression
:
1642 EdkLogger
.error("Build", FORMAT_INVALID
, "Invalid value format for %s.%s, from DEC: %s" %
1643 (Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, DefaultValueFromDec
))
1644 DefaultValueFromDec
= StringToArray(DefaultValueFromDec
)
1645 Value
, ValueSize
= ParseFieldValue (DefaultValueFromDec
)
1646 if isinstance(Value
, str):
1647 CApp
= CApp
+ ' Pcd = %s; // From DEC Default Value %s\n' % (Value
, Pcd
.DefaultValueFromDec
)
1650 # Use memcpy() to copy value into field
1652 CApp
= CApp
+ ' Value = %s; // From DEC Default Value %s\n' % (DscBuildData
.IntToCString(Value
, ValueSize
), Pcd
.DefaultValueFromDec
)
1653 CApp
= CApp
+ ' memcpy (Pcd, Value, %d);\n' % (ValueSize
)
1654 for FieldList
in [Pcd
.DefaultValues
]:
1657 for FieldName
in FieldList
:
1658 IsArray
= IsFieldValueAnArray(FieldList
[FieldName
][0])
1661 FieldList
[FieldName
][0] = ValueExpressionEx(FieldList
[FieldName
][0], TAB_VOID
, self
._GuidDict
)(True)
1662 except BadExpression
:
1663 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid value format for %s. From %s Line %d " %
1664 (".".join((Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, FieldName
)), FieldList
[FieldName
][1],FieldList
[FieldName
][2]))
1667 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
][0])
1669 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd
.TokenSpaceGuidCName
,Pcd
.TokenCName
,FieldName
)),FieldList
[FieldName
][1], FieldList
[FieldName
][2]))
1670 if isinstance(Value
, str):
1671 CApp
= CApp
+ ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1674 # Use memcpy() to copy value into field
1676 CApp
= CApp
+ ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd
.DatumType
, FieldName
)
1677 CApp
= CApp
+ ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData
.IntToCString(Value
, ValueSize
), FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1678 CApp
= CApp
+ ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName
, ValueSize
, ValueSize
)
1681 CApp
= CApp
+ ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1683 CApp
= CApp
+ ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1688 def GenerateDefaultValueAssignStatement(Pcd
):
1689 CApp
= ' Assign_%s_%s_Default_Value(Pcd);\n' % (Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1692 def GenerateInitValueFunction(self
,Pcd
,SkuName
,DefaultStoreName
):
1693 CApp
= "// Value in Dsc for Sku: %s, DefaultStore %s\n" % (SkuName
,DefaultStoreName
)
1694 CApp
= CApp
+ "void Assign_%s_%s_%s_%s_Value(%s *Pcd){\n" % (Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
,SkuName
,DefaultStoreName
,Pcd
.DatumType
)
1695 CApp
= CApp
+ ' UINT32 FieldSize;\n'
1696 CApp
= CApp
+ ' CHAR8 *Value;\n'
1698 CApp
= CApp
+ "// SkuName: %s, DefaultStoreName: %s \n" % (TAB_DEFAULT
, TAB_DEFAULT_STORES_DEFAULT
)
1699 inherit_OverrideValues
= Pcd
.SkuOverrideValues
[SkuName
]
1700 if (SkuName
,DefaultStoreName
) == (TAB_DEFAULT
,TAB_DEFAULT_STORES_DEFAULT
):
1701 pcddefaultvalue
= Pcd
.DefaultFromDSC
.get(TAB_DEFAULT
,{}).get(TAB_DEFAULT_STORES_DEFAULT
, Pcd
.DefaultValue
) if Pcd
.DefaultFromDSC
else Pcd
.DefaultValue
1703 if not Pcd
.DscRawValue
:
1704 # handle the case that structure pcd is not appear in DSC
1705 self
.CopyDscRawValue(Pcd
)
1706 pcddefaultvalue
= Pcd
.DscRawValue
.get(SkuName
,{}).get(DefaultStoreName
)
1707 for FieldList
in [pcddefaultvalue
,inherit_OverrideValues
.get(DefaultStoreName
)]:
1710 if pcddefaultvalue
and FieldList
== pcddefaultvalue
:
1711 IsArray
= IsFieldValueAnArray(FieldList
)
1714 FieldList
= ValueExpressionEx(FieldList
, TAB_VOID
)(True)
1715 except BadExpression
:
1716 EdkLogger
.error("Build", FORMAT_INVALID
, "Invalid value format for %s.%s, from DSC: %s" %
1717 (Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, FieldList
))
1718 Value
, ValueSize
= ParseFieldValue (FieldList
)
1720 if (SkuName
,DefaultStoreName
) == (TAB_DEFAULT
,TAB_DEFAULT_STORES_DEFAULT
):
1721 if isinstance(Value
, str):
1722 CApp
= CApp
+ ' Pcd = %s; // From DSC Default Value %s\n' % (Value
, Pcd
.DefaultFromDSC
.get(TAB_DEFAULT
,{}).get(TAB_DEFAULT_STORES_DEFAULT
, Pcd
.DefaultValue
) if Pcd
.DefaultFromDSC
else Pcd
.DefaultValue
)
1725 # Use memcpy() to copy value into field
1727 CApp
= CApp
+ ' Value = %s; // From DSC Default Value %s\n' % (DscBuildData
.IntToCString(Value
, ValueSize
), Pcd
.DefaultFromDSC
.get(TAB_DEFAULT
,{}).get(TAB_DEFAULT_STORES_DEFAULT
, Pcd
.DefaultValue
) if Pcd
.DefaultFromDSC
else Pcd
.DefaultValue
)
1728 CApp
= CApp
+ ' memcpy (Pcd, Value, %d);\n' % (ValueSize
)
1730 if isinstance(Value
, str):
1731 CApp
= CApp
+ ' Pcd = %s; // From DSC Default Value %s\n' % (Value
, Pcd
.DscRawValue
.get(SkuName
,{}).get(DefaultStoreName
))
1734 # Use memcpy() to copy value into field
1736 CApp
= CApp
+ ' Value = %s; // From DSC Default Value %s\n' % (DscBuildData
.IntToCString(Value
, ValueSize
), Pcd
.DscRawValue
.get(SkuName
,{}).get(DefaultStoreName
))
1737 CApp
= CApp
+ ' memcpy (Pcd, Value, %d);\n' % (ValueSize
)
1739 if (SkuName
,DefaultStoreName
) == (TAB_DEFAULT
,TAB_DEFAULT_STORES_DEFAULT
) or (( (SkuName
,'') not in Pcd
.ValueChain
) and ( (SkuName
,DefaultStoreName
) not in Pcd
.ValueChain
)):
1740 for FieldName
in FieldList
:
1741 IsArray
= IsFieldValueAnArray(FieldList
[FieldName
][0])
1744 FieldList
[FieldName
][0] = ValueExpressionEx(FieldList
[FieldName
][0], TAB_VOID
, self
._GuidDict
)(True)
1745 except BadExpression
:
1746 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid value format for %s. From %s Line %d " %
1747 (".".join((Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, FieldName
)), FieldList
[FieldName
][1], FieldList
[FieldName
][2]))
1749 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
][0])
1751 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd
.TokenSpaceGuidCName
,Pcd
.TokenCName
,FieldName
)),FieldList
[FieldName
][1], FieldList
[FieldName
][2]))
1752 if isinstance(Value
, str):
1753 CApp
= CApp
+ ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1756 # Use memcpy() to copy value into field
1758 CApp
= CApp
+ ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd
.DatumType
, FieldName
)
1759 CApp
= CApp
+ ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData
.IntToCString(Value
, ValueSize
), FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1760 CApp
= CApp
+ ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName
, ValueSize
, ValueSize
)
1763 CApp
= CApp
+ ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1765 CApp
= CApp
+ ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1770 def GenerateInitValueStatement(Pcd
,SkuName
,DefaultStoreName
):
1771 CApp
= ' Assign_%s_%s_%s_%s_Value(Pcd);\n' % (Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
,SkuName
,DefaultStoreName
)
1774 def GenerateCommandLineValue(self
,Pcd
):
1775 CApp
= "// Value in CommandLine\n"
1776 CApp
= CApp
+ "void Assign_%s_%s_CommandLine_Value(%s *Pcd){\n" % (Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
,Pcd
.DatumType
)
1777 CApp
= CApp
+ ' UINT32 FieldSize;\n'
1778 CApp
= CApp
+ ' CHAR8 *Value;\n'
1780 pcddefaultvalue
= Pcd
.PcdValueFromComm
1781 for FieldList
in [pcddefaultvalue
,Pcd
.PcdFieldValueFromComm
]:
1784 if pcddefaultvalue
and FieldList
== pcddefaultvalue
:
1785 IsArray
= IsFieldValueAnArray(FieldList
)
1788 FieldList
= ValueExpressionEx(FieldList
, TAB_VOID
)(True)
1789 except BadExpression
:
1790 EdkLogger
.error("Build", FORMAT_INVALID
, "Invalid value format for %s.%s, from Command: %s" %
1791 (Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, FieldList
))
1792 Value
, ValueSize
= ParseFieldValue (FieldList
)
1794 if isinstance(Value
, str):
1795 CApp
= CApp
+ ' Pcd = %s; // From Command Line \n' % (Value
)
1798 # Use memcpy() to copy value into field
1800 CApp
= CApp
+ ' Value = %s; // From Command Line.\n' % (DscBuildData
.IntToCString(Value
, ValueSize
))
1801 CApp
= CApp
+ ' memcpy (Pcd, Value, %d);\n' % (ValueSize
)
1803 for FieldName
in FieldList
:
1804 IsArray
= IsFieldValueAnArray(FieldList
[FieldName
][0])
1807 FieldList
[FieldName
][0] = ValueExpressionEx(FieldList
[FieldName
][0], TAB_VOID
, self
._GuidDict
)(True)
1808 except BadExpression
:
1809 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid value format for %s. From %s Line %d " %
1810 (".".join((Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, FieldName
)), FieldList
[FieldName
][1], FieldList
[FieldName
][2]))
1814 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
][0])
1816 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd
.TokenSpaceGuidCName
,Pcd
.TokenCName
,FieldName
)),FieldList
[FieldName
][1], FieldList
[FieldName
][2]))
1817 if isinstance(Value
, str):
1818 CApp
= CApp
+ ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1821 # Use memcpy() to copy value into field
1823 CApp
= CApp
+ ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd
.DatumType
, FieldName
)
1824 CApp
= CApp
+ ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData
.IntToCString(Value
, ValueSize
), FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1825 CApp
= CApp
+ ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName
, ValueSize
, ValueSize
)
1828 CApp
= CApp
+ ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1830 CApp
= CApp
+ ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1835 def GenerateCommandLineValueStatement(Pcd
):
1836 CApp
= ' Assign_%s_%s_CommandLine_Value(Pcd);\n' % (Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1839 def GenerateInitializeFunc(self
, SkuName
, DefaultStore
, Pcd
, InitByteValue
, CApp
):
1840 OverrideValues
= {DefaultStore
:""}
1841 if Pcd
.SkuOverrideValues
:
1842 OverrideValues
= Pcd
.SkuOverrideValues
[SkuName
]
1843 for DefaultStoreName
in OverrideValues
:
1844 CApp
= CApp
+ 'void\n'
1845 CApp
= CApp
+ 'Initialize_%s_%s_%s_%s(\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1846 CApp
= CApp
+ ' void\n'
1847 CApp
= CApp
+ ' )\n'
1849 CApp
= CApp
+ ' UINT32 Size;\n'
1850 CApp
= CApp
+ ' UINT32 FieldSize;\n'
1851 CApp
= CApp
+ ' CHAR8 *Value;\n'
1852 CApp
= CApp
+ ' UINT32 OriginalSize;\n'
1853 CApp
= CApp
+ ' VOID *OriginalPcd;\n'
1854 CApp
= CApp
+ ' %s *Pcd; // From %s Line %d \n' % (Pcd
.DatumType
, Pcd
.PkgPath
, Pcd
.PcdDefineLineNo
)
1857 if SkuName
in Pcd
.SkuInfoList
:
1858 DefaultValue
= Pcd
.SkuInfoList
[SkuName
].DefaultStoreDict
.get(DefaultStoreName
,Pcd
.SkuInfoList
[SkuName
].HiiDefaultValue
if Pcd
.SkuInfoList
[SkuName
].HiiDefaultValue
else Pcd
.SkuInfoList
[SkuName
].DefaultValue
)
1860 DefaultValue
= Pcd
.DefaultValue
1861 PcdDefaultValue
= StringToArray(DefaultValue
.strip())
1863 InitByteValue
+= '%s.%s.%s.%s|%s|%s\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, Pcd
.DatumType
, PcdDefaultValue
)
1866 # Get current PCD value and size
1868 CApp
= CApp
+ ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1871 # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides
1872 # the correct value. For structures with a flexible array member, the flexible
1873 # array member is detected, and the size is based on the highest index used with
1874 # the flexible array member. The flexible array member must be the last field
1875 # in a structure. The size formula for this case is:
1876 # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
1878 CApp
= CApp
+ DscBuildData
.GenerateSizeStatments(Pcd
)
1881 # Allocate and zero buffer for the PCD
1882 # Must handle cases where current value is smaller, larger, or same size
1883 # Always keep that larger one as the current size
1885 CApp
= CApp
+ ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'
1886 CApp
= CApp
+ ' Pcd = (%s *)malloc (Size);\n' % (Pcd
.DatumType
)
1887 CApp
= CApp
+ ' memset (Pcd, 0, Size);\n'
1890 # Copy current PCD value into allocated buffer.
1892 CApp
= CApp
+ ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'
1895 # Assign field values in PCD
1897 CApp
= CApp
+ DscBuildData
.GenerateDefaultValueAssignStatement(Pcd
)
1898 if Pcd
.Type
not in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_FIXED_AT_BUILD
],
1899 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_PATCHABLE_IN_MODULE
]]:
1900 for skuname
in self
.SkuIdMgr
.GetSkuChain(SkuName
):
1901 storeset
= [DefaultStoreName
] if DefaultStoreName
== TAB_DEFAULT_STORES_DEFAULT
else [TAB_DEFAULT_STORES_DEFAULT
, DefaultStoreName
]
1902 for defaultstorenameitem
in storeset
:
1903 CApp
= CApp
+ "// SkuName: %s, DefaultStoreName: %s \n" % (skuname
, defaultstorenameitem
)
1904 CApp
= CApp
+ DscBuildData
.GenerateInitValueStatement(Pcd
,skuname
,defaultstorenameitem
)
1905 if skuname
== SkuName
:
1908 CApp
= CApp
+ "// SkuName: %s, DefaultStoreName: STANDARD \n" % self
.SkuIdMgr
.SystemSkuId
1909 CApp
= CApp
+ DscBuildData
.GenerateInitValueStatement(Pcd
,self
.SkuIdMgr
.SystemSkuId
,TAB_DEFAULT_STORES_DEFAULT
)
1910 CApp
= CApp
+ DscBuildData
.GenerateCommandLineValueStatement(Pcd
)
1912 # Set new PCD value and size
1914 CApp
= CApp
+ ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1919 CApp
= CApp
+ ' free (Pcd);\n'
1922 return InitByteValue
, CApp
1924 def GenerateByteArrayValue (self
, StructuredPcds
):
1926 # Generate/Compile/Run C application to determine if there are any flexible array members
1928 if not StructuredPcds
:
1932 CApp
= PcdMainCHeader
1934 IncludeFiles
= set()
1935 for PcdName
in StructuredPcds
:
1936 Pcd
= StructuredPcds
[PcdName
]
1937 for IncludeFile
in Pcd
.StructuredPcdIncludeFile
:
1938 if IncludeFile
not in IncludeFiles
:
1939 IncludeFiles
.add(IncludeFile
)
1940 CApp
= CApp
+ '#include <%s>\n' % (IncludeFile
)
1942 for PcdName
in StructuredPcds
:
1943 Pcd
= StructuredPcds
[PcdName
]
1944 CApp
= CApp
+ self
.GenerateSizeFunction(Pcd
)
1945 CApp
= CApp
+ self
.GenerateDefaultValueAssignFunction(Pcd
)
1946 CApp
= CApp
+ self
.GenerateCommandLineValue(Pcd
)
1947 if not Pcd
.SkuOverrideValues
or Pcd
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_FIXED_AT_BUILD
],
1948 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_PATCHABLE_IN_MODULE
]]:
1949 CApp
= CApp
+ self
.GenerateInitValueFunction(Pcd
,self
.SkuIdMgr
.SystemSkuId
, TAB_DEFAULT_STORES_DEFAULT
)
1951 for SkuName
in self
.SkuIdMgr
.SkuOverrideOrder():
1952 if SkuName
not in Pcd
.SkuOverrideValues
:
1954 for DefaultStoreName
in Pcd
.SkuOverrideValues
[SkuName
]:
1955 CApp
= CApp
+ self
.GenerateInitValueFunction(Pcd
,SkuName
,DefaultStoreName
)
1956 if not Pcd
.SkuOverrideValues
or Pcd
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_FIXED_AT_BUILD
],
1957 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_PATCHABLE_IN_MODULE
]]:
1958 InitByteValue
, CApp
= self
.GenerateInitializeFunc(self
.SkuIdMgr
.SystemSkuId
, TAB_DEFAULT_STORES_DEFAULT
, Pcd
, InitByteValue
, CApp
)
1960 for SkuName
in self
.SkuIdMgr
.SkuOverrideOrder():
1961 if SkuName
not in Pcd
.SkuOverrideValues
:
1963 for DefaultStoreName
in Pcd
.DefaultStoreName
:
1964 Pcd
= StructuredPcds
[PcdName
]
1965 InitByteValue
, CApp
= self
.GenerateInitializeFunc(SkuName
, DefaultStoreName
, Pcd
, InitByteValue
, CApp
)
1967 CApp
= CApp
+ 'VOID\n'
1968 CApp
= CApp
+ 'PcdEntryPoint(\n'
1969 CApp
= CApp
+ ' VOID\n'
1970 CApp
= CApp
+ ' )\n'
1972 for Pcd
in StructuredPcds
.values():
1973 if not Pcd
.SkuOverrideValues
or Pcd
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_FIXED_AT_BUILD
],self
._PCD
_TYPE
_STRING
_[MODEL_PCD_PATCHABLE_IN_MODULE
]]:
1974 CApp
= CApp
+ ' Initialize_%s_%s_%s_%s();\n' % (self
.SkuIdMgr
.SystemSkuId
, TAB_DEFAULT_STORES_DEFAULT
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1976 for SkuName
in self
.SkuIdMgr
.SkuOverrideOrder():
1977 if SkuName
not in Pcd
.SkuOverrideValues
:
1979 for DefaultStoreName
in Pcd
.SkuOverrideValues
[SkuName
]:
1980 CApp
= CApp
+ ' Initialize_%s_%s_%s_%s();\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1983 CApp
= CApp
+ PcdMainCEntry
+ '\n'
1985 if not os
.path
.exists(self
.OutputPath
):
1986 os
.makedirs(self
.OutputPath
)
1987 CAppBaseFileName
= os
.path
.join(self
.OutputPath
, PcdValueInitName
)
1988 SaveFileOnChange(CAppBaseFileName
+ '.c', CApp
, False)
1990 MakeApp
= PcdMakefileHeader
1991 if sys
.platform
== "win32":
1992 MakeApp
= MakeApp
+ 'APPNAME = %s\n' % (PcdValueInitName
) + 'OBJECTS = %s\%s.obj\n' % (self
.OutputPath
, PcdValueInitName
) + 'INC = '
1994 MakeApp
= MakeApp
+ PcdGccMakefile
1995 MakeApp
= MakeApp
+ 'APPNAME = %s\n' % (PcdValueInitName
) + 'OBJECTS = %s/%s.o\n' % (self
.OutputPath
, PcdValueInitName
) + \
1996 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'INCLUDE +='
2000 for Cache
in self
._Bdb
._CACHE
_.values():
2001 if Cache
.MetaFile
.Ext
.lower() != '.dec':
2004 if str(Cache
.MetaFile
.Path
) not in PlatformInc
:
2005 PlatformInc
[str(Cache
.MetaFile
.Path
)] = []
2006 PlatformInc
[str(Cache
.MetaFile
.Path
)].append (os
.path
.dirname(Cache
.MetaFile
.Path
))
2007 PlatformInc
[str(Cache
.MetaFile
.Path
)].extend (Cache
.CommonIncludes
)
2010 for Pcd
in StructuredPcds
.values():
2011 for PackageDec
in Pcd
.PackageDecs
:
2012 Package
= os
.path
.normpath(mws
.join(GlobalData
.gWorkspace
, PackageDec
))
2013 if not os
.path
.exists(Package
):
2014 EdkLogger
.error('Build', RESOURCE_NOT_AVAILABLE
, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
))
2015 if Package
not in PcdDependDEC
:
2016 PcdDependDEC
.append(Package
)
2018 if PlatformInc
and PcdDependDEC
:
2019 for pkg
in PcdDependDEC
:
2020 if pkg
in PlatformInc
:
2021 for inc
in PlatformInc
[pkg
]:
2022 MakeApp
+= '-I' + str(inc
) + ' '
2023 IncSearchList
.append(inc
)
2024 MakeApp
= MakeApp
+ '\n'
2026 CC_FLAGS
= LinuxCFLAGS
2027 if sys
.platform
== "win32":
2028 CC_FLAGS
= WindowsCFLAGS
2030 for Options
in self
.BuildOptions
:
2031 if Options
[2] != EDKII_NAME
:
2034 if Family
and Family
!= self
.ToolChainFamily
:
2036 Target
, Tag
, Arch
, Tool
, Attr
= Options
[1].split("_")
2040 if Target
== "*" or Target
== self
._Target
:
2041 if Tag
== "*" or Tag
== self
._Toolchain
:
2042 if Arch
== "*" or Arch
== self
.Arch
:
2043 if Tool
not in BuildOptions
:
2044 BuildOptions
[Tool
] = {}
2045 if Attr
!= "FLAGS" or Attr
not in BuildOptions
[Tool
] or self
.BuildOptions
[Options
].startswith('='):
2046 BuildOptions
[Tool
][Attr
] = self
.BuildOptions
[Options
]
2048 # append options for the same tool except PATH
2050 BuildOptions
[Tool
][Attr
] += " " + self
.BuildOptions
[Options
]
2052 BuildOptions
[Tool
][Attr
] = self
.BuildOptions
[Options
]
2054 for Tool
in BuildOptions
:
2055 for Attr
in BuildOptions
[Tool
]:
2057 Value
= BuildOptions
[Tool
][Attr
]
2058 ValueList
= Value
.split()
2060 for Id
, Item
in enumerate(ValueList
):
2061 if Item
in ['-D', '/D', '-U', '/U']:
2062 CC_FLAGS
+= ' ' + Item
2063 if Id
+ 1 < len(ValueList
):
2064 CC_FLAGS
+= ' ' + ValueList
[Id
+ 1]
2065 elif Item
.startswith(('-D', '/D', '-U', '/U')):
2066 CC_FLAGS
+= ' ' + Item
2069 if sys
.platform
== "win32":
2070 MakeApp
= MakeApp
+ PcdMakefileEnd
2071 MakeApp
= MakeApp
+ '\n'
2072 IncludeFileFullPaths
= []
2073 for includefile
in IncludeFiles
:
2074 for includepath
in IncSearchList
:
2075 includefullpath
= os
.path
.join(str(includepath
),includefile
)
2076 if os
.path
.exists(includefullpath
):
2077 IncludeFileFullPaths
.append(os
.path
.normpath(includefullpath
))
2080 SearchPathList
.append(os
.path
.normpath(mws
.join(GlobalData
.gWorkspace
, "BaseTools/Source/C/Include")))
2081 SearchPathList
.append(os
.path
.normpath(mws
.join(GlobalData
.gWorkspace
, "BaseTools/Source/C/Common")))
2082 SearchPathList
.extend(str(item
) for item
in IncSearchList
)
2083 IncFileList
= GetDependencyList(IncludeFileFullPaths
,SearchPathList
)
2084 for include_file
in IncFileList
:
2085 MakeApp
+= "$(OBJECTS) : %s\n" % include_file
2086 MakeFileName
= os
.path
.join(self
.OutputPath
, 'Makefile')
2087 MakeApp
+= "$(OBJECTS) : %s\n" % MakeFileName
2088 SaveFileOnChange(MakeFileName
, MakeApp
, False)
2090 InputValueFile
= os
.path
.join(self
.OutputPath
, 'Input.txt')
2091 OutputValueFile
= os
.path
.join(self
.OutputPath
, 'Output.txt')
2092 SaveFileOnChange(InputValueFile
, InitByteValue
, False)
2094 PcdValueInitExe
= PcdValueInitName
2095 if not sys
.platform
== "win32":
2096 PcdValueInitExe
= os
.path
.join(os
.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName
)
2098 PcdValueInitExe
= os
.path
.join(os
.getenv("EDK_TOOLS_PATH"), 'Bin', 'Win32', PcdValueInitName
) +".exe"
2101 if sys
.platform
== "win32":
2102 MakeCommand
= 'nmake -f %s' % (MakeFileName
)
2103 returncode
, StdOut
, StdErr
= DscBuildData
.ExecuteCommand (MakeCommand
)
2106 MakeCommand
= 'make -f %s' % (MakeFileName
)
2107 returncode
, StdOut
, StdErr
= DscBuildData
.ExecuteCommand (MakeCommand
)
2109 Messages
= Messages
.split('\n')
2112 CAppBaseFileName
= os
.path
.join(self
.OutputPath
, PcdValueInitName
)
2113 File
= open (CAppBaseFileName
+ '.c', 'r')
2114 FileData
= File
.readlines()
2116 for Message
in Messages
:
2117 if " error" in Message
or "warning" in Message
:
2118 FileInfo
= Message
.strip().split('(')
2119 if len (FileInfo
) > 1:
2120 FileName
= FileInfo
[0]
2121 FileLine
= FileInfo
[1].split (')')[0]
2123 FileInfo
= Message
.strip().split(':')
2124 FileName
= FileInfo
[0]
2125 FileLine
= FileInfo
[1]
2126 if FileLine
.isdigit():
2127 error_line
= FileData
[int (FileLine
) - 1]
2128 if r
"//" in error_line
:
2129 c_line
,dsc_line
= error_line
.split(r
"//")
2131 dsc_line
= error_line
2132 message_itmes
= Message
.split(":")
2134 if "PcdValueInit.c" not in Message
:
2135 if not MessageGroup
:
2136 MessageGroup
.append(Message
)
2139 for item
in message_itmes
:
2140 if "PcdValueInit.c" in item
:
2141 Index
= message_itmes
.index(item
)
2142 message_itmes
[Index
] = dsc_line
.strip()
2144 MessageGroup
.append(":".join(message_itmes
[Index
:]).strip())
2147 MessageGroup
.append(Message
)
2149 EdkLogger
.error("build", PCD_STRUCTURE_PCD_ERROR
, "\n".join(MessageGroup
) )
2151 EdkLogger
.error('Build', COMMAND_FAILURE
, 'Can not execute command: %s' % MakeCommand
)
2153 if DscBuildData
.NeedUpdateOutput(OutputValueFile
, PcdValueInitExe
,InputValueFile
):
2154 Command
= PcdValueInitExe
+ ' -i %s -o %s' % (InputValueFile
, OutputValueFile
)
2155 returncode
, StdOut
, StdErr
= DscBuildData
.ExecuteCommand (Command
)
2157 EdkLogger
.warn('Build', COMMAND_FAILURE
, 'Can not collect output from command: %s' % Command
)
2159 File
= open (OutputValueFile
, 'r')
2160 FileBuffer
= File
.readlines()
2163 StructurePcdSet
= []
2164 for Pcd
in FileBuffer
:
2165 PcdValue
= Pcd
.split ('|')
2166 PcdInfo
= PcdValue
[0].split ('.')
2167 StructurePcdSet
.append((PcdInfo
[0],PcdInfo
[1], PcdInfo
[2], PcdInfo
[3], PcdValue
[2].strip()))
2168 return StructurePcdSet
2171 def NeedUpdateOutput(OutputFile
, ValueCFile
, StructureInput
):
2172 if not os
.path
.exists(OutputFile
):
2174 if os
.stat(OutputFile
).st_mtime
<= os
.stat(ValueCFile
).st_mtime
:
2176 if os
.stat(OutputFile
).st_mtime
<= os
.stat(StructureInput
).st_mtime
:
2180 ## Retrieve dynamic PCD settings
2182 # @param Type PCD type
2184 # @retval a dict object contains settings of given PCD type
2186 def _GetDynamicPcd(self
, Type
):
2189 Pcds
= OrderedDict()
2191 # tdict is a special dict kind of type, used for selecting correct
2192 # PCD settings for certain ARCH and SKU
2194 PcdDict
= tdict(True, 4)
2196 # Find out all possible PCD candidates for self._Arch
2197 RecordList
= self
._RawData
[Type
, self
._Arch
]
2198 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
2201 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
2202 SkuName
= SkuName
.upper()
2203 SkuName
= TAB_DEFAULT
if SkuName
== TAB_COMMON
else SkuName
2204 if SkuName
not in AvailableSkuIdSet
:
2205 EdkLogger
.error('build', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
2206 File
=self
.MetaFile
, Line
=Dummy5
)
2207 if "." not in TokenSpaceGuid
:
2208 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy5
))
2209 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
2211 # Remove redundant PCD candidates, per the ARCH and SKU
2212 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
2214 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
2218 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
2219 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], '', '', '', '', '', PcdValue
)
2220 if (PcdCName
, TokenSpaceGuid
) in Pcds
:
2221 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
2222 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
2223 if MaxDatumSize
.strip():
2224 CurrentMaxSize
= int(MaxDatumSize
.strip(), 0)
2227 if pcdObject
.MaxDatumSize
:
2228 PcdMaxSize
= int(pcdObject
.MaxDatumSize
, 0)
2231 if CurrentMaxSize
> PcdMaxSize
:
2232 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
2234 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
2237 self
._PCD
_TYPE
_STRING
_[Type
],
2242 {SkuName
: SkuInfo
},
2247 for pcd
in Pcds
.values():
2248 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
2249 # Only fix the value while no value provided in DSC file.
2250 for sku
in pcd
.SkuInfoList
.values():
2251 if not sku
.DefaultValue
:
2252 sku
.DefaultValue
= pcdDecObject
.DefaultValue
2253 if TAB_DEFAULT
not in pcd
.SkuInfoList
and TAB_COMMON
not in pcd
.SkuInfoList
:
2254 valuefromDec
= pcdDecObject
.DefaultValue
2255 SkuInfo
= SkuInfoClass(TAB_DEFAULT
, '0', '', '', '', '', '', valuefromDec
)
2256 pcd
.SkuInfoList
[TAB_DEFAULT
] = SkuInfo
2257 elif TAB_DEFAULT
not in pcd
.SkuInfoList
and TAB_COMMON
in pcd
.SkuInfoList
:
2258 pcd
.SkuInfoList
[TAB_DEFAULT
] = pcd
.SkuInfoList
[TAB_COMMON
]
2259 del pcd
.SkuInfoList
[TAB_COMMON
]
2260 elif TAB_DEFAULT
in pcd
.SkuInfoList
and TAB_COMMON
in pcd
.SkuInfoList
:
2261 del pcd
.SkuInfoList
[TAB_COMMON
]
2263 map(self
.FilterSkuSettings
,Pcds
.values())
2267 def FilterSkuSettings(self
, PcdObj
):
2269 if self
.SkuIdMgr
.SkuUsageType
== self
.SkuIdMgr
.SINGLE
:
2270 if TAB_DEFAULT
in PcdObj
.SkuInfoList
and self
.SkuIdMgr
.SystemSkuId
not in PcdObj
.SkuInfoList
:
2271 PcdObj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
] = PcdObj
.SkuInfoList
[TAB_DEFAULT
]
2272 PcdObj
.SkuInfoList
= {TAB_DEFAULT
:PcdObj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
]}
2273 PcdObj
.SkuInfoList
[TAB_DEFAULT
].SkuIdName
= TAB_DEFAULT
2274 PcdObj
.SkuInfoList
[TAB_DEFAULT
].SkuId
= '0'
2276 elif self
.SkuIdMgr
.SkuUsageType
== self
.SkuIdMgr
.DEFAULT
:
2277 PcdObj
.SkuInfoList
= {TAB_DEFAULT
:PcdObj
.SkuInfoList
[TAB_DEFAULT
]}
2282 def CompareVarAttr(Attr1
, Attr2
):
2283 if not Attr1
or not Attr2
: # for empty string
2285 Attr1s
= [attr
.strip() for attr
in Attr1
.split(",")]
2286 Attr1Set
= set(Attr1s
)
2287 Attr2s
= [attr
.strip() for attr
in Attr2
.split(",")]
2288 Attr2Set
= set(Attr2s
)
2289 if Attr2Set
== Attr1Set
:
2294 def CopyDscRawValue(self
,Pcd
):
2295 if Pcd
.DscRawValue
is None:
2296 Pcd
.DscRawValue
= dict()
2297 if Pcd
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_FIXED_AT_BUILD
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_PATCHABLE_IN_MODULE
]]:
2298 if self
.SkuIdMgr
.SystemSkuId
not in Pcd
.DscRawValue
:
2299 Pcd
.DscRawValue
[self
.SkuIdMgr
.SystemSkuId
] = {}
2300 Pcd
.DscRawValue
[self
.SkuIdMgr
.SystemSkuId
][TAB_DEFAULT_STORES_DEFAULT
] = Pcd
.DefaultValue
2301 for skuname
in Pcd
.SkuInfoList
:
2302 Pcd
.DscRawValue
[skuname
] = {}
2303 if Pcd
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
2304 for defaultstore
in Pcd
.SkuInfoList
[skuname
].DefaultStoreDict
:
2305 Pcd
.DscRawValue
[skuname
][defaultstore
] = Pcd
.SkuInfoList
[skuname
].DefaultStoreDict
[defaultstore
]
2307 Pcd
.DscRawValue
[skuname
][TAB_DEFAULT_STORES_DEFAULT
] = Pcd
.SkuInfoList
[skuname
].DefaultValue
2308 def CompletePcdValues(self
,PcdSet
):
2310 DefaultStoreObj
= DefaultStore(self
._GetDefaultStores
())
2311 SkuIds
= {skuname
:skuid
for skuname
,skuid
in self
.SkuIdMgr
.AvailableSkuIdSet
.items() if skuname
!= TAB_COMMON
}
2312 DefaultStores
= set(storename
for pcdobj
in PcdSet
.values() for skuobj
in pcdobj
.SkuInfoList
.values() for storename
in skuobj
.DefaultStoreDict
)
2313 for PcdCName
, TokenSpaceGuid
in PcdSet
:
2314 PcdObj
= PcdSet
[(PcdCName
, TokenSpaceGuid
)]
2315 self
.CopyDscRawValue(PcdObj
)
2316 if PcdObj
.Type
not in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_DEFAULT
],
2317 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
2318 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_VPD
],
2319 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_DEFAULT
],
2320 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
],
2321 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_VPD
]]:
2322 Pcds
[PcdCName
, TokenSpaceGuid
]= PcdObj
2324 PcdType
= PcdObj
.Type
2325 if PcdType
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
2326 for skuid
in PcdObj
.SkuInfoList
:
2327 skuobj
= PcdObj
.SkuInfoList
[skuid
]
2328 mindefaultstorename
= DefaultStoreObj
.GetMin(set(defaultstorename
for defaultstorename
in skuobj
.DefaultStoreDict
))
2329 for defaultstorename
in DefaultStores
:
2330 if defaultstorename
not in skuobj
.DefaultStoreDict
:
2331 skuobj
.DefaultStoreDict
[defaultstorename
] = copy
.deepcopy(skuobj
.DefaultStoreDict
[mindefaultstorename
])
2332 skuobj
.HiiDefaultValue
= skuobj
.DefaultStoreDict
[mindefaultstorename
]
2333 for skuname
,skuid
in SkuIds
.items():
2334 if skuname
not in PcdObj
.SkuInfoList
:
2335 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(skuname
)
2336 while nextskuid
not in PcdObj
.SkuInfoList
:
2337 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
2338 PcdObj
.SkuInfoList
[skuname
] = copy
.deepcopy(PcdObj
.SkuInfoList
[nextskuid
])
2339 PcdObj
.SkuInfoList
[skuname
].SkuId
= skuid
2340 PcdObj
.SkuInfoList
[skuname
].SkuIdName
= skuname
2341 if PcdType
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
2342 PcdObj
.DefaultValue
= PcdObj
.SkuInfoList
.values()[0].HiiDefaultValue
if self
.SkuIdMgr
.SkuUsageType
== self
.SkuIdMgr
.SINGLE
else PcdObj
.SkuInfoList
[TAB_DEFAULT
].HiiDefaultValue
2343 Pcds
[PcdCName
, TokenSpaceGuid
]= PcdObj
2345 ## Retrieve dynamic HII PCD settings
2347 # @param Type PCD type
2349 # @retval a dict object contains settings of given PCD type
2351 def _GetDynamicHiiPcd(self
, Type
):
2355 Pcds
= OrderedDict()
2357 # tdict is a special dict kind of type, used for selecting correct
2358 # PCD settings for certain ARCH and SKU
2360 PcdDict
= tdict(True, 5)
2362 RecordList
= self
._RawData
[Type
, self
._Arch
]
2363 # Find out all possible PCD candidates for self._Arch
2364 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
2365 DefaultStoresDefine
= self
._GetDefaultStores
()
2367 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, DefaultStore
, Dummy4
,Dummy5
in RecordList
:
2368 SkuName
= SkuName
.upper()
2369 SkuName
= TAB_DEFAULT
if SkuName
== TAB_COMMON
else SkuName
2370 DefaultStore
= DefaultStore
.upper()
2371 if DefaultStore
== TAB_COMMON
:
2372 DefaultStore
= TAB_DEFAULT_STORES_DEFAULT
2373 if SkuName
not in AvailableSkuIdSet
:
2374 EdkLogger
.error('build', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
2375 File
=self
.MetaFile
, Line
=Dummy5
)
2376 if DefaultStore
not in DefaultStoresDefine
:
2377 EdkLogger
.error('build', PARAMETER_INVALID
, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore
,
2378 File
=self
.MetaFile
, Line
=Dummy5
)
2379 if "." not in TokenSpaceGuid
:
2380 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,DefaultStore
, Dummy5
))
2381 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
,DefaultStore
] = Setting
2384 # Remove redundant PCD candidates, per the ARCH and SKU
2385 for PcdCName
, TokenSpaceGuid
, SkuName
,DefaultStore
, Dummy4
in PcdSet
:
2387 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
,DefaultStore
]
2390 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VarAttribute
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
2392 rt
, Msg
= VariableAttributes
.ValidateVarAttributes(VarAttribute
)
2394 EdkLogger
.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR
, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid
, PcdCName
)), Msg
),
2395 ExtraData
="[%s]" % VarAttribute
)
2397 FormatCorrect
= True
2398 if VariableOffset
.isdigit():
2399 if int(VariableOffset
, 10) > 0xFFFF:
2401 elif variablePattern
.match(VariableOffset
):
2402 if int(VariableOffset
, 16) > 0xFFFF:
2404 # For Offset written in "A.B"
2405 elif VariableOffset
.find('.') > -1:
2406 VariableOffsetList
= VariableOffset
.split(".")
2407 if not (len(VariableOffsetList
) == 2
2408 and IsValidWord(VariableOffsetList
[0])
2409 and IsValidWord(VariableOffsetList
[1])):
2410 FormatCorrect
= False
2412 FormatCorrect
= False
2413 if not FormatCorrect
:
2414 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid
, PcdCName
)))
2417 EdkLogger
.error('Build', OPTION_VALUE_INVALID
, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid
, PcdCName
)))
2418 if (VariableName
, VariableGuid
) not in VariableAttrs
:
2419 VariableAttrs
[(VariableName
, VariableGuid
)] = VarAttribute
2421 if not DscBuildData
.CompareVarAttr(VariableAttrs
[(VariableName
, VariableGuid
)], VarAttribute
):
2422 EdkLogger
.error('Build', PCD_VARIABLE_ATTRIBUTES_CONFLICT_ERROR
, "The variable %s.%s for DynamicHii PCDs has conflicting attributes [%s] and [%s] " % (VariableGuid
, VariableName
, VarAttribute
, VariableAttrs
[(VariableName
, VariableGuid
)]))
2424 pcdDecObject
= self
._DecPcds
[PcdCName
, TokenSpaceGuid
]
2425 if (PcdCName
, TokenSpaceGuid
) in Pcds
:
2426 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
2427 if SkuName
in pcdObject
.SkuInfoList
:
2428 Skuitem
= pcdObject
.SkuInfoList
[SkuName
]
2429 Skuitem
.DefaultStoreDict
.update({DefaultStore
:DefaultValue
})
2431 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
=VarAttribute
,DefaultStore
={DefaultStore
:DefaultValue
})
2432 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
2434 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
=VarAttribute
,DefaultStore
={DefaultStore
:DefaultValue
})
2435 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
2438 self
._PCD
_TYPE
_STRING
_[Type
],
2443 {SkuName
: SkuInfo
},
2446 pcdDecObject
.validateranges
,
2447 pcdDecObject
.validlists
,
2448 pcdDecObject
.expressions
,
2452 for pcd
in Pcds
.values():
2453 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
2454 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
2455 pcd
.DatumType
= pcdDecObject
.DatumType
2456 # Only fix the value while no value provided in DSC file.
2457 for sku
in pcd
.SkuInfoList
.values():
2458 if (sku
.HiiDefaultValue
== "" or sku
.HiiDefaultValue
is None):
2459 sku
.HiiDefaultValue
= pcdDecObject
.DefaultValue
2460 for default_store
in sku
.DefaultStoreDict
:
2461 sku
.DefaultStoreDict
[default_store
]=pcdDecObject
.DefaultValue
2462 pcd
.DefaultValue
= pcdDecObject
.DefaultValue
2463 if TAB_DEFAULT
not in pcd
.SkuInfoList
and TAB_COMMON
not in pcd
.SkuInfoList
:
2464 valuefromDec
= pcdDecObject
.DefaultValue
2465 SkuInfo
= SkuInfoClass(TAB_DEFAULT
, '0', SkuInfoObj
.VariableName
, SkuInfoObj
.VariableGuid
, SkuInfoObj
.VariableOffset
, valuefromDec
,VariableAttribute
=SkuInfoObj
.VariableAttribute
,DefaultStore
={DefaultStore
:valuefromDec
})
2466 pcd
.SkuInfoList
[TAB_DEFAULT
] = SkuInfo
2467 elif TAB_DEFAULT
not in pcd
.SkuInfoList
and TAB_COMMON
in pcd
.SkuInfoList
:
2468 pcd
.SkuInfoList
[TAB_DEFAULT
] = pcd
.SkuInfoList
[TAB_COMMON
]
2469 del pcd
.SkuInfoList
[TAB_COMMON
]
2470 elif TAB_DEFAULT
in pcd
.SkuInfoList
and TAB_COMMON
in pcd
.SkuInfoList
:
2471 del pcd
.SkuInfoList
[TAB_COMMON
]
2473 if pcd
.MaxDatumSize
.strip():
2474 MaxSize
= int(pcd
.MaxDatumSize
, 0)
2477 if pcd
.DatumType
not in TAB_PCD_NUMERIC_TYPES
:
2478 for (_
, skuobj
) in pcd
.SkuInfoList
.items():
2480 skuobj
.HiiDefaultValue
= StringToArray(skuobj
.HiiDefaultValue
)
2481 datalen
= len(skuobj
.HiiDefaultValue
.split(","))
2482 if datalen
> MaxSize
:
2484 for defaultst
in skuobj
.DefaultStoreDict
:
2485 skuobj
.DefaultStoreDict
[defaultst
] = StringToArray(skuobj
.DefaultStoreDict
[defaultst
])
2486 pcd
.DefaultValue
= StringToArray(pcd
.DefaultValue
)
2487 pcd
.MaxDatumSize
= str(MaxSize
)
2488 rt
, invalidhii
= DscBuildData
.CheckVariableNameAssignment(Pcds
)
2490 invalidpcd
= ",".join(invalidhii
)
2491 EdkLogger
.error('build', PCD_VARIABLE_INFO_ERROR
, Message
='The same HII PCD must map to the same EFI variable for all SKUs', File
=self
.MetaFile
, ExtraData
=invalidpcd
)
2493 map(self
.FilterSkuSettings
,Pcds
.values())
2498 def CheckVariableNameAssignment(Pcds
):
2500 for pcdname
in Pcds
:
2502 varnameset
= set(sku
.VariableName
for (skuid
,sku
) in pcd
.SkuInfoList
.items())
2503 if len(varnameset
) > 1:
2504 invalidhii
.append(".".join((pcdname
[1],pcdname
[0])))
2506 return False,invalidhii
2509 ## Retrieve dynamic VPD PCD settings
2511 # @param Type PCD type
2513 # @retval a dict object contains settings of given PCD type
2515 def _GetDynamicVpdPcd(self
, Type
):
2518 Pcds
= OrderedDict()
2520 # tdict is a special dict kind of type, used for selecting correct
2521 # PCD settings for certain ARCH and SKU
2523 PcdDict
= tdict(True, 4)
2526 # Find out all possible PCD candidates for self._Arch
2527 RecordList
= self
._RawData
[Type
, self
._Arch
]
2528 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
2530 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
2531 SkuName
= SkuName
.upper()
2532 SkuName
= TAB_DEFAULT
if SkuName
== TAB_COMMON
else SkuName
2533 if SkuName
not in AvailableSkuIdSet
:
2534 EdkLogger
.error('build', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
2535 File
=self
.MetaFile
, Line
=Dummy5
)
2536 if "." not in TokenSpaceGuid
:
2537 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy5
))
2538 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
2540 # Remove redundant PCD candidates, per the ARCH and SKU
2541 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
2542 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
2546 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
2547 # For the Integer & Boolean type, the optional data can only be InitialValue.
2548 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
2549 # until the DEC parser has been called.
2551 VpdOffset
, MaxDatumSize
, InitialValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
2552 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], '', '', '', '', VpdOffset
, InitialValue
)
2553 if (PcdCName
, TokenSpaceGuid
) in Pcds
:
2554 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
2555 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
2556 if MaxDatumSize
.strip():
2557 CurrentMaxSize
= int(MaxDatumSize
.strip(), 0)
2560 if pcdObject
.MaxDatumSize
:
2561 PcdMaxSize
= int(pcdObject
.MaxDatumSize
, 0)
2564 if CurrentMaxSize
> PcdMaxSize
:
2565 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
2567 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
2570 self
._PCD
_TYPE
_STRING
_[Type
],
2575 {SkuName
: SkuInfo
},
2579 for pcd
in Pcds
.values():
2580 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
2581 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
2582 pcd
.DatumType
= pcdDecObject
.DatumType
2583 # Only fix the value while no value provided in DSC file.
2584 for sku
in pcd
.SkuInfoList
.values():
2585 if not sku
.DefaultValue
:
2586 sku
.DefaultValue
= pcdDecObject
.DefaultValue
2587 if TAB_DEFAULT
not in pcd
.SkuInfoList
and TAB_COMMON
not in pcd
.SkuInfoList
:
2588 valuefromDec
= pcdDecObject
.DefaultValue
2589 SkuInfo
= SkuInfoClass(TAB_DEFAULT
, '0', '', '', '', '', SkuInfoObj
.VpdOffset
, valuefromDec
)
2590 pcd
.SkuInfoList
[TAB_DEFAULT
] = SkuInfo
2591 elif TAB_DEFAULT
not in pcd
.SkuInfoList
and TAB_COMMON
in pcd
.SkuInfoList
:
2592 pcd
.SkuInfoList
[TAB_DEFAULT
] = pcd
.SkuInfoList
[TAB_COMMON
]
2593 del pcd
.SkuInfoList
[TAB_COMMON
]
2594 elif TAB_DEFAULT
in pcd
.SkuInfoList
and TAB_COMMON
in pcd
.SkuInfoList
:
2595 del pcd
.SkuInfoList
[TAB_COMMON
]
2598 map(self
.FilterSkuSettings
,Pcds
.values())
2601 ## Add external modules
2603 # The external modules are mostly those listed in FDF file, which don't
2606 # @param FilePath The path of module description file
2608 def AddModule(self
, FilePath
):
2609 FilePath
= NormPath(FilePath
)
2610 if FilePath
not in self
.Modules
:
2611 Module
= ModuleBuildClassObject()
2612 Module
.MetaFile
= FilePath
2613 self
.Modules
.append(Module
)
2615 def _GetToolChainFamily(self
):
2616 self
._ToolChainFamily
= "MSFT"
2617 BuildConfigurationFile
= os
.path
.normpath(os
.path
.join(GlobalData
.gConfDirectory
, "target.txt"))
2618 if os
.path
.isfile(BuildConfigurationFile
) == True:
2619 TargetTxt
= TargetTxtClassObject()
2620 TargetTxt
.LoadTargetTxtFile(BuildConfigurationFile
)
2621 ToolDefinitionFile
= TargetTxt
.TargetTxtDictionary
[DataType
.TAB_TAT_DEFINES_TOOL_CHAIN_CONF
]
2622 if ToolDefinitionFile
== '':
2623 ToolDefinitionFile
= "tools_def.txt"
2624 ToolDefinitionFile
= os
.path
.normpath(mws
.join(self
.WorkspaceDir
, 'Conf', ToolDefinitionFile
))
2625 if os
.path
.isfile(ToolDefinitionFile
) == True:
2626 ToolDef
= ToolDefClassObject()
2627 ToolDef
.LoadToolDefFile(ToolDefinitionFile
)
2628 ToolDefinition
= ToolDef
.ToolsDefTxtDatabase
2629 if TAB_TOD_DEFINES_FAMILY
not in ToolDefinition \
2630 or self
._Toolchain
not in ToolDefinition
[TAB_TOD_DEFINES_FAMILY
] \
2631 or not ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
._Toolchain
]:
2632 self
._ToolChainFamily
= "MSFT"
2634 self
._ToolChainFamily
= ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
._Toolchain
]
2635 return self
._ToolChainFamily
2637 ## Add external PCDs
2639 # The external PCDs are mostly those listed in FDF file to specify address
2640 # or offset information.
2642 # @param Name Name of the PCD
2643 # @param Guid Token space guid of the PCD
2644 # @param Value Value of the PCD
2646 def AddPcd(self
, Name
, Guid
, Value
):
2647 if (Name
, Guid
) not in self
.Pcds
:
2648 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
2649 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
2652 if self
._DecPcds
is None:
2654 if GlobalData
.gFdfParser
:
2655 FdfInfList
= GlobalData
.gFdfParser
.Profile
.InfList
2657 for Inf
in FdfInfList
:
2658 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
2659 if ModuleFile
in self
._Modules
:
2661 ModuleData
= self
._Bdb
[ModuleFile
, self
._Arch
, self
._Target
, self
._Toolchain
]
2662 PkgSet
.update(ModuleData
.Packages
)
2663 self
._DecPcds
, self
._GuidDict
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
,PkgSet
)
2664 return self
._DecPcds
2665 _Macros
= property(_GetMacros
)
2666 Arch
= property(_GetArch
, _SetArch
)
2667 Platform
= property(_GetPlatformName
)
2668 PlatformName
= property(_GetPlatformName
)
2669 Guid
= property(_GetFileGuid
)
2670 Version
= property(_GetVersion
)
2671 DscSpecification
= property(_GetDscSpec
)
2672 OutputDirectory
= property(_GetOutpuDir
)
2673 SupArchList
= property(_GetSupArch
)
2674 BuildTargets
= property(_GetBuildTarget
)
2675 SkuName
= property(_GetSkuName
, _SetSkuName
)
2676 PcdInfoFlag
= property(_GetPcdInfoFlag
)
2677 VarCheckFlag
= property(_GetVarCheckFlag
)
2678 FlashDefinition
= property(_GetFdfFile
)
2679 Prebuild
= property(_GetPrebuild
)
2680 Postbuild
= property(_GetPostbuild
)
2681 BuildNumber
= property(_GetBuildNumber
)
2682 MakefileName
= property(_GetMakefileName
)
2683 BsBaseAddress
= property(_GetBsBaseAddress
)
2684 RtBaseAddress
= property(_GetRtBaseAddress
)
2685 LoadFixAddress
= property(_GetLoadFixAddress
)
2686 RFCLanguages
= property(_GetRFCLanguages
)
2687 ISOLanguages
= property(_GetISOLanguages
)
2688 VpdToolGuid
= property(_GetVpdToolGuid
)
2689 SkuIds
= property(_GetSkuIds
)
2690 Modules
= property(_GetModules
)
2691 LibraryInstances
= property(_GetLibraryInstances
)
2692 LibraryClasses
= property(_GetLibraryClasses
)
2693 Pcds
= property(_GetPcds
)
2694 BuildOptions
= property(_GetBuildOptions
)
2695 ToolChainFamily
= property(_GetToolChainFamily
)