]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
Sync BaseTools Branch (version r2271) to EDKII main trunk.
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / GenFdsGlobalVariable.py
CommitLineData
30fdf114
LG
1## @file
2# Global variables for GenFds
3#
40d841f6 4# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
30fdf114 5#
40d841f6 6# This program and the accompanying materials
30fdf114
LG
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
10#
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.
13#
14
15##
16# Import Modules
17#
18import os
19import sys
20import subprocess
21import struct
22import array
23
24from Common.BuildToolError import *
25from Common import EdkLogger
26from Common.Misc import SaveFileOnChange
27
4234283c
LG
28from Common.TargetTxtClassObject import TargetTxtClassObject
29from Common.ToolDefClassObject import ToolDefClassObject
30from AutoGen.BuildEngine import BuildRule
31import Common.DataType as DataType
32from Common.Misc import PathClass
33
30fdf114
LG
34## Global variables
35#
36#
37class GenFdsGlobalVariable:
38 FvDir = ''
39 OutputDirDict = {}
40 BinDir = ''
41 # will be FvDir + os.sep + 'Ffs'
42 FfsDir = ''
43 FdfParser = None
44 LibDir = ''
45 WorkSpace = None
46 WorkSpaceDir = ''
47 EdkSourceDir = ''
48 OutputDirFromDscDict = {}
49 TargetName = ''
50 ToolChainTag = ''
51 RuleDict = {}
52 ArchList = None
53 VtfDict = {}
54 ActivePlatform = None
55 FvAddressFileName = ''
56 VerboseMode = False
57 DebugLevel = -1
58 SharpCounter = 0
59 SharpNumberPerLine = 40
60 FdfFile = ''
61 FdfFileTimeStamp = 0
62 FixedLoadAddress = False
52302d4d 63 PlatformName = ''
4234283c
LG
64
65 BuildRuleFamily = "MSFT"
66 ToolChainFamily = "MSFT"
67 __BuildRuleDatabase = None
30fdf114
LG
68
69 SectionHeader = struct.Struct("3B 1B")
4234283c
LG
70
71 ## LoadBuildRule
72 #
73 @staticmethod
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]
97
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
103
104 ## GetBuildRules
105 # @param Inf: object of InfBuildData
106 # @param Arch: current arch
107 #
108 @staticmethod
109 def GetBuildRules(Inf, Arch):
110 if not Arch:
111 Arch = 'COMMON'
112
113 if not Arch in GenFdsGlobalVariable.OutputDirDict:
114 return {}
115
116 BuildRuleDatabase = GenFdsGlobalVariable.__LoadBuildRule()
117 if not BuildRuleDatabase:
118 return {}
119
120 PathClassObj = PathClass(str(Inf.MetaFile).lstrip(GenFdsGlobalVariable.WorkSpaceDir),
121 GenFdsGlobalVariable.WorkSpaceDir)
122 Macro = {}
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
132
133 Macro["BASE_NAME" ] = Inf.BaseName
134
135 Macro["ARCH" ] = Arch
136 Macro["TOOLCHAIN" ] = GenFdsGlobalVariable.ToolChainTag
137 Macro["TOOLCHAIN_TAG" ] = GenFdsGlobalVariable.ToolChainTag
138 Macro["TARGET" ] = GenFdsGlobalVariable.TargetName
139
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],
145 Arch,
146 PathClassObj.SubDir,
147 PathClassObj.BaseName
148 )
149 Macro["MODULE_BUILD_DIR" ] = BuildDir
150 Macro["OUTPUT_DIR" ] = os.path.join(BuildDir, "OUTPUT")
151 Macro["DEBUG_DIR" ] = os.path.join(BuildDir, "DEBUG")
152
153 BuildRules = {}
154 for Type in BuildRuleDatabase.FileTypeList:
155 #first try getting build rule by BuildRuleFamily
156 RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.BuildRuleFamily]
157 if not RuleObject:
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
162 if not RuleObject:
163 RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.ToolChainFamily]
164 if not RuleObject:
165 # build type is always module type, but ...
166 if Inf.ModuleType != Inf.BuildType:
167 RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.ToolChainFamily]
168 if not RuleObject:
169 continue
170 RuleObject = RuleObject.Instantiate(Macro)
171 BuildRules[Type] = RuleObject
172 for Ext in RuleObject.SourceFileExtList:
173 BuildRules[Ext] = RuleObject
174 return BuildRules
175
176 ## GetModuleCodaTargetList
177 #
178 # @param Inf: object of InfBuildData
179 # @param Arch: current arch
180 #
181 @staticmethod
182 def GetModuleCodaTargetList(Inf, Arch):
183 BuildRules = GenFdsGlobalVariable.GetBuildRules(Inf, Arch)
184 if not BuildRules:
185 return []
186
187 TargetList = set()
188 FileList = []
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))
193
194 for File in Inf.Binaries:
195 if File.Target in ['COMMON', '*', GenFdsGlobalVariable.TargetName]:
196 FileList.append((File, File.Type))
197
198 for File, FileType in FileList:
199 LastTarget = None
200 RuleChain = []
201 SourceList = [File]
202 Index = 0
203 while Index < len(SourceList):
204 Source = SourceList[Index]
205 Index = Index + 1
206
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:
210 continue
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]
216 else:
217 # stop at no more rules
218 if LastTarget:
219 TargetList.add(str(LastTarget))
220 break
221
222 FileType = RuleObject.SourceFileType
223
224 # stop at STATIC_LIBRARY for library
225 if Inf.LibraryClass and FileType == DataType.TAB_STATIC_LIBRARY:
226 if LastTarget:
227 TargetList.add(str(LastTarget))
228 break
229
230 Target = RuleObject.Apply(Source)
231 if not Target:
232 if LastTarget:
233 TargetList.add(str(LastTarget))
234 break
235 elif not Target.Outputs:
236 # Only do build for target with outputs
237 TargetList.add(str(Target))
238
239 # to avoid cyclic rule
240 if FileType in RuleChain:
241 break
242
243 RuleChain.append(FileType)
244 SourceList.extend(Target.Outputs)
245 LastTarget = Target
246 FileType = DataType.TAB_UNKNOWN_FILE
247
248 return list(TargetList)
30fdf114
LG
249
250 ## SetDir()
251 #
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
256 #
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)
268 if ArchList != None:
269 GenFdsGlobalVariable.ArchList = ArchList
270
271 T_CHAR_LF = '\n'
272 #
273 # Create FV Address inf file
274 #
275 GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf')
276 FvAddressFile = open (GenFdsGlobalVariable.FvAddressFileName, 'w')
277 #
278 # Add [Options]
279 #
280 FvAddressFile.writelines("[options]" + T_CHAR_LF)
281 BsAddress = '0'
282 for Arch in ArchList:
283 if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].BsBaseAddress:
284 BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].BsBaseAddress
285 break
286
287 FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \
288 BsAddress + \
289 T_CHAR_LF)
290
291 RtAddress = '0'
292 for Arch in ArchList:
293 if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].RtBaseAddress:
294 RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].RtBaseAddress
295
296 FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \
297 RtAddress + \
298 T_CHAR_LF)
299
300 FvAddressFile.close()
301
302 ## ReplaceWorkspaceMacro()
303 #
304 # @param String String that may contain macro
305 #
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)
311 else:
312 Str = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, String)
313 return os.path.normpath(Str)
314
315 ## Check if the input files are newer than output files
316 #
317 # @param Output Path of output file
318 # @param Input Path list of input files
319 #
320 # @retval True if Output doesn't exist, or any Input is newer
321 # @retval False if all Input is older than Output
322 #
323 @staticmethod
324 def NeedsUpdate(Output, Input):
325 if not os.path.exists(Output):
326 return True
327 # always update "Output" if no "Input" given
328 if Input == None or len(Input) == 0:
329 return True
330
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:
334 return True
335
336 for F in Input:
337 # always update "Output" if any "Input" doesn't exist
338 if not os.path.exists(F):
339 return True
340 # always update "Output" if any "Input" is newer than "Output"
341 if os.path.getmtime(F) > OutputTime:
342 return True
343 return False
344
345 @staticmethod
346 def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None,
52302d4d 347 GuidHdrLen=None, GuidAttr=[], Ui=None, Ver=None, InputAlign=None):
30fdf114
LG
348 if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
349 return
350 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
351
352 Cmd = ["GenSec"]
353 if Type not in [None, '']:
354 Cmd += ["-s", Type]
355 if CompressionType not in [None, '']:
356 Cmd += ["-c", CompressionType]
357 if Guid != None:
358 Cmd += ["-g", Guid]
359 if GuidHdrLen not in [None, '']:
360 Cmd += ["-l", GuidHdrLen]
52302d4d
LG
361 if len(GuidAttr) != 0:
362 #Add each guided attribute
363 for Attr in GuidAttr:
364 Cmd += ["-r", Attr]
365 if InputAlign != None:
366 #Section Align is only for dummy section without section type
367 for SecAlign in InputAlign:
368 Cmd += ["--sectionalign", SecAlign]
30fdf114
LG
369
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, '']:
380 #Cmd += ["-j", Ver]
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())
388 else:
389 Cmd += ["-o", Output]
390 Cmd += Input
391 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")
392
52302d4d
LG
393 @staticmethod
394 def GetAlignment (AlignString):
395 if AlignString == None:
396 return 0
397 if AlignString in ("1K", "2K", "4K", "8K", "16K", "32K", "64K"):\r
398 return int (AlignString.rstrip('K')) * 1024\r
399 else:\r
400 return int (AlignString)\r
401
30fdf114
LG
402 @staticmethod
403 def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None,
404 SectionAlign=None):
405 if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
406 return
407 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
408
409 Cmd = ["GenFfs", "-t", Type, "-g", Guid]
410 if Fixed == True:
411 Cmd += ["-x"]
412 if CheckSum:
413 Cmd += ["-s"]
414 if Align not in [None, '']:
415 Cmd += ["-a", Align]
416
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")
423
424 @staticmethod
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):
428 return
429 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
430
431 Cmd = ["GenFv"]
432 if BaseAddress not in [None, '']:
433 Cmd += ["-r", BaseAddress]
434 if Capsule:
435 Cmd += ["-c"]
436 if Dump:
437 Cmd += ["-p"]
438 if AddressFile not in [None, '']:
439 Cmd += ["-a", AddressFile]
440 if MapFile not in [None, '']:
441 Cmd += ["-m", MapFile]
442 Cmd += ["-o", Output]
443 for I in Input:
444 Cmd += ["-i", I]
445
446 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FV")
447
448 @staticmethod
449 def GenerateVtf(Output, Input, BaseAddress=None, FvSize=None):
450 if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
451 return
452 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
453
454 Cmd = ["GenVtf"]
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]
460 for F in Input:
461 Cmd += ["-f", F]
462
463 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate VTF")
464
465 @staticmethod
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):
470 return
471 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
472
473 Cmd = ["GenFw"]
474 if Type.lower() == "te":
475 Cmd += ["-t"]
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, '']:
481 Cmd += ["-a", Align]
482 if Padding not in [None, '']:
483 Cmd += ["-p", Padding]
484 if Zero:
485 Cmd += ["-z"]
486 if Strip:
487 Cmd += ["-l"]
488 if Replace:
489 Cmd += ["-r"]
490 if Join:
491 Cmd += ["-j"]
492 if Convert:
493 Cmd += ["-m"]
494 Cmd += ["-o", Output]
495 Cmd += Input
496
497 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image")
498
499 @staticmethod
500 def GenerateOptionRom(Output, EfiInput, BinaryInput, Compress=False, ClassCode=None,
501 Revision=None, DeviceId=None, VendorId=None):
b303ea72 502 InputList = []
30fdf114
LG
503 Cmd = ["EfiRom"]
504 if len(EfiInput) > 0:
505
506 if Compress:
507 Cmd += ["-ec"]
508 else:
509 Cmd += ["-e"]
510
511 for EfiFile in EfiInput:
512 Cmd += [EfiFile]
b303ea72 513 InputList.append (EfiFile)
30fdf114
LG
514
515 if len(BinaryInput) > 0:
516 Cmd += ["-b"]
517 for BinFile in BinaryInput:
518 Cmd += [BinFile]
b303ea72
LG
519 InputList.append (BinFile)
520
521 # Check List
522 if not GenFdsGlobalVariable.NeedsUpdate(Output, InputList):
523 return
524 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, InputList))
30fdf114
LG
525
526 if ClassCode != None:
527 Cmd += ["-l", ClassCode]
528 if Revision != None:
529 Cmd += ["-r", Revision]
530 if DeviceId != None:
531 Cmd += ["-i", DeviceId]
532 if VendorId != None:
533 Cmd += ["-f", VendorId]
534
535 Cmd += ["-o", Output]
536 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate option rom")
537
538 @staticmethod
52302d4d 539 def GuidTool(Output, Input, ToolPath, Options='', returnValue=[]):
30fdf114
LG
540 if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
541 return
542 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
543
52302d4d
LG
544 Cmd = [ToolPath, ]
545 Cmd += Options.split(' ')
30fdf114
LG
546 Cmd += ["-o", Output]
547 Cmd += Input
548
52302d4d 549 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath, returnValue)
30fdf114 550
52302d4d 551 def CallExternalTool (cmd, errorMess, returnValue=[]):
30fdf114
LG
552
553 if type(cmd) not in (tuple, list):
554 GenFdsGlobalVariable.ErrorLogger("ToolError! Invalid parameter type in call to CallExternalTool")
555
556 if GenFdsGlobalVariable.DebugLevel != -1:
557 cmd += ('--debug', str(GenFdsGlobalVariable.DebugLevel))
558 GenFdsGlobalVariable.InfLogger (cmd)
559
560 if GenFdsGlobalVariable.VerboseMode:
561 cmd += ('-v',)
562 GenFdsGlobalVariable.InfLogger (cmd)
563 else:
564 sys.stdout.write ('#')
565 sys.stdout.flush()
566 GenFdsGlobalVariable.SharpCounter = GenFdsGlobalVariable.SharpCounter + 1
567 if GenFdsGlobalVariable.SharpCounter % GenFdsGlobalVariable.SharpNumberPerLine == 0:
568 sys.stdout.write('\n')
569
570 try:
571 PopenObject = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr= subprocess.PIPE)
572 except Exception, X:
fd171542 573 EdkLogger.error("GenFds", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0]))
30fdf114
LG
574 (out, error) = PopenObject.communicate()
575
576 while PopenObject.returncode == None :
577 PopenObject.wait()
52302d4d
LG
578 if returnValue != [] and returnValue[0] != 0:
579 #get command return value
580 returnValue[0] = PopenObject.returncode
581 return
30fdf114
LG
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:
587 print "###", cmd
fd171542 588 EdkLogger.error("GenFds", COMMAND_FAILURE, errorMess)
30fdf114
LG
589
590 def VerboseLogger (msg):
591 EdkLogger.verbose(msg)
592
593 def InfLogger (msg):
594 EdkLogger.info(msg)
595
596 def ErrorLogger (msg, File = None, Line = None, ExtraData = None):
fd171542 597 EdkLogger.error('GenFds', GENFDS_ERROR, msg, File, Line, ExtraData)
30fdf114
LG
598
599 def DebugLogger (Level, msg):
600 EdkLogger.debug(Level, msg)
601
602 ## ReplaceWorkspaceMacro()
603 #
604 # @param Str String that may contain macro
605 # @param MacroDict Dictionary that contains macro value pair
606 #
607 def MacroExtend (Str, MacroDict = {}, Arch = 'COMMON'):
608 if Str == None :
609 return None
610
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
616 }
617 OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[GenFdsGlobalVariable.ArchList[0]]
618 if Arch != 'COMMON' and Arch in GenFdsGlobalVariable.ArchList:
619 OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[Arch]
620
621 Dict['$(OUTPUT_DIRECTORY)'] = OutputDir
622
623 if MacroDict != None and len (MacroDict) != 0:
624 Dict.update(MacroDict)
625
626 for key in Dict.keys():
627 if Str.find(key) >= 0 :
628 Str = Str.replace (key, Dict[key])
629
630 if Str.find('$(ARCH)') >= 0:
631 if len(GenFdsGlobalVariable.ArchList) == 1:
632 Str = Str.replace('$(ARCH)', GenFdsGlobalVariable.ArchList[0])
633 else:
634 EdkLogger.error("GenFds", GENFDS_ERROR, "No way to determine $(ARCH) for %s" % Str)
635
636 return Str
637
638 ## GetPcdValue()
639 #
640 # @param PcdPattern pattern that labels a PCD.
641 #
642 def GetPcdValue (PcdPattern):
643 if PcdPattern == None :
644 return None
645 PcdPair = PcdPattern.lstrip('PCD(').rstrip(')').strip().split('.')
646 TokenSpace = PcdPair[0]
647 TokenCName = PcdPair[1]
648
649 PcdValue = ''
650 for Platform in GenFdsGlobalVariable.WorkSpace.PlatformList:
4234283c
LG
651 #
652 # Only process platform which match current build option.
653 #
654 if Platform.MetaFile == GenFdsGlobalVariable.ActivePlatform:
655 PcdDict = Platform.Pcds
656 for Key in PcdDict:
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)
663
664 PcdValue = PcdObj.DefaultValue
665 return PcdValue
30fdf114
LG
666
667 for Package in GenFdsGlobalVariable.WorkSpace.PackageList:
668 PcdDict = Package.Pcds
669 for Key in PcdDict:
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)
676
677 PcdValue = PcdObj.DefaultValue
678 return PcdValue
679
680 return PcdValue
681
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)