2 # Global variables for GenFds
4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
6 # SPDX-License-Identifier: BSD-2-Clause-Patent
12 from __future__
import print_function
13 from __future__
import absolute_import
15 import Common
.LongFilePathOs
as os
16 from sys
import stdout
17 from subprocess
import PIPE
,Popen
18 from struct
import Struct
19 from array
import array
21 from Common
.BuildToolError
import COMMAND_FAILURE
,GENFDS_ERROR
22 from Common
import EdkLogger
23 from Common
.Misc
import SaveFileOnChange
25 from Common
.TargetTxtClassObject
import TargetTxtClassObject
26 from Common
.ToolDefClassObject
import ToolDefClassObject
, ToolDefDict
27 from AutoGen
.BuildEngine
import BuildRule
28 import Common
.DataType
as DataType
29 from Common
.Misc
import PathClass
30 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
31 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
36 class GenFdsGlobalVariable
:
40 # will be FvDir + os.sep + 'Ffs'
47 OutputDirFromDscDict
= {}
53 FvAddressFileName
= ''
57 SharpNumberPerLine
= 40
60 FixedLoadAddress
= False
63 BuildRuleFamily
= DataType
.TAB_COMPILER_MSFT
64 ToolChainFamily
= DataType
.TAB_COMPILER_MSFT
65 __BuildRuleDatabase
= None
66 GuidToolDefinition
= {}
71 EnableGenfdsMultiThread
= False
74 # The list whose element are flags to indicate if large FFS or SECTION files exist in FV.
75 # At the beginning of each generation of FV, false flag is appended to the list,
76 # after the call to GenerateSection returns, check the size of the output file,
77 # if it is greater than 0xFFFFFF, the tail flag in list is set to true,
78 # and EFI_FIRMWARE_FILE_SYSTEM3_GUID is passed to C GenFv.
79 # At the end of generation of FV, pop the flag.
80 # List is used as a stack to handle nested FV generation.
82 LargeFileInFvFlags
= []
83 EFI_FIRMWARE_FILE_SYSTEM3_GUID
= '5473C07A-3DCB-4dca-BD6F-1E9689E7349A'
84 LARGE_FILE_SIZE
= 0x1000000
86 SectionHeader
= Struct("3B 1B")
88 # FvName, FdName, CapName in FDF, Image file name
95 if GenFdsGlobalVariable
.__BuildRuleDatabase
:
96 return GenFdsGlobalVariable
.__BuildRuleDatabase
97 BuildConfigurationFile
= os
.path
.normpath(os
.path
.join(GenFdsGlobalVariable
.ConfDir
, "target.txt"))
98 TargetTxt
= TargetTxtClassObject()
99 if os
.path
.isfile(BuildConfigurationFile
) == True:
100 TargetTxt
.LoadTargetTxtFile(BuildConfigurationFile
)
101 if DataType
.TAB_TAT_DEFINES_BUILD_RULE_CONF
in TargetTxt
.TargetTxtDictionary
:
102 BuildRuleFile
= TargetTxt
.TargetTxtDictionary
[DataType
.TAB_TAT_DEFINES_BUILD_RULE_CONF
]
103 if not BuildRuleFile
:
104 BuildRuleFile
= 'Conf/build_rule.txt'
105 GenFdsGlobalVariable
.__BuildRuleDatabase
= BuildRule(BuildRuleFile
)
106 ToolDefinitionFile
= TargetTxt
.TargetTxtDictionary
[DataType
.TAB_TAT_DEFINES_TOOL_CHAIN_CONF
]
107 if ToolDefinitionFile
== '':
108 ToolDefinitionFile
= "Conf/tools_def.txt"
109 if os
.path
.isfile(ToolDefinitionFile
):
110 ToolDef
= ToolDefClassObject()
111 ToolDef
.LoadToolDefFile(ToolDefinitionFile
)
112 ToolDefinition
= ToolDef
.ToolsDefTxtDatabase
113 if DataType
.TAB_TOD_DEFINES_BUILDRULEFAMILY
in ToolDefinition \
114 and GenFdsGlobalVariable
.ToolChainTag
in ToolDefinition
[DataType
.TAB_TOD_DEFINES_BUILDRULEFAMILY
] \
115 and ToolDefinition
[DataType
.TAB_TOD_DEFINES_BUILDRULEFAMILY
][GenFdsGlobalVariable
.ToolChainTag
]:
116 GenFdsGlobalVariable
.BuildRuleFamily
= ToolDefinition
[DataType
.TAB_TOD_DEFINES_BUILDRULEFAMILY
][GenFdsGlobalVariable
.ToolChainTag
]
118 if DataType
.TAB_TOD_DEFINES_FAMILY
in ToolDefinition \
119 and GenFdsGlobalVariable
.ToolChainTag
in ToolDefinition
[DataType
.TAB_TOD_DEFINES_FAMILY
] \
120 and ToolDefinition
[DataType
.TAB_TOD_DEFINES_FAMILY
][GenFdsGlobalVariable
.ToolChainTag
]:
121 GenFdsGlobalVariable
.ToolChainFamily
= ToolDefinition
[DataType
.TAB_TOD_DEFINES_FAMILY
][GenFdsGlobalVariable
.ToolChainTag
]
122 return GenFdsGlobalVariable
.__BuildRuleDatabase
125 # @param Inf: object of InfBuildData
126 # @param Arch: current arch
129 def GetBuildRules(Inf
, Arch
):
131 Arch
= DataType
.TAB_COMMON
133 if not Arch
in GenFdsGlobalVariable
.OutputDirDict
:
136 BuildRuleDatabase
= GenFdsGlobalVariable
._LoadBuildRule
()
137 if not BuildRuleDatabase
:
140 PathClassObj
= PathClass(Inf
.MetaFile
.File
,
141 GenFdsGlobalVariable
.WorkSpaceDir
)
142 BuildDir
= os
.path
.join(
143 GenFdsGlobalVariable
.OutputDirDict
[Arch
],
146 PathClassObj
.BaseName
148 BinDir
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
], Arch
)
150 "WORKSPACE":GenFdsGlobalVariable
.WorkSpaceDir
,
151 "MODULE_NAME":Inf
.BaseName
,
152 "MODULE_GUID":Inf
.Guid
,
153 "MODULE_VERSION":Inf
.Version
,
154 "MODULE_TYPE":Inf
.ModuleType
,
155 "MODULE_FILE":str(PathClassObj
),
156 "MODULE_FILE_BASE_NAME":PathClassObj
.BaseName
,
157 "MODULE_RELATIVE_DIR":PathClassObj
.SubDir
,
158 "MODULE_DIR":PathClassObj
.SubDir
,
159 "BASE_NAME":Inf
.BaseName
,
161 "TOOLCHAIN":GenFdsGlobalVariable
.ToolChainTag
,
162 "TOOLCHAIN_TAG":GenFdsGlobalVariable
.ToolChainTag
,
163 "TOOL_CHAIN_TAG":GenFdsGlobalVariable
.ToolChainTag
,
164 "TARGET":GenFdsGlobalVariable
.TargetName
,
165 "BUILD_DIR":GenFdsGlobalVariable
.OutputDirDict
[Arch
],
168 "MODULE_BUILD_DIR":BuildDir
,
169 "OUTPUT_DIR":os
.path
.join(BuildDir
, "OUTPUT"),
170 "DEBUG_DIR":os
.path
.join(BuildDir
, "DEBUG")
174 for Type
in BuildRuleDatabase
.FileTypeList
:
175 #first try getting build rule by BuildRuleFamily
176 RuleObject
= BuildRuleDatabase
[Type
, Inf
.BuildType
, Arch
, GenFdsGlobalVariable
.BuildRuleFamily
]
178 # build type is always module type, but ...
179 if Inf
.ModuleType
!= Inf
.BuildType
:
180 RuleObject
= BuildRuleDatabase
[Type
, Inf
.ModuleType
, Arch
, GenFdsGlobalVariable
.BuildRuleFamily
]
181 #second try getting build rule by ToolChainFamily
183 RuleObject
= BuildRuleDatabase
[Type
, Inf
.BuildType
, Arch
, GenFdsGlobalVariable
.ToolChainFamily
]
185 # build type is always module type, but ...
186 if Inf
.ModuleType
!= Inf
.BuildType
:
187 RuleObject
= BuildRuleDatabase
[Type
, Inf
.ModuleType
, Arch
, GenFdsGlobalVariable
.ToolChainFamily
]
190 RuleObject
= RuleObject
.Instantiate(Macro
)
191 BuildRules
[Type
] = RuleObject
192 for Ext
in RuleObject
.SourceFileExtList
:
193 BuildRules
[Ext
] = RuleObject
196 ## GetModuleCodaTargetList
198 # @param Inf: object of InfBuildData
199 # @param Arch: current arch
202 def GetModuleCodaTargetList(Inf
, Arch
):
203 BuildRules
= GenFdsGlobalVariable
.GetBuildRules(Inf
, Arch
)
210 if not Inf
.IsBinaryModule
:
211 for File
in Inf
.Sources
:
212 if File
.TagName
in {"", DataType
.TAB_STAR
, GenFdsGlobalVariable
.ToolChainTag
} and \
213 File
.ToolChainFamily
in {"", DataType
.TAB_STAR
, GenFdsGlobalVariable
.ToolChainFamily
}:
214 FileList
.append((File
, DataType
.TAB_UNKNOWN_FILE
))
216 for File
in Inf
.Binaries
:
217 if File
.Target
in {DataType
.TAB_COMMON
, DataType
.TAB_STAR
, GenFdsGlobalVariable
.TargetName
}:
218 FileList
.append((File
, File
.Type
))
220 for File
, FileType
in FileList
:
225 while Index
< len(SourceList
):
226 Source
= SourceList
[Index
]
229 if File
.IsBinary
and File
== Source
and Inf
.Binaries
and File
in Inf
.Binaries
:
230 # Skip all files that are not binary libraries
231 if not Inf
.LibraryClass
:
233 RuleObject
= BuildRules
[DataType
.TAB_DEFAULT_BINARY_FILE
]
234 elif FileType
in BuildRules
:
235 RuleObject
= BuildRules
[FileType
]
236 elif Source
.Ext
in BuildRules
:
237 RuleObject
= BuildRules
[Source
.Ext
]
239 # stop at no more rules
241 TargetList
.add(str(LastTarget
))
244 FileType
= RuleObject
.SourceFileType
246 # stop at STATIC_LIBRARY for library
247 if Inf
.LibraryClass
and FileType
== DataType
.TAB_STATIC_LIBRARY
:
249 TargetList
.add(str(LastTarget
))
252 Target
= RuleObject
.Apply(Source
)
255 TargetList
.add(str(LastTarget
))
257 elif not Target
.Outputs
:
258 # Only do build for target with outputs
259 TargetList
.add(str(Target
))
261 # to avoid cyclic rule
262 if FileType
in RuleChain
:
265 RuleChain
.append(FileType
)
266 SourceList
.extend(Target
.Outputs
)
268 FileType
= DataType
.TAB_UNKNOWN_FILE
269 for Cmd
in Target
.Commands
:
270 if "$(CP)" == Cmd
.split()[0]:
271 CpTarget
= Cmd
.split()[2]
272 TargetList
.add(CpTarget
)
274 return list(TargetList
)
278 # @param OutputDir Output directory
279 # @param FdfParser FDF contents parser
280 # @param Workspace The directory of workspace
281 # @param ArchList The Arch list of platform
284 def SetDir (OutputDir
, FdfParser
, WorkSpace
, ArchList
):
285 GenFdsGlobalVariable
.VerboseLogger("GenFdsGlobalVariable.OutputDir:%s" % OutputDir
)
286 GenFdsGlobalVariable
.FdfParser
= FdfParser
287 GenFdsGlobalVariable
.WorkSpace
= WorkSpace
288 GenFdsGlobalVariable
.FvDir
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[ArchList
[0]], DataType
.TAB_FV_DIRECTORY
)
289 if not os
.path
.exists(GenFdsGlobalVariable
.FvDir
):
290 os
.makedirs(GenFdsGlobalVariable
.FvDir
)
291 GenFdsGlobalVariable
.FfsDir
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, 'Ffs')
292 if not os
.path
.exists(GenFdsGlobalVariable
.FfsDir
):
293 os
.makedirs(GenFdsGlobalVariable
.FfsDir
)
296 # Create FV Address inf file
298 GenFdsGlobalVariable
.FvAddressFileName
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, 'FvAddress.inf')
299 FvAddressFile
= open(GenFdsGlobalVariable
.FvAddressFileName
, 'w')
303 FvAddressFile
.writelines("[options]" + DataType
.TAB_LINE_BREAK
)
305 for Arch
in ArchList
:
306 if GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
].BsBaseAddress
:
307 BsAddress
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
].BsBaseAddress
310 FvAddressFile
.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \
312 DataType
.TAB_LINE_BREAK
)
315 for Arch
in reversed(ArchList
):
316 temp
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
].RtBaseAddress
321 FvAddressFile
.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \
323 DataType
.TAB_LINE_BREAK
)
325 FvAddressFile
.close()
328 def SetEnv(FdfParser
, WorkSpace
, ArchList
, GlobalData
):
329 GenFdsGlobalVariable
.ModuleFile
= WorkSpace
.ModuleFile
330 GenFdsGlobalVariable
.FdfParser
= FdfParser
331 GenFdsGlobalVariable
.WorkSpace
= WorkSpace
.Db
332 GenFdsGlobalVariable
.ArchList
= ArchList
333 GenFdsGlobalVariable
.ToolChainTag
= GlobalData
.gGlobalDefines
["TOOL_CHAIN_TAG"]
334 GenFdsGlobalVariable
.TargetName
= GlobalData
.gGlobalDefines
["TARGET"]
335 GenFdsGlobalVariable
.ActivePlatform
= GlobalData
.gActivePlatform
336 GenFdsGlobalVariable
.ConfDir
= GlobalData
.gConfDirectory
337 GenFdsGlobalVariable
.EnableGenfdsMultiThread
= GlobalData
.gEnableGenfdsMultiThread
338 for Arch
in ArchList
:
339 GenFdsGlobalVariable
.OutputDirDict
[Arch
] = os
.path
.normpath(
340 os
.path
.join(GlobalData
.gWorkspace
,
341 WorkSpace
.Db
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GlobalData
.gGlobalDefines
['TARGET'],
342 GlobalData
.gGlobalDefines
['TOOLCHAIN']].OutputDirectory
,
343 GlobalData
.gGlobalDefines
['TARGET'] +'_' + GlobalData
.gGlobalDefines
['TOOLCHAIN']))
344 GenFdsGlobalVariable
.OutputDirFromDscDict
[Arch
] = os
.path
.normpath(
345 WorkSpace
.Db
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
,
346 GlobalData
.gGlobalDefines
['TARGET'], GlobalData
.gGlobalDefines
['TOOLCHAIN']].OutputDirectory
)
347 GenFdsGlobalVariable
.PlatformName
= WorkSpace
.Db
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
,
348 GlobalData
.gGlobalDefines
['TARGET'],
349 GlobalData
.gGlobalDefines
['TOOLCHAIN']].PlatformName
350 GenFdsGlobalVariable
.FvDir
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[ArchList
[0]], DataType
.TAB_FV_DIRECTORY
)
351 if not os
.path
.exists(GenFdsGlobalVariable
.FvDir
):
352 os
.makedirs(GenFdsGlobalVariable
.FvDir
)
353 GenFdsGlobalVariable
.FfsDir
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, 'Ffs')
354 if not os
.path
.exists(GenFdsGlobalVariable
.FfsDir
):
355 os
.makedirs(GenFdsGlobalVariable
.FfsDir
)
358 # Create FV Address inf file
360 GenFdsGlobalVariable
.FvAddressFileName
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, 'FvAddress.inf')
361 FvAddressFile
= open(GenFdsGlobalVariable
.FvAddressFileName
, 'w')
365 FvAddressFile
.writelines("[options]" + DataType
.TAB_LINE_BREAK
)
367 for Arch
in ArchList
:
368 BsAddress
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
,
369 GlobalData
.gGlobalDefines
['TARGET'],
370 GlobalData
.gGlobalDefines
["TOOL_CHAIN_TAG"]].BsBaseAddress
374 FvAddressFile
.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \
376 DataType
.TAB_LINE_BREAK
)
379 for Arch
in reversed(ArchList
):
380 temp
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[
381 GenFdsGlobalVariable
.ActivePlatform
, Arch
, GlobalData
.gGlobalDefines
['TARGET'],
382 GlobalData
.gGlobalDefines
["TOOL_CHAIN_TAG"]].RtBaseAddress
387 FvAddressFile
.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \
389 DataType
.TAB_LINE_BREAK
)
391 FvAddressFile
.close()
393 ## ReplaceWorkspaceMacro()
395 # @param String String that may contain macro
398 def ReplaceWorkspaceMacro(String
):
399 String
= mws
.handleWsMacro(String
)
400 Str
= String
.replace('$(WORKSPACE)', GenFdsGlobalVariable
.WorkSpaceDir
)
401 if os
.path
.exists(Str
):
402 if not os
.path
.isabs(Str
):
403 Str
= os
.path
.abspath(Str
)
405 Str
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, String
)
406 return os
.path
.normpath(Str
)
408 ## Check if the input files are newer than output files
410 # @param Output Path of output file
411 # @param Input Path list of input files
413 # @retval True if Output doesn't exist, or any Input is newer
414 # @retval False if all Input is older than Output
417 def NeedsUpdate(Output
, Input
):
418 if not os
.path
.exists(Output
):
420 # always update "Output" if no "Input" given
424 # if fdf file is changed after the 'Output" is generated, update the 'Output'
425 OutputTime
= os
.path
.getmtime(Output
)
426 if GenFdsGlobalVariable
.FdfFileTimeStamp
> OutputTime
:
430 # always update "Output" if any "Input" doesn't exist
431 if not os
.path
.exists(F
):
433 # always update "Output" if any "Input" is newer than "Output"
434 if os
.path
.getmtime(F
) > OutputTime
:
439 def GenerateSection(Output
, Input
, Type
=None, CompressionType
=None, Guid
=None,
440 GuidHdrLen
=None, GuidAttr
=[], Ui
=None, Ver
=None, InputAlign
=[], BuildNumber
=None, DummyFile
=None, IsMakefile
=False):
445 Cmd
+= ("-c", CompressionType
)
449 Cmd
+= ("--dummy", DummyFile
)
451 Cmd
+= ("-l", GuidHdrLen
)
452 #Add each guided attribute
453 for Attr
in GuidAttr
:
455 #Section Align is only for dummy section without section type
456 for SecAlign
in InputAlign
:
457 Cmd
+= ("--sectionalign", SecAlign
)
459 CommandFile
= Output
+ '.txt'
462 if Ui
== "$(MODULE_NAME)":
465 Cmd
+= ("-n", '"' + Ui
+ '"')
466 Cmd
+= ("-o", Output
)
467 if ' '.join(Cmd
).strip() not in GenFdsGlobalVariable
.SecCmdList
:
468 GenFdsGlobalVariable
.SecCmdList
.append(' '.join(Cmd
).strip())
470 SectionData
= array('B', [0, 0, 0, 0])
471 SectionData
.fromstring(Ui
.encode("utf_16_le"))
472 SectionData
.append(0)
473 SectionData
.append(0)
474 Len
= len(SectionData
)
475 GenFdsGlobalVariable
.SectionHeader
.pack_into(SectionData
, 0, Len
& 0xff, (Len
>> 8) & 0xff, (Len
>> 16) & 0xff, 0x15)
476 SaveFileOnChange(Output
, SectionData
.tostring())
481 Cmd
+= ("-j", BuildNumber
)
482 Cmd
+= ("-o", Output
)
484 SaveFileOnChange(CommandFile
, ' '.join(Cmd
), False)
486 if ' '.join(Cmd
).strip() not in GenFdsGlobalVariable
.SecCmdList
:
487 GenFdsGlobalVariable
.SecCmdList
.append(' '.join(Cmd
).strip())
489 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, list(Input
) + [CommandFile
]):
491 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate section")
493 Cmd
+= ("-o", Output
)
496 SaveFileOnChange(CommandFile
, ' '.join(Cmd
), False)
498 if ' '.join(Cmd
).strip() not in GenFdsGlobalVariable
.SecCmdList
:
499 GenFdsGlobalVariable
.SecCmdList
.append(' '.join(Cmd
).strip())
500 elif GenFdsGlobalVariable
.NeedsUpdate(Output
, list(Input
) + [CommandFile
]):
501 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
502 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate section")
503 if (os
.path
.getsize(Output
) >= GenFdsGlobalVariable
.LARGE_FILE_SIZE
and
504 GenFdsGlobalVariable
.LargeFileInFvFlags
):
505 GenFdsGlobalVariable
.LargeFileInFvFlags
[-1] = True
508 def GetAlignment (AlignString
):
511 if AlignString
.endswith('K'):
512 return int (AlignString
.rstrip('K')) * 1024
513 if AlignString
.endswith('M'):
514 return int (AlignString
.rstrip('M')) * 1024 * 1024
515 if AlignString
.endswith('G'):
516 return int (AlignString
.rstrip('G')) * 1024 * 1024 * 1024
517 return int (AlignString
)
520 def GenerateFfs(Output
, Input
, Type
, Guid
, Fixed
=False, CheckSum
=False, Align
=None,
521 SectionAlign
=None, MakefilePath
=None):
522 Cmd
= ["GenFfs", "-t", Type
, "-g", Guid
]
523 mFfsValidAlign
= ["0", "8", "16", "128", "512", "1K", "4K", "32K", "64K", "128K", "256K", "512K", "1M", "2M", "4M", "8M", "16M"]
529 if Align
not in mFfsValidAlign
:
530 Align
= GenFdsGlobalVariable
.GetAlignment (Align
)
531 for index
in range(0, len(mFfsValidAlign
) - 1):
532 if ((Align
> GenFdsGlobalVariable
.GetAlignment(mFfsValidAlign
[index
])) and (Align
<= GenFdsGlobalVariable
.GetAlignment(mFfsValidAlign
[index
+ 1]))):
534 Align
= mFfsValidAlign
[index
+ 1]
537 Cmd
+= ("-o", Output
)
538 for I
in range(0, len(Input
)):
539 Cmd
+= ("-i", Input
[I
])
540 if SectionAlign
and SectionAlign
[I
]:
541 Cmd
+= ("-n", SectionAlign
[I
])
543 CommandFile
= Output
+ '.txt'
544 SaveFileOnChange(CommandFile
, ' '.join(Cmd
), False)
546 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
548 if (tuple(Cmd
), tuple(GenFdsGlobalVariable
.SecCmdList
), tuple(GenFdsGlobalVariable
.CopyList
)) not in GenFdsGlobalVariable
.FfsCmdDict
:
549 GenFdsGlobalVariable
.FfsCmdDict
[tuple(Cmd
), tuple(GenFdsGlobalVariable
.SecCmdList
), tuple(GenFdsGlobalVariable
.CopyList
)] = MakefilePath
550 GenFdsGlobalVariable
.SecCmdList
= []
551 GenFdsGlobalVariable
.CopyList
= []
553 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, list(Input
) + [CommandFile
]):
555 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate FFS")
558 def GenerateFirmwareVolume(Output
, Input
, BaseAddress
=None, ForceRebase
=None, Capsule
=False, Dump
=False,
559 AddressFile
=None, MapFile
=None, FfsList
=[], FileSystemGuid
=None):
560 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
+FfsList
):
562 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
566 Cmd
+= ("-r", BaseAddress
)
568 if ForceRebase
== False:
569 Cmd
+= ("-F", "FALSE")
570 elif ForceRebase
== True:
571 Cmd
+= ("-F", "TRUE")
578 Cmd
+= ("-a", AddressFile
)
580 Cmd
+= ("-m", MapFile
)
582 Cmd
+= ("-g", FileSystemGuid
)
583 Cmd
+= ("-o", Output
)
587 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate FV")
590 def GenerateFirmwareImage(Output
, Input
, Type
="efi", SubType
=None, Zero
=False,
591 Strip
=False, Replace
=False, TimeStamp
=None, Join
=False,
592 Align
=None, Padding
=None, Convert
=False, IsMakefile
=False):
593 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
) and not IsMakefile
:
595 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
598 if Type
.lower() == "te":
601 Cmd
+= ("-e", SubType
)
603 Cmd
+= ("-s", TimeStamp
)
607 Cmd
+= ("-p", Padding
)
618 Cmd
+= ("-o", Output
)
621 if " ".join(Cmd
).strip() not in GenFdsGlobalVariable
.SecCmdList
:
622 GenFdsGlobalVariable
.SecCmdList
.append(" ".join(Cmd
).strip())
624 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate firmware image")
627 def GenerateOptionRom(Output
, EfiInput
, BinaryInput
, Compress
=False, ClassCode
=None,
628 Revision
=None, DeviceId
=None, VendorId
=None, IsMakefile
=False):
638 for EfiFile
in EfiInput
:
640 InputList
.append (EfiFile
)
644 for BinFile
in BinaryInput
:
646 InputList
.append (BinFile
)
649 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, InputList
) and not IsMakefile
:
651 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, InputList
))
654 Cmd
+= ("-l", ClassCode
)
656 Cmd
+= ("-r", Revision
)
658 Cmd
+= ("-i", DeviceId
)
660 Cmd
+= ("-f", VendorId
)
662 Cmd
+= ("-o", Output
)
664 if " ".join(Cmd
).strip() not in GenFdsGlobalVariable
.SecCmdList
:
665 GenFdsGlobalVariable
.SecCmdList
.append(" ".join(Cmd
).strip())
667 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate option rom")
670 def GuidTool(Output
, Input
, ToolPath
, Options
='', returnValue
=[], IsMakefile
=False):
671 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
) and not IsMakefile
:
673 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
676 Cmd
+= Options
.split(' ')
677 Cmd
+= ("-o", Output
)
680 if " ".join(Cmd
).strip() not in GenFdsGlobalVariable
.SecCmdList
:
681 GenFdsGlobalVariable
.SecCmdList
.append(" ".join(Cmd
).strip())
683 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to call " + ToolPath
, returnValue
)
686 def CallExternalTool (cmd
, errorMess
, returnValue
=[]):
688 if type(cmd
) not in (tuple, list):
689 GenFdsGlobalVariable
.ErrorLogger("ToolError! Invalid parameter type in call to CallExternalTool")
691 if GenFdsGlobalVariable
.DebugLevel
!= -1:
692 cmd
+= ('--debug', str(GenFdsGlobalVariable
.DebugLevel
))
693 GenFdsGlobalVariable
.InfLogger (cmd
)
695 if GenFdsGlobalVariable
.VerboseMode
:
697 GenFdsGlobalVariable
.InfLogger (cmd
)
701 GenFdsGlobalVariable
.SharpCounter
= GenFdsGlobalVariable
.SharpCounter
+ 1
702 if GenFdsGlobalVariable
.SharpCounter
% GenFdsGlobalVariable
.SharpNumberPerLine
== 0:
706 PopenObject
= Popen(' '.join(cmd
), stdout
=PIPE
, stderr
=PIPE
, shell
=True)
707 except Exception as X
:
708 EdkLogger
.error("GenFds", COMMAND_FAILURE
, ExtraData
="%s: %s" % (str(X
), cmd
[0]))
709 (out
, error
) = PopenObject
.communicate()
711 while PopenObject
.returncode
is None:
713 if returnValue
!= [] and returnValue
[0] != 0:
714 #get command return value
715 returnValue
[0] = PopenObject
.returncode
717 if PopenObject
.returncode
!= 0 or GenFdsGlobalVariable
.VerboseMode
or GenFdsGlobalVariable
.DebugLevel
!= -1:
718 GenFdsGlobalVariable
.InfLogger ("Return Value = %d" % PopenObject
.returncode
)
719 GenFdsGlobalVariable
.InfLogger(out
.decode(encoding
='utf-8', errors
='ignore'))
720 GenFdsGlobalVariable
.InfLogger(error
.decode(encoding
='utf-8', errors
='ignore'))
721 if PopenObject
.returncode
!= 0:
723 EdkLogger
.error("GenFds", COMMAND_FAILURE
, errorMess
)
726 def VerboseLogger (msg
):
727 EdkLogger
.verbose(msg
)
734 def ErrorLogger (msg
, File
=None, Line
=None, ExtraData
=None):
735 EdkLogger
.error('GenFds', GENFDS_ERROR
, msg
, File
, Line
, ExtraData
)
738 def DebugLogger (Level
, msg
):
739 EdkLogger
.debug(Level
, msg
)
743 # @param Str String that may contain macro
744 # @param MacroDict Dictionary that contains macro value pair
747 def MacroExtend (Str
, MacroDict
={}, Arch
=DataType
.TAB_COMMON
):
751 Dict
= {'$(WORKSPACE)': GenFdsGlobalVariable
.WorkSpaceDir
,
752 # '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc,
753 '$(TARGET)': GenFdsGlobalVariable
.TargetName
,
754 '$(TOOL_CHAIN_TAG)': GenFdsGlobalVariable
.ToolChainTag
,
758 if Arch
!= DataType
.TAB_COMMON
and Arch
in GenFdsGlobalVariable
.ArchList
:
759 OutputDir
= GenFdsGlobalVariable
.OutputDirFromDscDict
[Arch
]
761 OutputDir
= GenFdsGlobalVariable
.OutputDirFromDscDict
[GenFdsGlobalVariable
.ArchList
[0]]
763 Dict
['$(OUTPUT_DIRECTORY)'] = OutputDir
766 Dict
.update(MacroDict
)
769 if Str
.find(key
) >= 0:
770 Str
= Str
.replace (key
, Dict
[key
])
772 if Str
.find('$(ARCH)') >= 0:
773 if len(GenFdsGlobalVariable
.ArchList
) == 1:
774 Str
= Str
.replace('$(ARCH)', GenFdsGlobalVariable
.ArchList
[0])
776 EdkLogger
.error("GenFds", GENFDS_ERROR
, "No way to determine $(ARCH) for %s" % Str
)
782 # @param PcdPattern pattern that labels a PCD.
785 def GetPcdValue (PcdPattern
):
786 if PcdPattern
is None:
788 PcdPair
= PcdPattern
.lstrip('PCD(').rstrip(')').strip().split('.')
789 TokenSpace
= PcdPair
[0]
790 TokenCName
= PcdPair
[1]
792 for Arch
in GenFdsGlobalVariable
.ArchList
:
793 Platform
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
794 PcdDict
= Platform
.Pcds
796 PcdObj
= PcdDict
[Key
]
797 if (PcdObj
.TokenCName
== TokenCName
) and (PcdObj
.TokenSpaceGuidCName
== TokenSpace
):
798 if PcdObj
.Type
!= DataType
.TAB_PCDS_FIXED_AT_BUILD
:
799 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not FixedAtBuild type." % PcdPattern
)
800 if PcdObj
.DatumType
!= DataType
.TAB_VOID
:
801 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not VOID* datum type." % PcdPattern
)
803 return PcdObj
.DefaultValue
805 for Package
in GenFdsGlobalVariable
.WorkSpace
.GetPackageList(GenFdsGlobalVariable
.ActivePlatform
,
807 GenFdsGlobalVariable
.TargetName
,
808 GenFdsGlobalVariable
.ToolChainTag
):
809 PcdDict
= Package
.Pcds
811 PcdObj
= PcdDict
[Key
]
812 if (PcdObj
.TokenCName
== TokenCName
) and (PcdObj
.TokenSpaceGuidCName
== TokenSpace
):
813 if PcdObj
.Type
!= DataType
.TAB_PCDS_FIXED_AT_BUILD
:
814 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not FixedAtBuild type." % PcdPattern
)
815 if PcdObj
.DatumType
!= DataType
.TAB_VOID
:
816 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not VOID* datum type." % PcdPattern
)
818 return PcdObj
.DefaultValue
824 # Find location of tools to process data
826 # @param KeyStringList Filter for inputs of section generation
827 # @param CurrentArchList Arch list
828 # @param NameGuid The Guid name
830 def FindExtendTool(KeyStringList
, CurrentArchList
, NameGuid
):
831 ToolDb
= ToolDefDict(GenFdsGlobalVariable
.ConfDir
).ToolsDefTxtDatabase
832 # if user not specify filter, try to deduce it from global data.
833 if KeyStringList
is None or KeyStringList
== []:
834 Target
= GenFdsGlobalVariable
.TargetName
835 ToolChain
= GenFdsGlobalVariable
.ToolChainTag
836 if ToolChain
not in ToolDb
['TOOL_CHAIN_TAG']:
837 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Can not find external tool because tool tag %s is not defined in tools_def.txt!" % ToolChain
)
838 KeyStringList
= [Target
+ '_' + ToolChain
+ '_' + CurrentArchList
[0]]
839 for Arch
in CurrentArchList
:
840 if Target
+ '_' + ToolChain
+ '_' + Arch
not in KeyStringList
:
841 KeyStringList
.append(Target
+ '_' + ToolChain
+ '_' + Arch
)
843 if GenFdsGlobalVariable
.GuidToolDefinition
:
844 if NameGuid
in GenFdsGlobalVariable
.GuidToolDefinition
:
845 return GenFdsGlobalVariable
.GuidToolDefinition
[NameGuid
]
847 ToolDefinition
= ToolDefDict(GenFdsGlobalVariable
.ConfDir
).ToolsDefTxtDictionary
853 for ToolDef
in ToolDefinition
.items():
854 if NameGuid
.lower() == ToolDef
[1].lower():
855 KeyList
= ToolDef
[0].split('_')
861 if Key
in KeyStringList
and KeyList
[4] == DataType
.TAB_GUID
:
862 ToolPathKey
= Key
+ '_' + KeyList
[3] + '_PATH'
863 ToolOptionKey
= Key
+ '_' + KeyList
[3] + '_FLAGS'
864 ToolPath
= ToolDefinition
.get(ToolPathKey
)
865 ToolOption
= ToolDefinition
.get(ToolOptionKey
)
866 if ToolPathTmp
is None:
867 ToolPathTmp
= ToolPath
869 if ToolPathTmp
!= ToolPath
:
870 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Don't know which tool to use, %s or %s ?" % (ToolPathTmp
, ToolPath
))
873 for Arch
in CurrentArchList
:
874 Platform
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
875 # key is (ToolChainFamily, ToolChain, CodeBase)
876 for item
in Platform
.BuildOptions
:
877 if '_PATH' in item
[1] or '_FLAGS' in item
[1] or '_GUID' in item
[1]:
878 if not item
[0] or (item
[0] and GenFdsGlobalVariable
.ToolChainFamily
== item
[0]):
879 if item
[1] not in BuildOption
:
880 BuildOption
[item
[1]] = Platform
.BuildOptions
[item
]
882 ToolList
= [DataType
.TAB_TOD_DEFINES_TARGET
, DataType
.TAB_TOD_DEFINES_TOOL_CHAIN_TAG
, DataType
.TAB_TOD_DEFINES_TARGET_ARCH
]
883 for Index
in range(2, -1, -1):
884 for Key
in list(BuildOption
.keys()):
885 List
= Key
.split('_')
886 if List
[Index
] == DataType
.TAB_STAR
:
887 for String
in ToolDb
[ToolList
[Index
]]:
888 if String
in [Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]:
890 NewKey
= '%s_%s_%s_%s_%s' % tuple(List
)
891 if NewKey
not in BuildOption
:
892 BuildOption
[NewKey
] = BuildOption
[Key
]
895 elif List
[Index
] not in ToolDb
[ToolList
[Index
]]:
899 for Op
in BuildOption
:
900 if NameGuid
== BuildOption
[Op
]:
901 KeyList
= Op
.split('_')
902 Key
= KeyList
[0] + '_' + KeyList
[1] +'_' + KeyList
[2]
903 if Key
in KeyStringList
and KeyList
[4] == DataType
.TAB_GUID
:
904 ToolPathKey
= Key
+ '_' + KeyList
[3] + '_PATH'
905 ToolOptionKey
= Key
+ '_' + KeyList
[3] + '_FLAGS'
906 if ToolPathKey
in BuildOption
:
907 ToolPathTmp
= BuildOption
[ToolPathKey
]
908 if ToolOptionKey
in BuildOption
:
909 ToolOption
= BuildOption
[ToolOptionKey
]
911 GenFdsGlobalVariable
.GuidToolDefinition
[NameGuid
] = (ToolPathTmp
, ToolOption
)
912 return ToolPathTmp
, ToolOption