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