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