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