]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / BaseTools / Source / Python / AutoGen / ModuleAutoGenHelper.py
1 ## @file
2 # Create makefile for MS nmake and GNU make
3 #
4 # Copyright (c) 2019 - 2021, Intel Corporation. All rights reserved.<BR>
5 # SPDX-License-Identifier: BSD-2-Clause-Patent
6 #
7 from __future__ import absolute_import
8 from Workspace.WorkspaceDatabase import WorkspaceDatabase,BuildDB
9 from Common.caching import cached_property
10 from AutoGen.BuildEngine import BuildRule,AutoGenReqBuildRuleVerNum
11 from AutoGen.AutoGen import CalculatePriorityValue
12 from Common.Misc import CheckPcdDatum,GuidValue
13 from Common.Expression import ValueExpressionEx
14 from Common.DataType import *
15 from CommonDataClass.Exceptions import *
16 from CommonDataClass.CommonClass import SkuInfoClass
17 import Common.EdkLogger as EdkLogger
18 from Common.BuildToolError import OPTION_CONFLICT,FORMAT_INVALID,RESOURCE_NOT_AVAILABLE
19 from Common.MultipleWorkspace import MultipleWorkspace as mws
20 from collections import defaultdict
21 from Common.Misc import PathClass
22 import os
23
24
25 #
26 # The priority list while override build option
27 #
28 PrioList = {"0x11111" : 16, # TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE (Highest)
29 "0x01111" : 15, # ******_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE
30 "0x10111" : 14, # TARGET_*********_ARCH_COMMANDTYPE_ATTRIBUTE
31 "0x00111" : 13, # ******_*********_ARCH_COMMANDTYPE_ATTRIBUTE
32 "0x11011" : 12, # TARGET_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE
33 "0x01011" : 11, # ******_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE
34 "0x10011" : 10, # TARGET_*********_****_COMMANDTYPE_ATTRIBUTE
35 "0x00011" : 9, # ******_*********_****_COMMANDTYPE_ATTRIBUTE
36 "0x11101" : 8, # TARGET_TOOLCHAIN_ARCH_***********_ATTRIBUTE
37 "0x01101" : 7, # ******_TOOLCHAIN_ARCH_***********_ATTRIBUTE
38 "0x10101" : 6, # TARGET_*********_ARCH_***********_ATTRIBUTE
39 "0x00101" : 5, # ******_*********_ARCH_***********_ATTRIBUTE
40 "0x11001" : 4, # TARGET_TOOLCHAIN_****_***********_ATTRIBUTE
41 "0x01001" : 3, # ******_TOOLCHAIN_****_***********_ATTRIBUTE
42 "0x10001" : 2, # TARGET_*********_****_***********_ATTRIBUTE
43 "0x00001" : 1} # ******_*********_****_***********_ATTRIBUTE (Lowest)
44 ## Base class for AutoGen
45 #
46 # This class just implements the cache mechanism of AutoGen objects.
47 #
48 class AutoGenInfo(object):
49 # database to maintain the objects in each child class
50 __ObjectCache = {} # (BuildTarget, ToolChain, ARCH, platform file): AutoGen object
51
52 ## Factory method
53 #
54 # @param Class class object of real AutoGen class
55 # (WorkspaceAutoGen, ModuleAutoGen or PlatformAutoGen)
56 # @param Workspace Workspace directory or WorkspaceAutoGen object
57 # @param MetaFile The path of meta file
58 # @param Target Build target
59 # @param Toolchain Tool chain name
60 # @param Arch Target arch
61 # @param *args The specific class related parameters
62 # @param **kwargs The specific class related dict parameters
63 #
64 @classmethod
65 def GetCache(cls):
66 return cls.__ObjectCache
67 def __new__(cls, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):
68 # check if the object has been created
69 Key = (Target, Toolchain, Arch, MetaFile)
70 if Key in cls.__ObjectCache:
71 # if it exists, just return it directly
72 return cls.__ObjectCache[Key]
73 # it didnt exist. create it, cache it, then return it
74 RetVal = cls.__ObjectCache[Key] = super(AutoGenInfo, cls).__new__(cls)
75 return RetVal
76
77
78 ## hash() operator
79 #
80 # The file path of platform file will be used to represent hash value of this object
81 #
82 # @retval int Hash value of the file path of platform file
83 #
84 def __hash__(self):
85 return hash(self.MetaFile)
86
87 ## str() operator
88 #
89 # The file path of platform file will be used to represent this object
90 #
91 # @retval string String of platform file path
92 #
93 def __str__(self):
94 return str(self.MetaFile)
95
96 ## "==" operator
97 def __eq__(self, Other):
98 return Other and self.MetaFile == Other
99
100 ## Expand * in build option key
101 #
102 # @param Options Options to be expanded
103 # @param ToolDef Use specified ToolDef instead of full version.
104 # This is needed during initialization to prevent
105 # infinite recursion betweeh BuildOptions,
106 # ToolDefinition, and this function.
107 #
108 # @retval options Options expanded
109 #
110 def _ExpandBuildOption(self, Options, ModuleStyle=None, ToolDef=None):
111 if not ToolDef:
112 ToolDef = self.ToolDefinition
113 BuildOptions = {}
114 FamilyMatch = False
115 FamilyIsNull = True
116
117 OverrideList = {}
118 #
119 # Construct a list contain the build options which need override.
120 #
121 for Key in Options:
122 #
123 # Key[0] -- tool family
124 # Key[1] -- TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE
125 #
126 if (Key[0] == self.BuildRuleFamily and
127 (ModuleStyle is None or len(Key) < 3 or (len(Key) > 2 and Key[2] == ModuleStyle))):
128 Target, ToolChain, Arch, CommandType, Attr = Key[1].split('_')
129 if (Target == self.BuildTarget or Target == TAB_STAR) and\
130 (ToolChain == self.ToolChain or ToolChain == TAB_STAR) and\
131 (Arch == self.Arch or Arch == TAB_STAR) and\
132 Options[Key].startswith("="):
133
134 if OverrideList.get(Key[1]) is not None:
135 OverrideList.pop(Key[1])
136 OverrideList[Key[1]] = Options[Key]
137
138 #
139 # Use the highest priority value.
140 #
141 if (len(OverrideList) >= 2):
142 KeyList = list(OverrideList.keys())
143 for Index in range(len(KeyList)):
144 NowKey = KeyList[Index]
145 Target1, ToolChain1, Arch1, CommandType1, Attr1 = NowKey.split("_")
146 for Index1 in range(len(KeyList) - Index - 1):
147 NextKey = KeyList[Index1 + Index + 1]
148 #
149 # Compare two Key, if one is included by another, choose the higher priority one
150 #
151 Target2, ToolChain2, Arch2, CommandType2, Attr2 = NextKey.split("_")
152 if (Target1 == Target2 or Target1 == TAB_STAR or Target2 == TAB_STAR) and\
153 (ToolChain1 == ToolChain2 or ToolChain1 == TAB_STAR or ToolChain2 == TAB_STAR) and\
154 (Arch1 == Arch2 or Arch1 == TAB_STAR or Arch2 == TAB_STAR) and\
155 (CommandType1 == CommandType2 or CommandType1 == TAB_STAR or CommandType2 == TAB_STAR) and\
156 (Attr1 == Attr2 or Attr1 == TAB_STAR or Attr2 == TAB_STAR):
157
158 if CalculatePriorityValue(NowKey) > CalculatePriorityValue(NextKey):
159 if Options.get((self.BuildRuleFamily, NextKey)) is not None:
160 Options.pop((self.BuildRuleFamily, NextKey))
161 else:
162 if Options.get((self.BuildRuleFamily, NowKey)) is not None:
163 Options.pop((self.BuildRuleFamily, NowKey))
164
165 for Key in Options:
166 if ModuleStyle is not None and len (Key) > 2:
167 # Check Module style is EDK or EDKII.
168 # Only append build option for the matched style module.
169 if ModuleStyle == EDK_NAME and Key[2] != EDK_NAME:
170 continue
171 elif ModuleStyle == EDKII_NAME and Key[2] != EDKII_NAME:
172 continue
173 Family = Key[0]
174 Target, Tag, Arch, Tool, Attr = Key[1].split("_")
175 # if tool chain family doesn't match, skip it
176 if Family != "":
177 Found = False
178 if Tool in ToolDef:
179 FamilyIsNull = False
180 if TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDef[Tool]:
181 if Family == ToolDef[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
182 FamilyMatch = True
183 Found = True
184 if TAB_STAR in ToolDef:
185 FamilyIsNull = False
186 if TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDef[TAB_STAR]:
187 if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
188 FamilyMatch = True
189 Found = True
190 if not Found:
191 continue
192 # expand any wildcard
193 if Target == TAB_STAR or Target == self.BuildTarget:
194 if Tag == TAB_STAR or Tag == self.ToolChain:
195 if Arch == TAB_STAR or Arch == self.Arch:
196 if Tool not in BuildOptions:
197 BuildOptions[Tool] = {}
198 if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or Options[Key].startswith('='):
199 BuildOptions[Tool][Attr] = Options[Key]
200 else:
201 # append options for the same tool except PATH
202 if Attr != 'PATH':
203 BuildOptions[Tool][Attr] += " " + Options[Key]
204 else:
205 BuildOptions[Tool][Attr] = Options[Key]
206 # Build Option Family has been checked, which need't to be checked again for family.
207 if FamilyMatch or FamilyIsNull:
208 return BuildOptions
209
210 for Key in Options:
211 if ModuleStyle is not None and len (Key) > 2:
212 # Check Module style is EDK or EDKII.
213 # Only append build option for the matched style module.
214 if ModuleStyle == EDK_NAME and Key[2] != EDK_NAME:
215 continue
216 elif ModuleStyle == EDKII_NAME and Key[2] != EDKII_NAME:
217 continue
218 Family = Key[0]
219 Target, Tag, Arch, Tool, Attr = Key[1].split("_")
220 # if tool chain family doesn't match, skip it
221 if Family == "":
222 continue
223 # option has been added before
224 Found = False
225 if Tool in ToolDef:
226 if TAB_TOD_DEFINES_FAMILY in ToolDef[Tool]:
227 if Family == ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
228 Found = True
229 if TAB_STAR in ToolDef:
230 if TAB_TOD_DEFINES_FAMILY in ToolDef[TAB_STAR]:
231 if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_FAMILY]:
232 Found = True
233 if not Found:
234 continue
235
236 # expand any wildcard
237 if Target == TAB_STAR or Target == self.BuildTarget:
238 if Tag == TAB_STAR or Tag == self.ToolChain:
239 if Arch == TAB_STAR or Arch == self.Arch:
240 if Tool not in BuildOptions:
241 BuildOptions[Tool] = {}
242 if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or Options[Key].startswith('='):
243 BuildOptions[Tool][Attr] = Options[Key]
244 else:
245 # append options for the same tool except PATH
246 if Attr != 'PATH':
247 BuildOptions[Tool][Attr] += " " + Options[Key]
248 else:
249 BuildOptions[Tool][Attr] = Options[Key]
250 return BuildOptions
251 #
252 #This class is the pruned WorkSpaceAutoGen for ModuleAutoGen in multiple thread
253 #
254 class WorkSpaceInfo(AutoGenInfo):
255 def __init__(self,Workspace, MetaFile, Target, ToolChain, Arch):
256 if not hasattr(self, "_Init"):
257 self.do_init(Workspace, MetaFile, Target, ToolChain, Arch)
258 self._Init = True
259 def do_init(self,Workspace, MetaFile, Target, ToolChain, Arch):
260 self._SrcTimeStamp = 0
261 self.Db = BuildDB
262 self.BuildDatabase = self.Db.BuildObject
263 self.Target = Target
264 self.ToolChain = ToolChain
265 self.WorkspaceDir = Workspace
266 self.ActivePlatform = MetaFile
267 self.ArchList = Arch
268 self.AutoGenObjectList = []
269 @property
270 def BuildDir(self):
271 return self.AutoGenObjectList[0].BuildDir
272
273 @property
274 def Name(self):
275 return self.AutoGenObjectList[0].Platform.PlatformName
276
277 @property
278 def FlashDefinition(self):
279 return self.AutoGenObjectList[0].Platform.FlashDefinition
280 @property
281 def GenFdsCommandDict(self):
282 FdsCommandDict = self.AutoGenObjectList[0].DataPipe.Get("FdsCommandDict")
283 if FdsCommandDict:
284 return FdsCommandDict
285 return {}
286
287 @cached_property
288 def FvDir(self):
289 return os.path.join(self.BuildDir, TAB_FV_DIRECTORY)
290
291 class PlatformInfo(AutoGenInfo):
292 def __init__(self, Workspace, MetaFile, Target, ToolChain, Arch,DataPipe):
293 if not hasattr(self, "_Init"):
294 self.do_init(Workspace, MetaFile, Target, ToolChain, Arch,DataPipe)
295 self._Init = True
296 def do_init(self,Workspace, MetaFile, Target, ToolChain, Arch,DataPipe):
297 self.Wa = Workspace
298 self.WorkspaceDir = self.Wa.WorkspaceDir
299 self.MetaFile = MetaFile
300 self.Arch = Arch
301 self.Target = Target
302 self.BuildTarget = Target
303 self.ToolChain = ToolChain
304 self.Platform = self.Wa.BuildDatabase[self.MetaFile, self.Arch, self.Target, self.ToolChain]
305
306 self.SourceDir = MetaFile.SubDir
307 self.DataPipe = DataPipe
308 @cached_property
309 def _AsBuildModuleList(self):
310 retVal = self.DataPipe.Get("AsBuildModuleList")
311 if retVal is None:
312 retVal = {}
313 return retVal
314
315 ## Test if a module is supported by the platform
316 #
317 # An error will be raised directly if the module or its arch is not supported
318 # by the platform or current configuration
319 #
320 def ValidModule(self, Module):
321 return Module in self.Platform.Modules or Module in self.Platform.LibraryInstances \
322 or Module in self._AsBuildModuleList
323
324 @cached_property
325 def ToolChainFamily(self):
326 retVal = self.DataPipe.Get("ToolChainFamily")
327 if retVal is None:
328 retVal = {}
329 return retVal
330
331 @cached_property
332 def BuildRuleFamily(self):
333 retVal = self.DataPipe.Get("BuildRuleFamily")
334 if retVal is None:
335 retVal = {}
336 return retVal
337
338 @cached_property
339 def _MbList(self):
340 return [self.Wa.BuildDatabase[m, self.Arch, self.BuildTarget, self.ToolChain] for m in self.Platform.Modules]
341
342 @cached_property
343 def PackageList(self):
344 RetVal = set()
345 for dec_file,Arch in self.DataPipe.Get("PackageList"):
346 RetVal.add(self.Wa.BuildDatabase[dec_file,Arch,self.BuildTarget, self.ToolChain])
347 return list(RetVal)
348
349 ## Return the directory to store all intermediate and final files built
350 @cached_property
351 def BuildDir(self):
352 if os.path.isabs(self.OutputDir):
353 RetVal = os.path.join(
354 os.path.abspath(self.OutputDir),
355 self.Target + "_" + self.ToolChain,
356 )
357 else:
358 RetVal = os.path.join(
359 self.WorkspaceDir,
360 self.OutputDir,
361 self.Target + "_" + self.ToolChain,
362 )
363 return RetVal
364
365 ## Return the build output directory platform specifies
366 @cached_property
367 def OutputDir(self):
368 return self.Platform.OutputDirectory
369
370 ## Return platform name
371 @cached_property
372 def Name(self):
373 return self.Platform.PlatformName
374
375 ## Return meta-file GUID
376 @cached_property
377 def Guid(self):
378 return self.Platform.Guid
379
380 ## Return platform version
381 @cached_property
382 def Version(self):
383 return self.Platform.Version
384
385 ## Return paths of tools
386 @cached_property
387 def ToolDefinition(self):
388 retVal = self.DataPipe.Get("TOOLDEF")
389 if retVal is None:
390 retVal = {}
391 return retVal
392
393 ## Return build command string
394 #
395 # @retval string Build command string
396 #
397 @cached_property
398 def BuildCommand(self):
399 retVal = self.DataPipe.Get("BuildCommand")
400 if retVal is None:
401 retVal = []
402 return retVal
403
404 @cached_property
405 def PcdTokenNumber(self):
406 retVal = self.DataPipe.Get("PCD_TNUM")
407 if retVal is None:
408 retVal = {}
409 return retVal
410
411 ## Override PCD setting (type, value, ...)
412 #
413 # @param ToPcd The PCD to be overridden
414 # @param FromPcd The PCD overriding from
415 #
416 def _OverridePcd(self, ToPcd, FromPcd, Module="", Msg="", Library=""):
417 #
418 # in case there's PCDs coming from FDF file, which have no type given.
419 # at this point, ToPcd.Type has the type found from dependent
420 # package
421 #
422 TokenCName = ToPcd.TokenCName
423 for PcdItem in self.MixedPcd:
424 if (ToPcd.TokenCName, ToPcd.TokenSpaceGuidCName) in self.MixedPcd[PcdItem]:
425 TokenCName = PcdItem[0]
426 break
427 if FromPcd is not None:
428 if ToPcd.Pending and FromPcd.Type:
429 ToPcd.Type = FromPcd.Type
430 elif ToPcd.Type and FromPcd.Type\
431 and ToPcd.Type != FromPcd.Type and ToPcd.Type in FromPcd.Type:
432 if ToPcd.Type.strip() == TAB_PCDS_DYNAMIC_EX:
433 ToPcd.Type = FromPcd.Type
434 elif ToPcd.Type and FromPcd.Type \
435 and ToPcd.Type != FromPcd.Type:
436 if Library:
437 Module = str(Module) + " 's library file (" + str(Library) + ")"
438 EdkLogger.error("build", OPTION_CONFLICT, "Mismatched PCD type",
439 ExtraData="%s.%s is used as [%s] in module %s, but as [%s] in %s."\
440 % (ToPcd.TokenSpaceGuidCName, TokenCName,
441 ToPcd.Type, Module, FromPcd.Type, Msg),
442 File=self.MetaFile)
443
444 if FromPcd.MaxDatumSize:
445 ToPcd.MaxDatumSize = FromPcd.MaxDatumSize
446 ToPcd.MaxSizeUserSet = FromPcd.MaxDatumSize
447 if FromPcd.DefaultValue:
448 ToPcd.DefaultValue = FromPcd.DefaultValue
449 if FromPcd.TokenValue:
450 ToPcd.TokenValue = FromPcd.TokenValue
451 if FromPcd.DatumType:
452 ToPcd.DatumType = FromPcd.DatumType
453 if FromPcd.SkuInfoList:
454 ToPcd.SkuInfoList = FromPcd.SkuInfoList
455 if FromPcd.UserDefinedDefaultStoresFlag:
456 ToPcd.UserDefinedDefaultStoresFlag = FromPcd.UserDefinedDefaultStoresFlag
457 # Add Flexible PCD format parse
458 if ToPcd.DefaultValue:
459 try:
460 ToPcd.DefaultValue = ValueExpressionEx(ToPcd.DefaultValue, ToPcd.DatumType, self._GuidDict)(True)
461 except BadExpression as Value:
462 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %(ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName, ToPcd.DefaultValue, Value),
463 File=self.MetaFile)
464
465 # check the validation of datum
466 IsValid, Cause = CheckPcdDatum(ToPcd.DatumType, ToPcd.DefaultValue)
467 if not IsValid:
468 EdkLogger.error('build', FORMAT_INVALID, Cause, File=self.MetaFile,
469 ExtraData="%s.%s" % (ToPcd.TokenSpaceGuidCName, TokenCName))
470 ToPcd.validateranges = FromPcd.validateranges
471 ToPcd.validlists = FromPcd.validlists
472 ToPcd.expressions = FromPcd.expressions
473 ToPcd.CustomAttribute = FromPcd.CustomAttribute
474
475 if FromPcd is not None and ToPcd.DatumType == TAB_VOID and not ToPcd.MaxDatumSize:
476 EdkLogger.debug(EdkLogger.DEBUG_9, "No MaxDatumSize specified for PCD %s.%s" \
477 % (ToPcd.TokenSpaceGuidCName, TokenCName))
478 Value = ToPcd.DefaultValue
479 if not Value:
480 ToPcd.MaxDatumSize = '1'
481 elif Value[0] == 'L':
482 ToPcd.MaxDatumSize = str((len(Value) - 2) * 2)
483 elif Value[0] == '{':
484 ToPcd.MaxDatumSize = str(len(Value.split(',')))
485 else:
486 ToPcd.MaxDatumSize = str(len(Value) - 1)
487
488 # apply default SKU for dynamic PCDS if specified one is not available
489 if (ToPcd.Type in PCD_DYNAMIC_TYPE_SET or ToPcd.Type in PCD_DYNAMIC_EX_TYPE_SET) \
490 and not ToPcd.SkuInfoList:
491 if self.Platform.SkuName in self.Platform.SkuIds:
492 SkuName = self.Platform.SkuName
493 else:
494 SkuName = TAB_DEFAULT
495 ToPcd.SkuInfoList = {
496 SkuName : SkuInfoClass(SkuName, self.Platform.SkuIds[SkuName][0], '', '', '', '', '', ToPcd.DefaultValue)
497 }
498
499 def ApplyPcdSetting(self, Ma, Pcds, Library=""):
500 # for each PCD in module
501 Module=Ma.Module
502 for Name, Guid in Pcds:
503 PcdInModule = Pcds[Name, Guid]
504 # find out the PCD setting in platform
505 if (Name, Guid) in self.Pcds:
506 PcdInPlatform = self.Pcds[Name, Guid]
507 else:
508 PcdInPlatform = None
509 # then override the settings if any
510 self._OverridePcd(PcdInModule, PcdInPlatform, Module, Msg="DSC PCD sections", Library=Library)
511 # resolve the VariableGuid value
512 for SkuId in PcdInModule.SkuInfoList:
513 Sku = PcdInModule.SkuInfoList[SkuId]
514 if Sku.VariableGuid == '': continue
515 Sku.VariableGuidValue = GuidValue(Sku.VariableGuid, self.PackageList, self.MetaFile.Path)
516 if Sku.VariableGuidValue is None:
517 PackageList = "\n\t".join(str(P) for P in self.PackageList)
518 EdkLogger.error(
519 'build',
520 RESOURCE_NOT_AVAILABLE,
521 "Value of GUID [%s] is not found in" % Sku.VariableGuid,
522 ExtraData=PackageList + "\n\t(used with %s.%s from module %s)" \
523 % (Guid, Name, str(Module)),
524 File=self.MetaFile
525 )
526
527 # override PCD settings with module specific setting
528 ModuleScopePcds = self.DataPipe.Get("MOL_PCDS")
529 if Module in self.Platform.Modules:
530 PlatformModule = self.Platform.Modules[str(Module)]
531 PCD_DATA = ModuleScopePcds.get(Ma.Guid,{})
532 mPcds = {(pcd.TokenCName,pcd.TokenSpaceGuidCName): pcd for pcd in PCD_DATA}
533 for Key in mPcds:
534 if self.BuildOptionPcd:
535 for pcd in self.BuildOptionPcd:
536 (TokenSpaceGuidCName, TokenCName, FieldName, pcdvalue, _) = pcd
537 if (TokenCName, TokenSpaceGuidCName) == Key and FieldName =="":
538 PlatformModule.Pcds[Key].DefaultValue = pcdvalue
539 PlatformModule.Pcds[Key].PcdValueFromComm = pcdvalue
540 break
541 Flag = False
542 if Key in Pcds:
543 ToPcd = Pcds[Key]
544 Flag = True
545 elif Key in self.MixedPcd:
546 for PcdItem in self.MixedPcd[Key]:
547 if PcdItem in Pcds:
548 ToPcd = Pcds[PcdItem]
549 Flag = True
550 break
551 if Flag:
552 self._OverridePcd(ToPcd, mPcds[Key], Module, Msg="DSC Components Module scoped PCD section", Library=Library)
553 # use PCD value to calculate the MaxDatumSize when it is not specified
554 for Name, Guid in Pcds:
555 Pcd = Pcds[Name, Guid]
556 if Pcd.DatumType == TAB_VOID and not Pcd.MaxDatumSize:
557 Pcd.MaxSizeUserSet = None
558 Value = Pcd.DefaultValue
559 if not Value:
560 Pcd.MaxDatumSize = '1'
561 elif Value[0] == 'L':
562 Pcd.MaxDatumSize = str((len(Value) - 2) * 2)
563 elif Value[0] == '{':
564 Pcd.MaxDatumSize = str(len(Value.split(',')))
565 else:
566 Pcd.MaxDatumSize = str(len(Value) - 1)
567 return list(Pcds.values())
568
569 @cached_property
570 def Pcds(self):
571 PlatformPcdData = self.DataPipe.Get("PLA_PCD")
572 # for pcd in PlatformPcdData:
573 # for skuid in pcd.SkuInfoList:
574 # pcd.SkuInfoList[skuid] = self.CreateSkuInfoFromDict(pcd.SkuInfoList[skuid])
575 return {(pcddata.TokenCName,pcddata.TokenSpaceGuidCName):pcddata for pcddata in PlatformPcdData}
576
577 def CreateSkuInfoFromDict(self,SkuInfoDict):
578 return SkuInfoClass(
579 SkuInfoDict.get("SkuIdName"),
580 SkuInfoDict.get("SkuId"),
581 SkuInfoDict.get("VariableName"),
582 SkuInfoDict.get("VariableGuid"),
583 SkuInfoDict.get("VariableOffset"),
584 SkuInfoDict.get("HiiDefaultValue"),
585 SkuInfoDict.get("VpdOffset"),
586 SkuInfoDict.get("DefaultValue"),
587 SkuInfoDict.get("VariableGuidValue"),
588 SkuInfoDict.get("VariableAttribute",""),
589 SkuInfoDict.get("DefaultStore",None)
590 )
591 @cached_property
592 def MixedPcd(self):
593 return self.DataPipe.Get("MixedPcd")
594 @cached_property
595 def _GuidDict(self):
596 RetVal = self.DataPipe.Get("GuidDict")
597 if RetVal is None:
598 RetVal = {}
599 return RetVal
600 @cached_property
601 def BuildOptionPcd(self):
602 return self.DataPipe.Get("BuildOptPcd")
603 def ApplyBuildOption(self,module):
604 PlatformOptions = self.DataPipe.Get("PLA_BO")
605 ModuleBuildOptions = self.DataPipe.Get("MOL_BO")
606 ModuleOptionFromDsc = ModuleBuildOptions.get((module.MetaFile.File,module.MetaFile.Root))
607 if ModuleOptionFromDsc:
608 ModuleTypeOptions, PlatformModuleOptions = ModuleOptionFromDsc["ModuleTypeOptions"],ModuleOptionFromDsc["PlatformModuleOptions"]
609 else:
610 ModuleTypeOptions, PlatformModuleOptions = {}, {}
611 ToolDefinition = self.DataPipe.Get("TOOLDEF")
612 ModuleOptions = self._ExpandBuildOption(module.BuildOptions)
613 BuildRuleOrder = None
614 for Options in [ToolDefinition, ModuleOptions, PlatformOptions, ModuleTypeOptions, PlatformModuleOptions]:
615 for Tool in Options:
616 for Attr in Options[Tool]:
617 if Attr == TAB_TOD_DEFINES_BUILDRULEORDER:
618 BuildRuleOrder = Options[Tool][Attr]
619
620 AllTools = set(list(ModuleOptions.keys()) + list(PlatformOptions.keys()) +
621 list(PlatformModuleOptions.keys()) + list(ModuleTypeOptions.keys()) +
622 list(ToolDefinition.keys()))
623 BuildOptions = defaultdict(lambda: defaultdict(str))
624 for Tool in AllTools:
625 for Options in [ToolDefinition, ModuleOptions, PlatformOptions, ModuleTypeOptions, PlatformModuleOptions]:
626 if Tool not in Options:
627 continue
628 for Attr in Options[Tool]:
629 #
630 # Do not generate it in Makefile
631 #
632 if Attr == TAB_TOD_DEFINES_BUILDRULEORDER:
633 continue
634 Value = Options[Tool][Attr]
635 ToolList = [Tool]
636 if Tool == TAB_STAR:
637 ToolList = list(AllTools)
638 ToolList.remove(TAB_STAR)
639 for ExpandedTool in ToolList:
640 # check if override is indicated
641 if Value.startswith('='):
642 BuildOptions[ExpandedTool][Attr] = mws.handleWsMacro(Value[1:])
643 else:
644 if Attr != 'PATH':
645 BuildOptions[ExpandedTool][Attr] += " " + mws.handleWsMacro(Value)
646 else:
647 BuildOptions[ExpandedTool][Attr] = mws.handleWsMacro(Value)
648
649 return BuildOptions, BuildRuleOrder
650
651 def ApplyLibraryInstance(self,module):
652 alldeps = self.DataPipe.Get("DEPS")
653 if alldeps is None:
654 alldeps = {}
655 mod_libs = alldeps.get((module.MetaFile.File,module.MetaFile.Root,module.Arch,module.MetaFile.Path),[])
656 retVal = []
657 for (file_path,root,arch,abs_path) in mod_libs:
658 libMetaFile = PathClass(file_path,root)
659 libMetaFile.OriginalPath = PathClass(file_path,root)
660 libMetaFile.Path = abs_path
661 retVal.append(self.Wa.BuildDatabase[libMetaFile, arch, self.Target,self.ToolChain])
662 return retVal
663
664 ## Parse build_rule.txt in Conf Directory.
665 #
666 # @retval BuildRule object
667 #
668 @cached_property
669 def BuildRule(self):
670 WInfo = self.DataPipe.Get("P_Info")
671 RetVal = WInfo.get("BuildRuleFile")
672 if RetVal._FileVersion == "":
673 RetVal._FileVersion = AutoGenReqBuildRuleVerNum
674 return RetVal