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