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