]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
BaseTools: use set instead of list for a variable to be used with in
[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
4231a819 232 if File.IsBinary and File == Source and Inf.Binaries is not None and File in Inf.Binaries:\r
f51461c8
LG
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
4231a819 423 if Input is None or len(Input) == 0:\r
f51461c8
LG
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
4231a819 448 if Guid is not None:\r
f51461c8 449 Cmd += ["-g", Guid]\r
4231a819 450 if DummyFile is not None:\r
37de70b7 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
4231a819 458 if InputAlign is not None:\r
f51461c8
LG
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 466 if IsMakefile:\r
a146c532
FY
467 if Ui == "$(MODULE_NAME)":\r
468 Cmd += ['-n', Ui]\r
469 else:\r
470 Cmd += ["-n", '"' + Ui + '"']\r
37de70b7 471 Cmd += ["-o", Output]\r
37de70b7
YZ
472 if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r
473 GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())\r
474 else:\r
475 SectionData = array.array('B', [0, 0, 0, 0])\r
476 SectionData.fromstring(Ui.encode("utf_16_le"))\r
477 SectionData.append(0)\r
478 SectionData.append(0)\r
479 Len = len(SectionData)\r
480 GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x15)\r
481 SaveFileOnChange(Output, SectionData.tostring())\r
482\r
f51461c8
LG
483 elif Ver not in [None, '']:\r
484 Cmd += ["-n", Ver]\r
485 if BuildNumber:\r
486 Cmd += ["-j", BuildNumber]\r
487 Cmd += ["-o", Output]\r
488\r
489 SaveFileOnChange(CommandFile, ' '.join(Cmd), False)\r
37de70b7
YZ
490 if IsMakefile:\r
491 if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r
492 GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())\r
493 else:\r
494 if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):\r
495 return\r
496 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")\r
f51461c8
LG
497 else:\r
498 Cmd += ["-o", Output]\r
499 Cmd += Input\r
500\r
501 SaveFileOnChange(CommandFile, ' '.join(Cmd), False)\r
37de70b7
YZ
502 if IsMakefile:\r
503 if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r
504 GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())\r
6735645d 505 elif GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):\r
f51461c8
LG
506 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r
507 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")\r
37de70b7
YZ
508 if (os.path.getsize(Output) >= GenFdsGlobalVariable.LARGE_FILE_SIZE and\r
509 GenFdsGlobalVariable.LargeFileInFvFlags):\r
510 GenFdsGlobalVariable.LargeFileInFvFlags[-1] = True\r
f51461c8
LG
511\r
512 @staticmethod\r
513 def GetAlignment (AlignString):\r
4231a819 514 if AlignString is None:\r
f51461c8 515 return 0\r
e921f58d 516 if AlignString in ("1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K"):\r
52302d4d 517 return int (AlignString.rstrip('K')) * 1024\r
e921f58d
YZ
518 elif AlignString in ("1M", "2M", "4M", "8M", "16M"):\r
519 return int (AlignString.rstrip('M')) * 1024 * 1024\r
52302d4d
LG
520 else:\r
521 return int (AlignString)\r
f51461c8
LG
522\r
523 @staticmethod\r
524 def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None,\r
37de70b7 525 SectionAlign=None, MakefilePath=None):\r
f51461c8 526 Cmd = ["GenFfs", "-t", Type, "-g", Guid]\r
e921f58d 527 mFfsValidAlign = ["0", "8", "16", "128", "512", "1K", "4K", "32K", "64K", "128K", "256K", "512K", "1M", "2M", "4M", "8M", "16M"]\r
f51461c8
LG
528 if Fixed == True:\r
529 Cmd += ["-x"]\r
530 if CheckSum:\r
531 Cmd += ["-s"]\r
532 if Align not in [None, '']:\r
d2192f12
YZ
533 if Align not in mFfsValidAlign:\r
534 Align = GenFdsGlobalVariable.GetAlignment (Align)\r
535 for index in range(0, len(mFfsValidAlign) - 1):\r
536 if ((Align > GenFdsGlobalVariable.GetAlignment(mFfsValidAlign[index])) and (Align <= GenFdsGlobalVariable.GetAlignment(mFfsValidAlign[index + 1]))):\r
537 break\r
538 Align = mFfsValidAlign[index + 1]\r
f51461c8
LG
539 Cmd += ["-a", Align]\r
540\r
541 Cmd += ["-o", Output]\r
542 for I in range(0, len(Input)):\r
543 Cmd += ("-i", Input[I])\r
544 if SectionAlign not in [None, '', []] and SectionAlign[I] not in [None, '']:\r
545 Cmd += ("-n", SectionAlign[I])\r
546\r
547 CommandFile = Output + '.txt'\r
548 SaveFileOnChange(CommandFile, ' '.join(Cmd), False)\r
f51461c8 549\r
37de70b7
YZ
550 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r
551 if MakefilePath:\r
552 if (tuple(Cmd),tuple(GenFdsGlobalVariable.SecCmdList),tuple(GenFdsGlobalVariable.CopyList)) not in GenFdsGlobalVariable.FfsCmdDict.keys():\r
553 GenFdsGlobalVariable.FfsCmdDict[tuple(Cmd), tuple(GenFdsGlobalVariable.SecCmdList), tuple(GenFdsGlobalVariable.CopyList)] = MakefilePath\r
554 GenFdsGlobalVariable.SecCmdList = []\r
555 GenFdsGlobalVariable.CopyList = []\r
556 else:\r
6735645d 557 if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):\r
37de70b7
YZ
558 return\r
559 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS")\r
f51461c8
LG
560\r
561 @staticmethod\r
562 def GenerateFirmwareVolume(Output, Input, BaseAddress=None, ForceRebase=None, Capsule=False, Dump=False,\r
563 AddressFile=None, MapFile=None, FfsList=[], FileSystemGuid=None):\r
564 if not GenFdsGlobalVariable.NeedsUpdate(Output, Input+FfsList):\r
565 return\r
566 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r
567\r
568 Cmd = ["GenFv"]\r
569 if BaseAddress not in [None, '']:\r
570 Cmd += ["-r", BaseAddress]\r
47fea6af 571\r
f51461c8 572 if ForceRebase == False:\r
47fea6af 573 Cmd += ["-F", "FALSE"]\r
f51461c8 574 elif ForceRebase == True:\r
47fea6af
YZ
575 Cmd += ["-F", "TRUE"]\r
576\r
f51461c8
LG
577 if Capsule:\r
578 Cmd += ["-c"]\r
579 if Dump:\r
580 Cmd += ["-p"]\r
581 if AddressFile not in [None, '']:\r
582 Cmd += ["-a", AddressFile]\r
583 if MapFile not in [None, '']:\r
584 Cmd += ["-m", MapFile]\r
585 if FileSystemGuid:\r
586 Cmd += ["-g", FileSystemGuid]\r
587 Cmd += ["-o", Output]\r
588 for I in Input:\r
589 Cmd += ["-i", I]\r
590\r
591 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FV")\r
592\r
593 @staticmethod\r
594 def GenerateVtf(Output, Input, BaseAddress=None, FvSize=None):\r
595 if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):\r
596 return\r
597 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r
598\r
599 Cmd = ["GenVtf"]\r
600 if BaseAddress not in [None, ''] and FvSize not in [None, ''] \\r
601 and len(BaseAddress) == len(FvSize):\r
602 for I in range(0, len(BaseAddress)):\r
603 Cmd += ["-r", BaseAddress[I], "-s", FvSize[I]]\r
604 Cmd += ["-o", Output]\r
605 for F in Input:\r
606 Cmd += ["-f", F]\r
607\r
608 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate VTF")\r
609\r
610 @staticmethod\r
611 def GenerateFirmwareImage(Output, Input, Type="efi", SubType=None, Zero=False,\r
612 Strip=False, Replace=False, TimeStamp=None, Join=False,\r
37de70b7
YZ
613 Align=None, Padding=None, Convert=False, IsMakefile=False):\r
614 if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile:\r
f51461c8
LG
615 return\r
616 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r
617\r
618 Cmd = ["GenFw"]\r
619 if Type.lower() == "te":\r
620 Cmd += ["-t"]\r
621 if SubType not in [None, '']:\r
622 Cmd += ["-e", SubType]\r
623 if TimeStamp not in [None, '']:\r
624 Cmd += ["-s", TimeStamp]\r
625 if Align not in [None, '']:\r
626 Cmd += ["-a", Align]\r
627 if Padding not in [None, '']:\r
628 Cmd += ["-p", Padding]\r
629 if Zero:\r
630 Cmd += ["-z"]\r
631 if Strip:\r
632 Cmd += ["-l"]\r
633 if Replace:\r
634 Cmd += ["-r"]\r
635 if Join:\r
636 Cmd += ["-j"]\r
637 if Convert:\r
638 Cmd += ["-m"]\r
639 Cmd += ["-o", Output]\r
640 Cmd += Input\r
37de70b7
YZ
641 if IsMakefile:\r
642 if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r
643 GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())\r
644 else:\r
645 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image")\r
f51461c8
LG
646\r
647 @staticmethod\r
648 def GenerateOptionRom(Output, EfiInput, BinaryInput, Compress=False, ClassCode=None,\r
37de70b7 649 Revision=None, DeviceId=None, VendorId=None, IsMakefile=False):\r
f51461c8
LG
650 InputList = [] \r
651 Cmd = ["EfiRom"]\r
652 if len(EfiInput) > 0:\r
653 \r
654 if Compress:\r
655 Cmd += ["-ec"]\r
656 else:\r
657 Cmd += ["-e"]\r
658 \r
659 for EfiFile in EfiInput:\r
660 Cmd += [EfiFile]\r
661 InputList.append (EfiFile)\r
662 \r
663 if len(BinaryInput) > 0:\r
664 Cmd += ["-b"]\r
665 for BinFile in BinaryInput:\r
666 Cmd += [BinFile]\r
667 InputList.append (BinFile)\r
668\r
669 # Check List\r
37de70b7 670 if not GenFdsGlobalVariable.NeedsUpdate(Output, InputList) and not IsMakefile:\r
f51461c8
LG
671 return\r
672 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, InputList))\r
673 \r
4231a819 674 if ClassCode is not None:\r
f51461c8 675 Cmd += ["-l", ClassCode]\r
4231a819 676 if Revision is not None:\r
f51461c8 677 Cmd += ["-r", Revision]\r
4231a819 678 if DeviceId is not None:\r
f51461c8 679 Cmd += ["-i", DeviceId]\r
4231a819 680 if VendorId is not None:\r
f51461c8
LG
681 Cmd += ["-f", VendorId]\r
682\r
47fea6af 683 Cmd += ["-o", Output]\r
37de70b7
YZ
684 if IsMakefile:\r
685 if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r
686 GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())\r
687 else:\r
688 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate option rom")\r
f51461c8
LG
689\r
690 @staticmethod\r
37de70b7
YZ
691 def GuidTool(Output, Input, ToolPath, Options='', returnValue=[], IsMakefile=False):\r
692 if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile:\r
f51461c8
LG
693 return\r
694 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r
695\r
696 Cmd = [ToolPath, ]\r
697 Cmd += Options.split(' ')\r
698 Cmd += ["-o", Output]\r
699 Cmd += Input\r
37de70b7
YZ
700 if IsMakefile:\r
701 if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r
702 GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())\r
703 else:\r
704 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath, returnValue)\r
f51461c8
LG
705\r
706 def CallExternalTool (cmd, errorMess, returnValue=[]):\r
707\r
708 if type(cmd) not in (tuple, list):\r
709 GenFdsGlobalVariable.ErrorLogger("ToolError! Invalid parameter type in call to CallExternalTool")\r
710\r
711 if GenFdsGlobalVariable.DebugLevel != -1:\r
712 cmd += ('--debug', str(GenFdsGlobalVariable.DebugLevel))\r
713 GenFdsGlobalVariable.InfLogger (cmd)\r
714\r
715 if GenFdsGlobalVariable.VerboseMode:\r
716 cmd += ('-v',)\r
717 GenFdsGlobalVariable.InfLogger (cmd)\r
718 else:\r
719 sys.stdout.write ('#')\r
720 sys.stdout.flush()\r
721 GenFdsGlobalVariable.SharpCounter = GenFdsGlobalVariable.SharpCounter + 1\r
722 if GenFdsGlobalVariable.SharpCounter % GenFdsGlobalVariable.SharpNumberPerLine == 0:\r
723 sys.stdout.write('\n')\r
724\r
725 try:\r
47fea6af 726 PopenObject = subprocess.Popen(' '.join(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)\r
f51461c8
LG
727 except Exception, X:\r
728 EdkLogger.error("GenFds", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0]))\r
729 (out, error) = PopenObject.communicate()\r
730\r
4231a819 731 while PopenObject.returncode is None :\r
f51461c8
LG
732 PopenObject.wait()\r
733 if returnValue != [] and returnValue[0] != 0:\r
734 #get command return value\r
735 returnValue[0] = PopenObject.returncode\r
736 return\r
737 if PopenObject.returncode != 0 or GenFdsGlobalVariable.VerboseMode or GenFdsGlobalVariable.DebugLevel != -1:\r
47fea6af 738 GenFdsGlobalVariable.InfLogger ("Return Value = %d" % PopenObject.returncode)\r
f51461c8
LG
739 GenFdsGlobalVariable.InfLogger (out)\r
740 GenFdsGlobalVariable.InfLogger (error)\r
741 if PopenObject.returncode != 0:\r
742 print "###", cmd\r
743 EdkLogger.error("GenFds", COMMAND_FAILURE, errorMess)\r
744\r
745 def VerboseLogger (msg):\r
746 EdkLogger.verbose(msg)\r
747\r
748 def InfLogger (msg):\r
749 EdkLogger.info(msg)\r
750\r
47fea6af 751 def ErrorLogger (msg, File=None, Line=None, ExtraData=None):\r
f51461c8
LG
752 EdkLogger.error('GenFds', GENFDS_ERROR, msg, File, Line, ExtraData)\r
753\r
754 def DebugLogger (Level, msg):\r
755 EdkLogger.debug(Level, msg)\r
756\r
757 ## ReplaceWorkspaceMacro()\r
758 #\r
759 # @param Str String that may contain macro\r
760 # @param MacroDict Dictionary that contains macro value pair\r
761 #\r
47fea6af 762 def MacroExtend (Str, MacroDict={}, Arch='COMMON'):\r
4231a819 763 if Str is None :\r
f51461c8
LG
764 return None\r
765\r
766 Dict = {'$(WORKSPACE)' : GenFdsGlobalVariable.WorkSpaceDir,\r
767 '$(EDK_SOURCE)' : GenFdsGlobalVariable.EdkSourceDir,\r
768# '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc,\r
769 '$(TARGET)' : GenFdsGlobalVariable.TargetName,\r
97fa0ee9
YL
770 '$(TOOL_CHAIN_TAG)' : GenFdsGlobalVariable.ToolChainTag,\r
771 '$(SPACE)' : ' '\r
f51461c8
LG
772 }\r
773 OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[GenFdsGlobalVariable.ArchList[0]]\r
774 if Arch != 'COMMON' and Arch in GenFdsGlobalVariable.ArchList:\r
775 OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[Arch]\r
776\r
777 Dict['$(OUTPUT_DIRECTORY)'] = OutputDir\r
778\r
4231a819 779 if MacroDict is not None and len (MacroDict) != 0:\r
f51461c8
LG
780 Dict.update(MacroDict)\r
781\r
782 for key in Dict.keys():\r
783 if Str.find(key) >= 0 :\r
784 Str = Str.replace (key, Dict[key])\r
785\r
786 if Str.find('$(ARCH)') >= 0:\r
787 if len(GenFdsGlobalVariable.ArchList) == 1:\r
788 Str = Str.replace('$(ARCH)', GenFdsGlobalVariable.ArchList[0])\r
789 else:\r
790 EdkLogger.error("GenFds", GENFDS_ERROR, "No way to determine $(ARCH) for %s" % Str)\r
791\r
792 return Str\r
793\r
794 ## GetPcdValue()\r
795 #\r
796 # @param PcdPattern pattern that labels a PCD.\r
797 #\r
798 def GetPcdValue (PcdPattern):\r
4231a819 799 if PcdPattern is None :\r
f51461c8
LG
800 return None\r
801 PcdPair = PcdPattern.lstrip('PCD(').rstrip(')').strip().split('.')\r
802 TokenSpace = PcdPair[0]\r
803 TokenCName = PcdPair[1]\r
804\r
805 PcdValue = ''\r
806 for Arch in GenFdsGlobalVariable.ArchList:\r
807 Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
808 PcdDict = Platform.Pcds\r
809 for Key in PcdDict:\r
810 PcdObj = PcdDict[Key]\r
811 if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):\r
812 if PcdObj.Type != 'FixedAtBuild':\r
813 EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)\r
814 if PcdObj.DatumType != 'VOID*':\r
815 EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)\r
816 \r
817 PcdValue = PcdObj.DefaultValue\r
818 return PcdValue\r
47fea6af
YZ
819\r
820 for Package in GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform,\r
821 Arch,\r
822 GenFdsGlobalVariable.TargetName,\r
f51461c8
LG
823 GenFdsGlobalVariable.ToolChainTag):\r
824 PcdDict = Package.Pcds\r
825 for Key in PcdDict:\r
826 PcdObj = PcdDict[Key]\r
827 if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):\r
828 if PcdObj.Type != 'FixedAtBuild':\r
829 EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)\r
830 if PcdObj.DatumType != 'VOID*':\r
831 EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)\r
832 \r
833 PcdValue = PcdObj.DefaultValue\r
834 return PcdValue\r
835\r
836 return PcdValue\r
837\r
838 SetDir = staticmethod(SetDir)\r
37de70b7 839 SetEnv = staticmethod(SetEnv)\r
f51461c8
LG
840 ReplaceWorkspaceMacro = staticmethod(ReplaceWorkspaceMacro)\r
841 CallExternalTool = staticmethod(CallExternalTool)\r
842 VerboseLogger = staticmethod(VerboseLogger)\r
843 InfLogger = staticmethod(InfLogger)\r
844 ErrorLogger = staticmethod(ErrorLogger)\r
845 DebugLogger = staticmethod(DebugLogger)\r
846 MacroExtend = staticmethod (MacroExtend)\r
847 GetPcdValue = staticmethod(GetPcdValue)\r