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, ForceRebase
=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
]
435 if ForceRebase
== False:
436 Cmd
+=["-F", "FALSE"]
437 elif ForceRebase
== True:
444 if AddressFile
not in [None, '']:
445 Cmd
+= ["-a", AddressFile
]
446 if MapFile
not in [None, '']:
447 Cmd
+= ["-m", MapFile
]
448 Cmd
+= ["-o", Output
]
452 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate FV")
455 def GenerateVtf(Output
, Input
, BaseAddress
=None, FvSize
=None):
456 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
):
458 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
461 if BaseAddress
not in [None, ''] and FvSize
not in [None, ''] \
462 and len(BaseAddress
) == len(FvSize
):
463 for I
in range(0, len(BaseAddress
)):
464 Cmd
+= ["-r", BaseAddress
[I
], "-s", FvSize
[I
]]
465 Cmd
+= ["-o", Output
]
469 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate VTF")
472 def GenerateFirmwareImage(Output
, Input
, Type
="efi", SubType
=None, Zero
=False,
473 Strip
=False, Replace
=False, TimeStamp
=None, Join
=False,
474 Align
=None, Padding
=None, Convert
=False):
475 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
):
477 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
480 if Type
.lower() == "te":
482 if SubType
not in [None, '']:
483 Cmd
+= ["-e", SubType
]
484 if TimeStamp
not in [None, '']:
485 Cmd
+= ["-s", TimeStamp
]
486 if Align
not in [None, '']:
488 if Padding
not in [None, '']:
489 Cmd
+= ["-p", Padding
]
500 Cmd
+= ["-o", Output
]
503 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate firmware image")
506 def GenerateOptionRom(Output
, EfiInput
, BinaryInput
, Compress
=False, ClassCode
=None,
507 Revision
=None, DeviceId
=None, VendorId
=None):
510 if len(EfiInput
) > 0:
517 for EfiFile
in EfiInput
:
519 InputList
.append (EfiFile
)
521 if len(BinaryInput
) > 0:
523 for BinFile
in BinaryInput
:
525 InputList
.append (BinFile
)
528 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, InputList
):
530 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, InputList
))
532 if ClassCode
!= None:
533 Cmd
+= ["-l", ClassCode
]
535 Cmd
+= ["-r", Revision
]
537 Cmd
+= ["-i", DeviceId
]
539 Cmd
+= ["-f", VendorId
]
541 Cmd
+= ["-o", Output
]
542 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate option rom")
545 def GuidTool(Output
, Input
, ToolPath
, Options
='', returnValue
=[]):
546 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
):
548 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
551 Cmd
+= Options
.split(' ')
552 Cmd
+= ["-o", Output
]
555 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to call " + ToolPath
, returnValue
)
557 def CallExternalTool (cmd
, errorMess
, returnValue
=[]):
559 if type(cmd
) not in (tuple, list):
560 GenFdsGlobalVariable
.ErrorLogger("ToolError! Invalid parameter type in call to CallExternalTool")
562 if GenFdsGlobalVariable
.DebugLevel
!= -1:
563 cmd
+= ('--debug', str(GenFdsGlobalVariable
.DebugLevel
))
564 GenFdsGlobalVariable
.InfLogger (cmd
)
566 if GenFdsGlobalVariable
.VerboseMode
:
568 GenFdsGlobalVariable
.InfLogger (cmd
)
570 sys
.stdout
.write ('#')
572 GenFdsGlobalVariable
.SharpCounter
= GenFdsGlobalVariable
.SharpCounter
+ 1
573 if GenFdsGlobalVariable
.SharpCounter
% GenFdsGlobalVariable
.SharpNumberPerLine
== 0:
574 sys
.stdout
.write('\n')
577 PopenObject
= subprocess
.Popen(cmd
, stdout
=subprocess
.PIPE
, stderr
= subprocess
.PIPE
)
579 EdkLogger
.error("GenFds", COMMAND_FAILURE
, ExtraData
="%s: %s" % (str(X
), cmd
[0]))
580 (out
, error
) = PopenObject
.communicate()
582 while PopenObject
.returncode
== None :
584 if returnValue
!= [] and returnValue
[0] != 0:
585 #get command return value
586 returnValue
[0] = PopenObject
.returncode
588 if PopenObject
.returncode
!= 0 or GenFdsGlobalVariable
.VerboseMode
or GenFdsGlobalVariable
.DebugLevel
!= -1:
589 GenFdsGlobalVariable
.InfLogger ("Return Value = %d" %PopenObject
.returncode
)
590 GenFdsGlobalVariable
.InfLogger (out
)
591 GenFdsGlobalVariable
.InfLogger (error
)
592 if PopenObject
.returncode
!= 0:
594 EdkLogger
.error("GenFds", COMMAND_FAILURE
, errorMess
)
596 def VerboseLogger (msg
):
597 EdkLogger
.verbose(msg
)
602 def ErrorLogger (msg
, File
= None, Line
= None, ExtraData
= None):
603 EdkLogger
.error('GenFds', GENFDS_ERROR
, msg
, File
, Line
, ExtraData
)
605 def DebugLogger (Level
, msg
):
606 EdkLogger
.debug(Level
, msg
)
608 ## ReplaceWorkspaceMacro()
610 # @param Str String that may contain macro
611 # @param MacroDict Dictionary that contains macro value pair
613 def MacroExtend (Str
, MacroDict
= {}, Arch
= 'COMMON'):
617 Dict
= {'$(WORKSPACE)' : GenFdsGlobalVariable
.WorkSpaceDir
,
618 '$(EDK_SOURCE)' : GenFdsGlobalVariable
.EdkSourceDir
,
619 # '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc,
620 '$(TARGET)' : GenFdsGlobalVariable
.TargetName
,
621 '$(TOOL_CHAIN_TAG)' : GenFdsGlobalVariable
.ToolChainTag
623 OutputDir
= GenFdsGlobalVariable
.OutputDirFromDscDict
[GenFdsGlobalVariable
.ArchList
[0]]
624 if Arch
!= 'COMMON' and Arch
in GenFdsGlobalVariable
.ArchList
:
625 OutputDir
= GenFdsGlobalVariable
.OutputDirFromDscDict
[Arch
]
627 Dict
['$(OUTPUT_DIRECTORY)'] = OutputDir
629 if MacroDict
!= None and len (MacroDict
) != 0:
630 Dict
.update(MacroDict
)
632 for key
in Dict
.keys():
633 if Str
.find(key
) >= 0 :
634 Str
= Str
.replace (key
, Dict
[key
])
636 if Str
.find('$(ARCH)') >= 0:
637 if len(GenFdsGlobalVariable
.ArchList
) == 1:
638 Str
= Str
.replace('$(ARCH)', GenFdsGlobalVariable
.ArchList
[0])
640 EdkLogger
.error("GenFds", GENFDS_ERROR
, "No way to determine $(ARCH) for %s" % Str
)
646 # @param PcdPattern pattern that labels a PCD.
648 def GetPcdValue (PcdPattern
):
649 if PcdPattern
== None :
651 PcdPair
= PcdPattern
.lstrip('PCD(').rstrip(')').strip().split('.')
652 TokenSpace
= PcdPair
[0]
653 TokenCName
= PcdPair
[1]
656 for Platform
in GenFdsGlobalVariable
.WorkSpace
.PlatformList
:
658 # Only process platform which match current build option.
660 if Platform
.MetaFile
== GenFdsGlobalVariable
.ActivePlatform
:
661 PcdDict
= Platform
.Pcds
663 PcdObj
= PcdDict
[Key
]
664 if (PcdObj
.TokenCName
== TokenCName
) and (PcdObj
.TokenSpaceGuidCName
== TokenSpace
):
665 if PcdObj
.Type
!= 'FixedAtBuild':
666 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not FixedAtBuild type." % PcdPattern
)
667 if PcdObj
.DatumType
!= 'VOID*':
668 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not VOID* datum type." % PcdPattern
)
670 PcdValue
= PcdObj
.DefaultValue
673 for Package
in GenFdsGlobalVariable
.WorkSpace
.PackageList
:
674 PcdDict
= Package
.Pcds
676 PcdObj
= PcdDict
[Key
]
677 if (PcdObj
.TokenCName
== TokenCName
) and (PcdObj
.TokenSpaceGuidCName
== TokenSpace
):
678 if PcdObj
.Type
!= 'FixedAtBuild':
679 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not FixedAtBuild type." % PcdPattern
)
680 if PcdObj
.DatumType
!= 'VOID*':
681 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not VOID* datum type." % PcdPattern
)
683 PcdValue
= PcdObj
.DefaultValue
688 SetDir
= staticmethod(SetDir
)
689 ReplaceWorkspaceMacro
= staticmethod(ReplaceWorkspaceMacro
)
690 CallExternalTool
= staticmethod(CallExternalTool
)
691 VerboseLogger
= staticmethod(VerboseLogger
)
692 InfLogger
= staticmethod(InfLogger
)
693 ErrorLogger
= staticmethod(ErrorLogger
)
694 DebugLogger
= staticmethod(DebugLogger
)
695 MacroExtend
= staticmethod (MacroExtend
)
696 GetPcdValue
= staticmethod(GetPcdValue
)