]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
CorebootPayloadPkg: Conditionally add DebugAgentLib for DXE drivers
[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
1be2ed90 18import Common.LongFilePathOs as os\r
f51461c8
LG
19import sys\r
20import subprocess\r
21import struct\r
22import array\r
23\r
24from Common.BuildToolError import *\r
25from Common import EdkLogger\r
26from Common.Misc import SaveFileOnChange\r
27\r
28from Common.TargetTxtClassObject import TargetTxtClassObject\r
29from Common.ToolDefClassObject import ToolDefClassObject\r
30from AutoGen.BuildEngine import BuildRule\r
31import Common.DataType as DataType\r
32from Common.Misc import PathClass\r
1be2ed90 33from Common.LongFilePathSupport import OpenLongFilePath as open\r
05cc51ad 34from Common.MultipleWorkspace import MultipleWorkspace as mws\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 EdkSourceDir = ''\r
51 OutputDirFromDscDict = {}\r
52 TargetName = ''\r
53 ToolChainTag = ''\r
54 RuleDict = {}\r
55 ArchList = None\r
56 VtfDict = {}\r
57 ActivePlatform = None\r
58 FvAddressFileName = ''\r
59 VerboseMode = False\r
60 DebugLevel = -1\r
61 SharpCounter = 0\r
62 SharpNumberPerLine = 40\r
63 FdfFile = ''\r
64 FdfFileTimeStamp = 0\r
65 FixedLoadAddress = False\r
66 PlatformName = ''\r
67 \r
68 BuildRuleFamily = "MSFT"\r
69 ToolChainFamily = "MSFT"\r
70 __BuildRuleDatabase = None\r
213ae077 71 GuidToolDefinition = {}\r
37de70b7
YZ
72 FfsCmdDict = {}\r
73 SecCmdList = []\r
74 CopyList = []\r
75 ModuleFile = ''\r
76 EnableGenfdsMultiThread = False\r
f51461c8
LG
77 \r
78 #\r
79 # The list whose element are flags to indicate if large FFS or SECTION files exist in FV.\r
80 # At the beginning of each generation of FV, false flag is appended to the list,\r
81 # after the call to GenerateSection returns, check the size of the output file,\r
82 # if it is greater than 0xFFFFFF, the tail flag in list is set to true,\r
83 # and EFI_FIRMWARE_FILE_SYSTEM3_GUID is passed to C GenFv.\r
84 # At the end of generation of FV, pop the flag.\r
85 # List is used as a stack to handle nested FV generation.\r
86 #\r
87 LargeFileInFvFlags = []\r
88 EFI_FIRMWARE_FILE_SYSTEM3_GUID = '5473C07A-3DCB-4dca-BD6F-1E9689E7349A'\r
89 LARGE_FILE_SIZE = 0x1000000\r
90\r
91 SectionHeader = struct.Struct("3B 1B")\r
92 \r
93 ## LoadBuildRule\r
94 #\r
95 @staticmethod\r
96 def __LoadBuildRule():\r
97 if GenFdsGlobalVariable.__BuildRuleDatabase:\r
98 return GenFdsGlobalVariable.__BuildRuleDatabase\r
97fa0ee9 99 BuildConfigurationFile = os.path.normpath(os.path.join(GenFdsGlobalVariable.ConfDir, "target.txt"))\r
f51461c8
LG
100 TargetTxt = TargetTxtClassObject()\r
101 if os.path.isfile(BuildConfigurationFile) == True:\r
102 TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)\r
103 if DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF in TargetTxt.TargetTxtDictionary:\r
104 BuildRuleFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF]\r
105 if BuildRuleFile in [None, '']:\r
106 BuildRuleFile = 'Conf/build_rule.txt'\r
107 GenFdsGlobalVariable.__BuildRuleDatabase = BuildRule(BuildRuleFile)\r
108 ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]\r
109 if ToolDefinitionFile == '':\r
110 ToolDefinitionFile = "Conf/tools_def.txt"\r
111 if os.path.isfile(ToolDefinitionFile):\r
112 ToolDef = ToolDefClassObject()\r
113 ToolDef.LoadToolDefFile(ToolDefinitionFile)\r
114 ToolDefinition = ToolDef.ToolsDefTxtDatabase\r
115 if DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDefinition \\r
116 and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY] \\r
117 and ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]:\r
118 GenFdsGlobalVariable.BuildRuleFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]\r
119 \r
120 if DataType.TAB_TOD_DEFINES_FAMILY in ToolDefinition \\r
121 and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY] \\r
122 and ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]:\r
123 GenFdsGlobalVariable.ToolChainFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]\r
124 return GenFdsGlobalVariable.__BuildRuleDatabase\r
125\r
126 ## GetBuildRules\r
127 # @param Inf: object of InfBuildData\r
128 # @param Arch: current arch\r
129 #\r
130 @staticmethod\r
131 def GetBuildRules(Inf, Arch):\r
132 if not Arch:\r
133 Arch = 'COMMON'\r
134\r
135 if not Arch in GenFdsGlobalVariable.OutputDirDict:\r
136 return {}\r
137\r
138 BuildRuleDatabase = GenFdsGlobalVariable.__LoadBuildRule()\r
139 if not BuildRuleDatabase:\r
140 return {}\r
141\r
142 PathClassObj = PathClass(Inf.MetaFile.File,\r
143 GenFdsGlobalVariable.WorkSpaceDir)\r
144 Macro = {}\r
145 Macro["WORKSPACE" ] = GenFdsGlobalVariable.WorkSpaceDir\r
146 Macro["MODULE_NAME" ] = Inf.BaseName\r
147 Macro["MODULE_GUID" ] = Inf.Guid\r
148 Macro["MODULE_VERSION" ] = Inf.Version\r
149 Macro["MODULE_TYPE" ] = Inf.ModuleType\r
150 Macro["MODULE_FILE" ] = str(PathClassObj)\r
151 Macro["MODULE_FILE_BASE_NAME" ] = PathClassObj.BaseName\r
152 Macro["MODULE_RELATIVE_DIR" ] = PathClassObj.SubDir\r
153 Macro["MODULE_DIR" ] = PathClassObj.SubDir\r
154\r
155 Macro["BASE_NAME" ] = Inf.BaseName\r
156\r
157 Macro["ARCH" ] = Arch\r
158 Macro["TOOLCHAIN" ] = GenFdsGlobalVariable.ToolChainTag\r
159 Macro["TOOLCHAIN_TAG" ] = GenFdsGlobalVariable.ToolChainTag\r
160 Macro["TOOL_CHAIN_TAG" ] = GenFdsGlobalVariable.ToolChainTag\r
161 Macro["TARGET" ] = GenFdsGlobalVariable.TargetName\r
162\r
163 Macro["BUILD_DIR" ] = GenFdsGlobalVariable.OutputDirDict[Arch]\r
164 Macro["BIN_DIR" ] = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch)\r
165 Macro["LIB_DIR" ] = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch)\r
166 BuildDir = os.path.join(\r
167 GenFdsGlobalVariable.OutputDirDict[Arch],\r
168 Arch,\r
169 PathClassObj.SubDir,\r
170 PathClassObj.BaseName\r
171 )\r
172 Macro["MODULE_BUILD_DIR" ] = BuildDir\r
173 Macro["OUTPUT_DIR" ] = os.path.join(BuildDir, "OUTPUT")\r
174 Macro["DEBUG_DIR" ] = os.path.join(BuildDir, "DEBUG")\r
175\r
176 BuildRules = {}\r
177 for Type in BuildRuleDatabase.FileTypeList:\r
178 #first try getting build rule by BuildRuleFamily\r
179 RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.BuildRuleFamily]\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.BuildRuleFamily]\r
184 #second try getting build rule by ToolChainFamily\r
185 if not RuleObject:\r
186 RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.ToolChainFamily]\r
187 if not RuleObject:\r
188 # build type is always module type, but ...\r
189 if Inf.ModuleType != Inf.BuildType:\r
190 RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.ToolChainFamily]\r
191 if not RuleObject:\r
192 continue\r
193 RuleObject = RuleObject.Instantiate(Macro)\r
194 BuildRules[Type] = RuleObject\r
195 for Ext in RuleObject.SourceFileExtList:\r
196 BuildRules[Ext] = RuleObject\r
197 return BuildRules\r
198\r
199 ## GetModuleCodaTargetList\r
200 #\r
201 # @param Inf: object of InfBuildData\r
202 # @param Arch: current arch\r
203 #\r
204 @staticmethod\r
205 def GetModuleCodaTargetList(Inf, Arch):\r
206 BuildRules = GenFdsGlobalVariable.GetBuildRules(Inf, Arch)\r
207 if not BuildRules:\r
208 return []\r
209\r
210 TargetList = set()\r
211 FileList = []\r
97fa0ee9
YL
212\r
213 if not Inf.IsBinaryModule:\r
214 for File in Inf.Sources:\r
215 if File.TagName in ("", "*", GenFdsGlobalVariable.ToolChainTag) and \\r
216 File.ToolChainFamily in ("", "*", GenFdsGlobalVariable.ToolChainFamily):\r
217 FileList.append((File, DataType.TAB_UNKNOWN_FILE))\r
218\r
f51461c8
LG
219 for File in Inf.Binaries:\r
220 if File.Target in ['COMMON', '*', GenFdsGlobalVariable.TargetName]:\r
221 FileList.append((File, File.Type))\r
222\r
223 for File, FileType in FileList:\r
224 LastTarget = None\r
225 RuleChain = []\r
226 SourceList = [File]\r
227 Index = 0\r
228 while Index < len(SourceList):\r
229 Source = SourceList[Index]\r
230 Index = Index + 1\r
231 \r
232 if File.IsBinary and File == Source and Inf.Binaries != None and File in Inf.Binaries:\r
233 # Skip all files that are not binary libraries\r
234 if not Inf.LibraryClass:\r
235 continue \r
236 RuleObject = BuildRules[DataType.TAB_DEFAULT_BINARY_FILE]\r
237 elif FileType in BuildRules:\r
238 RuleObject = BuildRules[FileType]\r
239 elif Source.Ext in BuildRules:\r
240 RuleObject = BuildRules[Source.Ext]\r
241 else:\r
242 # stop at no more rules\r
243 if LastTarget:\r
244 TargetList.add(str(LastTarget))\r
245 break\r
246 \r
247 FileType = RuleObject.SourceFileType\r
248 \r
249 # stop at STATIC_LIBRARY for library\r
250 if Inf.LibraryClass and FileType == DataType.TAB_STATIC_LIBRARY:\r
251 if LastTarget:\r
252 TargetList.add(str(LastTarget))\r
253 break\r
254 \r
255 Target = RuleObject.Apply(Source)\r
256 if not Target:\r
257 if LastTarget:\r
258 TargetList.add(str(LastTarget))\r
259 break\r
260 elif not Target.Outputs:\r
261 # Only do build for target with outputs\r
262 TargetList.add(str(Target))\r
263 \r
264 # to avoid cyclic rule\r
265 if FileType in RuleChain:\r
266 break\r
267 \r
268 RuleChain.append(FileType)\r
269 SourceList.extend(Target.Outputs)\r
270 LastTarget = Target\r
271 FileType = DataType.TAB_UNKNOWN_FILE\r
37de70b7
YZ
272 for Cmd in Target.Commands:\r
273 if "$(CP)" == Cmd.split()[0]:\r
274 CpTarget = Cmd.split()[2]\r
275 TargetList.add(CpTarget)\r
f51461c8
LG
276\r
277 return list(TargetList)\r
278\r
279 ## SetDir()\r
280 #\r
281 # @param OutputDir Output directory\r
282 # @param FdfParser FDF contents parser\r
283 # @param Workspace The directory of workspace\r
284 # @param ArchList The Arch list of platform\r
285 #\r
286 def SetDir (OutputDir, FdfParser, WorkSpace, ArchList):\r
47fea6af 287 GenFdsGlobalVariable.VerboseLogger("GenFdsGlobalVariable.OutputDir :%s" % OutputDir)\r
f51461c8
LG
288# GenFdsGlobalVariable.OutputDirDict = OutputDir\r
289 GenFdsGlobalVariable.FdfParser = FdfParser\r
290 GenFdsGlobalVariable.WorkSpace = WorkSpace\r
291 GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], 'FV')\r
292 if not os.path.exists(GenFdsGlobalVariable.FvDir) :\r
293 os.makedirs(GenFdsGlobalVariable.FvDir)\r
294 GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')\r
295 if not os.path.exists(GenFdsGlobalVariable.FfsDir) :\r
296 os.makedirs(GenFdsGlobalVariable.FfsDir)\r
f51461c8
LG
297\r
298 T_CHAR_LF = '\n'\r
299 #\r
300 # Create FV Address inf file\r
301 #\r
302 GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf')\r
47fea6af 303 FvAddressFile = open(GenFdsGlobalVariable.FvAddressFileName, 'w')\r
f51461c8
LG
304 #\r
305 # Add [Options]\r
306 #\r
307 FvAddressFile.writelines("[options]" + T_CHAR_LF)\r
308 BsAddress = '0'\r
309 for Arch in ArchList:\r
310 if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress:\r
311 BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress\r
312 break\r
313\r
314 FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \\r
47fea6af 315 BsAddress + \\r
f51461c8
LG
316 T_CHAR_LF)\r
317\r
318 RtAddress = '0'\r
319 for Arch in ArchList:\r
320 if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress:\r
321 RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress\r
322\r
323 FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \\r
47fea6af 324 RtAddress + \\r
f51461c8
LG
325 T_CHAR_LF)\r
326\r
327 FvAddressFile.close()\r
328\r
37de70b7
YZ
329 def SetEnv(FdfParser, WorkSpace, ArchList, GlobalData):\r
330 GenFdsGlobalVariable.ModuleFile = WorkSpace.ModuleFile\r
331 GenFdsGlobalVariable.FdfParser = FdfParser\r
332 GenFdsGlobalVariable.WorkSpace = WorkSpace.Db\r
333 GenFdsGlobalVariable.ArchList = ArchList\r
334 GenFdsGlobalVariable.ToolChainTag = GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]\r
335 GenFdsGlobalVariable.TargetName = GlobalData.gGlobalDefines["TARGET"]\r
336 GenFdsGlobalVariable.ActivePlatform = GlobalData.gActivePlatform\r
337 GenFdsGlobalVariable.EdkSourceDir = GlobalData.gGlobalDefines["EDK_SOURCE"]\r
338 GenFdsGlobalVariable.ConfDir = GlobalData.gConfDirectory\r
339 GenFdsGlobalVariable.EnableGenfdsMultiThread = GlobalData.gEnableGenfdsMultiThread\r
340 for Arch in ArchList:\r
341 GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.normpath(\r
342 os.path.join(GlobalData.gWorkspace,\r
343 WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,GlobalData.gGlobalDefines['TARGET'],\r
344 GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory,\r
345 GlobalData.gGlobalDefines['TARGET'] +'_' + GlobalData.gGlobalDefines['TOOLCHAIN']))\r
346 GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = os.path.normpath(\r
347 WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,\r
348 GlobalData.gGlobalDefines['TARGET'], GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory)\r
349 GenFdsGlobalVariable.PlatformName = WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,\r
350 GlobalData.gGlobalDefines['TARGET'],\r
351 GlobalData.gGlobalDefines['TOOLCHAIN']].PlatformName\r
352 GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], 'FV')\r
353 if not os.path.exists(GenFdsGlobalVariable.FvDir):\r
354 os.makedirs(GenFdsGlobalVariable.FvDir)\r
355 GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')\r
356 if not os.path.exists(GenFdsGlobalVariable.FfsDir):\r
357 os.makedirs(GenFdsGlobalVariable.FfsDir)\r
358\r
359 T_CHAR_LF = '\n'\r
360 #\r
361 # Create FV Address inf file\r
362 #\r
363 GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf')\r
364 FvAddressFile = open(GenFdsGlobalVariable.FvAddressFileName, 'w')\r
365 #\r
366 # Add [Options]\r
367 #\r
368 FvAddressFile.writelines("[options]" + T_CHAR_LF)\r
369 BsAddress = '0'\r
370 for Arch in ArchList:\r
371 BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,\r
372 GlobalData.gGlobalDefines['TARGET'],\r
373 GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].BsBaseAddress\r
374 if BsAddress:\r
375 break\r
376\r
377 FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \\r
378 BsAddress + \\r
379 T_CHAR_LF)\r
380\r
381 RtAddress = '0'\r
382 for Arch in ArchList:\r
383 if GenFdsGlobalVariable.WorkSpace.BuildObject[\r
384 GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'],\r
385 GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].RtBaseAddress:\r
386 RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[\r
387 GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'],\r
388 GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].RtBaseAddress\r
389\r
390 FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \\r
391 RtAddress + \\r
392 T_CHAR_LF)\r
393\r
394 FvAddressFile.close()\r
395\r
f51461c8
LG
396 ## ReplaceWorkspaceMacro()\r
397 #\r
398 # @param String String that may contain macro\r
399 #\r
400 def ReplaceWorkspaceMacro(String):\r
05cc51ad 401 String = mws.handleWsMacro(String)\r
f51461c8
LG
402 Str = String.replace('$(WORKSPACE)', GenFdsGlobalVariable.WorkSpaceDir)\r
403 if os.path.exists(Str):\r
404 if not os.path.isabs(Str):\r
405 Str = os.path.abspath(Str)\r
406 else:\r
05cc51ad 407 Str = mws.join(GenFdsGlobalVariable.WorkSpaceDir, String)\r
f51461c8
LG
408 return os.path.normpath(Str)\r
409\r
410 ## Check if the input files are newer than output files\r
411 #\r
412 # @param Output Path of output file\r
413 # @param Input Path list of input files\r
414 #\r
415 # @retval True if Output doesn't exist, or any Input is newer\r
416 # @retval False if all Input is older than Output\r
417 #\r
418 @staticmethod\r
419 def NeedsUpdate(Output, Input):\r
420 if not os.path.exists(Output):\r
421 return True\r
422 # always update "Output" if no "Input" given\r
423 if Input == None or len(Input) == 0:\r
424 return True\r
425\r
426 # if fdf file is changed after the 'Output" is generated, update the 'Output'\r
427 OutputTime = os.path.getmtime(Output)\r
428 if GenFdsGlobalVariable.FdfFileTimeStamp > OutputTime:\r
429 return True\r
430\r
431 for F in Input:\r
432 # always update "Output" if any "Input" doesn't exist\r
433 if not os.path.exists(F):\r
434 return True\r
435 # always update "Output" if any "Input" is newer than "Output"\r
436 if os.path.getmtime(F) > OutputTime:\r
437 return True\r
438 return False\r
439\r
440 @staticmethod\r
441 def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None,\r
37de70b7 442 GuidHdrLen=None, GuidAttr=[], Ui=None, Ver=None, InputAlign=None, BuildNumber=None, DummyFile=None, IsMakefile=False):\r
f51461c8
LG
443 Cmd = ["GenSec"]\r
444 if Type not in [None, '']:\r
445 Cmd += ["-s", Type]\r
446 if CompressionType not in [None, '']:\r
447 Cmd += ["-c", CompressionType]\r
448 if Guid != None:\r
449 Cmd += ["-g", Guid]\r
37de70b7
YZ
450 if DummyFile != None:\r
451 Cmd += ["--dummy", DummyFile]\r
f51461c8
LG
452 if GuidHdrLen not in [None, '']:\r
453 Cmd += ["-l", GuidHdrLen]\r
454 if len(GuidAttr) != 0:\r
455 #Add each guided attribute\r
456 for Attr in GuidAttr:\r
457 Cmd += ["-r", Attr]\r
458 if InputAlign != None:\r
459 #Section Align is only for dummy section without section type\r
460 for SecAlign in InputAlign:\r
461 Cmd += ["--sectionalign", SecAlign]\r
462\r
463 CommandFile = Output + '.txt'\r
464 if Ui not in [None, '']:\r
465 #Cmd += ["-n", '"' + Ui + '"']\r
37de70b7
YZ
466 if IsMakefile:\r
467 Cmd += ["-n", "$(MODULE_NAME)"]\r
468 Cmd += ["-o", Output]\r
469 #SaveFileOnChange(CommandFile, ' '.join(Cmd), False)\r
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
f51461c8
LG
481 elif Ver not in [None, '']:\r
482 Cmd += ["-n", Ver]\r
483 if BuildNumber:\r
484 Cmd += ["-j", BuildNumber]\r
485 Cmd += ["-o", Output]\r
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
LG
495 else:\r
496 Cmd += ["-o", Output]\r
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
512 if AlignString == None:\r
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
LG
526 if Fixed == True:\r
527 Cmd += ["-x"]\r
528 if CheckSum:\r
529 Cmd += ["-s"]\r
530 if Align not in [None, '']:\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
f51461c8
LG
537 Cmd += ["-a", Align]\r
538\r
539 Cmd += ["-o", Output]\r
540 for I in range(0, len(Input)):\r
541 Cmd += ("-i", Input[I])\r
542 if SectionAlign not in [None, '', []] and SectionAlign[I] not in [None, '']:\r
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
550 if (tuple(Cmd),tuple(GenFdsGlobalVariable.SecCmdList),tuple(GenFdsGlobalVariable.CopyList)) not in GenFdsGlobalVariable.FfsCmdDict.keys():\r
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
567 if BaseAddress not in [None, '']:\r
568 Cmd += ["-r", BaseAddress]\r
47fea6af 569\r
f51461c8 570 if ForceRebase == False:\r
47fea6af 571 Cmd += ["-F", "FALSE"]\r
f51461c8 572 elif ForceRebase == True:\r
47fea6af
YZ
573 Cmd += ["-F", "TRUE"]\r
574\r
f51461c8
LG
575 if Capsule:\r
576 Cmd += ["-c"]\r
577 if Dump:\r
578 Cmd += ["-p"]\r
579 if AddressFile not in [None, '']:\r
580 Cmd += ["-a", AddressFile]\r
581 if MapFile not in [None, '']:\r
582 Cmd += ["-m", MapFile]\r
583 if FileSystemGuid:\r
584 Cmd += ["-g", FileSystemGuid]\r
585 Cmd += ["-o", Output]\r
586 for I in Input:\r
587 Cmd += ["-i", I]\r
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
598 if BaseAddress not in [None, ''] and FvSize not in [None, ''] \\r
599 and len(BaseAddress) == len(FvSize):\r
600 for I in range(0, len(BaseAddress)):\r
601 Cmd += ["-r", BaseAddress[I], "-s", FvSize[I]]\r
602 Cmd += ["-o", Output]\r
603 for F in Input:\r
604 Cmd += ["-f", F]\r
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
618 Cmd += ["-t"]\r
619 if SubType not in [None, '']:\r
620 Cmd += ["-e", SubType]\r
621 if TimeStamp not in [None, '']:\r
622 Cmd += ["-s", TimeStamp]\r
623 if Align not in [None, '']:\r
624 Cmd += ["-a", Align]\r
625 if Padding not in [None, '']:\r
626 Cmd += ["-p", Padding]\r
627 if Zero:\r
628 Cmd += ["-z"]\r
629 if Strip:\r
630 Cmd += ["-l"]\r
631 if Replace:\r
632 Cmd += ["-r"]\r
633 if Join:\r
634 Cmd += ["-j"]\r
635 if Convert:\r
636 Cmd += ["-m"]\r
637 Cmd += ["-o", Output]\r
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
f51461c8
LG
648 InputList = [] \r
649 Cmd = ["EfiRom"]\r
650 if len(EfiInput) > 0:\r
651 \r
652 if Compress:\r
653 Cmd += ["-ec"]\r
654 else:\r
655 Cmd += ["-e"]\r
656 \r
657 for EfiFile in EfiInput:\r
658 Cmd += [EfiFile]\r
659 InputList.append (EfiFile)\r
660 \r
661 if len(BinaryInput) > 0:\r
662 Cmd += ["-b"]\r
663 for BinFile in BinaryInput:\r
664 Cmd += [BinFile]\r
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
671 \r
672 if ClassCode != None:\r
673 Cmd += ["-l", ClassCode]\r
674 if Revision != None:\r
675 Cmd += ["-r", Revision]\r
676 if DeviceId != None:\r
677 Cmd += ["-i", DeviceId]\r
678 if VendorId != None:\r
679 Cmd += ["-f", VendorId]\r
680\r
47fea6af 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
696 Cmd += ["-o", Output]\r
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
f51461c8
LG
725 except Exception, X:\r
726 EdkLogger.error("GenFds", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0]))\r
727 (out, error) = PopenObject.communicate()\r
728\r
729 while PopenObject.returncode == None :\r
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
740 print "###", cmd\r
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
47fea6af 760 def MacroExtend (Str, MacroDict={}, Arch='COMMON'):\r
f51461c8
LG
761 if Str == None :\r
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
772 if Arch != 'COMMON' and Arch in GenFdsGlobalVariable.ArchList:\r
773 OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[Arch]\r
774\r
775 Dict['$(OUTPUT_DIRECTORY)'] = OutputDir\r
776\r
777 if MacroDict != None and len (MacroDict) != 0:\r
778 Dict.update(MacroDict)\r
779\r
780 for key in Dict.keys():\r
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
797 if PcdPattern == None :\r
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
810 if PcdObj.Type != 'FixedAtBuild':\r
811 EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)\r
812 if PcdObj.DatumType != 'VOID*':\r
813 EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)\r
814 \r
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
826 if PcdObj.Type != 'FixedAtBuild':\r
827 EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)\r
828 if PcdObj.DatumType != 'VOID*':\r
829 EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)\r
830 \r
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