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