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 self
._SrcTimeStamp
= 0
241 self
.BuildDatabase
= self
.Db
.BuildObject
243 self
.ToolChain
= ToolChain
244 self
.WorkspaceDir
= Workspace
245 self
.ActivePlatform
= MetaFile
249 class PlatformInfo(AutoGenInfo
):
250 def __init__(self
, Workspace
, MetaFile
, Target
, ToolChain
, Arch
,DataPipe
):
252 self
.WorkspaceDir
= self
.Wa
.WorkspaceDir
253 self
.MetaFile
= MetaFile
256 self
.BuildTarget
= Target
257 self
.ToolChain
= ToolChain
258 self
.Platform
= self
.Wa
.BuildDatabase
[self
.MetaFile
, self
.Arch
, self
.Target
, self
.ToolChain
]
260 self
.SourceDir
= MetaFile
.SubDir
261 self
.DataPipe
= DataPipe
263 def _AsBuildModuleList(self
):
264 retVal
= self
.DataPipe
.Get("AsBuildModuleList")
269 ## Test if a module is supported by the platform
271 # An error will be raised directly if the module or its arch is not supported
272 # by the platform or current configuration
274 def ValidModule(self
, Module
):
275 return Module
in self
.Platform
.Modules
or Module
in self
.Platform
.LibraryInstances \
276 or Module
in self
._AsBuildModuleList
279 def ToolChainFamily(self
):
280 retVal
= self
.DataPipe
.Get("ToolChainFamily")
286 def BuildRuleFamily(self
):
287 retVal
= self
.DataPipe
.Get("BuildRuleFamily")
294 return [self
.Wa
.BuildDatabase
[m
, self
.Arch
, self
.BuildTarget
, self
.ToolChain
] for m
in self
.Platform
.Modules
]
297 def PackageList(self
):
299 for dec_file
,Arch
in self
.DataPipe
.Get("PackageList"):
300 RetVal
.add(self
.Wa
.BuildDatabase
[dec_file
,Arch
,self
.BuildTarget
, self
.ToolChain
])
303 ## Return the directory to store all intermediate and final files built
306 if os
.path
.isabs(self
.OutputDir
):
307 RetVal
= os
.path
.join(
308 os
.path
.abspath(self
.OutputDir
),
309 self
.Target
+ "_" + self
.ToolChain
,
312 RetVal
= os
.path
.join(
315 self
.Target
+ "_" + self
.ToolChain
,
319 ## Return the build output directory platform specifies
322 return self
.Platform
.OutputDirectory
324 ## Return platform name
327 return self
.Platform
.PlatformName
329 ## Return meta-file GUID
332 return self
.Platform
.Guid
334 ## Return platform version
337 return self
.Platform
.Version
339 ## Return paths of tools
341 def ToolDefinition(self
):
342 retVal
= self
.DataPipe
.Get("TOOLDEF")
347 ## Return build command string
349 # @retval string Build command string
352 def BuildCommand(self
):
353 retVal
= self
.DataPipe
.Get("BuildCommand")
359 def PcdTokenNumber(self
):
360 retVal
= self
.DataPipe
.Get("PCD_TNUM")
365 ## Override PCD setting (type, value, ...)
367 # @param ToPcd The PCD to be overridden
368 # @param FromPcd The PCD overriding from
370 def _OverridePcd(self
, ToPcd
, FromPcd
, Module
="", Msg
="", Library
=""):
372 # in case there's PCDs coming from FDF file, which have no type given.
373 # at this point, ToPcd.Type has the type found from dependent
376 TokenCName
= ToPcd
.TokenCName
377 for PcdItem
in self
.MixedPcd
:
378 if (ToPcd
.TokenCName
, ToPcd
.TokenSpaceGuidCName
) in self
.MixedPcd
[PcdItem
]:
379 TokenCName
= PcdItem
[0]
381 if FromPcd
is not None:
382 if ToPcd
.Pending
and FromPcd
.Type
:
383 ToPcd
.Type
= FromPcd
.Type
384 elif ToPcd
.Type
and FromPcd
.Type\
385 and ToPcd
.Type
!= FromPcd
.Type
and ToPcd
.Type
in FromPcd
.Type
:
386 if ToPcd
.Type
.strip() == TAB_PCDS_DYNAMIC_EX
:
387 ToPcd
.Type
= FromPcd
.Type
388 elif ToPcd
.Type
and FromPcd
.Type \
389 and ToPcd
.Type
!= FromPcd
.Type
:
391 Module
= str(Module
) + " 's library file (" + str(Library
) + ")"
392 EdkLogger
.error("build", OPTION_CONFLICT
, "Mismatched PCD type",
393 ExtraData
="%s.%s is used as [%s] in module %s, but as [%s] in %s."\
394 % (ToPcd
.TokenSpaceGuidCName
, TokenCName
,
395 ToPcd
.Type
, Module
, FromPcd
.Type
, Msg
),
398 if FromPcd
.MaxDatumSize
:
399 ToPcd
.MaxDatumSize
= FromPcd
.MaxDatumSize
400 ToPcd
.MaxSizeUserSet
= FromPcd
.MaxDatumSize
401 if FromPcd
.DefaultValue
:
402 ToPcd
.DefaultValue
= FromPcd
.DefaultValue
403 if FromPcd
.TokenValue
:
404 ToPcd
.TokenValue
= FromPcd
.TokenValue
405 if FromPcd
.DatumType
:
406 ToPcd
.DatumType
= FromPcd
.DatumType
407 if FromPcd
.SkuInfoList
:
408 ToPcd
.SkuInfoList
= FromPcd
.SkuInfoList
409 if FromPcd
.UserDefinedDefaultStoresFlag
:
410 ToPcd
.UserDefinedDefaultStoresFlag
= FromPcd
.UserDefinedDefaultStoresFlag
411 # Add Flexible PCD format parse
412 if ToPcd
.DefaultValue
:
414 ToPcd
.DefaultValue
= ValueExpressionEx(ToPcd
.DefaultValue
, ToPcd
.DatumType
, self
._GuidDict
)(True)
415 except BadExpression
as Value
:
416 EdkLogger
.error('Parser', FORMAT_INVALID
, 'PCD [%s.%s] Value "%s", %s' %(ToPcd
.TokenSpaceGuidCName
, ToPcd
.TokenCName
, ToPcd
.DefaultValue
, Value
),
419 # check the validation of datum
420 IsValid
, Cause
= CheckPcdDatum(ToPcd
.DatumType
, ToPcd
.DefaultValue
)
422 EdkLogger
.error('build', FORMAT_INVALID
, Cause
, File
=self
.MetaFile
,
423 ExtraData
="%s.%s" % (ToPcd
.TokenSpaceGuidCName
, TokenCName
))
424 ToPcd
.validateranges
= FromPcd
.validateranges
425 ToPcd
.validlists
= FromPcd
.validlists
426 ToPcd
.expressions
= FromPcd
.expressions
427 ToPcd
.CustomAttribute
= FromPcd
.CustomAttribute
429 if FromPcd
is not None and ToPcd
.DatumType
== TAB_VOID
and not ToPcd
.MaxDatumSize
:
430 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "No MaxDatumSize specified for PCD %s.%s" \
431 % (ToPcd
.TokenSpaceGuidCName
, TokenCName
))
432 Value
= ToPcd
.DefaultValue
434 ToPcd
.MaxDatumSize
= '1'
435 elif Value
[0] == 'L':
436 ToPcd
.MaxDatumSize
= str((len(Value
) - 2) * 2)
437 elif Value
[0] == '{':
438 ToPcd
.MaxDatumSize
= str(len(Value
.split(',')))
440 ToPcd
.MaxDatumSize
= str(len(Value
) - 1)
442 # apply default SKU for dynamic PCDS if specified one is not available
443 if (ToPcd
.Type
in PCD_DYNAMIC_TYPE_SET
or ToPcd
.Type
in PCD_DYNAMIC_EX_TYPE_SET
) \
444 and not ToPcd
.SkuInfoList
:
445 if self
.Platform
.SkuName
in self
.Platform
.SkuIds
:
446 SkuName
= self
.Platform
.SkuName
448 SkuName
= TAB_DEFAULT
449 ToPcd
.SkuInfoList
= {
450 SkuName
: SkuInfoClass(SkuName
, self
.Platform
.SkuIds
[SkuName
][0], '', '', '', '', '', ToPcd
.DefaultValue
)
453 def ApplyPcdSetting(self
, Module
, Pcds
, Library
=""):
454 # for each PCD in module
455 for Name
, Guid
in Pcds
:
456 PcdInModule
= Pcds
[Name
, Guid
]
457 # find out the PCD setting in platform
458 if (Name
, Guid
) in self
.Pcds
:
459 PcdInPlatform
= self
.Pcds
[Name
, Guid
]
462 # then override the settings if any
463 self
._OverridePcd
(PcdInModule
, PcdInPlatform
, Module
, Msg
="DSC PCD sections", Library
=Library
)
464 # resolve the VariableGuid value
465 for SkuId
in PcdInModule
.SkuInfoList
:
466 Sku
= PcdInModule
.SkuInfoList
[SkuId
]
467 if Sku
.VariableGuid
== '': continue
468 Sku
.VariableGuidValue
= GuidValue(Sku
.VariableGuid
, self
.PackageList
, self
.MetaFile
.Path
)
469 if Sku
.VariableGuidValue
is None:
470 PackageList
= "\n\t".join(str(P
) for P
in self
.PackageList
)
473 RESOURCE_NOT_AVAILABLE
,
474 "Value of GUID [%s] is not found in" % Sku
.VariableGuid
,
475 ExtraData
=PackageList
+ "\n\t(used with %s.%s from module %s)" \
476 % (Guid
, Name
, str(Module
)),
480 # override PCD settings with module specific setting
481 if Module
in self
.Platform
.Modules
:
482 PlatformModule
= self
.Platform
.Modules
[str(Module
)]
483 for Key
in PlatformModule
.Pcds
:
484 if self
.BuildOptionPcd
:
485 for pcd
in self
.BuildOptionPcd
:
486 (TokenSpaceGuidCName
, TokenCName
, FieldName
, pcdvalue
, _
) = pcd
487 if (TokenCName
, TokenSpaceGuidCName
) == Key
and FieldName
=="":
488 PlatformModule
.Pcds
[Key
].DefaultValue
= pcdvalue
489 PlatformModule
.Pcds
[Key
].PcdValueFromComm
= pcdvalue
495 elif Key
in self
.MixedPcd
:
496 for PcdItem
in self
.MixedPcd
[Key
]:
498 ToPcd
= Pcds
[PcdItem
]
502 self
._OverridePcd
(ToPcd
, PlatformModule
.Pcds
[Key
], Module
, Msg
="DSC Components Module scoped PCD section", Library
=Library
)
503 # use PCD value to calculate the MaxDatumSize when it is not specified
504 for Name
, Guid
in Pcds
:
505 Pcd
= Pcds
[Name
, Guid
]
506 if Pcd
.DatumType
== TAB_VOID
and not Pcd
.MaxDatumSize
:
507 Pcd
.MaxSizeUserSet
= None
508 Value
= Pcd
.DefaultValue
510 Pcd
.MaxDatumSize
= '1'
511 elif Value
[0] == 'L':
512 Pcd
.MaxDatumSize
= str((len(Value
) - 2) * 2)
513 elif Value
[0] == '{':
514 Pcd
.MaxDatumSize
= str(len(Value
.split(',')))
516 Pcd
.MaxDatumSize
= str(len(Value
) - 1)
517 return list(Pcds
.values())
521 PlatformPcdData
= self
.DataPipe
.Get("PLA_PCD")
522 # for pcd in PlatformPcdData:
523 # for skuid in pcd.SkuInfoList:
524 # pcd.SkuInfoList[skuid] = self.CreateSkuInfoFromDict(pcd.SkuInfoList[skuid])
525 return {(pcddata
.TokenCName
,pcddata
.TokenSpaceGuidCName
):pcddata
for pcddata
in PlatformPcdData
}
527 def CreateSkuInfoFromDict(self
,SkuInfoDict
):
529 SkuInfoDict
.get("SkuIdName"),
530 SkuInfoDict
.get("SkuId"),
531 SkuInfoDict
.get("VariableName"),
532 SkuInfoDict
.get("VariableGuid"),
533 SkuInfoDict
.get("VariableOffset"),
534 SkuInfoDict
.get("HiiDefaultValue"),
535 SkuInfoDict
.get("VpdOffset"),
536 SkuInfoDict
.get("DefaultValue"),
537 SkuInfoDict
.get("VariableGuidValue"),
538 SkuInfoDict
.get("VariableAttribute",""),
539 SkuInfoDict
.get("DefaultStore",None)
543 return self
.DataPipe
.Get("MixedPcd")
546 RetVal
= self
.DataPipe
.Get("GuidDict")
551 def BuildOptionPcd(self
):
552 return self
.DataPipe
.Get("BuildOptPcd")
553 def ApplyBuildOption(self
,module
):
554 PlatformOptions
= self
.DataPipe
.Get("PLA_BO")
555 ModuleBuildOptions
= self
.DataPipe
.Get("MOL_BO")
556 ModuleOptionFromDsc
= ModuleBuildOptions
.get((module
.MetaFile
.File
,module
.MetaFile
.Root
))
557 if ModuleOptionFromDsc
:
558 ModuleTypeOptions
, PlatformModuleOptions
= ModuleOptionFromDsc
["ModuleTypeOptions"],ModuleOptionFromDsc
["PlatformModuleOptions"]
560 ModuleTypeOptions
, PlatformModuleOptions
= {}, {}
561 ToolDefinition
= self
.DataPipe
.Get("TOOLDEF")
562 ModuleOptions
= self
._ExpandBuildOption
(module
.BuildOptions
)
563 BuildRuleOrder
= None
564 for Options
in [ToolDefinition
, ModuleOptions
, PlatformOptions
, ModuleTypeOptions
, PlatformModuleOptions
]:
566 for Attr
in Options
[Tool
]:
567 if Attr
== TAB_TOD_DEFINES_BUILDRULEORDER
:
568 BuildRuleOrder
= Options
[Tool
][Attr
]
570 AllTools
= set(list(ModuleOptions
.keys()) + list(PlatformOptions
.keys()) +
571 list(PlatformModuleOptions
.keys()) + list(ModuleTypeOptions
.keys()) +
572 list(ToolDefinition
.keys()))
573 BuildOptions
= defaultdict(lambda: defaultdict(str))
574 for Tool
in AllTools
:
575 for Options
in [ToolDefinition
, ModuleOptions
, PlatformOptions
, ModuleTypeOptions
, PlatformModuleOptions
]:
576 if Tool
not in Options
:
578 for Attr
in Options
[Tool
]:
580 # Do not generate it in Makefile
582 if Attr
== TAB_TOD_DEFINES_BUILDRULEORDER
:
584 Value
= Options
[Tool
][Attr
]
585 # check if override is indicated
586 if Value
.startswith('='):
587 BuildOptions
[Tool
][Attr
] = mws
.handleWsMacro(Value
[1:])
590 BuildOptions
[Tool
][Attr
] += " " + mws
.handleWsMacro(Value
)
592 BuildOptions
[Tool
][Attr
] = mws
.handleWsMacro(Value
)
594 return BuildOptions
, BuildRuleOrder
596 def ApplyLibraryInstance(self
,module
):
597 alldeps
= self
.DataPipe
.Get("DEPS")
600 mod_libs
= alldeps
.get((module
.MetaFile
.File
,module
.MetaFile
.Root
,module
.Arch
,module
.MetaFile
.Path
),[])
602 for (file_path
,root
,arch
,abs_path
) in mod_libs
:
603 libMetaFile
= PathClass(file_path
,root
)
604 libMetaFile
.OriginalPath
= PathClass(file_path
,root
)
605 libMetaFile
.Path
= abs_path
606 retVal
.append(self
.Wa
.BuildDatabase
[libMetaFile
, arch
, self
.Target
,self
.ToolChain
])
609 ## Parse build_rule.txt in Conf Directory.
611 # @retval BuildRule object
615 WInfo
= self
.DataPipe
.Get("P_Info")
616 RetVal
= WInfo
.get("BuildRuleFile")
617 if RetVal
._FileVersion
== "":
618 RetVal
._FileVersion
= AutoGenReqBuildRuleVerNum