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