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