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