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