2 # Global variables for GenFds
4 # Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<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.
24 from Common
.BuildToolError
import *
25 from Common
import EdkLogger
26 from Common
.Misc
import SaveFileOnChange
28 from Common
.TargetTxtClassObject
import TargetTxtClassObject
29 from Common
.ToolDefClassObject
import ToolDefClassObject
30 from AutoGen
.BuildEngine
import BuildRule
31 import Common
.DataType
as DataType
32 from Common
.Misc
import PathClass
37 class GenFdsGlobalVariable
:
41 # will be FvDir + os.sep + 'Ffs'
48 OutputDirFromDscDict
= {}
55 FvAddressFileName
= ''
59 SharpNumberPerLine
= 40
62 FixedLoadAddress
= False
65 BuildRuleFamily
= "MSFT"
66 ToolChainFamily
= "MSFT"
67 __BuildRuleDatabase
= None
69 SectionHeader
= struct
.Struct("3B 1B")
74 def __LoadBuildRule():
75 if GenFdsGlobalVariable
.__BuildRuleDatabase
:
76 return GenFdsGlobalVariable
.__BuildRuleDatabase
77 BuildConfigurationFile
= os
.path
.normpath(os
.path
.join(GenFdsGlobalVariable
.WorkSpaceDir
, "Conf/target.txt"))
78 TargetTxt
= TargetTxtClassObject()
79 if os
.path
.isfile(BuildConfigurationFile
) == True:
80 TargetTxt
.LoadTargetTxtFile(BuildConfigurationFile
)
81 if DataType
.TAB_TAT_DEFINES_BUILD_RULE_CONF
in TargetTxt
.TargetTxtDictionary
:
82 BuildRuleFile
= TargetTxt
.TargetTxtDictionary
[DataType
.TAB_TAT_DEFINES_BUILD_RULE_CONF
]
83 if BuildRuleFile
in [None, '']:
84 BuildRuleFile
= 'Conf/build_rule.txt'
85 GenFdsGlobalVariable
.__BuildRuleDatabase
= BuildRule(BuildRuleFile
)
86 ToolDefinitionFile
= TargetTxt
.TargetTxtDictionary
[DataType
.TAB_TAT_DEFINES_TOOL_CHAIN_CONF
]
87 if ToolDefinitionFile
== '':
88 ToolDefinitionFile
= "Conf/tools_def.txt"
89 if os
.path
.isfile(ToolDefinitionFile
):
90 ToolDef
= ToolDefClassObject()
91 ToolDef
.LoadToolDefFile(ToolDefinitionFile
)
92 ToolDefinition
= ToolDef
.ToolsDefTxtDatabase
93 if DataType
.TAB_TOD_DEFINES_BUILDRULEFAMILY
in ToolDefinition \
94 and GenFdsGlobalVariable
.ToolChainTag
in ToolDefinition
[DataType
.TAB_TOD_DEFINES_BUILDRULEFAMILY
] \
95 and ToolDefinition
[DataType
.TAB_TOD_DEFINES_BUILDRULEFAMILY
][GenFdsGlobalVariable
.ToolChainTag
]:
96 GenFdsGlobalVariable
.BuildRuleFamily
= ToolDefinition
[DataType
.TAB_TOD_DEFINES_BUILDRULEFAMILY
][GenFdsGlobalVariable
.ToolChainTag
]
98 if DataType
.TAB_TOD_DEFINES_FAMILY
in ToolDefinition \
99 and GenFdsGlobalVariable
.ToolChainTag
in ToolDefinition
[DataType
.TAB_TOD_DEFINES_FAMILY
] \
100 and ToolDefinition
[DataType
.TAB_TOD_DEFINES_FAMILY
][GenFdsGlobalVariable
.ToolChainTag
]:
101 GenFdsGlobalVariable
.ToolChainFamily
= ToolDefinition
[DataType
.TAB_TOD_DEFINES_FAMILY
][GenFdsGlobalVariable
.ToolChainTag
]
102 return GenFdsGlobalVariable
.__BuildRuleDatabase
105 # @param Inf: object of InfBuildData
106 # @param Arch: current arch
109 def GetBuildRules(Inf
, Arch
):
113 if not Arch
in GenFdsGlobalVariable
.OutputDirDict
:
116 BuildRuleDatabase
= GenFdsGlobalVariable
.__LoadBuildRule
()
117 if not BuildRuleDatabase
:
120 PathClassObj
= PathClass(str(Inf
.MetaFile
).lstrip(GenFdsGlobalVariable
.WorkSpaceDir
),
121 GenFdsGlobalVariable
.WorkSpaceDir
)
123 Macro
["WORKSPACE" ] = GenFdsGlobalVariable
.WorkSpaceDir
124 Macro
["MODULE_NAME" ] = Inf
.BaseName
125 Macro
["MODULE_GUID" ] = Inf
.Guid
126 Macro
["MODULE_VERSION" ] = Inf
.Version
127 Macro
["MODULE_TYPE" ] = Inf
.ModuleType
128 Macro
["MODULE_FILE" ] = str(PathClassObj
)
129 Macro
["MODULE_FILE_BASE_NAME" ] = PathClassObj
.BaseName
130 Macro
["MODULE_RELATIVE_DIR" ] = PathClassObj
.SubDir
131 Macro
["MODULE_DIR" ] = PathClassObj
.SubDir
133 Macro
["BASE_NAME" ] = Inf
.BaseName
135 Macro
["ARCH" ] = Arch
136 Macro
["TOOLCHAIN" ] = GenFdsGlobalVariable
.ToolChainTag
137 Macro
["TOOLCHAIN_TAG" ] = GenFdsGlobalVariable
.ToolChainTag
138 Macro
["TARGET" ] = GenFdsGlobalVariable
.TargetName
140 Macro
["BUILD_DIR" ] = GenFdsGlobalVariable
.OutputDirDict
[Arch
]
141 Macro
["BIN_DIR" ] = os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
], Arch
)
142 Macro
["LIB_DIR" ] = os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
], Arch
)
143 BuildDir
= os
.path
.join(
144 GenFdsGlobalVariable
.OutputDirDict
[Arch
],
147 PathClassObj
.BaseName
149 Macro
["MODULE_BUILD_DIR" ] = BuildDir
150 Macro
["OUTPUT_DIR" ] = os
.path
.join(BuildDir
, "OUTPUT")
151 Macro
["DEBUG_DIR" ] = os
.path
.join(BuildDir
, "DEBUG")
154 for Type
in BuildRuleDatabase
.FileTypeList
:
155 #first try getting build rule by BuildRuleFamily
156 RuleObject
= BuildRuleDatabase
[Type
, Inf
.BuildType
, Arch
, GenFdsGlobalVariable
.BuildRuleFamily
]
158 # build type is always module type, but ...
159 if Inf
.ModuleType
!= Inf
.BuildType
:
160 RuleObject
= BuildRuleDatabase
[Type
, Inf
.ModuleType
, Arch
, GenFdsGlobalVariable
.BuildRuleFamily
]
161 #second try getting build rule by ToolChainFamily
163 RuleObject
= BuildRuleDatabase
[Type
, Inf
.BuildType
, Arch
, GenFdsGlobalVariable
.ToolChainFamily
]
165 # build type is always module type, but ...
166 if Inf
.ModuleType
!= Inf
.BuildType
:
167 RuleObject
= BuildRuleDatabase
[Type
, Inf
.ModuleType
, Arch
, GenFdsGlobalVariable
.ToolChainFamily
]
170 RuleObject
= RuleObject
.Instantiate(Macro
)
171 BuildRules
[Type
] = RuleObject
172 for Ext
in RuleObject
.SourceFileExtList
:
173 BuildRules
[Ext
] = RuleObject
176 ## GetModuleCodaTargetList
178 # @param Inf: object of InfBuildData
179 # @param Arch: current arch
182 def GetModuleCodaTargetList(Inf
, Arch
):
183 BuildRules
= GenFdsGlobalVariable
.GetBuildRules(Inf
, Arch
)
189 for File
in Inf
.Sources
:
190 if File
.TagName
in ("", "*", GenFdsGlobalVariable
.ToolChainTag
) and \
191 File
.ToolChainFamily
in ("", "*", GenFdsGlobalVariable
.ToolChainFamily
):
192 FileList
.append((File
, DataType
.TAB_UNKNOWN_FILE
))
194 for File
in Inf
.Binaries
:
195 if File
.Target
in ['COMMON', '*', GenFdsGlobalVariable
.TargetName
]:
196 FileList
.append((File
, File
.Type
))
198 for File
, FileType
in FileList
:
203 while Index
< len(SourceList
):
204 Source
= SourceList
[Index
]
207 if File
.IsBinary
and File
== Source
and Inf
.Binaries
!= None and File
in Inf
.Binaries
:
208 # Skip all files that are not binary libraries
209 if not Inf
.LibraryClass
:
211 RuleObject
= BuildRules
[DataType
.TAB_DEFAULT_BINARY_FILE
]
212 elif FileType
in BuildRules
:
213 RuleObject
= BuildRules
[FileType
]
214 elif Source
.Ext
in BuildRules
:
215 RuleObject
= BuildRules
[Source
.Ext
]
217 # stop at no more rules
219 TargetList
.add(str(LastTarget
))
222 FileType
= RuleObject
.SourceFileType
224 # stop at STATIC_LIBRARY for library
225 if Inf
.LibraryClass
and FileType
== DataType
.TAB_STATIC_LIBRARY
:
227 TargetList
.add(str(LastTarget
))
230 Target
= RuleObject
.Apply(Source
)
233 TargetList
.add(str(LastTarget
))
235 elif not Target
.Outputs
:
236 # Only do build for target with outputs
237 TargetList
.add(str(Target
))
239 # to avoid cyclic rule
240 if FileType
in RuleChain
:
243 RuleChain
.append(FileType
)
244 SourceList
.extend(Target
.Outputs
)
246 FileType
= DataType
.TAB_UNKNOWN_FILE
248 return list(TargetList
)
252 # @param OutputDir Output directory
253 # @param FdfParser FDF contents parser
254 # @param Workspace The directory of workspace
255 # @param ArchList The Arch list of platform
257 def SetDir (OutputDir
, FdfParser
, WorkSpace
, ArchList
):
258 GenFdsGlobalVariable
.VerboseLogger( "GenFdsGlobalVariable.OutputDir :%s" %OutputDir
)
259 # GenFdsGlobalVariable.OutputDirDict = OutputDir
260 GenFdsGlobalVariable
.FdfParser
= FdfParser
261 GenFdsGlobalVariable
.WorkSpace
= WorkSpace
262 GenFdsGlobalVariable
.FvDir
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[ArchList
[0]], 'FV')
263 if not os
.path
.exists(GenFdsGlobalVariable
.FvDir
) :
264 os
.makedirs(GenFdsGlobalVariable
.FvDir
)
265 GenFdsGlobalVariable
.FfsDir
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, 'Ffs')
266 if not os
.path
.exists(GenFdsGlobalVariable
.FfsDir
) :
267 os
.makedirs(GenFdsGlobalVariable
.FfsDir
)
269 GenFdsGlobalVariable
.ArchList
= ArchList
273 # Create FV Address inf file
275 GenFdsGlobalVariable
.FvAddressFileName
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, 'FvAddress.inf')
276 FvAddressFile
= open (GenFdsGlobalVariable
.FvAddressFileName
, 'w')
280 FvAddressFile
.writelines("[options]" + T_CHAR_LF
)
282 for Arch
in ArchList
:
283 if GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
].BsBaseAddress
:
284 BsAddress
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
].BsBaseAddress
287 FvAddressFile
.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \
292 for Arch
in ArchList
:
293 if GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
].RtBaseAddress
:
294 RtAddress
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
].RtBaseAddress
296 FvAddressFile
.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \
300 FvAddressFile
.close()
302 ## ReplaceWorkspaceMacro()
304 # @param String String that may contain macro
306 def ReplaceWorkspaceMacro(String
):
307 Str
= String
.replace('$(WORKSPACE)', GenFdsGlobalVariable
.WorkSpaceDir
)
308 if os
.path
.exists(Str
):
309 if not os
.path
.isabs(Str
):
310 Str
= os
.path
.abspath(Str
)
312 Str
= os
.path
.join(GenFdsGlobalVariable
.WorkSpaceDir
, String
)
313 return os
.path
.normpath(Str
)
315 ## Check if the input files are newer than output files
317 # @param Output Path of output file
318 # @param Input Path list of input files
320 # @retval True if Output doesn't exist, or any Input is newer
321 # @retval False if all Input is older than Output
324 def NeedsUpdate(Output
, Input
):
325 if not os
.path
.exists(Output
):
327 # always update "Output" if no "Input" given
328 if Input
== None or len(Input
) == 0:
331 # if fdf file is changed after the 'Output" is generated, update the 'Output'
332 OutputTime
= os
.path
.getmtime(Output
)
333 if GenFdsGlobalVariable
.FdfFileTimeStamp
> OutputTime
:
337 # always update "Output" if any "Input" doesn't exist
338 if not os
.path
.exists(F
):
340 # always update "Output" if any "Input" is newer than "Output"
341 if os
.path
.getmtime(F
) > OutputTime
:
346 def GenerateSection(Output
, Input
, Type
=None, CompressionType
=None, Guid
=None,
347 GuidHdrLen
=None, GuidAttr
=[], Ui
=None, Ver
=None, InputAlign
=None):
348 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
):
350 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
353 if Type
not in [None, '']:
355 if CompressionType
not in [None, '']:
356 Cmd
+= ["-c", CompressionType
]
359 if GuidHdrLen
not in [None, '']:
360 Cmd
+= ["-l", GuidHdrLen
]
361 if len(GuidAttr
) != 0:
362 #Add each guided attribute
363 for Attr
in GuidAttr
:
365 if InputAlign
!= None:
366 #Section Align is only for dummy section without section type
367 for SecAlign
in InputAlign
:
368 Cmd
+= ["--sectionalign", SecAlign
]
370 if Ui
not in [None, '']:
371 #Cmd += ["-n", '"' + Ui + '"']
372 SectionData
= array
.array('B', [0,0,0,0])
373 SectionData
.fromstring(Ui
.encode("utf_16_le"))
374 SectionData
.append(0)
375 SectionData
.append(0)
376 Len
= len(SectionData
)
377 GenFdsGlobalVariable
.SectionHeader
.pack_into(SectionData
, 0, Len
& 0xff, (Len
>> 8) & 0xff, (Len
>> 16) & 0xff, 0x15)
378 SaveFileOnChange(Output
, SectionData
.tostring())
379 elif Ver
not in [None, '']:
381 SectionData
= array
.array('B', [0,0,0,0])
382 SectionData
.fromstring(Ver
.encode("utf_16_le"))
383 SectionData
.append(0)
384 SectionData
.append(0)
385 Len
= len(SectionData
)
386 GenFdsGlobalVariable
.SectionHeader
.pack_into(SectionData
, 0, Len
& 0xff, (Len
>> 8) & 0xff, (Len
>> 16) & 0xff, 0x14)
387 SaveFileOnChange(Output
, SectionData
.tostring())
389 Cmd
+= ["-o", Output
]
391 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate section")
394 def GetAlignment (AlignString
):
395 if AlignString
== None:
397 if AlignString
in ("1K", "2K", "4K", "8K", "16K", "32K", "64K"):
398 return int (AlignString
.rstrip('K')) * 1024
400 return int (AlignString
)
403 def GenerateFfs(Output
, Input
, Type
, Guid
, Fixed
=False, CheckSum
=False, Align
=None,
405 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
):
407 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
409 Cmd
= ["GenFfs", "-t", Type
, "-g", Guid
]
414 if Align
not in [None, '']:
417 Cmd
+= ["-o", Output
]
418 for I
in range(0, len(Input
)):
419 Cmd
+= ("-i", Input
[I
])
420 if SectionAlign
not in [None, '', []] and SectionAlign
[I
] not in [None, '']:
421 Cmd
+= ("-n", SectionAlign
[I
])
422 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate FFS")
425 def GenerateFirmwareVolume(Output
, Input
, BaseAddress
=None, Capsule
=False, Dump
=False,
426 AddressFile
=None, MapFile
=None, FfsList
=[]):
427 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
+FfsList
):
429 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
432 if BaseAddress
not in [None, '']:
433 Cmd
+= ["-r", BaseAddress
]
438 if AddressFile
not in [None, '']:
439 Cmd
+= ["-a", AddressFile
]
440 if MapFile
not in [None, '']:
441 Cmd
+= ["-m", MapFile
]
442 Cmd
+= ["-o", Output
]
446 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate FV")
449 def GenerateVtf(Output
, Input
, BaseAddress
=None, FvSize
=None):
450 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
):
452 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
455 if BaseAddress
not in [None, ''] and FvSize
not in [None, ''] \
456 and len(BaseAddress
) == len(FvSize
):
457 for I
in range(0, len(BaseAddress
)):
458 Cmd
+= ["-r", BaseAddress
[I
], "-s", FvSize
[I
]]
459 Cmd
+= ["-o", Output
]
463 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate VTF")
466 def GenerateFirmwareImage(Output
, Input
, Type
="efi", SubType
=None, Zero
=False,
467 Strip
=False, Replace
=False, TimeStamp
=None, Join
=False,
468 Align
=None, Padding
=None, Convert
=False):
469 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
):
471 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
474 if Type
.lower() == "te":
476 if SubType
not in [None, '']:
477 Cmd
+= ["-e", SubType
]
478 if TimeStamp
not in [None, '']:
479 Cmd
+= ["-s", TimeStamp
]
480 if Align
not in [None, '']:
482 if Padding
not in [None, '']:
483 Cmd
+= ["-p", Padding
]
494 Cmd
+= ["-o", Output
]
497 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate firmware image")
500 def GenerateOptionRom(Output
, EfiInput
, BinaryInput
, Compress
=False, ClassCode
=None,
501 Revision
=None, DeviceId
=None, VendorId
=None):
504 if len(EfiInput
) > 0:
511 for EfiFile
in EfiInput
:
513 InputList
.append (EfiFile
)
515 if len(BinaryInput
) > 0:
517 for BinFile
in BinaryInput
:
519 InputList
.append (BinFile
)
522 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, InputList
):
524 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, InputList
))
526 if ClassCode
!= None:
527 Cmd
+= ["-l", ClassCode
]
529 Cmd
+= ["-r", Revision
]
531 Cmd
+= ["-i", DeviceId
]
533 Cmd
+= ["-f", VendorId
]
535 Cmd
+= ["-o", Output
]
536 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate option rom")
539 def GuidTool(Output
, Input
, ToolPath
, Options
='', returnValue
=[]):
540 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
):
542 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
545 Cmd
+= Options
.split(' ')
546 Cmd
+= ["-o", Output
]
549 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to call " + ToolPath
, returnValue
)
551 def CallExternalTool (cmd
, errorMess
, returnValue
=[]):
553 if type(cmd
) not in (tuple, list):
554 GenFdsGlobalVariable
.ErrorLogger("ToolError! Invalid parameter type in call to CallExternalTool")
556 if GenFdsGlobalVariable
.DebugLevel
!= -1:
557 cmd
+= ('--debug', str(GenFdsGlobalVariable
.DebugLevel
))
558 GenFdsGlobalVariable
.InfLogger (cmd
)
560 if GenFdsGlobalVariable
.VerboseMode
:
562 GenFdsGlobalVariable
.InfLogger (cmd
)
564 sys
.stdout
.write ('#')
566 GenFdsGlobalVariable
.SharpCounter
= GenFdsGlobalVariable
.SharpCounter
+ 1
567 if GenFdsGlobalVariable
.SharpCounter
% GenFdsGlobalVariable
.SharpNumberPerLine
== 0:
568 sys
.stdout
.write('\n')
571 PopenObject
= subprocess
.Popen(cmd
, stdout
=subprocess
.PIPE
, stderr
= subprocess
.PIPE
)
573 EdkLogger
.error("GenFds", COMMAND_FAILURE
, ExtraData
="%s: %s" % (str(X
), cmd
[0]))
574 (out
, error
) = PopenObject
.communicate()
576 while PopenObject
.returncode
== None :
578 if returnValue
!= [] and returnValue
[0] != 0:
579 #get command return value
580 returnValue
[0] = PopenObject
.returncode
582 if PopenObject
.returncode
!= 0 or GenFdsGlobalVariable
.VerboseMode
or GenFdsGlobalVariable
.DebugLevel
!= -1:
583 GenFdsGlobalVariable
.InfLogger ("Return Value = %d" %PopenObject
.returncode
)
584 GenFdsGlobalVariable
.InfLogger (out
)
585 GenFdsGlobalVariable
.InfLogger (error
)
586 if PopenObject
.returncode
!= 0:
588 EdkLogger
.error("GenFds", COMMAND_FAILURE
, errorMess
)
590 def VerboseLogger (msg
):
591 EdkLogger
.verbose(msg
)
596 def ErrorLogger (msg
, File
= None, Line
= None, ExtraData
= None):
597 EdkLogger
.error('GenFds', GENFDS_ERROR
, msg
, File
, Line
, ExtraData
)
599 def DebugLogger (Level
, msg
):
600 EdkLogger
.debug(Level
, msg
)
602 ## ReplaceWorkspaceMacro()
604 # @param Str String that may contain macro
605 # @param MacroDict Dictionary that contains macro value pair
607 def MacroExtend (Str
, MacroDict
= {}, Arch
= 'COMMON'):
611 Dict
= {'$(WORKSPACE)' : GenFdsGlobalVariable
.WorkSpaceDir
,
612 '$(EDK_SOURCE)' : GenFdsGlobalVariable
.EdkSourceDir
,
613 # '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc,
614 '$(TARGET)' : GenFdsGlobalVariable
.TargetName
,
615 '$(TOOL_CHAIN_TAG)' : GenFdsGlobalVariable
.ToolChainTag
617 OutputDir
= GenFdsGlobalVariable
.OutputDirFromDscDict
[GenFdsGlobalVariable
.ArchList
[0]]
618 if Arch
!= 'COMMON' and Arch
in GenFdsGlobalVariable
.ArchList
:
619 OutputDir
= GenFdsGlobalVariable
.OutputDirFromDscDict
[Arch
]
621 Dict
['$(OUTPUT_DIRECTORY)'] = OutputDir
623 if MacroDict
!= None and len (MacroDict
) != 0:
624 Dict
.update(MacroDict
)
626 for key
in Dict
.keys():
627 if Str
.find(key
) >= 0 :
628 Str
= Str
.replace (key
, Dict
[key
])
630 if Str
.find('$(ARCH)') >= 0:
631 if len(GenFdsGlobalVariable
.ArchList
) == 1:
632 Str
= Str
.replace('$(ARCH)', GenFdsGlobalVariable
.ArchList
[0])
634 EdkLogger
.error("GenFds", GENFDS_ERROR
, "No way to determine $(ARCH) for %s" % Str
)
640 # @param PcdPattern pattern that labels a PCD.
642 def GetPcdValue (PcdPattern
):
643 if PcdPattern
== None :
645 PcdPair
= PcdPattern
.lstrip('PCD(').rstrip(')').strip().split('.')
646 TokenSpace
= PcdPair
[0]
647 TokenCName
= PcdPair
[1]
650 for Platform
in GenFdsGlobalVariable
.WorkSpace
.PlatformList
:
652 # Only process platform which match current build option.
654 if Platform
.MetaFile
== GenFdsGlobalVariable
.ActivePlatform
:
655 PcdDict
= Platform
.Pcds
657 PcdObj
= PcdDict
[Key
]
658 if (PcdObj
.TokenCName
== TokenCName
) and (PcdObj
.TokenSpaceGuidCName
== TokenSpace
):
659 if PcdObj
.Type
!= 'FixedAtBuild':
660 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not FixedAtBuild type." % PcdPattern
)
661 if PcdObj
.DatumType
!= 'VOID*':
662 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not VOID* datum type." % PcdPattern
)
664 PcdValue
= PcdObj
.DefaultValue
667 for Package
in GenFdsGlobalVariable
.WorkSpace
.PackageList
:
668 PcdDict
= Package
.Pcds
670 PcdObj
= PcdDict
[Key
]
671 if (PcdObj
.TokenCName
== TokenCName
) and (PcdObj
.TokenSpaceGuidCName
== TokenSpace
):
672 if PcdObj
.Type
!= 'FixedAtBuild':
673 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not FixedAtBuild type." % PcdPattern
)
674 if PcdObj
.DatumType
!= 'VOID*':
675 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not VOID* datum type." % PcdPattern
)
677 PcdValue
= PcdObj
.DefaultValue
682 SetDir
= staticmethod(SetDir
)
683 ReplaceWorkspaceMacro
= staticmethod(ReplaceWorkspaceMacro
)
684 CallExternalTool
= staticmethod(CallExternalTool
)
685 VerboseLogger
= staticmethod(VerboseLogger
)
686 InfLogger
= staticmethod(InfLogger
)
687 ErrorLogger
= staticmethod(ErrorLogger
)
688 DebugLogger
= staticmethod(DebugLogger
)
689 MacroExtend
= staticmethod (MacroExtend
)
690 GetPcdValue
= staticmethod(GetPcdValue
)