]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
Sync BaseTool trunk (version r2599) into EDKII BaseTools.
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / GenFdsGlobalVariable.py
1 ## @file
2 # Global variables for GenFds
3 #
4 # Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
5 #
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
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 #
18 import os
19 import sys
20 import subprocess
21 import struct
22 import array
23
24 from Common.BuildToolError import *
25 from Common import EdkLogger
26 from Common.Misc import SaveFileOnChange
27
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
34 ## Global variables
35 #
36 #
37 class 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
63 PlatformName = ''
64
65 BuildRuleFamily = "MSFT"
66 ToolChainFamily = "MSFT"
67 __BuildRuleDatabase = None
68
69 SectionHeader = struct.Struct("3B 1B")
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(Inf.MetaFile.File,
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["TOOL_CHAIN_TAG" ] = GenFdsGlobalVariable.ToolChainTag
139 Macro["TARGET" ] = GenFdsGlobalVariable.TargetName
140
141 Macro["BUILD_DIR" ] = GenFdsGlobalVariable.OutputDirDict[Arch]
142 Macro["BIN_DIR" ] = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch)
143 Macro["LIB_DIR" ] = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch)
144 BuildDir = os.path.join(
145 GenFdsGlobalVariable.OutputDirDict[Arch],
146 Arch,
147 PathClassObj.SubDir,
148 PathClassObj.BaseName
149 )
150 Macro["MODULE_BUILD_DIR" ] = BuildDir
151 Macro["OUTPUT_DIR" ] = os.path.join(BuildDir, "OUTPUT")
152 Macro["DEBUG_DIR" ] = os.path.join(BuildDir, "DEBUG")
153
154 BuildRules = {}
155 for Type in BuildRuleDatabase.FileTypeList:
156 #first try getting build rule by BuildRuleFamily
157 RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.BuildRuleFamily]
158 if not RuleObject:
159 # build type is always module type, but ...
160 if Inf.ModuleType != Inf.BuildType:
161 RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.BuildRuleFamily]
162 #second try getting build rule by ToolChainFamily
163 if not RuleObject:
164 RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.ToolChainFamily]
165 if not RuleObject:
166 # build type is always module type, but ...
167 if Inf.ModuleType != Inf.BuildType:
168 RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.ToolChainFamily]
169 if not RuleObject:
170 continue
171 RuleObject = RuleObject.Instantiate(Macro)
172 BuildRules[Type] = RuleObject
173 for Ext in RuleObject.SourceFileExtList:
174 BuildRules[Ext] = RuleObject
175 return BuildRules
176
177 ## GetModuleCodaTargetList
178 #
179 # @param Inf: object of InfBuildData
180 # @param Arch: current arch
181 #
182 @staticmethod
183 def GetModuleCodaTargetList(Inf, Arch):
184 BuildRules = GenFdsGlobalVariable.GetBuildRules(Inf, Arch)
185 if not BuildRules:
186 return []
187
188 TargetList = set()
189 FileList = []
190 for File in Inf.Sources:
191 if File.TagName in ("", "*", GenFdsGlobalVariable.ToolChainTag) and \
192 File.ToolChainFamily in ("", "*", GenFdsGlobalVariable.ToolChainFamily):
193 FileList.append((File, DataType.TAB_UNKNOWN_FILE))
194
195 for File in Inf.Binaries:
196 if File.Target in ['COMMON', '*', GenFdsGlobalVariable.TargetName]:
197 FileList.append((File, File.Type))
198
199 for File, FileType in FileList:
200 LastTarget = None
201 RuleChain = []
202 SourceList = [File]
203 Index = 0
204 while Index < len(SourceList):
205 Source = SourceList[Index]
206 Index = Index + 1
207
208 if File.IsBinary and File == Source and Inf.Binaries != None and File in Inf.Binaries:
209 # Skip all files that are not binary libraries
210 if not Inf.LibraryClass:
211 continue
212 RuleObject = BuildRules[DataType.TAB_DEFAULT_BINARY_FILE]
213 elif FileType in BuildRules:
214 RuleObject = BuildRules[FileType]
215 elif Source.Ext in BuildRules:
216 RuleObject = BuildRules[Source.Ext]
217 else:
218 # stop at no more rules
219 if LastTarget:
220 TargetList.add(str(LastTarget))
221 break
222
223 FileType = RuleObject.SourceFileType
224
225 # stop at STATIC_LIBRARY for library
226 if Inf.LibraryClass and FileType == DataType.TAB_STATIC_LIBRARY:
227 if LastTarget:
228 TargetList.add(str(LastTarget))
229 break
230
231 Target = RuleObject.Apply(Source)
232 if not Target:
233 if LastTarget:
234 TargetList.add(str(LastTarget))
235 break
236 elif not Target.Outputs:
237 # Only do build for target with outputs
238 TargetList.add(str(Target))
239
240 # to avoid cyclic rule
241 if FileType in RuleChain:
242 break
243
244 RuleChain.append(FileType)
245 SourceList.extend(Target.Outputs)
246 LastTarget = Target
247 FileType = DataType.TAB_UNKNOWN_FILE
248
249 return list(TargetList)
250
251 ## SetDir()
252 #
253 # @param OutputDir Output directory
254 # @param FdfParser FDF contents parser
255 # @param Workspace The directory of workspace
256 # @param ArchList The Arch list of platform
257 #
258 def SetDir (OutputDir, FdfParser, WorkSpace, ArchList):
259 GenFdsGlobalVariable.VerboseLogger( "GenFdsGlobalVariable.OutputDir :%s" %OutputDir)
260 # GenFdsGlobalVariable.OutputDirDict = OutputDir
261 GenFdsGlobalVariable.FdfParser = FdfParser
262 GenFdsGlobalVariable.WorkSpace = WorkSpace
263 GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], 'FV')
264 if not os.path.exists(GenFdsGlobalVariable.FvDir) :
265 os.makedirs(GenFdsGlobalVariable.FvDir)
266 GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')
267 if not os.path.exists(GenFdsGlobalVariable.FfsDir) :
268 os.makedirs(GenFdsGlobalVariable.FfsDir)
269 if ArchList != None:
270 GenFdsGlobalVariable.ArchList = ArchList
271
272 T_CHAR_LF = '\n'
273 #
274 # Create FV Address inf file
275 #
276 GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf')
277 FvAddressFile = open (GenFdsGlobalVariable.FvAddressFileName, 'w')
278 #
279 # Add [Options]
280 #
281 FvAddressFile.writelines("[options]" + T_CHAR_LF)
282 BsAddress = '0'
283 for Arch in ArchList:
284 if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress:
285 BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress
286 break
287
288 FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \
289 BsAddress + \
290 T_CHAR_LF)
291
292 RtAddress = '0'
293 for Arch in ArchList:
294 if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress:
295 RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress
296
297 FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \
298 RtAddress + \
299 T_CHAR_LF)
300
301 FvAddressFile.close()
302
303 ## ReplaceWorkspaceMacro()
304 #
305 # @param String String that may contain macro
306 #
307 def ReplaceWorkspaceMacro(String):
308 Str = String.replace('$(WORKSPACE)', GenFdsGlobalVariable.WorkSpaceDir)
309 if os.path.exists(Str):
310 if not os.path.isabs(Str):
311 Str = os.path.abspath(Str)
312 else:
313 Str = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, String)
314 return os.path.normpath(Str)
315
316 ## Check if the input files are newer than output files
317 #
318 # @param Output Path of output file
319 # @param Input Path list of input files
320 #
321 # @retval True if Output doesn't exist, or any Input is newer
322 # @retval False if all Input is older than Output
323 #
324 @staticmethod
325 def NeedsUpdate(Output, Input):
326 if not os.path.exists(Output):
327 return True
328 # always update "Output" if no "Input" given
329 if Input == None or len(Input) == 0:
330 return True
331
332 # if fdf file is changed after the 'Output" is generated, update the 'Output'
333 OutputTime = os.path.getmtime(Output)
334 if GenFdsGlobalVariable.FdfFileTimeStamp > OutputTime:
335 return True
336
337 for F in Input:
338 # always update "Output" if any "Input" doesn't exist
339 if not os.path.exists(F):
340 return True
341 # always update "Output" if any "Input" is newer than "Output"
342 if os.path.getmtime(F) > OutputTime:
343 return True
344 return False
345
346 @staticmethod
347 def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None,
348 GuidHdrLen=None, GuidAttr=[], Ui=None, Ver=None, InputAlign=None, BuildNumber=None):
349 Cmd = ["GenSec"]
350 if Type not in [None, '']:
351 Cmd += ["-s", Type]
352 if CompressionType not in [None, '']:
353 Cmd += ["-c", CompressionType]
354 if Guid != None:
355 Cmd += ["-g", Guid]
356 if GuidHdrLen not in [None, '']:
357 Cmd += ["-l", GuidHdrLen]
358 if len(GuidAttr) != 0:
359 #Add each guided attribute
360 for Attr in GuidAttr:
361 Cmd += ["-r", Attr]
362 if InputAlign != None:
363 #Section Align is only for dummy section without section type
364 for SecAlign in InputAlign:
365 Cmd += ["--sectionalign", SecAlign]
366
367 CommandFile = Output + '.txt'
368 if Ui not in [None, '']:
369 #Cmd += ["-n", '"' + Ui + '"']
370 SectionData = array.array('B', [0,0,0,0])
371 SectionData.fromstring(Ui.encode("utf_16_le"))
372 SectionData.append(0)
373 SectionData.append(0)
374 Len = len(SectionData)
375 GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x15)
376 SaveFileOnChange(Output, SectionData.tostring())
377 elif Ver not in [None, '']:
378 Cmd += ["-n", Ver]
379 if BuildNumber:
380 Cmd += ["-j", BuildNumber]
381 Cmd += ["-o", Output]
382
383 SaveFileOnChange(CommandFile, ' '.join(Cmd), False)
384 if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
385 return
386
387 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")
388 else:
389 Cmd += ["-o", Output]
390 Cmd += Input
391
392 SaveFileOnChange(CommandFile, ' '.join(Cmd), False)
393 if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
394 return
395 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
396
397 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")
398
399 @staticmethod
400 def GetAlignment (AlignString):
401 if AlignString == None:
402 return 0
403 if AlignString in ("1K", "2K", "4K", "8K", "16K", "32K", "64K"):
404 return int (AlignString.rstrip('K')) * 1024
405 else:
406 return int (AlignString)
407
408 @staticmethod
409 def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None,
410 SectionAlign=None):
411 Cmd = ["GenFfs", "-t", Type, "-g", Guid]
412 if Fixed == True:
413 Cmd += ["-x"]
414 if CheckSum:
415 Cmd += ["-s"]
416 if Align not in [None, '']:
417 Cmd += ["-a", Align]
418
419 Cmd += ["-o", Output]
420 for I in range(0, len(Input)):
421 Cmd += ("-i", Input[I])
422 if SectionAlign not in [None, '', []] and SectionAlign[I] not in [None, '']:
423 Cmd += ("-n", SectionAlign[I])
424
425 CommandFile = Output + '.txt'
426 SaveFileOnChange(CommandFile, ' '.join(Cmd), False)
427 if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
428 return
429 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
430
431 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS")
432
433 @staticmethod
434 def GenerateFirmwareVolume(Output, Input, BaseAddress=None, ForceRebase=None, Capsule=False, Dump=False,
435 AddressFile=None, MapFile=None, FfsList=[]):
436 if not GenFdsGlobalVariable.NeedsUpdate(Output, Input+FfsList):
437 return
438 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
439
440 Cmd = ["GenFv"]
441 if BaseAddress not in [None, '']:
442 Cmd += ["-r", BaseAddress]
443
444 if ForceRebase == False:
445 Cmd +=["-F", "FALSE"]
446 elif ForceRebase == True:
447 Cmd +=["-F", "TRUE"]
448
449 if Capsule:
450 Cmd += ["-c"]
451 if Dump:
452 Cmd += ["-p"]
453 if AddressFile not in [None, '']:
454 Cmd += ["-a", AddressFile]
455 if MapFile not in [None, '']:
456 Cmd += ["-m", MapFile]
457 Cmd += ["-o", Output]
458 for I in Input:
459 Cmd += ["-i", I]
460
461 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FV")
462
463 @staticmethod
464 def GenerateVtf(Output, Input, BaseAddress=None, FvSize=None):
465 if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
466 return
467 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
468
469 Cmd = ["GenVtf"]
470 if BaseAddress not in [None, ''] and FvSize not in [None, ''] \
471 and len(BaseAddress) == len(FvSize):
472 for I in range(0, len(BaseAddress)):
473 Cmd += ["-r", BaseAddress[I], "-s", FvSize[I]]
474 Cmd += ["-o", Output]
475 for F in Input:
476 Cmd += ["-f", F]
477
478 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate VTF")
479
480 @staticmethod
481 def GenerateFirmwareImage(Output, Input, Type="efi", SubType=None, Zero=False,
482 Strip=False, Replace=False, TimeStamp=None, Join=False,
483 Align=None, Padding=None, Convert=False):
484 if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
485 return
486 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
487
488 Cmd = ["GenFw"]
489 if Type.lower() == "te":
490 Cmd += ["-t"]
491 if SubType not in [None, '']:
492 Cmd += ["-e", SubType]
493 if TimeStamp not in [None, '']:
494 Cmd += ["-s", TimeStamp]
495 if Align not in [None, '']:
496 Cmd += ["-a", Align]
497 if Padding not in [None, '']:
498 Cmd += ["-p", Padding]
499 if Zero:
500 Cmd += ["-z"]
501 if Strip:
502 Cmd += ["-l"]
503 if Replace:
504 Cmd += ["-r"]
505 if Join:
506 Cmd += ["-j"]
507 if Convert:
508 Cmd += ["-m"]
509 Cmd += ["-o", Output]
510 Cmd += Input
511
512 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image")
513
514 @staticmethod
515 def GenerateOptionRom(Output, EfiInput, BinaryInput, Compress=False, ClassCode=None,
516 Revision=None, DeviceId=None, VendorId=None):
517 InputList = []
518 Cmd = ["EfiRom"]
519 if len(EfiInput) > 0:
520
521 if Compress:
522 Cmd += ["-ec"]
523 else:
524 Cmd += ["-e"]
525
526 for EfiFile in EfiInput:
527 Cmd += [EfiFile]
528 InputList.append (EfiFile)
529
530 if len(BinaryInput) > 0:
531 Cmd += ["-b"]
532 for BinFile in BinaryInput:
533 Cmd += [BinFile]
534 InputList.append (BinFile)
535
536 # Check List
537 if not GenFdsGlobalVariable.NeedsUpdate(Output, InputList):
538 return
539 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, InputList))
540
541 if ClassCode != None:
542 Cmd += ["-l", ClassCode]
543 if Revision != None:
544 Cmd += ["-r", Revision]
545 if DeviceId != None:
546 Cmd += ["-i", DeviceId]
547 if VendorId != None:
548 Cmd += ["-f", VendorId]
549
550 Cmd += ["-o", Output]
551 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate option rom")
552
553 @staticmethod
554 def GuidTool(Output, Input, ToolPath, Options='', returnValue=[]):
555 if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
556 return
557 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
558
559 Cmd = [ToolPath, ]
560 Cmd += Options.split(' ')
561 Cmd += ["-o", Output]
562 Cmd += Input
563
564 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath, returnValue)
565
566 def CallExternalTool (cmd, errorMess, returnValue=[]):
567
568 if type(cmd) not in (tuple, list):
569 GenFdsGlobalVariable.ErrorLogger("ToolError! Invalid parameter type in call to CallExternalTool")
570
571 if GenFdsGlobalVariable.DebugLevel != -1:
572 cmd += ('--debug', str(GenFdsGlobalVariable.DebugLevel))
573 GenFdsGlobalVariable.InfLogger (cmd)
574
575 if GenFdsGlobalVariable.VerboseMode:
576 cmd += ('-v',)
577 GenFdsGlobalVariable.InfLogger (cmd)
578 else:
579 sys.stdout.write ('#')
580 sys.stdout.flush()
581 GenFdsGlobalVariable.SharpCounter = GenFdsGlobalVariable.SharpCounter + 1
582 if GenFdsGlobalVariable.SharpCounter % GenFdsGlobalVariable.SharpNumberPerLine == 0:
583 sys.stdout.write('\n')
584
585 try:
586 PopenObject = subprocess.Popen(' '.join(cmd), stdout=subprocess.PIPE, stderr= subprocess.PIPE, shell=True)
587 except Exception, X:
588 EdkLogger.error("GenFds", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0]))
589 (out, error) = PopenObject.communicate()
590
591 while PopenObject.returncode == None :
592 PopenObject.wait()
593 if returnValue != [] and returnValue[0] != 0:
594 #get command return value
595 returnValue[0] = PopenObject.returncode
596 return
597 if PopenObject.returncode != 0 or GenFdsGlobalVariable.VerboseMode or GenFdsGlobalVariable.DebugLevel != -1:
598 GenFdsGlobalVariable.InfLogger ("Return Value = %d" %PopenObject.returncode)
599 GenFdsGlobalVariable.InfLogger (out)
600 GenFdsGlobalVariable.InfLogger (error)
601 if PopenObject.returncode != 0:
602 print "###", cmd
603 EdkLogger.error("GenFds", COMMAND_FAILURE, errorMess)
604
605 def VerboseLogger (msg):
606 EdkLogger.verbose(msg)
607
608 def InfLogger (msg):
609 EdkLogger.info(msg)
610
611 def ErrorLogger (msg, File = None, Line = None, ExtraData = None):
612 EdkLogger.error('GenFds', GENFDS_ERROR, msg, File, Line, ExtraData)
613
614 def DebugLogger (Level, msg):
615 EdkLogger.debug(Level, msg)
616
617 ## ReplaceWorkspaceMacro()
618 #
619 # @param Str String that may contain macro
620 # @param MacroDict Dictionary that contains macro value pair
621 #
622 def MacroExtend (Str, MacroDict = {}, Arch = 'COMMON'):
623 if Str == None :
624 return None
625
626 Dict = {'$(WORKSPACE)' : GenFdsGlobalVariable.WorkSpaceDir,
627 '$(EDK_SOURCE)' : GenFdsGlobalVariable.EdkSourceDir,
628 # '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc,
629 '$(TARGET)' : GenFdsGlobalVariable.TargetName,
630 '$(TOOL_CHAIN_TAG)' : GenFdsGlobalVariable.ToolChainTag
631 }
632 OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[GenFdsGlobalVariable.ArchList[0]]
633 if Arch != 'COMMON' and Arch in GenFdsGlobalVariable.ArchList:
634 OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[Arch]
635
636 Dict['$(OUTPUT_DIRECTORY)'] = OutputDir
637
638 if MacroDict != None and len (MacroDict) != 0:
639 Dict.update(MacroDict)
640
641 for key in Dict.keys():
642 if Str.find(key) >= 0 :
643 Str = Str.replace (key, Dict[key])
644
645 if Str.find('$(ARCH)') >= 0:
646 if len(GenFdsGlobalVariable.ArchList) == 1:
647 Str = Str.replace('$(ARCH)', GenFdsGlobalVariable.ArchList[0])
648 else:
649 EdkLogger.error("GenFds", GENFDS_ERROR, "No way to determine $(ARCH) for %s" % Str)
650
651 return Str
652
653 ## GetPcdValue()
654 #
655 # @param PcdPattern pattern that labels a PCD.
656 #
657 def GetPcdValue (PcdPattern):
658 if PcdPattern == None :
659 return None
660 PcdPair = PcdPattern.lstrip('PCD(').rstrip(')').strip().split('.')
661 TokenSpace = PcdPair[0]
662 TokenCName = PcdPair[1]
663
664 PcdValue = ''
665 for Arch in GenFdsGlobalVariable.ArchList:
666 Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
667 PcdDict = Platform.Pcds
668 for Key in PcdDict:
669 PcdObj = PcdDict[Key]
670 if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):
671 if PcdObj.Type != 'FixedAtBuild':
672 EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)
673 if PcdObj.DatumType != 'VOID*':
674 EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)
675
676 PcdValue = PcdObj.DefaultValue
677 return PcdValue
678
679 for Package in GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform,
680 Arch,
681 GenFdsGlobalVariable.TargetName,
682 GenFdsGlobalVariable.ToolChainTag):
683 PcdDict = Package.Pcds
684 for Key in PcdDict:
685 PcdObj = PcdDict[Key]
686 if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):
687 if PcdObj.Type != 'FixedAtBuild':
688 EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)
689 if PcdObj.DatumType != 'VOID*':
690 EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)
691
692 PcdValue = PcdObj.DefaultValue
693 return PcdValue
694
695 return PcdValue
696
697 SetDir = staticmethod(SetDir)
698 ReplaceWorkspaceMacro = staticmethod(ReplaceWorkspaceMacro)
699 CallExternalTool = staticmethod(CallExternalTool)
700 VerboseLogger = staticmethod(VerboseLogger)
701 InfLogger = staticmethod(InfLogger)
702 ErrorLogger = staticmethod(ErrorLogger)
703 DebugLogger = staticmethod(DebugLogger)
704 MacroExtend = staticmethod (MacroExtend)
705 GetPcdValue = staticmethod(GetPcdValue)