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