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