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