2 # Create makefile for MS nmake and GNU make
4 # Copyright (c) 2019, 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
]:
181 elif Family
!= ToolDef
[Tool
][TAB_TOD_DEFINES_FAMILY
]:
184 # expand any wildcard
185 if Target
== TAB_STAR
or Target
== self
.BuildTarget
:
186 if Tag
== TAB_STAR
or Tag
== self
.ToolChain
:
187 if Arch
== TAB_STAR
or Arch
== self
.Arch
:
188 if Tool
not in BuildOptions
:
189 BuildOptions
[Tool
] = {}
190 if Attr
!= "FLAGS" or Attr
not in BuildOptions
[Tool
] or Options
[Key
].startswith('='):
191 BuildOptions
[Tool
][Attr
] = Options
[Key
]
193 # append options for the same tool except PATH
195 BuildOptions
[Tool
][Attr
] += " " + Options
[Key
]
197 BuildOptions
[Tool
][Attr
] = Options
[Key
]
198 # Build Option Family has been checked, which need't to be checked again for family.
199 if FamilyMatch
or FamilyIsNull
:
203 if ModuleStyle
is not None and len (Key
) > 2:
204 # Check Module style is EDK or EDKII.
205 # Only append build option for the matched style module.
206 if ModuleStyle
== EDK_NAME
and Key
[2] != EDK_NAME
:
208 elif ModuleStyle
== EDKII_NAME
and Key
[2] != EDKII_NAME
:
211 Target
, Tag
, Arch
, Tool
, Attr
= Key
[1].split("_")
212 # if tool chain family doesn't match, skip it
213 if Tool
not in ToolDef
or Family
== "":
215 # option has been added before
216 if Family
!= ToolDef
[Tool
][TAB_TOD_DEFINES_FAMILY
]:
219 # expand any wildcard
220 if Target
== TAB_STAR
or Target
== self
.BuildTarget
:
221 if Tag
== TAB_STAR
or Tag
== self
.ToolChain
:
222 if Arch
== TAB_STAR
or Arch
== self
.Arch
:
223 if Tool
not in BuildOptions
:
224 BuildOptions
[Tool
] = {}
225 if Attr
!= "FLAGS" or Attr
not in BuildOptions
[Tool
] or Options
[Key
].startswith('='):
226 BuildOptions
[Tool
][Attr
] = Options
[Key
]
228 # append options for the same tool except PATH
230 BuildOptions
[Tool
][Attr
] += " " + Options
[Key
]
232 BuildOptions
[Tool
][Attr
] = Options
[Key
]
235 #This class is the pruned WorkSpaceAutoGen for ModuleAutoGen in multiple thread
237 class WorkSpaceInfo(AutoGenInfo
):
238 def __init__(self
,Workspace
, MetaFile
, Target
, ToolChain
, Arch
):
239 if not hasattr(self
, "_Init"):
240 self
.do_init(Workspace
, MetaFile
, Target
, ToolChain
, Arch
)
242 def do_init(self
,Workspace
, MetaFile
, Target
, ToolChain
, Arch
):
243 self
._SrcTimeStamp
= 0
245 self
.BuildDatabase
= self
.Db
.BuildObject
247 self
.ToolChain
= ToolChain
248 self
.WorkspaceDir
= Workspace
249 self
.ActivePlatform
= MetaFile
251 self
.AutoGenObjectList
= []
254 return self
.AutoGenObjectList
[0].BuildDir
258 return self
.AutoGenObjectList
[0].Platform
.PlatformName
261 def FlashDefinition(self
):
262 return self
.AutoGenObjectList
[0].Platform
.FlashDefinition
264 def GenFdsCommandDict(self
):
265 FdsCommandDict
= self
.AutoGenObjectList
[0].DataPipe
.Get("FdsCommandDict")
267 return FdsCommandDict
272 return os
.path
.join(self
.BuildDir
, TAB_FV_DIRECTORY
)
274 class PlatformInfo(AutoGenInfo
):
275 def __init__(self
, Workspace
, MetaFile
, Target
, ToolChain
, Arch
,DataPipe
):
276 if not hasattr(self
, "_Init"):
277 self
.do_init(Workspace
, MetaFile
, Target
, ToolChain
, Arch
,DataPipe
)
279 def do_init(self
,Workspace
, MetaFile
, Target
, ToolChain
, Arch
,DataPipe
):
281 self
.WorkspaceDir
= self
.Wa
.WorkspaceDir
282 self
.MetaFile
= MetaFile
285 self
.BuildTarget
= Target
286 self
.ToolChain
= ToolChain
287 self
.Platform
= self
.Wa
.BuildDatabase
[self
.MetaFile
, self
.Arch
, self
.Target
, self
.ToolChain
]
289 self
.SourceDir
= MetaFile
.SubDir
290 self
.DataPipe
= DataPipe
292 def _AsBuildModuleList(self
):
293 retVal
= self
.DataPipe
.Get("AsBuildModuleList")
298 ## Test if a module is supported by the platform
300 # An error will be raised directly if the module or its arch is not supported
301 # by the platform or current configuration
303 def ValidModule(self
, Module
):
304 return Module
in self
.Platform
.Modules
or Module
in self
.Platform
.LibraryInstances \
305 or Module
in self
._AsBuildModuleList
308 def ToolChainFamily(self
):
309 retVal
= self
.DataPipe
.Get("ToolChainFamily")
315 def BuildRuleFamily(self
):
316 retVal
= self
.DataPipe
.Get("BuildRuleFamily")
323 return [self
.Wa
.BuildDatabase
[m
, self
.Arch
, self
.BuildTarget
, self
.ToolChain
] for m
in self
.Platform
.Modules
]
326 def PackageList(self
):
328 for dec_file
,Arch
in self
.DataPipe
.Get("PackageList"):
329 RetVal
.add(self
.Wa
.BuildDatabase
[dec_file
,Arch
,self
.BuildTarget
, self
.ToolChain
])
332 ## Return the directory to store all intermediate and final files built
335 if os
.path
.isabs(self
.OutputDir
):
336 RetVal
= os
.path
.join(
337 os
.path
.abspath(self
.OutputDir
),
338 self
.Target
+ "_" + self
.ToolChain
,
341 RetVal
= os
.path
.join(
344 self
.Target
+ "_" + self
.ToolChain
,
348 ## Return the build output directory platform specifies
351 return self
.Platform
.OutputDirectory
353 ## Return platform name
356 return self
.Platform
.PlatformName
358 ## Return meta-file GUID
361 return self
.Platform
.Guid
363 ## Return platform version
366 return self
.Platform
.Version
368 ## Return paths of tools
370 def ToolDefinition(self
):
371 retVal
= self
.DataPipe
.Get("TOOLDEF")
376 ## Return build command string
378 # @retval string Build command string
381 def BuildCommand(self
):
382 retVal
= self
.DataPipe
.Get("BuildCommand")
388 def PcdTokenNumber(self
):
389 retVal
= self
.DataPipe
.Get("PCD_TNUM")
394 ## Override PCD setting (type, value, ...)
396 # @param ToPcd The PCD to be overridden
397 # @param FromPcd The PCD overriding from
399 def _OverridePcd(self
, ToPcd
, FromPcd
, Module
="", Msg
="", Library
=""):
401 # in case there's PCDs coming from FDF file, which have no type given.
402 # at this point, ToPcd.Type has the type found from dependent
405 TokenCName
= ToPcd
.TokenCName
406 for PcdItem
in self
.MixedPcd
:
407 if (ToPcd
.TokenCName
, ToPcd
.TokenSpaceGuidCName
) in self
.MixedPcd
[PcdItem
]:
408 TokenCName
= PcdItem
[0]
410 if FromPcd
is not None:
411 if ToPcd
.Pending
and FromPcd
.Type
:
412 ToPcd
.Type
= FromPcd
.Type
413 elif ToPcd
.Type
and FromPcd
.Type\
414 and ToPcd
.Type
!= FromPcd
.Type
and ToPcd
.Type
in FromPcd
.Type
:
415 if ToPcd
.Type
.strip() == TAB_PCDS_DYNAMIC_EX
:
416 ToPcd
.Type
= FromPcd
.Type
417 elif ToPcd
.Type
and FromPcd
.Type \
418 and ToPcd
.Type
!= FromPcd
.Type
:
420 Module
= str(Module
) + " 's library file (" + str(Library
) + ")"
421 EdkLogger
.error("build", OPTION_CONFLICT
, "Mismatched PCD type",
422 ExtraData
="%s.%s is used as [%s] in module %s, but as [%s] in %s."\
423 % (ToPcd
.TokenSpaceGuidCName
, TokenCName
,
424 ToPcd
.Type
, Module
, FromPcd
.Type
, Msg
),
427 if FromPcd
.MaxDatumSize
:
428 ToPcd
.MaxDatumSize
= FromPcd
.MaxDatumSize
429 ToPcd
.MaxSizeUserSet
= FromPcd
.MaxDatumSize
430 if FromPcd
.DefaultValue
:
431 ToPcd
.DefaultValue
= FromPcd
.DefaultValue
432 if FromPcd
.TokenValue
:
433 ToPcd
.TokenValue
= FromPcd
.TokenValue
434 if FromPcd
.DatumType
:
435 ToPcd
.DatumType
= FromPcd
.DatumType
436 if FromPcd
.SkuInfoList
:
437 ToPcd
.SkuInfoList
= FromPcd
.SkuInfoList
438 if FromPcd
.UserDefinedDefaultStoresFlag
:
439 ToPcd
.UserDefinedDefaultStoresFlag
= FromPcd
.UserDefinedDefaultStoresFlag
440 # Add Flexible PCD format parse
441 if ToPcd
.DefaultValue
:
443 ToPcd
.DefaultValue
= ValueExpressionEx(ToPcd
.DefaultValue
, ToPcd
.DatumType
, self
._GuidDict
)(True)
444 except BadExpression
as Value
:
445 EdkLogger
.error('Parser', FORMAT_INVALID
, 'PCD [%s.%s] Value "%s", %s' %(ToPcd
.TokenSpaceGuidCName
, ToPcd
.TokenCName
, ToPcd
.DefaultValue
, Value
),
448 # check the validation of datum
449 IsValid
, Cause
= CheckPcdDatum(ToPcd
.DatumType
, ToPcd
.DefaultValue
)
451 EdkLogger
.error('build', FORMAT_INVALID
, Cause
, File
=self
.MetaFile
,
452 ExtraData
="%s.%s" % (ToPcd
.TokenSpaceGuidCName
, TokenCName
))
453 ToPcd
.validateranges
= FromPcd
.validateranges
454 ToPcd
.validlists
= FromPcd
.validlists
455 ToPcd
.expressions
= FromPcd
.expressions
456 ToPcd
.CustomAttribute
= FromPcd
.CustomAttribute
458 if FromPcd
is not None and ToPcd
.DatumType
== TAB_VOID
and not ToPcd
.MaxDatumSize
:
459 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "No MaxDatumSize specified for PCD %s.%s" \
460 % (ToPcd
.TokenSpaceGuidCName
, TokenCName
))
461 Value
= ToPcd
.DefaultValue
463 ToPcd
.MaxDatumSize
= '1'
464 elif Value
[0] == 'L':
465 ToPcd
.MaxDatumSize
= str((len(Value
) - 2) * 2)
466 elif Value
[0] == '{':
467 ToPcd
.MaxDatumSize
= str(len(Value
.split(',')))
469 ToPcd
.MaxDatumSize
= str(len(Value
) - 1)
471 # apply default SKU for dynamic PCDS if specified one is not available
472 if (ToPcd
.Type
in PCD_DYNAMIC_TYPE_SET
or ToPcd
.Type
in PCD_DYNAMIC_EX_TYPE_SET
) \
473 and not ToPcd
.SkuInfoList
:
474 if self
.Platform
.SkuName
in self
.Platform
.SkuIds
:
475 SkuName
= self
.Platform
.SkuName
477 SkuName
= TAB_DEFAULT
478 ToPcd
.SkuInfoList
= {
479 SkuName
: SkuInfoClass(SkuName
, self
.Platform
.SkuIds
[SkuName
][0], '', '', '', '', '', ToPcd
.DefaultValue
)
482 def ApplyPcdSetting(self
, Module
, Pcds
, Library
=""):
483 # for each PCD in module
484 for Name
, Guid
in Pcds
:
485 PcdInModule
= Pcds
[Name
, Guid
]
486 # find out the PCD setting in platform
487 if (Name
, Guid
) in self
.Pcds
:
488 PcdInPlatform
= self
.Pcds
[Name
, Guid
]
491 # then override the settings if any
492 self
._OverridePcd
(PcdInModule
, PcdInPlatform
, Module
, Msg
="DSC PCD sections", Library
=Library
)
493 # resolve the VariableGuid value
494 for SkuId
in PcdInModule
.SkuInfoList
:
495 Sku
= PcdInModule
.SkuInfoList
[SkuId
]
496 if Sku
.VariableGuid
== '': continue
497 Sku
.VariableGuidValue
= GuidValue(Sku
.VariableGuid
, self
.PackageList
, self
.MetaFile
.Path
)
498 if Sku
.VariableGuidValue
is None:
499 PackageList
= "\n\t".join(str(P
) for P
in self
.PackageList
)
502 RESOURCE_NOT_AVAILABLE
,
503 "Value of GUID [%s] is not found in" % Sku
.VariableGuid
,
504 ExtraData
=PackageList
+ "\n\t(used with %s.%s from module %s)" \
505 % (Guid
, Name
, str(Module
)),
509 # override PCD settings with module specific setting
510 if Module
in self
.Platform
.Modules
:
511 PlatformModule
= self
.Platform
.Modules
[str(Module
)]
512 for Key
in PlatformModule
.Pcds
:
513 if self
.BuildOptionPcd
:
514 for pcd
in self
.BuildOptionPcd
:
515 (TokenSpaceGuidCName
, TokenCName
, FieldName
, pcdvalue
, _
) = pcd
516 if (TokenCName
, TokenSpaceGuidCName
) == Key
and FieldName
=="":
517 PlatformModule
.Pcds
[Key
].DefaultValue
= pcdvalue
518 PlatformModule
.Pcds
[Key
].PcdValueFromComm
= pcdvalue
524 elif Key
in self
.MixedPcd
:
525 for PcdItem
in self
.MixedPcd
[Key
]:
527 ToPcd
= Pcds
[PcdItem
]
531 self
._OverridePcd
(ToPcd
, PlatformModule
.Pcds
[Key
], Module
, Msg
="DSC Components Module scoped PCD section", Library
=Library
)
532 # use PCD value to calculate the MaxDatumSize when it is not specified
533 for Name
, Guid
in Pcds
:
534 Pcd
= Pcds
[Name
, Guid
]
535 if Pcd
.DatumType
== TAB_VOID
and not Pcd
.MaxDatumSize
:
536 Pcd
.MaxSizeUserSet
= None
537 Value
= Pcd
.DefaultValue
539 Pcd
.MaxDatumSize
= '1'
540 elif Value
[0] == 'L':
541 Pcd
.MaxDatumSize
= str((len(Value
) - 2) * 2)
542 elif Value
[0] == '{':
543 Pcd
.MaxDatumSize
= str(len(Value
.split(',')))
545 Pcd
.MaxDatumSize
= str(len(Value
) - 1)
546 return list(Pcds
.values())
550 PlatformPcdData
= self
.DataPipe
.Get("PLA_PCD")
551 # for pcd in PlatformPcdData:
552 # for skuid in pcd.SkuInfoList:
553 # pcd.SkuInfoList[skuid] = self.CreateSkuInfoFromDict(pcd.SkuInfoList[skuid])
554 return {(pcddata
.TokenCName
,pcddata
.TokenSpaceGuidCName
):pcddata
for pcddata
in PlatformPcdData
}
556 def CreateSkuInfoFromDict(self
,SkuInfoDict
):
558 SkuInfoDict
.get("SkuIdName"),
559 SkuInfoDict
.get("SkuId"),
560 SkuInfoDict
.get("VariableName"),
561 SkuInfoDict
.get("VariableGuid"),
562 SkuInfoDict
.get("VariableOffset"),
563 SkuInfoDict
.get("HiiDefaultValue"),
564 SkuInfoDict
.get("VpdOffset"),
565 SkuInfoDict
.get("DefaultValue"),
566 SkuInfoDict
.get("VariableGuidValue"),
567 SkuInfoDict
.get("VariableAttribute",""),
568 SkuInfoDict
.get("DefaultStore",None)
572 return self
.DataPipe
.Get("MixedPcd")
575 RetVal
= self
.DataPipe
.Get("GuidDict")
580 def BuildOptionPcd(self
):
581 return self
.DataPipe
.Get("BuildOptPcd")
582 def ApplyBuildOption(self
,module
):
583 PlatformOptions
= self
.DataPipe
.Get("PLA_BO")
584 ModuleBuildOptions
= self
.DataPipe
.Get("MOL_BO")
585 ModuleOptionFromDsc
= ModuleBuildOptions
.get((module
.MetaFile
.File
,module
.MetaFile
.Root
))
586 if ModuleOptionFromDsc
:
587 ModuleTypeOptions
, PlatformModuleOptions
= ModuleOptionFromDsc
["ModuleTypeOptions"],ModuleOptionFromDsc
["PlatformModuleOptions"]
589 ModuleTypeOptions
, PlatformModuleOptions
= {}, {}
590 ToolDefinition
= self
.DataPipe
.Get("TOOLDEF")
591 ModuleOptions
= self
._ExpandBuildOption
(module
.BuildOptions
)
592 BuildRuleOrder
= None
593 for Options
in [ToolDefinition
, ModuleOptions
, PlatformOptions
, ModuleTypeOptions
, PlatformModuleOptions
]:
595 for Attr
in Options
[Tool
]:
596 if Attr
== TAB_TOD_DEFINES_BUILDRULEORDER
:
597 BuildRuleOrder
= Options
[Tool
][Attr
]
599 AllTools
= set(list(ModuleOptions
.keys()) + list(PlatformOptions
.keys()) +
600 list(PlatformModuleOptions
.keys()) + list(ModuleTypeOptions
.keys()) +
601 list(ToolDefinition
.keys()))
602 BuildOptions
= defaultdict(lambda: defaultdict(str))
603 for Tool
in AllTools
:
604 for Options
in [ToolDefinition
, ModuleOptions
, PlatformOptions
, ModuleTypeOptions
, PlatformModuleOptions
]:
605 if Tool
not in Options
:
607 for Attr
in Options
[Tool
]:
609 # Do not generate it in Makefile
611 if Attr
== TAB_TOD_DEFINES_BUILDRULEORDER
:
613 Value
= Options
[Tool
][Attr
]
614 # check if override is indicated
615 if Value
.startswith('='):
616 BuildOptions
[Tool
][Attr
] = mws
.handleWsMacro(Value
[1:])
619 BuildOptions
[Tool
][Attr
] += " " + mws
.handleWsMacro(Value
)
621 BuildOptions
[Tool
][Attr
] = mws
.handleWsMacro(Value
)
623 return BuildOptions
, BuildRuleOrder
625 def ApplyLibraryInstance(self
,module
):
626 alldeps
= self
.DataPipe
.Get("DEPS")
629 mod_libs
= alldeps
.get((module
.MetaFile
.File
,module
.MetaFile
.Root
,module
.Arch
,module
.MetaFile
.Path
),[])
631 for (file_path
,root
,arch
,abs_path
) in mod_libs
:
632 libMetaFile
= PathClass(file_path
,root
)
633 libMetaFile
.OriginalPath
= PathClass(file_path
,root
)
634 libMetaFile
.Path
= abs_path
635 retVal
.append(self
.Wa
.BuildDatabase
[libMetaFile
, arch
, self
.Target
,self
.ToolChain
])
638 ## Parse build_rule.txt in Conf Directory.
640 # @retval BuildRule object
644 WInfo
= self
.DataPipe
.Get("P_Info")
645 RetVal
= WInfo
.get("BuildRuleFile")
646 if RetVal
._FileVersion
== "":
647 RetVal
._FileVersion
= AutoGenReqBuildRuleVerNum