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