2 # Global variables for GenFds
4 # Copyright (c) 2007 - 2017, 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.
18 import Common
.LongFilePathOs
as os
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
33 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
34 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
39 class GenFdsGlobalVariable
:
43 # will be FvDir + os.sep + 'Ffs'
51 OutputDirFromDscDict
= {}
58 FvAddressFileName
= ''
62 SharpNumberPerLine
= 40
65 FixedLoadAddress
= False
68 BuildRuleFamily
= "MSFT"
69 ToolChainFamily
= "MSFT"
70 __BuildRuleDatabase
= None
71 GuidToolDefinition
= {}
74 # The list whose element are flags to indicate if large FFS or SECTION files exist in FV.
75 # At the beginning of each generation of FV, false flag is appended to the list,
76 # after the call to GenerateSection returns, check the size of the output file,
77 # if it is greater than 0xFFFFFF, the tail flag in list is set to true,
78 # and EFI_FIRMWARE_FILE_SYSTEM3_GUID is passed to C GenFv.
79 # At the end of generation of FV, pop the flag.
80 # List is used as a stack to handle nested FV generation.
82 LargeFileInFvFlags
= []
83 EFI_FIRMWARE_FILE_SYSTEM3_GUID
= '5473C07A-3DCB-4dca-BD6F-1E9689E7349A'
84 LARGE_FILE_SIZE
= 0x1000000
86 SectionHeader
= struct
.Struct("3B 1B")
91 def __LoadBuildRule():
92 if GenFdsGlobalVariable
.__BuildRuleDatabase
:
93 return GenFdsGlobalVariable
.__BuildRuleDatabase
94 BuildConfigurationFile
= os
.path
.normpath(os
.path
.join(GenFdsGlobalVariable
.ConfDir
, "target.txt"))
95 TargetTxt
= TargetTxtClassObject()
96 if os
.path
.isfile(BuildConfigurationFile
) == True:
97 TargetTxt
.LoadTargetTxtFile(BuildConfigurationFile
)
98 if DataType
.TAB_TAT_DEFINES_BUILD_RULE_CONF
in TargetTxt
.TargetTxtDictionary
:
99 BuildRuleFile
= TargetTxt
.TargetTxtDictionary
[DataType
.TAB_TAT_DEFINES_BUILD_RULE_CONF
]
100 if BuildRuleFile
in [None, '']:
101 BuildRuleFile
= 'Conf/build_rule.txt'
102 GenFdsGlobalVariable
.__BuildRuleDatabase
= BuildRule(BuildRuleFile
)
103 ToolDefinitionFile
= TargetTxt
.TargetTxtDictionary
[DataType
.TAB_TAT_DEFINES_TOOL_CHAIN_CONF
]
104 if ToolDefinitionFile
== '':
105 ToolDefinitionFile
= "Conf/tools_def.txt"
106 if os
.path
.isfile(ToolDefinitionFile
):
107 ToolDef
= ToolDefClassObject()
108 ToolDef
.LoadToolDefFile(ToolDefinitionFile
)
109 ToolDefinition
= ToolDef
.ToolsDefTxtDatabase
110 if DataType
.TAB_TOD_DEFINES_BUILDRULEFAMILY
in ToolDefinition \
111 and GenFdsGlobalVariable
.ToolChainTag
in ToolDefinition
[DataType
.TAB_TOD_DEFINES_BUILDRULEFAMILY
] \
112 and ToolDefinition
[DataType
.TAB_TOD_DEFINES_BUILDRULEFAMILY
][GenFdsGlobalVariable
.ToolChainTag
]:
113 GenFdsGlobalVariable
.BuildRuleFamily
= ToolDefinition
[DataType
.TAB_TOD_DEFINES_BUILDRULEFAMILY
][GenFdsGlobalVariable
.ToolChainTag
]
115 if DataType
.TAB_TOD_DEFINES_FAMILY
in ToolDefinition \
116 and GenFdsGlobalVariable
.ToolChainTag
in ToolDefinition
[DataType
.TAB_TOD_DEFINES_FAMILY
] \
117 and ToolDefinition
[DataType
.TAB_TOD_DEFINES_FAMILY
][GenFdsGlobalVariable
.ToolChainTag
]:
118 GenFdsGlobalVariable
.ToolChainFamily
= ToolDefinition
[DataType
.TAB_TOD_DEFINES_FAMILY
][GenFdsGlobalVariable
.ToolChainTag
]
119 return GenFdsGlobalVariable
.__BuildRuleDatabase
122 # @param Inf: object of InfBuildData
123 # @param Arch: current arch
126 def GetBuildRules(Inf
, Arch
):
130 if not Arch
in GenFdsGlobalVariable
.OutputDirDict
:
133 BuildRuleDatabase
= GenFdsGlobalVariable
.__LoadBuildRule
()
134 if not BuildRuleDatabase
:
137 PathClassObj
= PathClass(Inf
.MetaFile
.File
,
138 GenFdsGlobalVariable
.WorkSpaceDir
)
140 Macro
["WORKSPACE" ] = GenFdsGlobalVariable
.WorkSpaceDir
141 Macro
["MODULE_NAME" ] = Inf
.BaseName
142 Macro
["MODULE_GUID" ] = Inf
.Guid
143 Macro
["MODULE_VERSION" ] = Inf
.Version
144 Macro
["MODULE_TYPE" ] = Inf
.ModuleType
145 Macro
["MODULE_FILE" ] = str(PathClassObj
)
146 Macro
["MODULE_FILE_BASE_NAME" ] = PathClassObj
.BaseName
147 Macro
["MODULE_RELATIVE_DIR" ] = PathClassObj
.SubDir
148 Macro
["MODULE_DIR" ] = PathClassObj
.SubDir
150 Macro
["BASE_NAME" ] = Inf
.BaseName
152 Macro
["ARCH" ] = Arch
153 Macro
["TOOLCHAIN" ] = GenFdsGlobalVariable
.ToolChainTag
154 Macro
["TOOLCHAIN_TAG" ] = GenFdsGlobalVariable
.ToolChainTag
155 Macro
["TOOL_CHAIN_TAG" ] = GenFdsGlobalVariable
.ToolChainTag
156 Macro
["TARGET" ] = GenFdsGlobalVariable
.TargetName
158 Macro
["BUILD_DIR" ] = GenFdsGlobalVariable
.OutputDirDict
[Arch
]
159 Macro
["BIN_DIR" ] = os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
], Arch
)
160 Macro
["LIB_DIR" ] = os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
], Arch
)
161 BuildDir
= os
.path
.join(
162 GenFdsGlobalVariable
.OutputDirDict
[Arch
],
165 PathClassObj
.BaseName
167 Macro
["MODULE_BUILD_DIR" ] = BuildDir
168 Macro
["OUTPUT_DIR" ] = os
.path
.join(BuildDir
, "OUTPUT")
169 Macro
["DEBUG_DIR" ] = os
.path
.join(BuildDir
, "DEBUG")
172 for Type
in BuildRuleDatabase
.FileTypeList
:
173 #first try getting build rule by BuildRuleFamily
174 RuleObject
= BuildRuleDatabase
[Type
, Inf
.BuildType
, Arch
, GenFdsGlobalVariable
.BuildRuleFamily
]
176 # build type is always module type, but ...
177 if Inf
.ModuleType
!= Inf
.BuildType
:
178 RuleObject
= BuildRuleDatabase
[Type
, Inf
.ModuleType
, Arch
, GenFdsGlobalVariable
.BuildRuleFamily
]
179 #second try getting build rule by ToolChainFamily
181 RuleObject
= BuildRuleDatabase
[Type
, Inf
.BuildType
, Arch
, GenFdsGlobalVariable
.ToolChainFamily
]
183 # build type is always module type, but ...
184 if Inf
.ModuleType
!= Inf
.BuildType
:
185 RuleObject
= BuildRuleDatabase
[Type
, Inf
.ModuleType
, Arch
, GenFdsGlobalVariable
.ToolChainFamily
]
188 RuleObject
= RuleObject
.Instantiate(Macro
)
189 BuildRules
[Type
] = RuleObject
190 for Ext
in RuleObject
.SourceFileExtList
:
191 BuildRules
[Ext
] = RuleObject
194 ## GetModuleCodaTargetList
196 # @param Inf: object of InfBuildData
197 # @param Arch: current arch
200 def GetModuleCodaTargetList(Inf
, Arch
):
201 BuildRules
= GenFdsGlobalVariable
.GetBuildRules(Inf
, Arch
)
208 if not Inf
.IsBinaryModule
:
209 for File
in Inf
.Sources
:
210 if File
.TagName
in ("", "*", GenFdsGlobalVariable
.ToolChainTag
) and \
211 File
.ToolChainFamily
in ("", "*", GenFdsGlobalVariable
.ToolChainFamily
):
212 FileList
.append((File
, DataType
.TAB_UNKNOWN_FILE
))
214 for File
in Inf
.Binaries
:
215 if File
.Target
in ['COMMON', '*', GenFdsGlobalVariable
.TargetName
]:
216 FileList
.append((File
, File
.Type
))
218 for File
, FileType
in FileList
:
223 while Index
< len(SourceList
):
224 Source
= SourceList
[Index
]
227 if File
.IsBinary
and File
== Source
and Inf
.Binaries
!= None and File
in Inf
.Binaries
:
228 # Skip all files that are not binary libraries
229 if not Inf
.LibraryClass
:
231 RuleObject
= BuildRules
[DataType
.TAB_DEFAULT_BINARY_FILE
]
232 elif FileType
in BuildRules
:
233 RuleObject
= BuildRules
[FileType
]
234 elif Source
.Ext
in BuildRules
:
235 RuleObject
= BuildRules
[Source
.Ext
]
237 # stop at no more rules
239 TargetList
.add(str(LastTarget
))
242 FileType
= RuleObject
.SourceFileType
244 # stop at STATIC_LIBRARY for library
245 if Inf
.LibraryClass
and FileType
== DataType
.TAB_STATIC_LIBRARY
:
247 TargetList
.add(str(LastTarget
))
250 Target
= RuleObject
.Apply(Source
)
253 TargetList
.add(str(LastTarget
))
255 elif not Target
.Outputs
:
256 # Only do build for target with outputs
257 TargetList
.add(str(Target
))
259 # to avoid cyclic rule
260 if FileType
in RuleChain
:
263 RuleChain
.append(FileType
)
264 SourceList
.extend(Target
.Outputs
)
266 FileType
= DataType
.TAB_UNKNOWN_FILE
268 return list(TargetList
)
272 # @param OutputDir Output directory
273 # @param FdfParser FDF contents parser
274 # @param Workspace The directory of workspace
275 # @param ArchList The Arch list of platform
277 def SetDir (OutputDir
, FdfParser
, WorkSpace
, ArchList
):
278 GenFdsGlobalVariable
.VerboseLogger("GenFdsGlobalVariable.OutputDir :%s" % OutputDir
)
279 # GenFdsGlobalVariable.OutputDirDict = OutputDir
280 GenFdsGlobalVariable
.FdfParser
= FdfParser
281 GenFdsGlobalVariable
.WorkSpace
= WorkSpace
282 GenFdsGlobalVariable
.FvDir
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[ArchList
[0]], 'FV')
283 if not os
.path
.exists(GenFdsGlobalVariable
.FvDir
) :
284 os
.makedirs(GenFdsGlobalVariable
.FvDir
)
285 GenFdsGlobalVariable
.FfsDir
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, 'Ffs')
286 if not os
.path
.exists(GenFdsGlobalVariable
.FfsDir
) :
287 os
.makedirs(GenFdsGlobalVariable
.FfsDir
)
291 # Create FV Address inf file
293 GenFdsGlobalVariable
.FvAddressFileName
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, 'FvAddress.inf')
294 FvAddressFile
= open(GenFdsGlobalVariable
.FvAddressFileName
, 'w')
298 FvAddressFile
.writelines("[options]" + T_CHAR_LF
)
300 for Arch
in ArchList
:
301 if GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
].BsBaseAddress
:
302 BsAddress
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
].BsBaseAddress
305 FvAddressFile
.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \
310 for Arch
in ArchList
:
311 if GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
].RtBaseAddress
:
312 RtAddress
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
].RtBaseAddress
314 FvAddressFile
.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \
318 FvAddressFile
.close()
320 ## ReplaceWorkspaceMacro()
322 # @param String String that may contain macro
324 def ReplaceWorkspaceMacro(String
):
325 String
= mws
.handleWsMacro(String
)
326 Str
= String
.replace('$(WORKSPACE)', GenFdsGlobalVariable
.WorkSpaceDir
)
327 if os
.path
.exists(Str
):
328 if not os
.path
.isabs(Str
):
329 Str
= os
.path
.abspath(Str
)
331 Str
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, String
)
332 return os
.path
.normpath(Str
)
334 ## Check if the input files are newer than output files
336 # @param Output Path of output file
337 # @param Input Path list of input files
339 # @retval True if Output doesn't exist, or any Input is newer
340 # @retval False if all Input is older than Output
343 def NeedsUpdate(Output
, Input
):
344 if not os
.path
.exists(Output
):
346 # always update "Output" if no "Input" given
347 if Input
== None or len(Input
) == 0:
350 # if fdf file is changed after the 'Output" is generated, update the 'Output'
351 OutputTime
= os
.path
.getmtime(Output
)
352 if GenFdsGlobalVariable
.FdfFileTimeStamp
> OutputTime
:
356 # always update "Output" if any "Input" doesn't exist
357 if not os
.path
.exists(F
):
359 # always update "Output" if any "Input" is newer than "Output"
360 if os
.path
.getmtime(F
) > OutputTime
:
365 def GenerateSection(Output
, Input
, Type
=None, CompressionType
=None, Guid
=None,
366 GuidHdrLen
=None, GuidAttr
=[], Ui
=None, Ver
=None, InputAlign
=None, BuildNumber
=None):
368 if Type
not in [None, '']:
370 if CompressionType
not in [None, '']:
371 Cmd
+= ["-c", CompressionType
]
374 if GuidHdrLen
not in [None, '']:
375 Cmd
+= ["-l", GuidHdrLen
]
376 if len(GuidAttr
) != 0:
377 #Add each guided attribute
378 for Attr
in GuidAttr
:
380 if InputAlign
!= None:
381 #Section Align is only for dummy section without section type
382 for SecAlign
in InputAlign
:
383 Cmd
+= ["--sectionalign", SecAlign
]
385 CommandFile
= Output
+ '.txt'
386 if Ui
not in [None, '']:
387 #Cmd += ["-n", '"' + Ui + '"']
388 SectionData
= array
.array('B', [0, 0, 0, 0])
389 SectionData
.fromstring(Ui
.encode("utf_16_le"))
390 SectionData
.append(0)
391 SectionData
.append(0)
392 Len
= len(SectionData
)
393 GenFdsGlobalVariable
.SectionHeader
.pack_into(SectionData
, 0, Len
& 0xff, (Len
>> 8) & 0xff, (Len
>> 16) & 0xff, 0x15)
394 SaveFileOnChange(Output
, SectionData
.tostring())
395 elif Ver
not in [None, '']:
398 Cmd
+= ["-j", BuildNumber
]
399 Cmd
+= ["-o", Output
]
401 SaveFileOnChange(CommandFile
, ' '.join(Cmd
), False)
402 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, list(Input
) + [CommandFile
]):
405 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate section")
407 Cmd
+= ["-o", Output
]
410 SaveFileOnChange(CommandFile
, ' '.join(Cmd
), False)
411 if GenFdsGlobalVariable
.NeedsUpdate(Output
, list(Input
) + [CommandFile
]):
412 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
413 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate section")
415 if (os
.path
.getsize(Output
) >= GenFdsGlobalVariable
.LARGE_FILE_SIZE
and
416 GenFdsGlobalVariable
.LargeFileInFvFlags
):
417 GenFdsGlobalVariable
.LargeFileInFvFlags
[-1] = True
420 def GetAlignment (AlignString
):
421 if AlignString
== None:
423 if AlignString
in ("1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K"):
424 return int (AlignString
.rstrip('K')) * 1024
425 elif AlignString
in ("1M", "2M", "4M", "8M", "16M"):
426 return int (AlignString
.rstrip('M')) * 1024 * 1024
428 return int (AlignString
)
431 def GenerateFfs(Output
, Input
, Type
, Guid
, Fixed
=False, CheckSum
=False, Align
=None,
433 Cmd
= ["GenFfs", "-t", Type
, "-g", Guid
]
434 mFfsValidAlign
= ["0", "8", "16", "128", "512", "1K", "4K", "32K", "64K", "128K", "256K", "512K", "1M", "2M", "4M", "8M", "16M"]
439 if Align
not in [None, '']:
440 if Align
not in mFfsValidAlign
:
441 Align
= GenFdsGlobalVariable
.GetAlignment (Align
)
442 for index
in range(0, len(mFfsValidAlign
) - 1):
443 if ((Align
> GenFdsGlobalVariable
.GetAlignment(mFfsValidAlign
[index
])) and (Align
<= GenFdsGlobalVariable
.GetAlignment(mFfsValidAlign
[index
+ 1]))):
445 Align
= mFfsValidAlign
[index
+ 1]
448 Cmd
+= ["-o", Output
]
449 for I
in range(0, len(Input
)):
450 Cmd
+= ("-i", Input
[I
])
451 if SectionAlign
not in [None, '', []] and SectionAlign
[I
] not in [None, '']:
452 Cmd
+= ("-n", SectionAlign
[I
])
454 CommandFile
= Output
+ '.txt'
455 SaveFileOnChange(CommandFile
, ' '.join(Cmd
), False)
456 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, list(Input
) + [CommandFile
]):
458 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
460 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate FFS")
463 def GenerateFirmwareVolume(Output
, Input
, BaseAddress
=None, ForceRebase
=None, Capsule
=False, Dump
=False,
464 AddressFile
=None, MapFile
=None, FfsList
=[], FileSystemGuid
=None):
465 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
+FfsList
):
467 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
470 if BaseAddress
not in [None, '']:
471 Cmd
+= ["-r", BaseAddress
]
473 if ForceRebase
== False:
474 Cmd
+= ["-F", "FALSE"]
475 elif ForceRebase
== True:
476 Cmd
+= ["-F", "TRUE"]
482 if AddressFile
not in [None, '']:
483 Cmd
+= ["-a", AddressFile
]
484 if MapFile
not in [None, '']:
485 Cmd
+= ["-m", MapFile
]
487 Cmd
+= ["-g", FileSystemGuid
]
488 Cmd
+= ["-o", Output
]
492 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate FV")
495 def GenerateVtf(Output
, Input
, BaseAddress
=None, FvSize
=None):
496 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
):
498 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
501 if BaseAddress
not in [None, ''] and FvSize
not in [None, ''] \
502 and len(BaseAddress
) == len(FvSize
):
503 for I
in range(0, len(BaseAddress
)):
504 Cmd
+= ["-r", BaseAddress
[I
], "-s", FvSize
[I
]]
505 Cmd
+= ["-o", Output
]
509 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate VTF")
512 def GenerateFirmwareImage(Output
, Input
, Type
="efi", SubType
=None, Zero
=False,
513 Strip
=False, Replace
=False, TimeStamp
=None, Join
=False,
514 Align
=None, Padding
=None, Convert
=False):
515 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
):
517 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
520 if Type
.lower() == "te":
522 if SubType
not in [None, '']:
523 Cmd
+= ["-e", SubType
]
524 if TimeStamp
not in [None, '']:
525 Cmd
+= ["-s", TimeStamp
]
526 if Align
not in [None, '']:
528 if Padding
not in [None, '']:
529 Cmd
+= ["-p", Padding
]
540 Cmd
+= ["-o", Output
]
543 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate firmware image")
546 def GenerateOptionRom(Output
, EfiInput
, BinaryInput
, Compress
=False, ClassCode
=None,
547 Revision
=None, DeviceId
=None, VendorId
=None):
550 if len(EfiInput
) > 0:
557 for EfiFile
in EfiInput
:
559 InputList
.append (EfiFile
)
561 if len(BinaryInput
) > 0:
563 for BinFile
in BinaryInput
:
565 InputList
.append (BinFile
)
568 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, InputList
):
570 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, InputList
))
572 if ClassCode
!= None:
573 Cmd
+= ["-l", ClassCode
]
575 Cmd
+= ["-r", Revision
]
577 Cmd
+= ["-i", DeviceId
]
579 Cmd
+= ["-f", VendorId
]
581 Cmd
+= ["-o", Output
]
582 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate option rom")
585 def GuidTool(Output
, Input
, ToolPath
, Options
='', returnValue
=[]):
586 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
):
588 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
591 Cmd
+= Options
.split(' ')
592 Cmd
+= ["-o", Output
]
595 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to call " + ToolPath
, returnValue
)
597 def CallExternalTool (cmd
, errorMess
, returnValue
=[]):
599 if type(cmd
) not in (tuple, list):
600 GenFdsGlobalVariable
.ErrorLogger("ToolError! Invalid parameter type in call to CallExternalTool")
602 if GenFdsGlobalVariable
.DebugLevel
!= -1:
603 cmd
+= ('--debug', str(GenFdsGlobalVariable
.DebugLevel
))
604 GenFdsGlobalVariable
.InfLogger (cmd
)
606 if GenFdsGlobalVariable
.VerboseMode
:
608 GenFdsGlobalVariable
.InfLogger (cmd
)
610 sys
.stdout
.write ('#')
612 GenFdsGlobalVariable
.SharpCounter
= GenFdsGlobalVariable
.SharpCounter
+ 1
613 if GenFdsGlobalVariable
.SharpCounter
% GenFdsGlobalVariable
.SharpNumberPerLine
== 0:
614 sys
.stdout
.write('\n')
617 PopenObject
= subprocess
.Popen(' '.join(cmd
), stdout
=subprocess
.PIPE
, stderr
=subprocess
.PIPE
, shell
=True)
619 EdkLogger
.error("GenFds", COMMAND_FAILURE
, ExtraData
="%s: %s" % (str(X
), cmd
[0]))
620 (out
, error
) = PopenObject
.communicate()
622 while PopenObject
.returncode
== None :
624 if returnValue
!= [] and returnValue
[0] != 0:
625 #get command return value
626 returnValue
[0] = PopenObject
.returncode
628 if PopenObject
.returncode
!= 0 or GenFdsGlobalVariable
.VerboseMode
or GenFdsGlobalVariable
.DebugLevel
!= -1:
629 GenFdsGlobalVariable
.InfLogger ("Return Value = %d" % PopenObject
.returncode
)
630 GenFdsGlobalVariable
.InfLogger (out
)
631 GenFdsGlobalVariable
.InfLogger (error
)
632 if PopenObject
.returncode
!= 0:
634 EdkLogger
.error("GenFds", COMMAND_FAILURE
, errorMess
)
636 def VerboseLogger (msg
):
637 EdkLogger
.verbose(msg
)
642 def ErrorLogger (msg
, File
=None, Line
=None, ExtraData
=None):
643 EdkLogger
.error('GenFds', GENFDS_ERROR
, msg
, File
, Line
, ExtraData
)
645 def DebugLogger (Level
, msg
):
646 EdkLogger
.debug(Level
, msg
)
648 ## ReplaceWorkspaceMacro()
650 # @param Str String that may contain macro
651 # @param MacroDict Dictionary that contains macro value pair
653 def MacroExtend (Str
, MacroDict
={}, Arch
='COMMON'):
657 Dict
= {'$(WORKSPACE)' : GenFdsGlobalVariable
.WorkSpaceDir
,
658 '$(EDK_SOURCE)' : GenFdsGlobalVariable
.EdkSourceDir
,
659 # '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc,
660 '$(TARGET)' : GenFdsGlobalVariable
.TargetName
,
661 '$(TOOL_CHAIN_TAG)' : GenFdsGlobalVariable
.ToolChainTag
,
664 OutputDir
= GenFdsGlobalVariable
.OutputDirFromDscDict
[GenFdsGlobalVariable
.ArchList
[0]]
665 if Arch
!= 'COMMON' and Arch
in GenFdsGlobalVariable
.ArchList
:
666 OutputDir
= GenFdsGlobalVariable
.OutputDirFromDscDict
[Arch
]
668 Dict
['$(OUTPUT_DIRECTORY)'] = OutputDir
670 if MacroDict
!= None and len (MacroDict
) != 0:
671 Dict
.update(MacroDict
)
673 for key
in Dict
.keys():
674 if Str
.find(key
) >= 0 :
675 Str
= Str
.replace (key
, Dict
[key
])
677 if Str
.find('$(ARCH)') >= 0:
678 if len(GenFdsGlobalVariable
.ArchList
) == 1:
679 Str
= Str
.replace('$(ARCH)', GenFdsGlobalVariable
.ArchList
[0])
681 EdkLogger
.error("GenFds", GENFDS_ERROR
, "No way to determine $(ARCH) for %s" % Str
)
687 # @param PcdPattern pattern that labels a PCD.
689 def GetPcdValue (PcdPattern
):
690 if PcdPattern
== None :
692 PcdPair
= PcdPattern
.lstrip('PCD(').rstrip(')').strip().split('.')
693 TokenSpace
= PcdPair
[0]
694 TokenCName
= PcdPair
[1]
697 for Arch
in GenFdsGlobalVariable
.ArchList
:
698 Platform
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
699 PcdDict
= Platform
.Pcds
701 PcdObj
= PcdDict
[Key
]
702 if (PcdObj
.TokenCName
== TokenCName
) and (PcdObj
.TokenSpaceGuidCName
== TokenSpace
):
703 if PcdObj
.Type
!= 'FixedAtBuild':
704 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not FixedAtBuild type." % PcdPattern
)
705 if PcdObj
.DatumType
!= 'VOID*':
706 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not VOID* datum type." % PcdPattern
)
708 PcdValue
= PcdObj
.DefaultValue
711 for Package
in GenFdsGlobalVariable
.WorkSpace
.GetPackageList(GenFdsGlobalVariable
.ActivePlatform
,
713 GenFdsGlobalVariable
.TargetName
,
714 GenFdsGlobalVariable
.ToolChainTag
):
715 PcdDict
= Package
.Pcds
717 PcdObj
= PcdDict
[Key
]
718 if (PcdObj
.TokenCName
== TokenCName
) and (PcdObj
.TokenSpaceGuidCName
== TokenSpace
):
719 if PcdObj
.Type
!= 'FixedAtBuild':
720 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not FixedAtBuild type." % PcdPattern
)
721 if PcdObj
.DatumType
!= 'VOID*':
722 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not VOID* datum type." % PcdPattern
)
724 PcdValue
= PcdObj
.DefaultValue
729 SetDir
= staticmethod(SetDir
)
730 ReplaceWorkspaceMacro
= staticmethod(ReplaceWorkspaceMacro
)
731 CallExternalTool
= staticmethod(CallExternalTool
)
732 VerboseLogger
= staticmethod(VerboseLogger
)
733 InfLogger
= staticmethod(InfLogger
)
734 ErrorLogger
= staticmethod(ErrorLogger
)
735 DebugLogger
= staticmethod(DebugLogger
)
736 MacroExtend
= staticmethod (MacroExtend
)
737 GetPcdValue
= staticmethod(GetPcdValue
)