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