]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
BaseTools: cleanup LongFilePathSupport usage
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / GenFdsGlobalVariable.py
... / ...
CommitLineData
1## @file\r
2# Global variables for GenFds\r
3#\r
4# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
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
18from __future__ import print_function\r
19from __future__ import absolute_import\r
20\r
21import Common.LongFilePathOs as os\r
22from sys import stdout\r
23from subprocess import PIPE,Popen\r
24from struct import Struct\r
25from array import array\r
26\r
27from Common.BuildToolError import COMMAND_FAILURE,GENFDS_ERROR\r
28from Common import EdkLogger\r
29from Common.Misc import SaveFileOnChange\r
30\r
31from Common.TargetTxtClassObject import TargetTxtClassObject\r
32from Common.ToolDefClassObject import ToolDefClassObject, ToolDefDict\r
33from AutoGen.BuildEngine import BuildRule\r
34import Common.DataType as DataType\r
35from Common.Misc import PathClass\r
36from Common.LongFilePathSupport import OpenLongFilePath as open\r
37from Common.MultipleWorkspace import MultipleWorkspace as mws\r
38\r
39## Global variables\r
40#\r
41#\r
42class GenFdsGlobalVariable:\r
43 FvDir = ''\r
44 OutputDirDict = {}\r
45 BinDir = ''\r
46 # will be FvDir + os.sep + 'Ffs'\r
47 FfsDir = ''\r
48 FdfParser = None\r
49 LibDir = ''\r
50 WorkSpace = None\r
51 WorkSpaceDir = ''\r
52 ConfDir = ''\r
53 EdkSourceDir = ''\r
54 OutputDirFromDscDict = {}\r
55 TargetName = ''\r
56 ToolChainTag = ''\r
57 RuleDict = {}\r
58 ArchList = None\r
59 VtfDict = {}\r
60 ActivePlatform = None\r
61 FvAddressFileName = ''\r
62 VerboseMode = False\r
63 DebugLevel = -1\r
64 SharpCounter = 0\r
65 SharpNumberPerLine = 40\r
66 FdfFile = ''\r
67 FdfFileTimeStamp = 0\r
68 FixedLoadAddress = False\r
69 PlatformName = ''\r
70\r
71 BuildRuleFamily = DataType.TAB_COMPILER_MSFT\r
72 ToolChainFamily = DataType.TAB_COMPILER_MSFT\r
73 __BuildRuleDatabase = None\r
74 GuidToolDefinition = {}\r
75 FfsCmdDict = {}\r
76 SecCmdList = []\r
77 CopyList = []\r
78 ModuleFile = ''\r
79 EnableGenfdsMultiThread = False\r
80\r
81 #\r
82 # The list whose element are flags to indicate if large FFS or SECTION files exist in FV.\r
83 # At the beginning of each generation of FV, false flag is appended to the list,\r
84 # after the call to GenerateSection returns, check the size of the output file,\r
85 # if it is greater than 0xFFFFFF, the tail flag in list is set to true,\r
86 # and EFI_FIRMWARE_FILE_SYSTEM3_GUID is passed to C GenFv.\r
87 # At the end of generation of FV, pop the flag.\r
88 # List is used as a stack to handle nested FV generation.\r
89 #\r
90 LargeFileInFvFlags = []\r
91 EFI_FIRMWARE_FILE_SYSTEM3_GUID = '5473C07A-3DCB-4dca-BD6F-1E9689E7349A'\r
92 LARGE_FILE_SIZE = 0x1000000\r
93\r
94 SectionHeader = Struct("3B 1B")\r
95\r
96 # FvName, FdName, CapName in FDF, Image file name\r
97 ImageBinDict = {}\r
98\r
99 ## LoadBuildRule\r
100 #\r
101 @staticmethod\r
102 def _LoadBuildRule():\r
103 if GenFdsGlobalVariable.__BuildRuleDatabase:\r
104 return GenFdsGlobalVariable.__BuildRuleDatabase\r
105 BuildConfigurationFile = os.path.normpath(os.path.join(GenFdsGlobalVariable.ConfDir, "target.txt"))\r
106 TargetTxt = TargetTxtClassObject()\r
107 if os.path.isfile(BuildConfigurationFile) == True:\r
108 TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)\r
109 if DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF in TargetTxt.TargetTxtDictionary:\r
110 BuildRuleFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF]\r
111 if not BuildRuleFile:\r
112 BuildRuleFile = 'Conf/build_rule.txt'\r
113 GenFdsGlobalVariable.__BuildRuleDatabase = BuildRule(BuildRuleFile)\r
114 ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]\r
115 if ToolDefinitionFile == '':\r
116 ToolDefinitionFile = "Conf/tools_def.txt"\r
117 if os.path.isfile(ToolDefinitionFile):\r
118 ToolDef = ToolDefClassObject()\r
119 ToolDef.LoadToolDefFile(ToolDefinitionFile)\r
120 ToolDefinition = ToolDef.ToolsDefTxtDatabase\r
121 if DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDefinition \\r
122 and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY] \\r
123 and ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]:\r
124 GenFdsGlobalVariable.BuildRuleFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]\r
125\r
126 if DataType.TAB_TOD_DEFINES_FAMILY in ToolDefinition \\r
127 and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY] \\r
128 and ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]:\r
129 GenFdsGlobalVariable.ToolChainFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]\r
130 return GenFdsGlobalVariable.__BuildRuleDatabase\r
131\r
132 ## GetBuildRules\r
133 # @param Inf: object of InfBuildData\r
134 # @param Arch: current arch\r
135 #\r
136 @staticmethod\r
137 def GetBuildRules(Inf, Arch):\r
138 if not Arch:\r
139 Arch = DataType.TAB_COMMON\r
140\r
141 if not Arch in GenFdsGlobalVariable.OutputDirDict:\r
142 return {}\r
143\r
144 BuildRuleDatabase = GenFdsGlobalVariable._LoadBuildRule()\r
145 if not BuildRuleDatabase:\r
146 return {}\r
147\r
148 PathClassObj = PathClass(Inf.MetaFile.File,\r
149 GenFdsGlobalVariable.WorkSpaceDir)\r
150 BuildDir = os.path.join(\r
151 GenFdsGlobalVariable.OutputDirDict[Arch],\r
152 Arch,\r
153 PathClassObj.SubDir,\r
154 PathClassObj.BaseName\r
155 )\r
156 BinDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch)\r
157 Macro = {\r
158 "WORKSPACE":GenFdsGlobalVariable.WorkSpaceDir,\r
159 "MODULE_NAME":Inf.BaseName,\r
160 "MODULE_GUID":Inf.Guid,\r
161 "MODULE_VERSION":Inf.Version,\r
162 "MODULE_TYPE":Inf.ModuleType,\r
163 "MODULE_FILE":str(PathClassObj),\r
164 "MODULE_FILE_BASE_NAME":PathClassObj.BaseName,\r
165 "MODULE_RELATIVE_DIR":PathClassObj.SubDir,\r
166 "MODULE_DIR":PathClassObj.SubDir,\r
167 "BASE_NAME":Inf.BaseName,\r
168 "ARCH":Arch,\r
169 "TOOLCHAIN":GenFdsGlobalVariable.ToolChainTag,\r
170 "TOOLCHAIN_TAG":GenFdsGlobalVariable.ToolChainTag,\r
171 "TOOL_CHAIN_TAG":GenFdsGlobalVariable.ToolChainTag,\r
172 "TARGET":GenFdsGlobalVariable.TargetName,\r
173 "BUILD_DIR":GenFdsGlobalVariable.OutputDirDict[Arch],\r
174 "BIN_DIR":BinDir,\r
175 "LIB_DIR":BinDir,\r
176 "MODULE_BUILD_DIR":BuildDir,\r
177 "OUTPUT_DIR":os.path.join(BuildDir, "OUTPUT"),\r
178 "DEBUG_DIR":os.path.join(BuildDir, "DEBUG")\r
179 }\r
180 \r
181 BuildRules = {}\r
182 for Type in BuildRuleDatabase.FileTypeList:\r
183 #first try getting build rule by BuildRuleFamily\r
184 RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.BuildRuleFamily]\r
185 if not RuleObject:\r
186 # build type is always module type, but ...\r
187 if Inf.ModuleType != Inf.BuildType:\r
188 RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.BuildRuleFamily]\r
189 #second try getting build rule by ToolChainFamily\r
190 if not RuleObject:\r
191 RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.ToolChainFamily]\r
192 if not RuleObject:\r
193 # build type is always module type, but ...\r
194 if Inf.ModuleType != Inf.BuildType:\r
195 RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.ToolChainFamily]\r
196 if not RuleObject:\r
197 continue\r
198 RuleObject = RuleObject.Instantiate(Macro)\r
199 BuildRules[Type] = RuleObject\r
200 for Ext in RuleObject.SourceFileExtList:\r
201 BuildRules[Ext] = RuleObject\r
202 return BuildRules\r
203\r
204 ## GetModuleCodaTargetList\r
205 #\r
206 # @param Inf: object of InfBuildData\r
207 # @param Arch: current arch\r
208 #\r
209 @staticmethod\r
210 def GetModuleCodaTargetList(Inf, Arch):\r
211 BuildRules = GenFdsGlobalVariable.GetBuildRules(Inf, Arch)\r
212 if not BuildRules:\r
213 return []\r
214\r
215 TargetList = set()\r
216 FileList = []\r
217\r
218 if not Inf.IsBinaryModule:\r
219 for File in Inf.Sources:\r
220 if File.TagName in {"", "*", GenFdsGlobalVariable.ToolChainTag} and \\r
221 File.ToolChainFamily in {"", "*", GenFdsGlobalVariable.ToolChainFamily}:\r
222 FileList.append((File, DataType.TAB_UNKNOWN_FILE))\r
223\r
224 for File in Inf.Binaries:\r
225 if File.Target in {DataType.TAB_COMMON, '*', GenFdsGlobalVariable.TargetName}:\r
226 FileList.append((File, File.Type))\r
227\r
228 for File, FileType in FileList:\r
229 LastTarget = None\r
230 RuleChain = []\r
231 SourceList = [File]\r
232 Index = 0\r
233 while Index < len(SourceList):\r
234 Source = SourceList[Index]\r
235 Index = Index + 1\r
236\r
237 if File.IsBinary and File == Source and Inf.Binaries and File in Inf.Binaries:\r
238 # Skip all files that are not binary libraries\r
239 if not Inf.LibraryClass:\r
240 continue\r
241 RuleObject = BuildRules[DataType.TAB_DEFAULT_BINARY_FILE]\r
242 elif FileType in BuildRules:\r
243 RuleObject = BuildRules[FileType]\r
244 elif Source.Ext in BuildRules:\r
245 RuleObject = BuildRules[Source.Ext]\r
246 else:\r
247 # stop at no more rules\r
248 if LastTarget:\r
249 TargetList.add(str(LastTarget))\r
250 break\r
251\r
252 FileType = RuleObject.SourceFileType\r
253\r
254 # stop at STATIC_LIBRARY for library\r
255 if Inf.LibraryClass and FileType == DataType.TAB_STATIC_LIBRARY:\r
256 if LastTarget:\r
257 TargetList.add(str(LastTarget))\r
258 break\r
259\r
260 Target = RuleObject.Apply(Source)\r
261 if not Target:\r
262 if LastTarget:\r
263 TargetList.add(str(LastTarget))\r
264 break\r
265 elif not Target.Outputs:\r
266 # Only do build for target with outputs\r
267 TargetList.add(str(Target))\r
268\r
269 # to avoid cyclic rule\r
270 if FileType in RuleChain:\r
271 break\r
272\r
273 RuleChain.append(FileType)\r
274 SourceList.extend(Target.Outputs)\r
275 LastTarget = Target\r
276 FileType = DataType.TAB_UNKNOWN_FILE\r
277 for Cmd in Target.Commands:\r
278 if "$(CP)" == Cmd.split()[0]:\r
279 CpTarget = Cmd.split()[2]\r
280 TargetList.add(CpTarget)\r
281\r
282 return list(TargetList)\r
283\r
284 ## SetDir()\r
285 #\r
286 # @param OutputDir Output directory\r
287 # @param FdfParser FDF contents parser\r
288 # @param Workspace The directory of workspace\r
289 # @param ArchList The Arch list of platform\r
290 #\r
291 @staticmethod\r
292 def SetDir (OutputDir, FdfParser, WorkSpace, ArchList):\r
293 GenFdsGlobalVariable.VerboseLogger("GenFdsGlobalVariable.OutputDir:%s" % OutputDir)\r
294 GenFdsGlobalVariable.FdfParser = FdfParser\r
295 GenFdsGlobalVariable.WorkSpace = WorkSpace\r
296 GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], DataType.TAB_FV_DIRECTORY)\r
297 if not os.path.exists(GenFdsGlobalVariable.FvDir):\r
298 os.makedirs(GenFdsGlobalVariable.FvDir)\r
299 GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')\r
300 if not os.path.exists(GenFdsGlobalVariable.FfsDir):\r
301 os.makedirs(GenFdsGlobalVariable.FfsDir)\r
302\r
303 #\r
304 # Create FV Address inf file\r
305 #\r
306 GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf')\r
307 FvAddressFile = open(GenFdsGlobalVariable.FvAddressFileName, 'w')\r
308 #\r
309 # Add [Options]\r
310 #\r
311 FvAddressFile.writelines("[options]" + DataType.TAB_LINE_BREAK)\r
312 BsAddress = '0'\r
313 for Arch in ArchList:\r
314 if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress:\r
315 BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress\r
316 break\r
317\r
318 FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \\r
319 BsAddress + \\r
320 DataType.TAB_LINE_BREAK)\r
321\r
322 RtAddress = '0'\r
323 for Arch in reversed(ArchList):\r
324 temp = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress\r
325 if temp:\r
326 RtAddress = temp\r
327 break\r
328\r
329 FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \\r
330 RtAddress + \\r
331 DataType.TAB_LINE_BREAK)\r
332\r
333 FvAddressFile.close()\r
334\r
335 @staticmethod\r
336 def SetEnv(FdfParser, WorkSpace, ArchList, GlobalData):\r
337 GenFdsGlobalVariable.ModuleFile = WorkSpace.ModuleFile\r
338 GenFdsGlobalVariable.FdfParser = FdfParser\r
339 GenFdsGlobalVariable.WorkSpace = WorkSpace.Db\r
340 GenFdsGlobalVariable.ArchList = ArchList\r
341 GenFdsGlobalVariable.ToolChainTag = GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]\r
342 GenFdsGlobalVariable.TargetName = GlobalData.gGlobalDefines["TARGET"]\r
343 GenFdsGlobalVariable.ActivePlatform = GlobalData.gActivePlatform\r
344 GenFdsGlobalVariable.EdkSourceDir = GlobalData.gGlobalDefines["EDK_SOURCE"]\r
345 GenFdsGlobalVariable.ConfDir = GlobalData.gConfDirectory\r
346 GenFdsGlobalVariable.EnableGenfdsMultiThread = GlobalData.gEnableGenfdsMultiThread\r
347 for Arch in ArchList:\r
348 GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.normpath(\r
349 os.path.join(GlobalData.gWorkspace,\r
350 WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'],\r
351 GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory,\r
352 GlobalData.gGlobalDefines['TARGET'] +'_' + GlobalData.gGlobalDefines['TOOLCHAIN']))\r
353 GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = os.path.normpath(\r
354 WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,\r
355 GlobalData.gGlobalDefines['TARGET'], GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory)\r
356 GenFdsGlobalVariable.PlatformName = WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,\r
357 GlobalData.gGlobalDefines['TARGET'],\r
358 GlobalData.gGlobalDefines['TOOLCHAIN']].PlatformName\r
359 GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], DataType.TAB_FV_DIRECTORY)\r
360 if not os.path.exists(GenFdsGlobalVariable.FvDir):\r
361 os.makedirs(GenFdsGlobalVariable.FvDir)\r
362 GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')\r
363 if not os.path.exists(GenFdsGlobalVariable.FfsDir):\r
364 os.makedirs(GenFdsGlobalVariable.FfsDir)\r
365\r
366 #\r
367 # Create FV Address inf file\r
368 #\r
369 GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf')\r
370 FvAddressFile = open(GenFdsGlobalVariable.FvAddressFileName, 'w')\r
371 #\r
372 # Add [Options]\r
373 #\r
374 FvAddressFile.writelines("[options]" + DataType.TAB_LINE_BREAK)\r
375 BsAddress = '0'\r
376 for Arch in ArchList:\r
377 BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,\r
378 GlobalData.gGlobalDefines['TARGET'],\r
379 GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].BsBaseAddress\r
380 if BsAddress:\r
381 break\r
382\r
383 FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \\r
384 BsAddress + \\r
385 DataType.TAB_LINE_BREAK)\r
386\r
387 RtAddress = '0'\r
388 for Arch in reversed(ArchList):\r
389 temp = GenFdsGlobalVariable.WorkSpace.BuildObject[\r
390 GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'],\r
391 GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].RtBaseAddress\r
392 if temp:\r
393 RtAddress = temp\r
394 break\r
395\r
396 FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \\r
397 RtAddress + \\r
398 DataType.TAB_LINE_BREAK)\r
399\r
400 FvAddressFile.close()\r
401\r
402 ## ReplaceWorkspaceMacro()\r
403 #\r
404 # @param String String that may contain macro\r
405 #\r
406 @staticmethod\r
407 def ReplaceWorkspaceMacro(String):\r
408 String = mws.handleWsMacro(String)\r
409 Str = String.replace('$(WORKSPACE)', GenFdsGlobalVariable.WorkSpaceDir)\r
410 if os.path.exists(Str):\r
411 if not os.path.isabs(Str):\r
412 Str = os.path.abspath(Str)\r
413 else:\r
414 Str = mws.join(GenFdsGlobalVariable.WorkSpaceDir, String)\r
415 return os.path.normpath(Str)\r
416\r
417 ## Check if the input files are newer than output files\r
418 #\r
419 # @param Output Path of output file\r
420 # @param Input Path list of input files\r
421 #\r
422 # @retval True if Output doesn't exist, or any Input is newer\r
423 # @retval False if all Input is older than Output\r
424 #\r
425 @staticmethod\r
426 def NeedsUpdate(Output, Input):\r
427 if not os.path.exists(Output):\r
428 return True\r
429 # always update "Output" if no "Input" given\r
430 if not Input:\r
431 return True\r
432\r
433 # if fdf file is changed after the 'Output" is generated, update the 'Output'\r
434 OutputTime = os.path.getmtime(Output)\r
435 if GenFdsGlobalVariable.FdfFileTimeStamp > OutputTime:\r
436 return True\r
437\r
438 for F in Input:\r
439 # always update "Output" if any "Input" doesn't exist\r
440 if not os.path.exists(F):\r
441 return True\r
442 # always update "Output" if any "Input" is newer than "Output"\r
443 if os.path.getmtime(F) > OutputTime:\r
444 return True\r
445 return False\r
446\r
447 @staticmethod\r
448 def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None,\r
449 GuidHdrLen=None, GuidAttr=[], Ui=None, Ver=None, InputAlign=[], BuildNumber=None, DummyFile=None, IsMakefile=False):\r
450 Cmd = ["GenSec"]\r
451 if Type:\r
452 Cmd += ("-s", Type)\r
453 if CompressionType:\r
454 Cmd += ("-c", CompressionType)\r
455 if Guid:\r
456 Cmd += ("-g", Guid)\r
457 if DummyFile:\r
458 Cmd += ("--dummy", DummyFile)\r
459 if GuidHdrLen:\r
460 Cmd += ("-l", GuidHdrLen)\r
461 #Add each guided attribute\r
462 for Attr in GuidAttr:\r
463 Cmd += ("-r", Attr)\r
464 #Section Align is only for dummy section without section type\r
465 for SecAlign in InputAlign:\r
466 Cmd += ("--sectionalign", SecAlign)\r
467\r
468 CommandFile = Output + '.txt'\r
469 if Ui:\r
470 if IsMakefile:\r
471 if Ui == "$(MODULE_NAME)":\r
472 Cmd += ('-n', Ui)\r
473 else:\r
474 Cmd += ("-n", '"' + Ui + '"')\r
475 Cmd += ("-o", Output)\r
476 if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r
477 GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())\r
478 else:\r
479 SectionData = array('B', [0, 0, 0, 0])\r
480 SectionData.fromstring(Ui.encode("utf_16_le"))\r
481 SectionData.append(0)\r
482 SectionData.append(0)\r
483 Len = len(SectionData)\r
484 GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x15)\r
485 SaveFileOnChange(Output, SectionData.tostring())\r
486\r
487 elif Ver:\r
488 Cmd += ("-n", Ver)\r
489 if BuildNumber:\r
490 Cmd += ("-j", BuildNumber)\r
491 Cmd += ("-o", Output)\r
492\r
493 SaveFileOnChange(CommandFile, ' '.join(Cmd), False)\r
494 if IsMakefile:\r
495 if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r
496 GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())\r
497 else:\r
498 if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):\r
499 return\r
500 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")\r
501 else:\r
502 Cmd += ("-o", Output)\r
503 Cmd += Input\r
504\r
505 SaveFileOnChange(CommandFile, ' '.join(Cmd), False)\r
506 if IsMakefile:\r
507 if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r
508 GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())\r
509 elif GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):\r
510 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r
511 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")\r
512 if (os.path.getsize(Output) >= GenFdsGlobalVariable.LARGE_FILE_SIZE and\r
513 GenFdsGlobalVariable.LargeFileInFvFlags):\r
514 GenFdsGlobalVariable.LargeFileInFvFlags[-1] = True\r
515\r
516 @staticmethod\r
517 def GetAlignment (AlignString):\r
518 if not AlignString:\r
519 return 0\r
520 if AlignString.endswith('K'):\r
521 return int (AlignString.rstrip('K')) * 1024\r
522 if AlignString.endswith('M'):\r
523 return int (AlignString.rstrip('M')) * 1024 * 1024\r
524 if AlignString.endswith('G'):\r
525 return int (AlignString.rstrip('G')) * 1024 * 1024 * 1024\r
526 return int (AlignString)\r
527\r
528 @staticmethod\r
529 def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None,\r
530 SectionAlign=None, MakefilePath=None):\r
531 Cmd = ["GenFfs", "-t", Type, "-g", Guid]\r
532 mFfsValidAlign = ["0", "8", "16", "128", "512", "1K", "4K", "32K", "64K", "128K", "256K", "512K", "1M", "2M", "4M", "8M", "16M"]\r
533 if Fixed == True:\r
534 Cmd.append("-x")\r
535 if CheckSum:\r
536 Cmd.append("-s")\r
537 if Align:\r
538 if Align not in mFfsValidAlign:\r
539 Align = GenFdsGlobalVariable.GetAlignment (Align)\r
540 for index in range(0, len(mFfsValidAlign) - 1):\r
541 if ((Align > GenFdsGlobalVariable.GetAlignment(mFfsValidAlign[index])) and (Align <= GenFdsGlobalVariable.GetAlignment(mFfsValidAlign[index + 1]))):\r
542 break\r
543 Align = mFfsValidAlign[index + 1]\r
544 Cmd += ("-a", Align)\r
545\r
546 Cmd += ("-o", Output)\r
547 for I in range(0, len(Input)):\r
548 Cmd += ("-i", Input[I])\r
549 if SectionAlign and SectionAlign[I]:\r
550 Cmd += ("-n", SectionAlign[I])\r
551\r
552 CommandFile = Output + '.txt'\r
553 SaveFileOnChange(CommandFile, ' '.join(Cmd), False)\r
554\r
555 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r
556 if MakefilePath:\r
557 if (tuple(Cmd), tuple(GenFdsGlobalVariable.SecCmdList), tuple(GenFdsGlobalVariable.CopyList)) not in GenFdsGlobalVariable.FfsCmdDict:\r
558 GenFdsGlobalVariable.FfsCmdDict[tuple(Cmd), tuple(GenFdsGlobalVariable.SecCmdList), tuple(GenFdsGlobalVariable.CopyList)] = MakefilePath\r
559 GenFdsGlobalVariable.SecCmdList = []\r
560 GenFdsGlobalVariable.CopyList = []\r
561 else:\r
562 if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):\r
563 return\r
564 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS")\r
565\r
566 @staticmethod\r
567 def GenerateFirmwareVolume(Output, Input, BaseAddress=None, ForceRebase=None, Capsule=False, Dump=False,\r
568 AddressFile=None, MapFile=None, FfsList=[], FileSystemGuid=None):\r
569 if not GenFdsGlobalVariable.NeedsUpdate(Output, Input+FfsList):\r
570 return\r
571 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r
572\r
573 Cmd = ["GenFv"]\r
574 if BaseAddress:\r
575 Cmd += ("-r", BaseAddress)\r
576\r
577 if ForceRebase == False:\r
578 Cmd += ("-F", "FALSE")\r
579 elif ForceRebase == True:\r
580 Cmd += ("-F", "TRUE")\r
581\r
582 if Capsule:\r
583 Cmd.append("-c")\r
584 if Dump:\r
585 Cmd.append("-p")\r
586 if AddressFile:\r
587 Cmd += ("-a", AddressFile)\r
588 if MapFile:\r
589 Cmd += ("-m", MapFile)\r
590 if FileSystemGuid:\r
591 Cmd += ("-g", FileSystemGuid)\r
592 Cmd += ("-o", Output)\r
593 for I in Input:\r
594 Cmd += ("-i", I)\r
595\r
596 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FV")\r
597\r
598 @staticmethod\r
599 def GenerateFirmwareImage(Output, Input, Type="efi", SubType=None, Zero=False,\r
600 Strip=False, Replace=False, TimeStamp=None, Join=False,\r
601 Align=None, Padding=None, Convert=False, IsMakefile=False):\r
602 if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile:\r
603 return\r
604 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r
605\r
606 Cmd = ["GenFw"]\r
607 if Type.lower() == "te":\r
608 Cmd.append("-t")\r
609 if SubType:\r
610 Cmd += ("-e", SubType)\r
611 if TimeStamp:\r
612 Cmd += ("-s", TimeStamp)\r
613 if Align:\r
614 Cmd += ("-a", Align)\r
615 if Padding:\r
616 Cmd += ("-p", Padding)\r
617 if Zero:\r
618 Cmd.append("-z")\r
619 if Strip:\r
620 Cmd.append("-l")\r
621 if Replace:\r
622 Cmd.append("-r")\r
623 if Join:\r
624 Cmd.append("-j")\r
625 if Convert:\r
626 Cmd.append("-m")\r
627 Cmd += ("-o", Output)\r
628 Cmd += Input\r
629 if IsMakefile:\r
630 if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r
631 GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())\r
632 else:\r
633 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image")\r
634\r
635 @staticmethod\r
636 def GenerateOptionRom(Output, EfiInput, BinaryInput, Compress=False, ClassCode=None,\r
637 Revision=None, DeviceId=None, VendorId=None, IsMakefile=False):\r
638 InputList = []\r
639 Cmd = ["EfiRom"]\r
640 if EfiInput:\r
641\r
642 if Compress:\r
643 Cmd.append("-ec")\r
644 else:\r
645 Cmd.append("-e")\r
646\r
647 for EfiFile in EfiInput:\r
648 Cmd.append(EfiFile)\r
649 InputList.append (EfiFile)\r
650\r
651 if BinaryInput:\r
652 Cmd.append("-b")\r
653 for BinFile in BinaryInput:\r
654 Cmd.append(BinFile)\r
655 InputList.append (BinFile)\r
656\r
657 # Check List\r
658 if not GenFdsGlobalVariable.NeedsUpdate(Output, InputList) and not IsMakefile:\r
659 return\r
660 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, InputList))\r
661\r
662 if ClassCode:\r
663 Cmd += ("-l", ClassCode)\r
664 if Revision:\r
665 Cmd += ("-r", Revision)\r
666 if DeviceId:\r
667 Cmd += ("-i", DeviceId)\r
668 if VendorId:\r
669 Cmd += ("-f", VendorId)\r
670\r
671 Cmd += ("-o", Output)\r
672 if IsMakefile:\r
673 if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r
674 GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())\r
675 else:\r
676 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate option rom")\r
677\r
678 @staticmethod\r
679 def GuidTool(Output, Input, ToolPath, Options='', returnValue=[], IsMakefile=False):\r
680 if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile:\r
681 return\r
682 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r
683\r
684 Cmd = [ToolPath, ]\r
685 Cmd += Options.split(' ')\r
686 Cmd += ("-o", Output)\r
687 Cmd += Input\r
688 if IsMakefile:\r
689 if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r
690 GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())\r
691 else:\r
692 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath, returnValue)\r
693\r
694 @staticmethod\r
695 def CallExternalTool (cmd, errorMess, returnValue=[]):\r
696\r
697 if type(cmd) not in (tuple, list):\r
698 GenFdsGlobalVariable.ErrorLogger("ToolError! Invalid parameter type in call to CallExternalTool")\r
699\r
700 if GenFdsGlobalVariable.DebugLevel != -1:\r
701 cmd += ('--debug', str(GenFdsGlobalVariable.DebugLevel))\r
702 GenFdsGlobalVariable.InfLogger (cmd)\r
703\r
704 if GenFdsGlobalVariable.VerboseMode:\r
705 cmd += ('-v',)\r
706 GenFdsGlobalVariable.InfLogger (cmd)\r
707 else:\r
708 stdout.write ('#')\r
709 stdout.flush()\r
710 GenFdsGlobalVariable.SharpCounter = GenFdsGlobalVariable.SharpCounter + 1\r
711 if GenFdsGlobalVariable.SharpCounter % GenFdsGlobalVariable.SharpNumberPerLine == 0:\r
712 stdout.write('\n')\r
713\r
714 try:\r
715 PopenObject = Popen(' '.join(cmd), stdout=PIPE, stderr=PIPE, shell=True)\r
716 except Exception as X:\r
717 EdkLogger.error("GenFds", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0]))\r
718 (out, error) = PopenObject.communicate()\r
719\r
720 while PopenObject.returncode is None:\r
721 PopenObject.wait()\r
722 if returnValue != [] and returnValue[0] != 0:\r
723 #get command return value\r
724 returnValue[0] = PopenObject.returncode\r
725 return\r
726 if PopenObject.returncode != 0 or GenFdsGlobalVariable.VerboseMode or GenFdsGlobalVariable.DebugLevel != -1:\r
727 GenFdsGlobalVariable.InfLogger ("Return Value = %d" % PopenObject.returncode)\r
728 GenFdsGlobalVariable.InfLogger (out)\r
729 GenFdsGlobalVariable.InfLogger (error)\r
730 if PopenObject.returncode != 0:\r
731 print("###", cmd)\r
732 EdkLogger.error("GenFds", COMMAND_FAILURE, errorMess)\r
733\r
734 @staticmethod\r
735 def VerboseLogger (msg):\r
736 EdkLogger.verbose(msg)\r
737\r
738 @staticmethod\r
739 def InfLogger (msg):\r
740 EdkLogger.info(msg)\r
741\r
742 @staticmethod\r
743 def ErrorLogger (msg, File=None, Line=None, ExtraData=None):\r
744 EdkLogger.error('GenFds', GENFDS_ERROR, msg, File, Line, ExtraData)\r
745\r
746 @staticmethod\r
747 def DebugLogger (Level, msg):\r
748 EdkLogger.debug(Level, msg)\r
749\r
750 ## MacroExtend()\r
751 #\r
752 # @param Str String that may contain macro\r
753 # @param MacroDict Dictionary that contains macro value pair\r
754 #\r
755 @staticmethod\r
756 def MacroExtend (Str, MacroDict={}, Arch=DataType.TAB_COMMON):\r
757 if Str is None:\r
758 return None\r
759\r
760 Dict = {'$(WORKSPACE)': GenFdsGlobalVariable.WorkSpaceDir,\r
761 '$(EDK_SOURCE)': GenFdsGlobalVariable.EdkSourceDir,\r
762# '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc,\r
763 '$(TARGET)': GenFdsGlobalVariable.TargetName,\r
764 '$(TOOL_CHAIN_TAG)': GenFdsGlobalVariable.ToolChainTag,\r
765 '$(SPACE)': ' '\r
766 }\r
767\r
768 if Arch != DataType.TAB_COMMON and Arch in GenFdsGlobalVariable.ArchList:\r
769 OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[Arch]\r
770 else:\r
771 OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[GenFdsGlobalVariable.ArchList[0]]\r
772\r
773 Dict['$(OUTPUT_DIRECTORY)'] = OutputDir\r
774\r
775 if MacroDict:\r
776 Dict.update(MacroDict)\r
777\r
778 for key in Dict:\r
779 if Str.find(key) >= 0:\r
780 Str = Str.replace (key, Dict[key])\r
781\r
782 if Str.find('$(ARCH)') >= 0:\r
783 if len(GenFdsGlobalVariable.ArchList) == 1:\r
784 Str = Str.replace('$(ARCH)', GenFdsGlobalVariable.ArchList[0])\r
785 else:\r
786 EdkLogger.error("GenFds", GENFDS_ERROR, "No way to determine $(ARCH) for %s" % Str)\r
787\r
788 return Str\r
789\r
790 ## GetPcdValue()\r
791 #\r
792 # @param PcdPattern pattern that labels a PCD.\r
793 #\r
794 @staticmethod\r
795 def GetPcdValue (PcdPattern):\r
796 if PcdPattern is None:\r
797 return None\r
798 PcdPair = PcdPattern.lstrip('PCD(').rstrip(')').strip().split('.')\r
799 TokenSpace = PcdPair[0]\r
800 TokenCName = PcdPair[1]\r
801\r
802 for Arch in GenFdsGlobalVariable.ArchList:\r
803 Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
804 PcdDict = Platform.Pcds\r
805 for Key in PcdDict:\r
806 PcdObj = PcdDict[Key]\r
807 if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):\r
808 if PcdObj.Type != DataType.TAB_PCDS_FIXED_AT_BUILD:\r
809 EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)\r
810 if PcdObj.DatumType != DataType.TAB_VOID:\r
811 EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)\r
812\r
813 return PcdObj.DefaultValue\r
814\r
815 for Package in GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform,\r
816 Arch,\r
817 GenFdsGlobalVariable.TargetName,\r
818 GenFdsGlobalVariable.ToolChainTag):\r
819 PcdDict = Package.Pcds\r
820 for Key in PcdDict:\r
821 PcdObj = PcdDict[Key]\r
822 if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):\r
823 if PcdObj.Type != DataType.TAB_PCDS_FIXED_AT_BUILD:\r
824 EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)\r
825 if PcdObj.DatumType != DataType.TAB_VOID:\r
826 EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)\r
827\r
828 return PcdObj.DefaultValue\r
829\r
830 return ''\r
831\r
832## FindExtendTool()\r
833#\r
834# Find location of tools to process data\r
835#\r
836# @param KeyStringList Filter for inputs of section generation\r
837# @param CurrentArchList Arch list\r
838# @param NameGuid The Guid name\r
839#\r
840def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):\r
841 ToolDb = ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDatabase\r
842 # if user not specify filter, try to deduce it from global data.\r
843 if KeyStringList is None or KeyStringList == []:\r
844 Target = GenFdsGlobalVariable.TargetName\r
845 ToolChain = GenFdsGlobalVariable.ToolChainTag\r
846 if ToolChain not in ToolDb['TOOL_CHAIN_TAG']:\r
847 EdkLogger.error("GenFds", GENFDS_ERROR, "Can not find external tool because tool tag %s is not defined in tools_def.txt!" % ToolChain)\r
848 KeyStringList = [Target + '_' + ToolChain + '_' + CurrentArchList[0]]\r
849 for Arch in CurrentArchList:\r
850 if Target + '_' + ToolChain + '_' + Arch not in KeyStringList:\r
851 KeyStringList.append(Target + '_' + ToolChain + '_' + Arch)\r
852\r
853 if GenFdsGlobalVariable.GuidToolDefinition:\r
854 if NameGuid in GenFdsGlobalVariable.GuidToolDefinition:\r
855 return GenFdsGlobalVariable.GuidToolDefinition[NameGuid]\r
856\r
857 ToolDefinition = ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDictionary\r
858 ToolPathTmp = None\r
859 ToolOption = None\r
860 ToolPathKey = None\r
861 ToolOptionKey = None\r
862 KeyList = None\r
863 for ToolDef in ToolDefinition.items():\r
864 if NameGuid.lower() == ToolDef[1].lower():\r
865 KeyList = ToolDef[0].split('_')\r
866 Key = KeyList[0] + \\r
867 '_' + \\r
868 KeyList[1] + \\r
869 '_' + \\r
870 KeyList[2]\r
871 if Key in KeyStringList and KeyList[4] == DataType.TAB_GUID:\r
872 ToolPathKey = Key + '_' + KeyList[3] + '_PATH'\r
873 ToolOptionKey = Key + '_' + KeyList[3] + '_FLAGS'\r
874 ToolPath = ToolDefinition.get(ToolPathKey)\r
875 ToolOption = ToolDefinition.get(ToolOptionKey)\r
876 if ToolPathTmp is None:\r
877 ToolPathTmp = ToolPath\r
878 else:\r
879 if ToolPathTmp != ToolPath:\r
880 EdkLogger.error("GenFds", GENFDS_ERROR, "Don't know which tool to use, %s or %s ?" % (ToolPathTmp, ToolPath))\r
881\r
882 BuildOption = {}\r
883 for Arch in CurrentArchList:\r
884 Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
885 # key is (ToolChainFamily, ToolChain, CodeBase)\r
886 for item in Platform.BuildOptions:\r
887 if '_PATH' in item[1] or '_FLAGS' in item[1] or '_GUID' in item[1]:\r
888 if not item[0] or (item[0] and GenFdsGlobalVariable.ToolChainFamily== item[0]):\r
889 if item[1] not in BuildOption:\r
890 BuildOption[item[1]] = Platform.BuildOptions[item]\r
891 if BuildOption:\r
892 ToolList = [DataType.TAB_TOD_DEFINES_TARGET, DataType.TAB_TOD_DEFINES_TOOL_CHAIN_TAG, DataType.TAB_TOD_DEFINES_TARGET_ARCH]\r
893 for Index in range(2, -1, -1):\r
894 for Key in list(BuildOption.keys()):\r
895 List = Key.split('_')\r
896 if List[Index] == '*':\r
897 for String in ToolDb[ToolList[Index]]:\r
898 if String in [Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]:\r
899 List[Index] = String\r
900 NewKey = '%s_%s_%s_%s_%s' % tuple(List)\r
901 if NewKey not in BuildOption:\r
902 BuildOption[NewKey] = BuildOption[Key]\r
903 continue\r
904 del BuildOption[Key]\r
905 elif List[Index] not in ToolDb[ToolList[Index]]:\r
906 del BuildOption[Key]\r
907 if BuildOption:\r
908 if not KeyList:\r
909 for Op in BuildOption:\r
910 if NameGuid == BuildOption[Op]:\r
911 KeyList = Op.split('_')\r
912 Key = KeyList[0] + '_' + KeyList[1] +'_' + KeyList[2]\r
913 if Key in KeyStringList and KeyList[4] == DataType.TAB_GUID:\r
914 ToolPathKey = Key + '_' + KeyList[3] + '_PATH'\r
915 ToolOptionKey = Key + '_' + KeyList[3] + '_FLAGS'\r
916 if ToolPathKey in BuildOption:\r
917 ToolPathTmp = BuildOption[ToolPathKey]\r
918 if ToolOptionKey in BuildOption:\r
919 ToolOption = BuildOption[ToolOptionKey]\r
920\r
921 GenFdsGlobalVariable.GuidToolDefinition[NameGuid] = (ToolPathTmp, ToolOption)\r
922 return ToolPathTmp, ToolOption\r