]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/GenFds/GenFds.py
BaseTools: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / GenFds.py
CommitLineData
f51461c8
LG
1## @file\r
2# generate flash image\r
3#\r
938cf4c3 4# Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>\r
f51461c8 5#\r
2e351cbe 6# SPDX-License-Identifier: BSD-2-Clause-Patent\r
f51461c8
LG
7#\r
8\r
9##\r
10# Import Modules\r
11#\r
1ccc4d89
LG
12from __future__ import print_function\r
13from __future__ import absolute_import\r
9e47e6f9 14from re import compile\r
f51461c8 15from optparse import OptionParser\r
9e47e6f9
CJ
16from sys import exit\r
17from glob import glob\r
18from struct import unpack\r
19from linecache import getlines\r
86379ac4 20from io import BytesIO\r
9e47e6f9
CJ
21\r
22import Common.LongFilePathOs as os\r
23from Common.TargetTxtClassObject import TargetTxtClassObject\r
95816356 24from Common.DataType import *\r
f51461c8
LG
25import Common.GlobalData as GlobalData\r
26from Common import EdkLogger\r
9e47e6f9
CJ
27from Common.StringUtils import NormPath\r
28from Common.Misc import DirCache, PathClass, GuidStructureStringToGuidString\r
29from Common.Misc import SaveFileOnChange, ClearDuplicatedInf\r
f51461c8 30from Common.BuildVersion import gBUILD_VERSION\r
05cc51ad 31from Common.MultipleWorkspace import MultipleWorkspace as mws\r
b3497bad 32from Common.BuildToolError import FatalError, GENFDS_ERROR, CODE_ERROR, FORMAT_INVALID, RESOURCE_NOT_AVAILABLE, FILE_NOT_FOUND, OPTION_MISSING, FORMAT_NOT_SUPPORTED, OPTION_VALUE_INVALID, PARAMETER_INVALID\r
9e47e6f9
CJ
33from Workspace.WorkspaceDatabase import WorkspaceDatabase\r
34\r
35from .FdfParser import FdfParser, Warning\r
36from .GenFdsGlobalVariable import GenFdsGlobalVariable\r
37from .FfsFileStatement import FileStatement\r
abc4c338
FB
38import Common.DataType as DataType\r
39from struct import Struct\r
f51461c8
LG
40\r
41## Version and Copyright\r
42versionNumber = "1.0" + ' ' + gBUILD_VERSION\r
43__version__ = "%prog Version " + versionNumber\r
f7496d71 44__copyright__ = "Copyright (c) 2007 - 2018, Intel Corporation All rights reserved."\r
f51461c8
LG
45\r
46## Tool entrance method\r
47#\r
48# This method mainly dispatch specific methods per the command line options.\r
49# If no error found, return zero value so the caller of this tool can know\r
50# if it's executed successfully or not.\r
51#\r
52# @retval 0 Tool was successful\r
53# @retval 1 Tool failed\r
54#\r
55def main():\r
56 global Options\r
57 Options = myOptionParser()\r
b3497bad
ZZ
58 EdkLogger.Initialize()\r
59 return GenFdsApi(OptionsToCommandDict(Options))\r
f51461c8 60\r
abc4c338
FB
61def resetFdsGlobalVariable():\r
62 GenFdsGlobalVariable.FvDir = ''\r
63 GenFdsGlobalVariable.OutputDirDict = {}\r
64 GenFdsGlobalVariable.BinDir = ''\r
65 # will be FvDir + os.sep + 'Ffs'\r
66 GenFdsGlobalVariable.FfsDir = ''\r
67 GenFdsGlobalVariable.FdfParser = None\r
68 GenFdsGlobalVariable.LibDir = ''\r
69 GenFdsGlobalVariable.WorkSpace = None\r
70 GenFdsGlobalVariable.WorkSpaceDir = ''\r
71 GenFdsGlobalVariable.ConfDir = ''\r
abc4c338
FB
72 GenFdsGlobalVariable.OutputDirFromDscDict = {}\r
73 GenFdsGlobalVariable.TargetName = ''\r
74 GenFdsGlobalVariable.ToolChainTag = ''\r
75 GenFdsGlobalVariable.RuleDict = {}\r
76 GenFdsGlobalVariable.ArchList = None\r
abc4c338
FB
77 GenFdsGlobalVariable.ActivePlatform = None\r
78 GenFdsGlobalVariable.FvAddressFileName = ''\r
79 GenFdsGlobalVariable.VerboseMode = False\r
80 GenFdsGlobalVariable.DebugLevel = -1\r
81 GenFdsGlobalVariable.SharpCounter = 0\r
82 GenFdsGlobalVariable.SharpNumberPerLine = 40\r
83 GenFdsGlobalVariable.FdfFile = ''\r
84 GenFdsGlobalVariable.FdfFileTimeStamp = 0\r
85 GenFdsGlobalVariable.FixedLoadAddress = False\r
86 GenFdsGlobalVariable.PlatformName = ''\r
87\r
88 GenFdsGlobalVariable.BuildRuleFamily = DataType.TAB_COMPILER_MSFT\r
89 GenFdsGlobalVariable.ToolChainFamily = DataType.TAB_COMPILER_MSFT\r
90 GenFdsGlobalVariable.__BuildRuleDatabase = None\r
91 GenFdsGlobalVariable.GuidToolDefinition = {}\r
92 GenFdsGlobalVariable.FfsCmdDict = {}\r
93 GenFdsGlobalVariable.SecCmdList = []\r
94 GenFdsGlobalVariable.CopyList = []\r
95 GenFdsGlobalVariable.ModuleFile = ''\r
96 GenFdsGlobalVariable.EnableGenfdsMultiThread = False\r
97\r
98 GenFdsGlobalVariable.LargeFileInFvFlags = []\r
99 GenFdsGlobalVariable.EFI_FIRMWARE_FILE_SYSTEM3_GUID = '5473C07A-3DCB-4dca-BD6F-1E9689E7349A'\r
100 GenFdsGlobalVariable.LARGE_FILE_SIZE = 0x1000000\r
101\r
102 GenFdsGlobalVariable.SectionHeader = Struct("3B 1B")\r
103\r
104 # FvName, FdName, CapName in FDF, Image file name\r
105 GenFdsGlobalVariable.ImageBinDict = {}\r
106\r
b3497bad 107def GenFdsApi(FdsCommandDict, WorkSpaceDataBase=None):\r
f51461c8
LG
108 global Workspace\r
109 Workspace = ""\r
110 ArchList = None\r
111 ReturnCode = 0\r
abc4c338 112 resetFdsGlobalVariable()\r
f51461c8 113\r
f51461c8 114 try:\r
b3497bad 115 if FdsCommandDict.get("verbose"):\r
f51461c8
LG
116 EdkLogger.SetLevel(EdkLogger.VERBOSE)\r
117 GenFdsGlobalVariable.VerboseMode = True\r
f7496d71 118\r
b3497bad 119 if FdsCommandDict.get("FixedAddress"):\r
f51461c8 120 GenFdsGlobalVariable.FixedLoadAddress = True\r
f7496d71 121\r
b3497bad 122 if FdsCommandDict.get("quiet"):\r
f51461c8 123 EdkLogger.SetLevel(EdkLogger.QUIET)\r
b3497bad
ZZ
124 if FdsCommandDict.get("debug"):\r
125 EdkLogger.SetLevel(FdsCommandDict.get("debug") + 1)\r
126 GenFdsGlobalVariable.DebugLevel = FdsCommandDict.get("debug")\r
f51461c8
LG
127 else:\r
128 EdkLogger.SetLevel(EdkLogger.INFO)\r
129\r
b3497bad 130 if not FdsCommandDict.get("Workspace",os.environ.get('WORKSPACE')):\r
f51461c8
LG
131 EdkLogger.error("GenFds", OPTION_MISSING, "WORKSPACE not defined",\r
132 ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")\r
b3497bad 133 elif not os.path.exists(FdsCommandDict.get("Workspace",os.environ.get('WORKSPACE'))):\r
f51461c8
LG
134 EdkLogger.error("GenFds", PARAMETER_INVALID, "WORKSPACE is invalid",\r
135 ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")\r
136 else:\r
b3497bad 137 Workspace = os.path.normcase(FdsCommandDict.get("Workspace",os.environ.get('WORKSPACE')))\r
f51461c8 138 GenFdsGlobalVariable.WorkSpaceDir = Workspace\r
b3497bad 139 if FdsCommandDict.get("debug"):\r
47fea6af 140 GenFdsGlobalVariable.VerboseLogger("Using Workspace:" + Workspace)\r
b3497bad 141 if FdsCommandDict.get("GenfdsMultiThread"):\r
37de70b7 142 GenFdsGlobalVariable.EnableGenfdsMultiThread = True\r
f51461c8 143 os.chdir(GenFdsGlobalVariable.WorkSpaceDir)\r
f7496d71 144\r
05cc51ad
LY
145 # set multiple workspace\r
146 PackagesPath = os.getenv("PACKAGES_PATH")\r
147 mws.setWs(GenFdsGlobalVariable.WorkSpaceDir, PackagesPath)\r
f51461c8 148\r
b3497bad
ZZ
149 if FdsCommandDict.get("fdf_file"):\r
150 FdfFilename = FdsCommandDict.get("fdf_file")[0].Path\r
f51461c8
LG
151 FdfFilename = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdfFilename)\r
152\r
153 if FdfFilename[0:2] == '..':\r
154 FdfFilename = os.path.realpath(FdfFilename)\r
47fea6af 155 if not os.path.isabs(FdfFilename):\r
05cc51ad 156 FdfFilename = mws.join(GenFdsGlobalVariable.WorkSpaceDir, FdfFilename)\r
f51461c8
LG
157 if not os.path.exists(FdfFilename):\r
158 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=FdfFilename)\r
f51461c8
LG
159\r
160 GenFdsGlobalVariable.FdfFile = FdfFilename\r
161 GenFdsGlobalVariable.FdfFileTimeStamp = os.path.getmtime(FdfFilename)\r
162 else:\r
163 EdkLogger.error("GenFds", OPTION_MISSING, "Missing FDF filename")\r
164\r
b3497bad
ZZ
165 if FdsCommandDict.get("build_target"):\r
166 GenFdsGlobalVariable.TargetName = FdsCommandDict.get("build_target")\r
f51461c8 167\r
b3497bad
ZZ
168 if FdsCommandDict.get("toolchain_tag"):\r
169 GenFdsGlobalVariable.ToolChainTag = FdsCommandDict.get("toolchain_tag")\r
f51461c8 170\r
b3497bad
ZZ
171 if FdsCommandDict.get("active_platform"):\r
172 ActivePlatform = FdsCommandDict.get("active_platform")\r
f51461c8
LG
173 ActivePlatform = GenFdsGlobalVariable.ReplaceWorkspaceMacro(ActivePlatform)\r
174\r
175 if ActivePlatform[0:2] == '..':\r
176 ActivePlatform = os.path.realpath(ActivePlatform)\r
177\r
178 if not os.path.isabs (ActivePlatform):\r
05cc51ad 179 ActivePlatform = mws.join(GenFdsGlobalVariable.WorkSpaceDir, ActivePlatform)\r
f51461c8 180\r
9e47e6f9 181 if not os.path.exists(ActivePlatform):\r
f51461c8 182 EdkLogger.error("GenFds", FILE_NOT_FOUND, "ActivePlatform doesn't exist!")\r
f51461c8
LG
183 else:\r
184 EdkLogger.error("GenFds", OPTION_MISSING, "Missing active platform")\r
185\r
e642ceb8 186 GenFdsGlobalVariable.ActivePlatform = PathClass(NormPath(ActivePlatform))\r
f51461c8 187\r
b3497bad 188 if FdsCommandDict.get("conf_directory"):\r
97fa0ee9 189 # Get alternate Conf location, if it is absolute, then just use the absolute directory name\r
b3497bad 190 ConfDirectoryPath = os.path.normpath(FdsCommandDict.get("conf_directory"))\r
97fa0ee9
YL
191 if ConfDirectoryPath.startswith('"'):\r
192 ConfDirectoryPath = ConfDirectoryPath[1:]\r
193 if ConfDirectoryPath.endswith('"'):\r
194 ConfDirectoryPath = ConfDirectoryPath[:-1]\r
195 if not os.path.isabs(ConfDirectoryPath):\r
196 # Since alternate directory name is not absolute, the alternate directory is located within the WORKSPACE\r
197 # This also handles someone specifying the Conf directory in the workspace. Using --conf=Conf\r
198 ConfDirectoryPath = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, ConfDirectoryPath)\r
199 else:\r
9eb87141 200 if "CONF_PATH" in os.environ:\r
00bcb5c2
YZ
201 ConfDirectoryPath = os.path.normcase(os.environ["CONF_PATH"])\r
202 else:\r
203 # Get standard WORKSPACE/Conf, use the absolute path to the WORKSPACE/Conf\r
204 ConfDirectoryPath = mws.join(GenFdsGlobalVariable.WorkSpaceDir, 'Conf')\r
97fa0ee9 205 GenFdsGlobalVariable.ConfDir = ConfDirectoryPath\r
541a3f58
FY
206 if not GlobalData.gConfDirectory:\r
207 GlobalData.gConfDirectory = GenFdsGlobalVariable.ConfDir\r
97fa0ee9 208 BuildConfigurationFile = os.path.normpath(os.path.join(ConfDirectoryPath, "target.txt"))\r
f51461c8 209 if os.path.isfile(BuildConfigurationFile) == True:\r
9e47e6f9 210 TargetTxt = TargetTxtClassObject()\r
e4979bee
YZ
211 TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)\r
212 # if no build target given in command line, get it from target.txt\r
213 if not GenFdsGlobalVariable.TargetName:\r
b3497bad 214 BuildTargetList = TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_TARGET]\r
e4979bee
YZ
215 if len(BuildTargetList) != 1:\r
216 EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="Only allows one instance for Target.")\r
217 GenFdsGlobalVariable.TargetName = BuildTargetList[0]\r
218\r
219 # if no tool chain given in command line, get it from target.txt\r
220 if not GenFdsGlobalVariable.ToolChainTag:\r
b3497bad 221 ToolChainList = TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_TOOL_CHAIN_TAG]\r
4231a819 222 if ToolChainList is None or len(ToolChainList) == 0:\r
e4979bee
YZ
223 EdkLogger.error("GenFds", RESOURCE_NOT_AVAILABLE, ExtraData="No toolchain given. Don't know how to build.")\r
224 if len(ToolChainList) != 1:\r
225 EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="Only allows one instance for ToolChain.")\r
226 GenFdsGlobalVariable.ToolChainTag = ToolChainList[0]\r
f51461c8
LG
227 else:\r
228 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=BuildConfigurationFile)\r
229\r
97fa0ee9 230 #Set global flag for build mode\r
b3497bad 231 GlobalData.gIgnoreSource = FdsCommandDict.get("IgnoreSources")\r
97fa0ee9 232\r
b3497bad
ZZ
233 if FdsCommandDict.get("macro"):\r
234 for Pair in FdsCommandDict.get("macro"):\r
97fa0ee9
YL
235 if Pair.startswith('"'):\r
236 Pair = Pair[1:]\r
237 if Pair.endswith('"'):\r
238 Pair = Pair[:-1]\r
f51461c8
LG
239 List = Pair.split('=')\r
240 if len(List) == 2:\r
e4979bee
YZ
241 if not List[1].strip():\r
242 EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="No Value given for Macro %s" %List[0])\r
39879ef2 243 if List[0].strip() in ["WORKSPACE", "TARGET", "TOOLCHAIN"]:\r
f51461c8
LG
244 GlobalData.gGlobalDefines[List[0].strip()] = List[1].strip()\r
245 else:\r
246 GlobalData.gCommandLineDefines[List[0].strip()] = List[1].strip()\r
247 else:\r
248 GlobalData.gCommandLineDefines[List[0].strip()] = "TRUE"\r
249 os.environ["WORKSPACE"] = Workspace\r
250\r
e4979bee 251 # Use the -t and -b option as gGlobalDefines's TOOLCHAIN and TARGET if they are not defined\r
9eb87141 252 if "TARGET" not in GlobalData.gGlobalDefines:\r
e4979bee 253 GlobalData.gGlobalDefines["TARGET"] = GenFdsGlobalVariable.TargetName\r
9eb87141 254 if "TOOLCHAIN" not in GlobalData.gGlobalDefines:\r
e4979bee 255 GlobalData.gGlobalDefines["TOOLCHAIN"] = GenFdsGlobalVariable.ToolChainTag\r
9eb87141 256 if "TOOL_CHAIN_TAG" not in GlobalData.gGlobalDefines:\r
e4979bee
YZ
257 GlobalData.gGlobalDefines['TOOL_CHAIN_TAG'] = GenFdsGlobalVariable.ToolChainTag\r
258\r
f51461c8 259 """call Workspace build create database"""\r
97fa0ee9 260 GlobalData.gDatabasePath = os.path.normpath(os.path.join(ConfDirectoryPath, GlobalData.gDatabasePath))\r
2f818ed0 261\r
b3497bad
ZZ
262 if WorkSpaceDataBase:\r
263 BuildWorkSpace = WorkSpaceDataBase\r
264 else:\r
2f818ed0 265 BuildWorkSpace = WorkspaceDatabase()\r
f51461c8
LG
266 #\r
267 # Get files real name in workspace dir\r
268 #\r
269 GlobalData.gAllFiles = DirCache(Workspace)\r
270 GlobalData.gWorkspace = Workspace\r
271\r
b3497bad
ZZ
272 if FdsCommandDict.get("build_architecture_list"):\r
273 ArchList = FdsCommandDict.get("build_architecture_list").split(',')\r
f51461c8 274 else:\r
b3497bad 275 ArchList = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, TAB_COMMON, FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].SupArchList\r
f51461c8 276\r
b3497bad 277 TargetArchList = set(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, TAB_COMMON, FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].SupArchList) & set(ArchList)\r
f51461c8 278 if len(TargetArchList) == 0:\r
55c84777 279 EdkLogger.error("GenFds", GENFDS_ERROR, "Target ARCH %s not in platform supported ARCH %s" % (str(ArchList), str(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, TAB_COMMON].SupArchList)))\r
f7496d71 280\r
f51461c8 281 for Arch in ArchList:\r
b3497bad 282 GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = NormPath(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].OutputDirectory)\r
f51461c8 283\r
9e47e6f9 284 # assign platform name based on last entry in ArchList\r
b3497bad 285 GenFdsGlobalVariable.PlatformName = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, ArchList[-1], FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].PlatformName\r
9e47e6f9 286\r
b3497bad
ZZ
287 if FdsCommandDict.get("platform_build_directory"):\r
288 OutputDirFromCommandLine = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdsCommandDict.get("platform_build_directory"))\r
f51461c8
LG
289 if not os.path.isabs (OutputDirFromCommandLine):\r
290 OutputDirFromCommandLine = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, OutputDirFromCommandLine)\r
291 for Arch in ArchList:\r
292 GenFdsGlobalVariable.OutputDirDict[Arch] = OutputDirFromCommandLine\r
293 else:\r
294 for Arch in ArchList:\r
295 GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.join(GenFdsGlobalVariable.OutputDirFromDscDict[Arch], GenFdsGlobalVariable.TargetName + '_' + GenFdsGlobalVariable.ToolChainTag)\r
296\r
297 for Key in GenFdsGlobalVariable.OutputDirDict:\r
298 OutputDir = GenFdsGlobalVariable.OutputDirDict[Key]\r
299 if OutputDir[0:2] == '..':\r
300 OutputDir = os.path.realpath(OutputDir)\r
301\r
302 if OutputDir[1] != ':':\r
303 OutputDir = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, OutputDir)\r
304\r
305 if not os.path.exists(OutputDir):\r
306 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=OutputDir)\r
307 GenFdsGlobalVariable.OutputDirDict[Key] = OutputDir\r
308\r
309 """ Parse Fdf file, has to place after build Workspace as FDF may contain macros from DSC file """\r
b3497bad
ZZ
310 if WorkSpaceDataBase:\r
311 FdfParserObj = GlobalData.gFdfParser\r
312 else:\r
313 FdfParserObj = FdfParser(FdfFilename)\r
314 FdfParserObj.ParseFile()\r
f51461c8
LG
315\r
316 if FdfParserObj.CycleReferenceCheck():\r
317 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Cycle Reference Detected in FDF file")\r
318\r
b3497bad
ZZ
319 if FdsCommandDict.get("fd"):\r
320 if FdsCommandDict.get("fd")[0].upper() in FdfParserObj.Profile.FdDict:\r
321 GenFds.OnlyGenerateThisFd = FdsCommandDict.get("fd")[0]\r
f51461c8
LG
322 else:\r
323 EdkLogger.error("GenFds", OPTION_VALUE_INVALID,\r
b3497bad 324 "No such an FD in FDF file: %s" % FdsCommandDict.get("fd")[0])\r
f51461c8 325\r
b3497bad
ZZ
326 if FdsCommandDict.get("fv"):\r
327 if FdsCommandDict.get("fv")[0].upper() in FdfParserObj.Profile.FvDict:\r
328 GenFds.OnlyGenerateThisFv = FdsCommandDict.get("fv")[0]\r
f51461c8
LG
329 else:\r
330 EdkLogger.error("GenFds", OPTION_VALUE_INVALID,\r
b3497bad 331 "No such an FV in FDF file: %s" % FdsCommandDict.get("fv")[0])\r
f51461c8 332\r
b3497bad
ZZ
333 if FdsCommandDict.get("cap"):\r
334 if FdsCommandDict.get("cap")[0].upper() in FdfParserObj.Profile.CapsuleDict:\r
335 GenFds.OnlyGenerateThisCap = FdsCommandDict.get("cap")[0]\r
f51461c8
LG
336 else:\r
337 EdkLogger.error("GenFds", OPTION_VALUE_INVALID,\r
b3497bad 338 "No such a Capsule in FDF file: %s" % FdsCommandDict.get("cap")[0])\r
f51461c8 339\r
6b17c11b 340 GenFdsGlobalVariable.WorkSpace = BuildWorkSpace\r
9e47e6f9 341 if ArchList:\r
6b17c11b
YZ
342 GenFdsGlobalVariable.ArchList = ArchList\r
343\r
6f49996c 344 # Dsc Build Data will handle Pcd Settings from CommandLine.\r
6b17c11b 345\r
f51461c8
LG
346 """Modify images from build output if the feature of loading driver at fixed address is on."""\r
347 if GenFdsGlobalVariable.FixedLoadAddress:\r
348 GenFds.PreprocessImage(BuildWorkSpace, GenFdsGlobalVariable.ActivePlatform)\r
135ae8c8
YZ
349\r
350 # Record the FV Region info that may specific in the FD\r
351 if FdfParserObj.Profile.FvDict and FdfParserObj.Profile.FdDict:\r
9e47e6f9
CJ
352 for FvObj in FdfParserObj.Profile.FvDict.values():\r
353 for FdObj in FdfParserObj.Profile.FdDict.values():\r
135ae8c8 354 for RegionObj in FdObj.RegionList:\r
91fa33ee 355 if RegionObj.RegionType != BINARY_FILE_TYPE_FV:\r
135ae8c8
YZ
356 continue\r
357 for RegionData in RegionObj.RegionDataList:\r
358 if FvObj.UiFvName.upper() == RegionData.upper():\r
d7f40203
ZF
359 if not FvObj.BaseAddress:\r
360 FvObj.BaseAddress = '0x%x' % (int(FdObj.BaseAddress, 0) + RegionObj.Offset)\r
135ae8c8
YZ
361 if FvObj.FvRegionInFD:\r
362 if FvObj.FvRegionInFD != RegionObj.Size:\r
363 EdkLogger.error("GenFds", FORMAT_INVALID, "The FV %s's region is specified in multiple FD with different value." %FvObj.UiFvName)\r
364 else:\r
365 FvObj.FvRegionInFD = RegionObj.Size\r
366 RegionObj.BlockInfoOfRegion(FdObj.BlockSizeList, FvObj)\r
367\r
f51461c8
LG
368 """Call GenFds"""\r
369 GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList)\r
370\r
371 """Generate GUID cross reference file"""\r
5e9256cd 372 GenFds.GenerateGuidXRefFile(BuildWorkSpace, ArchList, FdfParserObj)\r
f51461c8
LG
373\r
374 """Display FV space info."""\r
375 GenFds.DisplayFvSpaceInfo(FdfParserObj)\r
376\r
9e47e6f9 377 except Warning as X:\r
47fea6af 378 EdkLogger.error(X.ToolName, FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError=False)\r
f51461c8 379 ReturnCode = FORMAT_INVALID\r
5b0671c1 380 except FatalError as X:\r
b3497bad 381 if FdsCommandDict.get("debug") is not None:\r
f51461c8
LG
382 import traceback\r
383 EdkLogger.quiet(traceback.format_exc())\r
384 ReturnCode = X.args[0]\r
385 except:\r
386 import traceback\r
387 EdkLogger.error(\r
388 "\nPython",\r
389 CODE_ERROR,\r
390 "Tools code failure",\r
3a0f8bde 391 ExtraData="Please send email to edk2-devel@lists.01.org for help, attaching following call stack trace!\n",\r
f51461c8
LG
392 RaiseError=False\r
393 )\r
394 EdkLogger.quiet(traceback.format_exc())\r
395 ReturnCode = CODE_ERROR\r
97fa0ee9
YL
396 finally:\r
397 ClearDuplicatedInf()\r
f51461c8
LG
398 return ReturnCode\r
399\r
b3497bad
ZZ
400def OptionsToCommandDict(Options):\r
401 FdsCommandDict = {}\r
402 FdsCommandDict["verbose"] = Options.verbose\r
403 FdsCommandDict["FixedAddress"] = Options.FixedAddress\r
404 FdsCommandDict["quiet"] = Options.quiet\r
405 FdsCommandDict["debug"] = Options.debug\r
406 FdsCommandDict["Workspace"] = Options.Workspace\r
407 FdsCommandDict["GenfdsMultiThread"] = Options.GenfdsMultiThread\r
408 FdsCommandDict["fdf_file"] = [PathClass(Options.filename)] if Options.filename else []\r
409 FdsCommandDict["build_target"] = Options.BuildTarget\r
410 FdsCommandDict["toolchain_tag"] = Options.ToolChain\r
411 FdsCommandDict["active_platform"] = Options.activePlatform\r
412 FdsCommandDict["OptionPcd"] = Options.OptionPcd\r
413 FdsCommandDict["conf_directory"] = Options.ConfDirectory\r
414 FdsCommandDict["IgnoreSources"] = Options.IgnoreSources\r
415 FdsCommandDict["macro"] = Options.Macros\r
416 FdsCommandDict["build_architecture_list"] = Options.archList\r
417 FdsCommandDict["platform_build_directory"] = Options.outputDir\r
418 FdsCommandDict["fd"] = [Options.uiFdName] if Options.uiFdName else []\r
419 FdsCommandDict["fv"] = [Options.uiFvName] if Options.uiFvName else []\r
420 FdsCommandDict["cap"] = [Options.uiCapName] if Options.uiCapName else []\r
421 return FdsCommandDict\r
422\r
423\r
f51461c8
LG
424gParamCheck = []\r
425def SingleCheckCallback(option, opt_str, value, parser):\r
426 if option not in gParamCheck:\r
427 setattr(parser.values, option.dest, value)\r
428 gParamCheck.append(option)\r
429 else:\r
430 parser.error("Option %s only allows one instance in command line!" % option)\r
6b17c11b 431\r
f51461c8
LG
432## Parse command line options\r
433#\r
434# Using standard Python module optparse to parse command line option of this tool.\r
435#\r
436# @retval Opt A optparse.Values object containing the parsed options\r
f51461c8
LG
437#\r
438def myOptionParser():\r
439 usage = "%prog [options] -f input_file -a arch_list -b build_target -p active_platform -t tool_chain_tag -D \"MacroName [= MacroValue]\""\r
47fea6af 440 Parser = OptionParser(usage=usage, description=__copyright__, version="%prog " + str(versionNumber))\r
f51461c8
LG
441 Parser.add_option("-f", "--file", dest="filename", type="string", help="Name of FDF file to convert", action="callback", callback=SingleCheckCallback)\r
442 Parser.add_option("-a", "--arch", dest="archList", help="comma separated list containing one or more of: IA32, X64, IPF, ARM, AARCH64 or EBC which should be built, overrides target.txt?s TARGET_ARCH")\r
443 Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")\r
444 Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed.")\r
445 Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")\r
446 Parser.add_option("-p", "--platform", type="string", dest="activePlatform", help="Set the ACTIVE_PLATFORM, overrides target.txt ACTIVE_PLATFORM setting.",\r
447 action="callback", callback=SingleCheckCallback)\r
448 Parser.add_option("-w", "--workspace", type="string", dest="Workspace", default=os.environ.get('WORKSPACE'), help="Set the WORKSPACE",\r
449 action="callback", callback=SingleCheckCallback)\r
450 Parser.add_option("-o", "--outputDir", type="string", dest="outputDir", help="Name of Build Output directory",\r
451 action="callback", callback=SingleCheckCallback)\r
452 Parser.add_option("-r", "--rom_image", dest="uiFdName", help="Build the image using the [FD] section named by FdUiName.")\r
453 Parser.add_option("-i", "--FvImage", dest="uiFvName", help="Build the FV image using the [FV] section named by UiFvName")\r
454 Parser.add_option("-C", "--CapsuleImage", dest="uiCapName", help="Build the Capsule image using the [Capsule] section named by UiCapName")\r
455 Parser.add_option("-b", "--buildtarget", type="string", dest="BuildTarget", help="Set the build TARGET, overrides target.txt TARGET setting.",\r
456 action="callback", callback=SingleCheckCallback)\r
457 Parser.add_option("-t", "--tagname", type="string", dest="ToolChain", help="Using the tools: TOOL_CHAIN_TAG name to build the platform.",\r
458 action="callback", callback=SingleCheckCallback)\r
459 Parser.add_option("-D", "--define", action="append", type="string", dest="Macros", help="Macro: \"Name [= Value]\".")\r
460 Parser.add_option("-s", "--specifyaddress", dest="FixedAddress", action="store_true", type=None, help="Specify driver load address.")\r
97fa0ee9
YL
461 Parser.add_option("--conf", action="store", type="string", dest="ConfDirectory", help="Specify the customized Conf directory.")\r
462 Parser.add_option("--ignore-sources", action="store_true", dest="IgnoreSources", default=False, help="Focus to a binary build and ignore all source files")\r
6b17c11b 463 Parser.add_option("--pcd", action="append", dest="OptionPcd", help="Set PCD value by command line. Format: \"PcdName=Value\" ")\r
37de70b7 464 Parser.add_option("--genfds-multi-thread", action="store_true", dest="GenfdsMultiThread", default=False, help="Enable GenFds multi thread to generate ffs file.")\r
97fa0ee9 465\r
9e47e6f9 466 Options, _ = Parser.parse_args()\r
f51461c8
LG
467 return Options\r
468\r
469## The class implementing the EDK2 flash image generation process\r
470#\r
471# This process includes:\r
472# 1. Collect workspace information, includes platform and module information\r
473# 2. Call methods of Fd class to generate FD\r
474# 3. Call methods of Fv class to generate FV that not belong to FD\r
475#\r
9e47e6f9 476class GenFds(object):\r
f51461c8 477 FdfParsef = None\r
f51461c8
LG
478 OnlyGenerateThisFd = None\r
479 OnlyGenerateThisFv = None\r
480 OnlyGenerateThisCap = None\r
481\r
482 ## GenFd()\r
483 #\r
484 # @param OutputDir Output directory\r
9e47e6f9 485 # @param FdfParserObject FDF contents parser\r
f51461c8
LG
486 # @param Workspace The directory of workspace\r
487 # @param ArchList The Arch list of platform\r
488 #\r
9e47e6f9
CJ
489 @staticmethod\r
490 def GenFd (OutputDir, FdfParserObject, WorkSpace, ArchList):\r
491 GenFdsGlobalVariable.SetDir ('', FdfParserObject, WorkSpace, ArchList)\r
f51461c8
LG
492\r
493 GenFdsGlobalVariable.VerboseLogger(" Generate all Fd images and their required FV and Capsule images!")\r
9eb87141
CJ
494 if GenFds.OnlyGenerateThisCap is not None and GenFds.OnlyGenerateThisCap.upper() in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict:\r
495 CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict[GenFds.OnlyGenerateThisCap.upper()]\r
4231a819 496 if CapsuleObj is not None:\r
f51461c8
LG
497 CapsuleObj.GenCapsule()\r
498 return\r
499\r
9eb87141
CJ
500 if GenFds.OnlyGenerateThisFd is not None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict:\r
501 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()]\r
4231a819 502 if FdObj is not None:\r
f51461c8
LG
503 FdObj.GenFd()\r
504 return\r
4231a819 505 elif GenFds.OnlyGenerateThisFd is None and GenFds.OnlyGenerateThisFv is None:\r
9eb87141 506 for FdObj in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():\r
f51461c8
LG
507 FdObj.GenFd()\r
508\r
509 GenFdsGlobalVariable.VerboseLogger("\n Generate other FV images! ")\r
9eb87141
CJ
510 if GenFds.OnlyGenerateThisFv is not None and GenFds.OnlyGenerateThisFv.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict:\r
511 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[GenFds.OnlyGenerateThisFv.upper()]\r
4231a819 512 if FvObj is not None:\r
86379ac4 513 Buffer = BytesIO()\r
f51461c8
LG
514 FvObj.AddToBuffer(Buffer)\r
515 Buffer.close()\r
516 return\r
4231a819 517 elif GenFds.OnlyGenerateThisFv is None:\r
9eb87141 518 for FvObj in GenFdsGlobalVariable.FdfParser.Profile.FvDict.values():\r
d943b0c3 519 Buffer = BytesIO()\r
f51461c8
LG
520 FvObj.AddToBuffer(Buffer)\r
521 Buffer.close()\r
f7496d71 522\r
4231a819 523 if GenFds.OnlyGenerateThisFv is None and GenFds.OnlyGenerateThisFd is None and GenFds.OnlyGenerateThisCap is None:\r
f51461c8
LG
524 if GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict != {}:\r
525 GenFdsGlobalVariable.VerboseLogger("\n Generate other Capsule images!")\r
9eb87141 526 for CapsuleObj in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.values():\r
f51461c8
LG
527 CapsuleObj.GenCapsule()\r
528\r
529 if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:\r
530 GenFdsGlobalVariable.VerboseLogger("\n Generate all Option ROM!")\r
9eb87141 531 for OptRomObj in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.values():\r
f51461c8 532 OptRomObj.AddToBuffer(None)\r
9e47e6f9 533\r
37de70b7 534 @staticmethod\r
9e47e6f9
CJ
535 def GenFfsMakefile(OutputDir, FdfParserObject, WorkSpace, ArchList, GlobalData):\r
536 GenFdsGlobalVariable.SetEnv(FdfParserObject, WorkSpace, ArchList, GlobalData)\r
9eb87141 537 for FdObj in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():\r
37de70b7
YZ
538 FdObj.GenFd(Flag=True)\r
539\r
9eb87141 540 for FvObj in GenFdsGlobalVariable.FdfParser.Profile.FvDict.values():\r
37de70b7
YZ
541 FvObj.AddToBuffer(Buffer=None, Flag=True)\r
542\r
543 if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:\r
9eb87141 544 for OptRomObj in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.values():\r
37de70b7
YZ
545 OptRomObj.AddToBuffer(Buffer=None, Flag=True)\r
546\r
547 return GenFdsGlobalVariable.FfsCmdDict\r
f51461c8
LG
548\r
549 ## GetFvBlockSize()\r
550 #\r
551 # @param FvObj Whose block size to get\r
552 # @retval int Block size value\r
553 #\r
9e47e6f9 554 @staticmethod\r
f51461c8
LG
555 def GetFvBlockSize(FvObj):\r
556 DefaultBlockSize = 0x1\r
557 FdObj = None\r
9eb87141 558 if GenFds.OnlyGenerateThisFd is not None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict:\r
f51461c8 559 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()]\r
4231a819 560 if FdObj is None:\r
f51461c8
LG
561 for ElementFd in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():\r
562 for ElementRegion in ElementFd.RegionList:\r
91fa33ee 563 if ElementRegion.RegionType == BINARY_FILE_TYPE_FV:\r
f51461c8 564 for ElementRegionData in ElementRegion.RegionDataList:\r
4231a819 565 if ElementRegionData is not None and ElementRegionData.upper() == FvObj.UiFvName:\r
f51461c8
LG
566 if FvObj.BlockSizeList != []:\r
567 return FvObj.BlockSizeList[0][0]\r
568 else:\r
569 return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)\r
570 if FvObj.BlockSizeList != []:\r
571 return FvObj.BlockSizeList[0][0]\r
572 return DefaultBlockSize\r
573 else:\r
574 for ElementRegion in FdObj.RegionList:\r
91fa33ee 575 if ElementRegion.RegionType == BINARY_FILE_TYPE_FV:\r
f51461c8 576 for ElementRegionData in ElementRegion.RegionDataList:\r
4231a819 577 if ElementRegionData is not None and ElementRegionData.upper() == FvObj.UiFvName:\r
f51461c8
LG
578 if FvObj.BlockSizeList != []:\r
579 return FvObj.BlockSizeList[0][0]\r
580 else:\r
581 return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)\r
582 return DefaultBlockSize\r
583\r
584 ## DisplayFvSpaceInfo()\r
585 #\r
586 # @param FvObj Whose block size to get\r
587 # @retval None\r
588 #\r
9e47e6f9
CJ
589 @staticmethod\r
590 def DisplayFvSpaceInfo(FdfParserObject):\r
f7496d71 591\r
f51461c8
LG
592 FvSpaceInfoList = []\r
593 MaxFvNameLength = 0\r
9e47e6f9 594 for FvName in FdfParserObject.Profile.FvDict:\r
f51461c8
LG
595 if len(FvName) > MaxFvNameLength:\r
596 MaxFvNameLength = len(FvName)\r
597 FvSpaceInfoFileName = os.path.join(GenFdsGlobalVariable.FvDir, FvName.upper() + '.Fv.map')\r
598 if os.path.exists(FvSpaceInfoFileName):\r
9e47e6f9 599 FileLinesList = getlines(FvSpaceInfoFileName)\r
f51461c8
LG
600 TotalFound = False\r
601 Total = ''\r
602 UsedFound = False\r
603 Used = ''\r
604 FreeFound = False\r
605 Free = ''\r
606 for Line in FileLinesList:\r
607 NameValue = Line.split('=')\r
608 if len(NameValue) == 2:\r
609 if NameValue[0].strip() == 'EFI_FV_TOTAL_SIZE':\r
610 TotalFound = True\r
611 Total = NameValue[1].strip()\r
612 if NameValue[0].strip() == 'EFI_FV_TAKEN_SIZE':\r
613 UsedFound = True\r
614 Used = NameValue[1].strip()\r
615 if NameValue[0].strip() == 'EFI_FV_SPACE_SIZE':\r
616 FreeFound = True\r
617 Free = NameValue[1].strip()\r
f7496d71 618\r
f51461c8
LG
619 if TotalFound and UsedFound and FreeFound:\r
620 FvSpaceInfoList.append((FvName, Total, Used, Free))\r
f7496d71 621\r
f51461c8
LG
622 GenFdsGlobalVariable.InfLogger('\nFV Space Information')\r
623 for FvSpaceInfo in FvSpaceInfoList:\r
624 Name = FvSpaceInfo[0]\r
af881abc
YF
625 TotalSizeValue = int(FvSpaceInfo[1], 0)\r
626 UsedSizeValue = int(FvSpaceInfo[2], 0)\r
627 FreeSizeValue = int(FvSpaceInfo[3], 0)\r
f51461c8
LG
628 if UsedSizeValue == TotalSizeValue:\r
629 Percentage = '100'\r
630 else:\r
47fea6af
YZ
631 Percentage = str((UsedSizeValue + 0.0) / TotalSizeValue)[0:4].lstrip('0.')\r
632\r
f51461c8
LG
633 GenFdsGlobalVariable.InfLogger(Name + ' ' + '[' + Percentage + '%Full] ' + str(TotalSizeValue) + ' total, ' + str(UsedSizeValue) + ' used, ' + str(FreeSizeValue) + ' free')\r
634\r
635 ## PreprocessImage()\r
636 #\r
637 # @param BuildDb Database from build meta data files\r
638 # @param DscFile modules from dsc file will be preprocessed\r
639 # @retval None\r
640 #\r
9e47e6f9 641 @staticmethod\r
f51461c8 642 def PreprocessImage(BuildDb, DscFile):\r
55c84777 643 PcdDict = BuildDb.BuildObject[DscFile, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Pcds\r
f51461c8
LG
644 PcdValue = ''\r
645 for Key in PcdDict:\r
646 PcdObj = PcdDict[Key]\r
647 if PcdObj.TokenCName == 'PcdBsBaseAddress':\r
648 PcdValue = PcdObj.DefaultValue\r
649 break\r
f7496d71 650\r
f51461c8
LG
651 if PcdValue == '':\r
652 return\r
f7496d71 653\r
af881abc 654 Int64PcdValue = int(PcdValue, 0)\r
f7496d71 655 if Int64PcdValue == 0 or Int64PcdValue < -1:\r
f51461c8 656 return\r
f7496d71 657\r
f51461c8
LG
658 TopAddress = 0\r
659 if Int64PcdValue > 0:\r
660 TopAddress = Int64PcdValue\r
f7496d71 661\r
55c84777 662 ModuleDict = BuildDb.BuildObject[DscFile, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Modules\r
f51461c8 663 for Key in ModuleDict:\r
55c84777 664 ModuleObj = BuildDb.BuildObject[Key, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
72443dd2 665 print(ModuleObj.BaseName + ' ' + ModuleObj.ModuleType)\r
f51461c8 666\r
9e47e6f9 667 @staticmethod\r
5e9256cd 668 def GenerateGuidXRefFile(BuildDb, ArchList, FdfParserObj):\r
f51461c8 669 GuidXRefFileName = os.path.join(GenFdsGlobalVariable.FvDir, "Guid.xref")\r
d943b0c3 670 GuidXRefFile = []\r
0fece18d 671 PkgGuidDict = {}\r
e4ac870f 672 GuidDict = {}\r
5e9256cd
YZ
673 ModuleList = []\r
674 FileGuidList = []\r
d7f40203 675 VariableGuidSet = set()\r
f51461c8
LG
676 for Arch in ArchList:\r
677 PlatformDataBase = BuildDb.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
0fece18d 678 PkgList = GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag)\r
679 for P in PkgList:\r
680 PkgGuidDict.update(P.Guids)\r
1ccc4d89 681 for Name, Guid in PlatformDataBase.Pcds:\r
0fece18d 682 Pcd = PlatformDataBase.Pcds[Name, Guid]\r
683 if Pcd.Type in [TAB_PCDS_DYNAMIC_HII, TAB_PCDS_DYNAMIC_EX_HII]:\r
684 for SkuId in Pcd.SkuInfoList:\r
685 Sku = Pcd.SkuInfoList[SkuId]\r
d7f40203
ZF
686 if Sku.VariableGuid in VariableGuidSet:continue\r
687 VariableGuidSet.add(Sku.VariableGuid)\r
0fece18d 688 if Sku.VariableGuid and Sku.VariableGuid in PkgGuidDict.keys():\r
689 GuidDict[Sku.VariableGuid] = PkgGuidDict[Sku.VariableGuid]\r
f51461c8
LG
690 for ModuleFile in PlatformDataBase.Modules:\r
691 Module = BuildDb.BuildObject[ModuleFile, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
5e9256cd
YZ
692 if Module in ModuleList:\r
693 continue\r
694 else:\r
695 ModuleList.append(Module)\r
9e47e6f9 696 if GlobalData.gGuidPattern.match(ModuleFile.BaseName):\r
d943b0c3 697 GuidXRefFile.append("%s %s\n" % (ModuleFile.BaseName, Module.BaseName))\r
1d802e23 698 else:\r
d943b0c3 699 GuidXRefFile.append("%s %s\n" % (Module.Guid, Module.BaseName))\r
9e47e6f9
CJ
700 GuidDict.update(Module.Protocols)\r
701 GuidDict.update(Module.Guids)\r
702 GuidDict.update(Module.Ppis)\r
5e9256cd
YZ
703 for FvName in FdfParserObj.Profile.FvDict:\r
704 for FfsObj in FdfParserObj.Profile.FvDict[FvName].FfsList:\r
9e47e6f9 705 if not isinstance(FfsObj, FileStatement):\r
5e9256cd
YZ
706 InfPath = PathClass(NormPath(mws.join(GenFdsGlobalVariable.WorkSpaceDir, FfsObj.InfFileName)))\r
707 FdfModule = BuildDb.BuildObject[InfPath, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
708 if FdfModule in ModuleList:\r
709 continue\r
710 else:\r
711 ModuleList.append(FdfModule)\r
d943b0c3 712 GuidXRefFile.append("%s %s\n" % (FdfModule.Guid, FdfModule.BaseName))\r
9e47e6f9
CJ
713 GuidDict.update(FdfModule.Protocols)\r
714 GuidDict.update(FdfModule.Guids)\r
715 GuidDict.update(FdfModule.Ppis)\r
5e9256cd
YZ
716 else:\r
717 FileStatementGuid = FfsObj.NameGuid\r
718 if FileStatementGuid in FileGuidList:\r
719 continue\r
720 else:\r
721 FileGuidList.append(FileStatementGuid)\r
722 Name = []\r
723 FfsPath = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')\r
bc39c5cb 724 FfsPath = glob(os.path.join(FfsPath, FileStatementGuid) + TAB_STAR)\r
5e9256cd
YZ
725 if not FfsPath:\r
726 continue\r
727 if not os.path.exists(FfsPath[0]):\r
728 continue\r
729 MatchDict = {}\r
9e47e6f9 730 ReFileEnds = compile('\S+(.ui)$|\S+(fv.sec.txt)$|\S+(.pe32.txt)$|\S+(.te.txt)$|\S+(.pic.txt)$|\S+(.raw.txt)$|\S+(.ffs.txt)$')\r
5e9256cd
YZ
731 FileList = os.listdir(FfsPath[0])\r
732 for File in FileList:\r
733 Match = ReFileEnds.search(File)\r
734 if Match:\r
735 for Index in range(1, 8):\r
736 if Match.group(Index) and Match.group(Index) in MatchDict:\r
737 MatchDict[Match.group(Index)].append(File)\r
738 elif Match.group(Index):\r
739 MatchDict[Match.group(Index)] = [File]\r
740 if not MatchDict:\r
741 continue\r
742 if '.ui' in MatchDict:\r
743 for File in MatchDict['.ui']:\r
744 with open(os.path.join(FfsPath[0], File), 'rb') as F:\r
745 F.read()\r
746 length = F.tell()\r
747 F.seek(4)\r
b3e94a06 748 TmpStr = unpack('%dh' % ((length - 4) // 2), F.read())\r
8252e6bf 749 Name = ''.join(chr(c) for c in TmpStr[:-1])\r
5e9256cd
YZ
750 else:\r
751 FileList = []\r
752 if 'fv.sec.txt' in MatchDict:\r
753 FileList = MatchDict['fv.sec.txt']\r
754 elif '.pe32.txt' in MatchDict:\r
755 FileList = MatchDict['.pe32.txt']\r
756 elif '.te.txt' in MatchDict:\r
757 FileList = MatchDict['.te.txt']\r
758 elif '.pic.txt' in MatchDict:\r
759 FileList = MatchDict['.pic.txt']\r
760 elif '.raw.txt' in MatchDict:\r
761 FileList = MatchDict['.raw.txt']\r
762 elif '.ffs.txt' in MatchDict:\r
763 FileList = MatchDict['.ffs.txt']\r
764 else:\r
765 pass\r
766 for File in FileList:\r
767 with open(os.path.join(FfsPath[0], File), 'r') as F:\r
768 Name.append((F.read().split()[-1]))\r
769 if not Name:\r
770 continue\r
771\r
0d1f5b2b 772 Name = ' '.join(Name) if isinstance(Name, type([])) else Name\r
d943b0c3 773 GuidXRefFile.append("%s %s\n" %(FileStatementGuid, Name))\r
5e9256cd 774\r
e4ac870f 775 # Append GUIDs, Protocols, and PPIs to the Xref file\r
d943b0c3 776 GuidXRefFile.append("\n")\r
e4ac870f 777 for key, item in GuidDict.items():\r
d943b0c3 778 GuidXRefFile.append("%s %s\n" % (GuidStructureStringToGuidString(item).upper(), key))\r
e4ac870f 779\r
d943b0c3
FB
780 if GuidXRefFile:\r
781 GuidXRefFile = ''.join(GuidXRefFile)\r
782 SaveFileOnChange(GuidXRefFileName, GuidXRefFile, False)\r
f51461c8
LG
783 GenFdsGlobalVariable.InfLogger("\nGUID cross reference file can be found at %s" % GuidXRefFileName)\r
784 elif os.path.exists(GuidXRefFileName):\r
785 os.remove(GuidXRefFileName)\r
f51461c8 786\r
b3497bad 787\r
f51461c8
LG
788if __name__ == '__main__':\r
789 r = main()\r
790 ## 0-127 is a safe return range, and 1 is a standard default error\r
9e47e6f9
CJ
791 if r < 0 or r > 127:\r
792 r = 1\r
793 exit(r)\r
f51461c8 794\r