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