2 # Create makefile for MS nmake and GNU make
4 # Copyright (c) 2019 - 2021, Intel Corporation. All rights reserved.<BR>
5 # SPDX-License-Identifier: BSD-2-Clause-Patent
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
26 # The priority list while override build option
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
46 # This class just implements the cache mechanism of AutoGen objects.
48 class AutoGenInfo(object):
49 # database to maintain the objects in each child class
50 __ObjectCache
= {} # (BuildTarget, ToolChain, ARCH, platform file): AutoGen object
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
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
)
80 # The file path of platform file will be used to represent hash value of this object
82 # @retval int Hash value of the file path of platform file
85 return hash(self
.MetaFile
)
89 # The file path of platform file will be used to represent this object
91 # @retval string String of platform file path
94 return str(self
.MetaFile
)
97 def __eq__(self
, Other
):
98 return Other
and self
.MetaFile
== Other
100 ## Expand * in build option key
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.
108 # @retval options Options expanded
110 def _ExpandBuildOption(self
, Options
, ModuleStyle
=None, ToolDef
=None):
112 ToolDef
= self
.ToolDefinition
119 # Construct a list contain the build options which need override.
123 # Key[0] -- tool family
124 # Key[1] -- TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE
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("="):
134 if OverrideList
.get(Key
[1]) is not None:
135 OverrideList
.pop(Key
[1])
136 OverrideList
[Key
[1]] = Options
[Key
]
139 # Use the highest priority value.
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]
149 # Compare two Key, if one is included by another, choose the higher priority one
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
):
158 if CalculatePriorityValue(NowKey
) > CalculatePriorityValue(NextKey
):
159 if Options
.get((self
.BuildRuleFamily
, NextKey
)) is not None:
160 Options
.pop((self
.BuildRuleFamily
, NextKey
))
162 if Options
.get((self
.BuildRuleFamily
, NowKey
)) is not None:
163 Options
.pop((self
.BuildRuleFamily
, NowKey
))
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
:
171 elif ModuleStyle
== EDKII_NAME
and Key
[2] != EDKII_NAME
:
174 Target
, Tag
, Arch
, Tool
, Attr
= Key
[1].split("_")
175 # if tool chain family doesn't match, skip it
176 if Tool
in ToolDef
and Family
!= "":
178 if ToolDef
[Tool
].get(TAB_TOD_DEFINES_BUILDRULEFAMILY
, "") != "":
179 if Family
!= ToolDef
[Tool
][TAB_TOD_DEFINES_BUILDRULEFAMILY
]:
182 if ToolDef
[Tool
].get(TAB_TOD_DEFINES_FAMILY
, "") == "":
184 if Family
!= ToolDef
[Tool
][TAB_TOD_DEFINES_FAMILY
]:
187 # expand any wildcard
188 if Target
== TAB_STAR
or Target
== self
.BuildTarget
:
189 if Tag
== TAB_STAR
or Tag
== self
.ToolChain
:
190 if Arch
== TAB_STAR
or Arch
== self
.Arch
:
191 if Tool
not in BuildOptions
:
192 BuildOptions
[Tool
] = {}
193 if Attr
!= "FLAGS" or Attr
not in BuildOptions
[Tool
] or Options
[Key
].startswith('='):
194 BuildOptions
[Tool
][Attr
] = Options
[Key
]
196 # append options for the same tool except PATH
198 BuildOptions
[Tool
][Attr
] += " " + Options
[Key
]
200 BuildOptions
[Tool
][Attr
] = Options
[Key
]
201 # Build Option Family has been checked, which need't to be checked again for family.
202 if FamilyMatch
or FamilyIsNull
:
206 if ModuleStyle
is not None and len (Key
) > 2:
207 # Check Module style is EDK or EDKII.
208 # Only append build option for the matched style module.
209 if ModuleStyle
== EDK_NAME
and Key
[2] != EDK_NAME
:
211 elif ModuleStyle
== EDKII_NAME
and Key
[2] != EDKII_NAME
:
214 Target
, Tag
, Arch
, Tool
, Attr
= Key
[1].split("_")
215 # if tool chain family doesn't match, skip it
216 if Tool
not in ToolDef
or Family
== "":
218 # option has been added before
219 if TAB_TOD_DEFINES_FAMILY
not in ToolDef
[Tool
]:
221 if Family
!= ToolDef
[Tool
][TAB_TOD_DEFINES_FAMILY
]:
224 # expand any wildcard
225 if Target
== TAB_STAR
or Target
== self
.BuildTarget
:
226 if Tag
== TAB_STAR
or Tag
== self
.ToolChain
:
227 if Arch
== TAB_STAR
or Arch
== self
.Arch
:
228 if Tool
not in BuildOptions
:
229 BuildOptions
[Tool
] = {}
230 if Attr
!= "FLAGS" or Attr
not in BuildOptions
[Tool
] or Options
[Key
].startswith('='):
231 BuildOptions
[Tool
][Attr
] = Options
[Key
]
233 # append options for the same tool except PATH
235 BuildOptions
[Tool
][Attr
] += " " + Options
[Key
]
237 BuildOptions
[Tool
][Attr
] = Options
[Key
]
240 #This class is the pruned WorkSpaceAutoGen for ModuleAutoGen in multiple thread
242 class WorkSpaceInfo(AutoGenInfo
):
243 def __init__(self
,Workspace
, MetaFile
, Target
, ToolChain
, Arch
):
244 if not hasattr(self
, "_Init"):
245 self
.do_init(Workspace
, MetaFile
, Target
, ToolChain
, Arch
)
247 def do_init(self
,Workspace
, MetaFile
, Target
, ToolChain
, Arch
):
248 self
._SrcTimeStamp
= 0
250 self
.BuildDatabase
= self
.Db
.BuildObject
252 self
.ToolChain
= ToolChain
253 self
.WorkspaceDir
= Workspace
254 self
.ActivePlatform
= MetaFile
256 self
.AutoGenObjectList
= []
259 return self
.AutoGenObjectList
[0].BuildDir
263 return self
.AutoGenObjectList
[0].Platform
.PlatformName
266 def FlashDefinition(self
):
267 return self
.AutoGenObjectList
[0].Platform
.FlashDefinition
269 def GenFdsCommandDict(self
):
270 FdsCommandDict
= self
.AutoGenObjectList
[0].DataPipe
.Get("FdsCommandDict")
272 return FdsCommandDict
277 return os
.path
.join(self
.BuildDir
, TAB_FV_DIRECTORY
)
279 class PlatformInfo(AutoGenInfo
):
280 def __init__(self
, Workspace
, MetaFile
, Target
, ToolChain
, Arch
,DataPipe
):
281 if not hasattr(self
, "_Init"):
282 self
.do_init(Workspace
, MetaFile
, Target
, ToolChain
, Arch
,DataPipe
)
284 def do_init(self
,Workspace
, MetaFile
, Target
, ToolChain
, Arch
,DataPipe
):
286 self
.WorkspaceDir
= self
.Wa
.WorkspaceDir
287 self
.MetaFile
= MetaFile
290 self
.BuildTarget
= Target
291 self
.ToolChain
= ToolChain
292 self
.Platform
= self
.Wa
.BuildDatabase
[self
.MetaFile
, self
.Arch
, self
.Target
, self
.ToolChain
]
294 self
.SourceDir
= MetaFile
.SubDir
295 self
.DataPipe
= DataPipe
297 def _AsBuildModuleList(self
):
298 retVal
= self
.DataPipe
.Get("AsBuildModuleList")
303 ## Test if a module is supported by the platform
305 # An error will be raised directly if the module or its arch is not supported
306 # by the platform or current configuration
308 def ValidModule(self
, Module
):
309 return Module
in self
.Platform
.Modules
or Module
in self
.Platform
.LibraryInstances \
310 or Module
in self
._AsBuildModuleList
313 def ToolChainFamily(self
):
314 retVal
= self
.DataPipe
.Get("ToolChainFamily")
320 def BuildRuleFamily(self
):
321 retVal
= self
.DataPipe
.Get("BuildRuleFamily")
328 return [self
.Wa
.BuildDatabase
[m
, self
.Arch
, self
.BuildTarget
, self
.ToolChain
] for m
in self
.Platform
.Modules
]
331 def PackageList(self
):
333 for dec_file
,Arch
in self
.DataPipe
.Get("PackageList"):
334 RetVal
.add(self
.Wa
.BuildDatabase
[dec_file
,Arch
,self
.BuildTarget
, self
.ToolChain
])
337 ## Return the directory to store all intermediate and final files built
340 if os
.path
.isabs(self
.OutputDir
):
341 RetVal
= os
.path
.join(
342 os
.path
.abspath(self
.OutputDir
),
343 self
.Target
+ "_" + self
.ToolChain
,
346 RetVal
= os
.path
.join(
349 self
.Target
+ "_" + self
.ToolChain
,
353 ## Return the build output directory platform specifies
356 return self
.Platform
.OutputDirectory
358 ## Return platform name
361 return self
.Platform
.PlatformName
363 ## Return meta-file GUID
366 return self
.Platform
.Guid
368 ## Return platform version
371 return self
.Platform
.Version
373 ## Return paths of tools
375 def ToolDefinition(self
):
376 retVal
= self
.DataPipe
.Get("TOOLDEF")
381 ## Return build command string
383 # @retval string Build command string
386 def BuildCommand(self
):
387 retVal
= self
.DataPipe
.Get("BuildCommand")
393 def PcdTokenNumber(self
):
394 retVal
= self
.DataPipe
.Get("PCD_TNUM")
399 ## Override PCD setting (type, value, ...)
401 # @param ToPcd The PCD to be overridden
402 # @param FromPcd The PCD overriding from
404 def _OverridePcd(self
, ToPcd
, FromPcd
, Module
="", Msg
="", Library
=""):
406 # in case there's PCDs coming from FDF file, which have no type given.
407 # at this point, ToPcd.Type has the type found from dependent
410 TokenCName
= ToPcd
.TokenCName
411 for PcdItem
in self
.MixedPcd
:
412 if (ToPcd
.TokenCName
, ToPcd
.TokenSpaceGuidCName
) in self
.MixedPcd
[PcdItem
]:
413 TokenCName
= PcdItem
[0]
415 if FromPcd
is not None:
416 if ToPcd
.Pending
and FromPcd
.Type
:
417 ToPcd
.Type
= FromPcd
.Type
418 elif ToPcd
.Type
and FromPcd
.Type\
419 and ToPcd
.Type
!= FromPcd
.Type
and ToPcd
.Type
in FromPcd
.Type
:
420 if ToPcd
.Type
.strip() == TAB_PCDS_DYNAMIC_EX
:
421 ToPcd
.Type
= FromPcd
.Type
422 elif ToPcd
.Type
and FromPcd
.Type \
423 and ToPcd
.Type
!= FromPcd
.Type
:
425 Module
= str(Module
) + " 's library file (" + str(Library
) + ")"
426 EdkLogger
.error("build", OPTION_CONFLICT
, "Mismatched PCD type",
427 ExtraData
="%s.%s is used as [%s] in module %s, but as [%s] in %s."\
428 % (ToPcd
.TokenSpaceGuidCName
, TokenCName
,
429 ToPcd
.Type
, Module
, FromPcd
.Type
, Msg
),
432 if FromPcd
.MaxDatumSize
:
433 ToPcd
.MaxDatumSize
= FromPcd
.MaxDatumSize
434 ToPcd
.MaxSizeUserSet
= FromPcd
.MaxDatumSize
435 if FromPcd
.DefaultValue
:
436 ToPcd
.DefaultValue
= FromPcd
.DefaultValue
437 if FromPcd
.TokenValue
:
438 ToPcd
.TokenValue
= FromPcd
.TokenValue
439 if FromPcd
.DatumType
:
440 ToPcd
.DatumType
= FromPcd
.DatumType
441 if FromPcd
.SkuInfoList
:
442 ToPcd
.SkuInfoList
= FromPcd
.SkuInfoList
443 if FromPcd
.UserDefinedDefaultStoresFlag
:
444 ToPcd
.UserDefinedDefaultStoresFlag
= FromPcd
.UserDefinedDefaultStoresFlag
445 # Add Flexible PCD format parse
446 if ToPcd
.DefaultValue
:
448 ToPcd
.DefaultValue
= ValueExpressionEx(ToPcd
.DefaultValue
, ToPcd
.DatumType
, self
._GuidDict
)(True)
449 except BadExpression
as Value
:
450 EdkLogger
.error('Parser', FORMAT_INVALID
, 'PCD [%s.%s] Value "%s", %s' %(ToPcd
.TokenSpaceGuidCName
, ToPcd
.TokenCName
, ToPcd
.DefaultValue
, Value
),
453 # check the validation of datum
454 IsValid
, Cause
= CheckPcdDatum(ToPcd
.DatumType
, ToPcd
.DefaultValue
)
456 EdkLogger
.error('build', FORMAT_INVALID
, Cause
, File
=self
.MetaFile
,
457 ExtraData
="%s.%s" % (ToPcd
.TokenSpaceGuidCName
, TokenCName
))
458 ToPcd
.validateranges
= FromPcd
.validateranges
459 ToPcd
.validlists
= FromPcd
.validlists
460 ToPcd
.expressions
= FromPcd
.expressions
461 ToPcd
.CustomAttribute
= FromPcd
.CustomAttribute
463 if FromPcd
is not None and ToPcd
.DatumType
== TAB_VOID
and not ToPcd
.MaxDatumSize
:
464 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "No MaxDatumSize specified for PCD %s.%s" \
465 % (ToPcd
.TokenSpaceGuidCName
, TokenCName
))
466 Value
= ToPcd
.DefaultValue
468 ToPcd
.MaxDatumSize
= '1'
469 elif Value
[0] == 'L':
470 ToPcd
.MaxDatumSize
= str((len(Value
) - 2) * 2)
471 elif Value
[0] == '{':
472 ToPcd
.MaxDatumSize
= str(len(Value
.split(',')))
474 ToPcd
.MaxDatumSize
= str(len(Value
) - 1)
476 # apply default SKU for dynamic PCDS if specified one is not available
477 if (ToPcd
.Type
in PCD_DYNAMIC_TYPE_SET
or ToPcd
.Type
in PCD_DYNAMIC_EX_TYPE_SET
) \
478 and not ToPcd
.SkuInfoList
:
479 if self
.Platform
.SkuName
in self
.Platform
.SkuIds
:
480 SkuName
= self
.Platform
.SkuName
482 SkuName
= TAB_DEFAULT
483 ToPcd
.SkuInfoList
= {
484 SkuName
: SkuInfoClass(SkuName
, self
.Platform
.SkuIds
[SkuName
][0], '', '', '', '', '', ToPcd
.DefaultValue
)
487 def ApplyPcdSetting(self
, Ma
, Pcds
, Library
=""):
488 # for each PCD in module
490 for Name
, Guid
in Pcds
:
491 PcdInModule
= Pcds
[Name
, Guid
]
492 # find out the PCD setting in platform
493 if (Name
, Guid
) in self
.Pcds
:
494 PcdInPlatform
= self
.Pcds
[Name
, Guid
]
497 # then override the settings if any
498 self
._OverridePcd
(PcdInModule
, PcdInPlatform
, Module
, Msg
="DSC PCD sections", Library
=Library
)
499 # resolve the VariableGuid value
500 for SkuId
in PcdInModule
.SkuInfoList
:
501 Sku
= PcdInModule
.SkuInfoList
[SkuId
]
502 if Sku
.VariableGuid
== '': continue
503 Sku
.VariableGuidValue
= GuidValue(Sku
.VariableGuid
, self
.PackageList
, self
.MetaFile
.Path
)
504 if Sku
.VariableGuidValue
is None:
505 PackageList
= "\n\t".join(str(P
) for P
in self
.PackageList
)
508 RESOURCE_NOT_AVAILABLE
,
509 "Value of GUID [%s] is not found in" % Sku
.VariableGuid
,
510 ExtraData
=PackageList
+ "\n\t(used with %s.%s from module %s)" \
511 % (Guid
, Name
, str(Module
)),
515 # override PCD settings with module specific setting
516 ModuleScopePcds
= self
.DataPipe
.Get("MOL_PCDS")
517 if Module
in self
.Platform
.Modules
:
518 PlatformModule
= self
.Platform
.Modules
[str(Module
)]
519 PCD_DATA
= ModuleScopePcds
.get(Ma
.Guid
,{})
520 mPcds
= {(pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
): pcd
for pcd
in PCD_DATA
}
522 if self
.BuildOptionPcd
:
523 for pcd
in self
.BuildOptionPcd
:
524 (TokenSpaceGuidCName
, TokenCName
, FieldName
, pcdvalue
, _
) = pcd
525 if (TokenCName
, TokenSpaceGuidCName
) == Key
and FieldName
=="":
526 PlatformModule
.Pcds
[Key
].DefaultValue
= pcdvalue
527 PlatformModule
.Pcds
[Key
].PcdValueFromComm
= pcdvalue
533 elif Key
in self
.MixedPcd
:
534 for PcdItem
in self
.MixedPcd
[Key
]:
536 ToPcd
= Pcds
[PcdItem
]
540 self
._OverridePcd
(ToPcd
, mPcds
[Key
], Module
, Msg
="DSC Components Module scoped PCD section", Library
=Library
)
541 # use PCD value to calculate the MaxDatumSize when it is not specified
542 for Name
, Guid
in Pcds
:
543 Pcd
= Pcds
[Name
, Guid
]
544 if Pcd
.DatumType
== TAB_VOID
and not Pcd
.MaxDatumSize
:
545 Pcd
.MaxSizeUserSet
= None
546 Value
= Pcd
.DefaultValue
548 Pcd
.MaxDatumSize
= '1'
549 elif Value
[0] == 'L':
550 Pcd
.MaxDatumSize
= str((len(Value
) - 2) * 2)
551 elif Value
[0] == '{':
552 Pcd
.MaxDatumSize
= str(len(Value
.split(',')))
554 Pcd
.MaxDatumSize
= str(len(Value
) - 1)
555 return list(Pcds
.values())
559 PlatformPcdData
= self
.DataPipe
.Get("PLA_PCD")
560 # for pcd in PlatformPcdData:
561 # for skuid in pcd.SkuInfoList:
562 # pcd.SkuInfoList[skuid] = self.CreateSkuInfoFromDict(pcd.SkuInfoList[skuid])
563 return {(pcddata
.TokenCName
,pcddata
.TokenSpaceGuidCName
):pcddata
for pcddata
in PlatformPcdData
}
565 def CreateSkuInfoFromDict(self
,SkuInfoDict
):
567 SkuInfoDict
.get("SkuIdName"),
568 SkuInfoDict
.get("SkuId"),
569 SkuInfoDict
.get("VariableName"),
570 SkuInfoDict
.get("VariableGuid"),
571 SkuInfoDict
.get("VariableOffset"),
572 SkuInfoDict
.get("HiiDefaultValue"),
573 SkuInfoDict
.get("VpdOffset"),
574 SkuInfoDict
.get("DefaultValue"),
575 SkuInfoDict
.get("VariableGuidValue"),
576 SkuInfoDict
.get("VariableAttribute",""),
577 SkuInfoDict
.get("DefaultStore",None)
581 return self
.DataPipe
.Get("MixedPcd")
584 RetVal
= self
.DataPipe
.Get("GuidDict")
589 def BuildOptionPcd(self
):
590 return self
.DataPipe
.Get("BuildOptPcd")
591 def ApplyBuildOption(self
,module
):
592 PlatformOptions
= self
.DataPipe
.Get("PLA_BO")
593 ModuleBuildOptions
= self
.DataPipe
.Get("MOL_BO")
594 ModuleOptionFromDsc
= ModuleBuildOptions
.get((module
.MetaFile
.File
,module
.MetaFile
.Root
))
595 if ModuleOptionFromDsc
:
596 ModuleTypeOptions
, PlatformModuleOptions
= ModuleOptionFromDsc
["ModuleTypeOptions"],ModuleOptionFromDsc
["PlatformModuleOptions"]
598 ModuleTypeOptions
, PlatformModuleOptions
= {}, {}
599 ToolDefinition
= self
.DataPipe
.Get("TOOLDEF")
600 ModuleOptions
= self
._ExpandBuildOption
(module
.BuildOptions
)
601 BuildRuleOrder
= None
602 for Options
in [ToolDefinition
, ModuleOptions
, PlatformOptions
, ModuleTypeOptions
, PlatformModuleOptions
]:
604 for Attr
in Options
[Tool
]:
605 if Attr
== TAB_TOD_DEFINES_BUILDRULEORDER
:
606 BuildRuleOrder
= Options
[Tool
][Attr
]
608 AllTools
= set(list(ModuleOptions
.keys()) + list(PlatformOptions
.keys()) +
609 list(PlatformModuleOptions
.keys()) + list(ModuleTypeOptions
.keys()) +
610 list(ToolDefinition
.keys()))
611 BuildOptions
= defaultdict(lambda: defaultdict(str))
612 for Tool
in AllTools
:
613 for Options
in [ToolDefinition
, ModuleOptions
, PlatformOptions
, ModuleTypeOptions
, PlatformModuleOptions
]:
614 if Tool
not in Options
:
616 for Attr
in Options
[Tool
]:
618 # Do not generate it in Makefile
620 if Attr
== TAB_TOD_DEFINES_BUILDRULEORDER
:
622 Value
= Options
[Tool
][Attr
]
623 # check if override is indicated
624 if Value
.startswith('='):
625 BuildOptions
[Tool
][Attr
] = mws
.handleWsMacro(Value
[1:])
628 BuildOptions
[Tool
][Attr
] += " " + mws
.handleWsMacro(Value
)
630 BuildOptions
[Tool
][Attr
] = mws
.handleWsMacro(Value
)
632 return BuildOptions
, BuildRuleOrder
634 def ApplyLibraryInstance(self
,module
):
635 alldeps
= self
.DataPipe
.Get("DEPS")
638 mod_libs
= alldeps
.get((module
.MetaFile
.File
,module
.MetaFile
.Root
,module
.Arch
,module
.MetaFile
.Path
),[])
640 for (file_path
,root
,arch
,abs_path
) in mod_libs
:
641 libMetaFile
= PathClass(file_path
,root
)
642 libMetaFile
.OriginalPath
= PathClass(file_path
,root
)
643 libMetaFile
.Path
= abs_path
644 retVal
.append(self
.Wa
.BuildDatabase
[libMetaFile
, arch
, self
.Target
,self
.ToolChain
])
647 ## Parse build_rule.txt in Conf Directory.
649 # @retval BuildRule object
653 WInfo
= self
.DataPipe
.Get("P_Info")
654 RetVal
= WInfo
.get("BuildRuleFile")
655 if RetVal
._FileVersion
== "":
656 RetVal
._FileVersion
= AutoGenReqBuildRuleVerNum