]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/GenFds/GenFds.py
Basetools: It went wrong when use os.linesep
[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
365 if FvObj.FvRegionInFD:\r
366 if FvObj.FvRegionInFD != RegionObj.Size:\r
367 EdkLogger.error("GenFds", FORMAT_INVALID, "The FV %s's region is specified in multiple FD with different value." %FvObj.UiFvName)\r
368 else:\r
369 FvObj.FvRegionInFD = RegionObj.Size\r
370 RegionObj.BlockInfoOfRegion(FdObj.BlockSizeList, FvObj)\r
371\r
f51461c8
LG
372 """Call GenFds"""\r
373 GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList)\r
374\r
375 """Generate GUID cross reference file"""\r
5e9256cd 376 GenFds.GenerateGuidXRefFile(BuildWorkSpace, ArchList, FdfParserObj)\r
f51461c8
LG
377\r
378 """Display FV space info."""\r
379 GenFds.DisplayFvSpaceInfo(FdfParserObj)\r
380\r
9e47e6f9 381 except Warning as X:\r
47fea6af 382 EdkLogger.error(X.ToolName, FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError=False)\r
f51461c8 383 ReturnCode = FORMAT_INVALID\r
5b0671c1 384 except FatalError as X:\r
b3497bad 385 if FdsCommandDict.get("debug") is not None:\r
f51461c8
LG
386 import traceback\r
387 EdkLogger.quiet(traceback.format_exc())\r
388 ReturnCode = X.args[0]\r
389 except:\r
390 import traceback\r
391 EdkLogger.error(\r
392 "\nPython",\r
393 CODE_ERROR,\r
394 "Tools code failure",\r
3a0f8bde 395 ExtraData="Please send email to edk2-devel@lists.01.org for help, attaching following call stack trace!\n",\r
f51461c8
LG
396 RaiseError=False\r
397 )\r
398 EdkLogger.quiet(traceback.format_exc())\r
399 ReturnCode = CODE_ERROR\r
97fa0ee9
YL
400 finally:\r
401 ClearDuplicatedInf()\r
f51461c8
LG
402 return ReturnCode\r
403\r
b3497bad
ZZ
404def OptionsToCommandDict(Options):\r
405 FdsCommandDict = {}\r
406 FdsCommandDict["verbose"] = Options.verbose\r
407 FdsCommandDict["FixedAddress"] = Options.FixedAddress\r
408 FdsCommandDict["quiet"] = Options.quiet\r
409 FdsCommandDict["debug"] = Options.debug\r
410 FdsCommandDict["Workspace"] = Options.Workspace\r
411 FdsCommandDict["GenfdsMultiThread"] = Options.GenfdsMultiThread\r
412 FdsCommandDict["fdf_file"] = [PathClass(Options.filename)] if Options.filename else []\r
413 FdsCommandDict["build_target"] = Options.BuildTarget\r
414 FdsCommandDict["toolchain_tag"] = Options.ToolChain\r
415 FdsCommandDict["active_platform"] = Options.activePlatform\r
416 FdsCommandDict["OptionPcd"] = Options.OptionPcd\r
417 FdsCommandDict["conf_directory"] = Options.ConfDirectory\r
418 FdsCommandDict["IgnoreSources"] = Options.IgnoreSources\r
419 FdsCommandDict["macro"] = Options.Macros\r
420 FdsCommandDict["build_architecture_list"] = Options.archList\r
421 FdsCommandDict["platform_build_directory"] = Options.outputDir\r
422 FdsCommandDict["fd"] = [Options.uiFdName] if Options.uiFdName else []\r
423 FdsCommandDict["fv"] = [Options.uiFvName] if Options.uiFvName else []\r
424 FdsCommandDict["cap"] = [Options.uiCapName] if Options.uiCapName else []\r
425 return FdsCommandDict\r
426\r
427\r
f51461c8
LG
428gParamCheck = []\r
429def SingleCheckCallback(option, opt_str, value, parser):\r
430 if option not in gParamCheck:\r
431 setattr(parser.values, option.dest, value)\r
432 gParamCheck.append(option)\r
433 else:\r
434 parser.error("Option %s only allows one instance in command line!" % option)\r
6b17c11b 435\r
f51461c8
LG
436## Parse command line options\r
437#\r
438# Using standard Python module optparse to parse command line option of this tool.\r
439#\r
440# @retval Opt A optparse.Values object containing the parsed options\r
f51461c8
LG
441#\r
442def myOptionParser():\r
443 usage = "%prog [options] -f input_file -a arch_list -b build_target -p active_platform -t tool_chain_tag -D \"MacroName [= MacroValue]\""\r
47fea6af 444 Parser = OptionParser(usage=usage, description=__copyright__, version="%prog " + str(versionNumber))\r
f51461c8
LG
445 Parser.add_option("-f", "--file", dest="filename", type="string", help="Name of FDF file to convert", action="callback", callback=SingleCheckCallback)\r
446 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
447 Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")\r
448 Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed.")\r
449 Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")\r
450 Parser.add_option("-p", "--platform", type="string", dest="activePlatform", help="Set the ACTIVE_PLATFORM, overrides target.txt ACTIVE_PLATFORM setting.",\r
451 action="callback", callback=SingleCheckCallback)\r
452 Parser.add_option("-w", "--workspace", type="string", dest="Workspace", default=os.environ.get('WORKSPACE'), help="Set the WORKSPACE",\r
453 action="callback", callback=SingleCheckCallback)\r
454 Parser.add_option("-o", "--outputDir", type="string", dest="outputDir", help="Name of Build Output directory",\r
455 action="callback", callback=SingleCheckCallback)\r
456 Parser.add_option("-r", "--rom_image", dest="uiFdName", help="Build the image using the [FD] section named by FdUiName.")\r
457 Parser.add_option("-i", "--FvImage", dest="uiFvName", help="Build the FV image using the [FV] section named by UiFvName")\r
458 Parser.add_option("-C", "--CapsuleImage", dest="uiCapName", help="Build the Capsule image using the [Capsule] section named by UiCapName")\r
459 Parser.add_option("-b", "--buildtarget", type="string", dest="BuildTarget", help="Set the build TARGET, overrides target.txt TARGET setting.",\r
460 action="callback", callback=SingleCheckCallback)\r
461 Parser.add_option("-t", "--tagname", type="string", dest="ToolChain", help="Using the tools: TOOL_CHAIN_TAG name to build the platform.",\r
462 action="callback", callback=SingleCheckCallback)\r
463 Parser.add_option("-D", "--define", action="append", type="string", dest="Macros", help="Macro: \"Name [= Value]\".")\r
464 Parser.add_option("-s", "--specifyaddress", dest="FixedAddress", action="store_true", type=None, help="Specify driver load address.")\r
97fa0ee9
YL
465 Parser.add_option("--conf", action="store", type="string", dest="ConfDirectory", help="Specify the customized Conf directory.")\r
466 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 467 Parser.add_option("--pcd", action="append", dest="OptionPcd", help="Set PCD value by command line. Format: \"PcdName=Value\" ")\r
37de70b7 468 Parser.add_option("--genfds-multi-thread", action="store_true", dest="GenfdsMultiThread", default=False, help="Enable GenFds multi thread to generate ffs file.")\r
97fa0ee9 469\r
9e47e6f9 470 Options, _ = Parser.parse_args()\r
f51461c8
LG
471 return Options\r
472\r
473## The class implementing the EDK2 flash image generation process\r
474#\r
475# This process includes:\r
476# 1. Collect workspace information, includes platform and module information\r
477# 2. Call methods of Fd class to generate FD\r
478# 3. Call methods of Fv class to generate FV that not belong to FD\r
479#\r
9e47e6f9 480class GenFds(object):\r
f51461c8 481 FdfParsef = None\r
f51461c8
LG
482 OnlyGenerateThisFd = None\r
483 OnlyGenerateThisFv = None\r
484 OnlyGenerateThisCap = None\r
485\r
486 ## GenFd()\r
487 #\r
488 # @param OutputDir Output directory\r
9e47e6f9 489 # @param FdfParserObject FDF contents parser\r
f51461c8
LG
490 # @param Workspace The directory of workspace\r
491 # @param ArchList The Arch list of platform\r
492 #\r
9e47e6f9
CJ
493 @staticmethod\r
494 def GenFd (OutputDir, FdfParserObject, WorkSpace, ArchList):\r
495 GenFdsGlobalVariable.SetDir ('', FdfParserObject, WorkSpace, ArchList)\r
f51461c8
LG
496\r
497 GenFdsGlobalVariable.VerboseLogger(" Generate all Fd images and their required FV and Capsule images!")\r
9eb87141
CJ
498 if GenFds.OnlyGenerateThisCap is not None and GenFds.OnlyGenerateThisCap.upper() in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict:\r
499 CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict[GenFds.OnlyGenerateThisCap.upper()]\r
4231a819 500 if CapsuleObj is not None:\r
f51461c8
LG
501 CapsuleObj.GenCapsule()\r
502 return\r
503\r
9eb87141
CJ
504 if GenFds.OnlyGenerateThisFd is not None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict:\r
505 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()]\r
4231a819 506 if FdObj is not None:\r
f51461c8
LG
507 FdObj.GenFd()\r
508 return\r
4231a819 509 elif GenFds.OnlyGenerateThisFd is None and GenFds.OnlyGenerateThisFv is None:\r
9eb87141 510 for FdObj in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():\r
f51461c8
LG
511 FdObj.GenFd()\r
512\r
513 GenFdsGlobalVariable.VerboseLogger("\n Generate other FV images! ")\r
9eb87141
CJ
514 if GenFds.OnlyGenerateThisFv is not None and GenFds.OnlyGenerateThisFv.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict:\r
515 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[GenFds.OnlyGenerateThisFv.upper()]\r
4231a819 516 if FvObj is not None:\r
86379ac4 517 Buffer = BytesIO()\r
f51461c8
LG
518 FvObj.AddToBuffer(Buffer)\r
519 Buffer.close()\r
520 return\r
4231a819 521 elif GenFds.OnlyGenerateThisFv is None:\r
9eb87141 522 for FvObj in GenFdsGlobalVariable.FdfParser.Profile.FvDict.values():\r
1ccc4d89 523 Buffer = BytesIO('')\r
f51461c8
LG
524 FvObj.AddToBuffer(Buffer)\r
525 Buffer.close()\r
f7496d71 526\r
4231a819 527 if GenFds.OnlyGenerateThisFv is None and GenFds.OnlyGenerateThisFd is None and GenFds.OnlyGenerateThisCap is None:\r
f51461c8
LG
528 if GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict != {}:\r
529 GenFdsGlobalVariable.VerboseLogger("\n Generate other Capsule images!")\r
9eb87141 530 for CapsuleObj in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.values():\r
f51461c8
LG
531 CapsuleObj.GenCapsule()\r
532\r
533 if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:\r
534 GenFdsGlobalVariable.VerboseLogger("\n Generate all Option ROM!")\r
9eb87141 535 for OptRomObj in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.values():\r
f51461c8 536 OptRomObj.AddToBuffer(None)\r
9e47e6f9 537\r
37de70b7 538 @staticmethod\r
9e47e6f9
CJ
539 def GenFfsMakefile(OutputDir, FdfParserObject, WorkSpace, ArchList, GlobalData):\r
540 GenFdsGlobalVariable.SetEnv(FdfParserObject, WorkSpace, ArchList, GlobalData)\r
9eb87141 541 for FdObj in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():\r
37de70b7
YZ
542 FdObj.GenFd(Flag=True)\r
543\r
9eb87141 544 for FvObj in GenFdsGlobalVariable.FdfParser.Profile.FvDict.values():\r
37de70b7
YZ
545 FvObj.AddToBuffer(Buffer=None, Flag=True)\r
546\r
547 if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:\r
9eb87141 548 for OptRomObj in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.values():\r
37de70b7
YZ
549 OptRomObj.AddToBuffer(Buffer=None, Flag=True)\r
550\r
551 return GenFdsGlobalVariable.FfsCmdDict\r
f51461c8
LG
552\r
553 ## GetFvBlockSize()\r
554 #\r
555 # @param FvObj Whose block size to get\r
556 # @retval int Block size value\r
557 #\r
9e47e6f9 558 @staticmethod\r
f51461c8
LG
559 def GetFvBlockSize(FvObj):\r
560 DefaultBlockSize = 0x1\r
561 FdObj = None\r
9eb87141 562 if GenFds.OnlyGenerateThisFd is not None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict:\r
f51461c8 563 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()]\r
4231a819 564 if FdObj is None:\r
f51461c8
LG
565 for ElementFd in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():\r
566 for ElementRegion in ElementFd.RegionList:\r
91fa33ee 567 if ElementRegion.RegionType == BINARY_FILE_TYPE_FV:\r
f51461c8 568 for ElementRegionData in ElementRegion.RegionDataList:\r
4231a819 569 if ElementRegionData is not None and ElementRegionData.upper() == FvObj.UiFvName:\r
f51461c8
LG
570 if FvObj.BlockSizeList != []:\r
571 return FvObj.BlockSizeList[0][0]\r
572 else:\r
573 return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)\r
574 if FvObj.BlockSizeList != []:\r
575 return FvObj.BlockSizeList[0][0]\r
576 return DefaultBlockSize\r
577 else:\r
578 for ElementRegion in FdObj.RegionList:\r
91fa33ee 579 if ElementRegion.RegionType == BINARY_FILE_TYPE_FV:\r
f51461c8 580 for ElementRegionData in ElementRegion.RegionDataList:\r
4231a819 581 if ElementRegionData is not None and ElementRegionData.upper() == FvObj.UiFvName:\r
f51461c8
LG
582 if FvObj.BlockSizeList != []:\r
583 return FvObj.BlockSizeList[0][0]\r
584 else:\r
585 return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)\r
586 return DefaultBlockSize\r
587\r
588 ## DisplayFvSpaceInfo()\r
589 #\r
590 # @param FvObj Whose block size to get\r
591 # @retval None\r
592 #\r
9e47e6f9
CJ
593 @staticmethod\r
594 def DisplayFvSpaceInfo(FdfParserObject):\r
f7496d71 595\r
f51461c8
LG
596 FvSpaceInfoList = []\r
597 MaxFvNameLength = 0\r
9e47e6f9 598 for FvName in FdfParserObject.Profile.FvDict:\r
f51461c8
LG
599 if len(FvName) > MaxFvNameLength:\r
600 MaxFvNameLength = len(FvName)\r
601 FvSpaceInfoFileName = os.path.join(GenFdsGlobalVariable.FvDir, FvName.upper() + '.Fv.map')\r
602 if os.path.exists(FvSpaceInfoFileName):\r
9e47e6f9 603 FileLinesList = getlines(FvSpaceInfoFileName)\r
f51461c8
LG
604 TotalFound = False\r
605 Total = ''\r
606 UsedFound = False\r
607 Used = ''\r
608 FreeFound = False\r
609 Free = ''\r
610 for Line in FileLinesList:\r
611 NameValue = Line.split('=')\r
612 if len(NameValue) == 2:\r
613 if NameValue[0].strip() == 'EFI_FV_TOTAL_SIZE':\r
614 TotalFound = True\r
615 Total = NameValue[1].strip()\r
616 if NameValue[0].strip() == 'EFI_FV_TAKEN_SIZE':\r
617 UsedFound = True\r
618 Used = NameValue[1].strip()\r
619 if NameValue[0].strip() == 'EFI_FV_SPACE_SIZE':\r
620 FreeFound = True\r
621 Free = NameValue[1].strip()\r
f7496d71 622\r
f51461c8
LG
623 if TotalFound and UsedFound and FreeFound:\r
624 FvSpaceInfoList.append((FvName, Total, Used, Free))\r
f7496d71 625\r
f51461c8
LG
626 GenFdsGlobalVariable.InfLogger('\nFV Space Information')\r
627 for FvSpaceInfo in FvSpaceInfoList:\r
628 Name = FvSpaceInfo[0]\r
af881abc
YF
629 TotalSizeValue = int(FvSpaceInfo[1], 0)\r
630 UsedSizeValue = int(FvSpaceInfo[2], 0)\r
631 FreeSizeValue = int(FvSpaceInfo[3], 0)\r
f51461c8
LG
632 if UsedSizeValue == TotalSizeValue:\r
633 Percentage = '100'\r
634 else:\r
47fea6af
YZ
635 Percentage = str((UsedSizeValue + 0.0) / TotalSizeValue)[0:4].lstrip('0.')\r
636\r
f51461c8
LG
637 GenFdsGlobalVariable.InfLogger(Name + ' ' + '[' + Percentage + '%Full] ' + str(TotalSizeValue) + ' total, ' + str(UsedSizeValue) + ' used, ' + str(FreeSizeValue) + ' free')\r
638\r
639 ## PreprocessImage()\r
640 #\r
641 # @param BuildDb Database from build meta data files\r
642 # @param DscFile modules from dsc file will be preprocessed\r
643 # @retval None\r
644 #\r
9e47e6f9 645 @staticmethod\r
f51461c8 646 def PreprocessImage(BuildDb, DscFile):\r
55c84777 647 PcdDict = BuildDb.BuildObject[DscFile, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Pcds\r
f51461c8
LG
648 PcdValue = ''\r
649 for Key in PcdDict:\r
650 PcdObj = PcdDict[Key]\r
651 if PcdObj.TokenCName == 'PcdBsBaseAddress':\r
652 PcdValue = PcdObj.DefaultValue\r
653 break\r
f7496d71 654\r
f51461c8
LG
655 if PcdValue == '':\r
656 return\r
f7496d71 657\r
af881abc 658 Int64PcdValue = int(PcdValue, 0)\r
f7496d71 659 if Int64PcdValue == 0 or Int64PcdValue < -1:\r
f51461c8 660 return\r
f7496d71 661\r
f51461c8
LG
662 TopAddress = 0\r
663 if Int64PcdValue > 0:\r
664 TopAddress = Int64PcdValue\r
f7496d71 665\r
55c84777 666 ModuleDict = BuildDb.BuildObject[DscFile, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Modules\r
f51461c8 667 for Key in ModuleDict:\r
55c84777 668 ModuleObj = BuildDb.BuildObject[Key, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
72443dd2 669 print(ModuleObj.BaseName + ' ' + ModuleObj.ModuleType)\r
f51461c8 670\r
9e47e6f9 671 @staticmethod\r
5e9256cd 672 def GenerateGuidXRefFile(BuildDb, ArchList, FdfParserObj):\r
f51461c8 673 GuidXRefFileName = os.path.join(GenFdsGlobalVariable.FvDir, "Guid.xref")\r
1ccc4d89 674 GuidXRefFile = BytesIO('')\r
0fece18d 675 PkgGuidDict = {}\r
e4ac870f 676 GuidDict = {}\r
5e9256cd
YZ
677 ModuleList = []\r
678 FileGuidList = []\r
f51461c8
LG
679 for Arch in ArchList:\r
680 PlatformDataBase = BuildDb.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
0fece18d 681 PkgList = GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag)\r
682 for P in PkgList:\r
683 PkgGuidDict.update(P.Guids)\r
1ccc4d89 684 for Name, Guid in PlatformDataBase.Pcds:\r
0fece18d 685 Pcd = PlatformDataBase.Pcds[Name, Guid]\r
686 if Pcd.Type in [TAB_PCDS_DYNAMIC_HII, TAB_PCDS_DYNAMIC_EX_HII]:\r
687 for SkuId in Pcd.SkuInfoList:\r
688 Sku = Pcd.SkuInfoList[SkuId]\r
689 if Sku.VariableGuid and Sku.VariableGuid in PkgGuidDict.keys():\r
690 GuidDict[Sku.VariableGuid] = PkgGuidDict[Sku.VariableGuid]\r
f51461c8
LG
691 for ModuleFile in PlatformDataBase.Modules:\r
692 Module = BuildDb.BuildObject[ModuleFile, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
5e9256cd
YZ
693 if Module in ModuleList:\r
694 continue\r
695 else:\r
696 ModuleList.append(Module)\r
9e47e6f9 697 if GlobalData.gGuidPattern.match(ModuleFile.BaseName):\r
1d802e23
YF
698 GuidXRefFile.write("%s %s\n" % (ModuleFile.BaseName, Module.BaseName))\r
699 else:\r
700 GuidXRefFile.write("%s %s\n" % (Module.Guid, Module.BaseName))\r
9e47e6f9
CJ
701 GuidDict.update(Module.Protocols)\r
702 GuidDict.update(Module.Guids)\r
703 GuidDict.update(Module.Ppis)\r
5e9256cd
YZ
704 for FvName in FdfParserObj.Profile.FvDict:\r
705 for FfsObj in FdfParserObj.Profile.FvDict[FvName].FfsList:\r
9e47e6f9 706 if not isinstance(FfsObj, FileStatement):\r
5e9256cd
YZ
707 InfPath = PathClass(NormPath(mws.join(GenFdsGlobalVariable.WorkSpaceDir, FfsObj.InfFileName)))\r
708 FdfModule = BuildDb.BuildObject[InfPath, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
709 if FdfModule in ModuleList:\r
710 continue\r
711 else:\r
712 ModuleList.append(FdfModule)\r
713 GuidXRefFile.write("%s %s\n" % (FdfModule.Guid, FdfModule.BaseName))\r
9e47e6f9
CJ
714 GuidDict.update(FdfModule.Protocols)\r
715 GuidDict.update(FdfModule.Guids)\r
716 GuidDict.update(FdfModule.Ppis)\r
5e9256cd
YZ
717 else:\r
718 FileStatementGuid = FfsObj.NameGuid\r
719 if FileStatementGuid in FileGuidList:\r
720 continue\r
721 else:\r
722 FileGuidList.append(FileStatementGuid)\r
723 Name = []\r
724 FfsPath = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')\r
bc39c5cb 725 FfsPath = glob(os.path.join(FfsPath, FileStatementGuid) + TAB_STAR)\r
5e9256cd
YZ
726 if not FfsPath:\r
727 continue\r
728 if not os.path.exists(FfsPath[0]):\r
729 continue\r
730 MatchDict = {}\r
9e47e6f9 731 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
732 FileList = os.listdir(FfsPath[0])\r
733 for File in FileList:\r
734 Match = ReFileEnds.search(File)\r
735 if Match:\r
736 for Index in range(1, 8):\r
737 if Match.group(Index) and Match.group(Index) in MatchDict:\r
738 MatchDict[Match.group(Index)].append(File)\r
739 elif Match.group(Index):\r
740 MatchDict[Match.group(Index)] = [File]\r
741 if not MatchDict:\r
742 continue\r
743 if '.ui' in MatchDict:\r
744 for File in MatchDict['.ui']:\r
745 with open(os.path.join(FfsPath[0], File), 'rb') as F:\r
746 F.read()\r
747 length = F.tell()\r
748 F.seek(4)\r
1ccc4d89 749 TmpStr = unpack('%dh' % ((length - 4) / 2), F.read())\r
8252e6bf 750 Name = ''.join(chr(c) for c in TmpStr[:-1])\r
5e9256cd
YZ
751 else:\r
752 FileList = []\r
753 if 'fv.sec.txt' in MatchDict:\r
754 FileList = MatchDict['fv.sec.txt']\r
755 elif '.pe32.txt' in MatchDict:\r
756 FileList = MatchDict['.pe32.txt']\r
757 elif '.te.txt' in MatchDict:\r
758 FileList = MatchDict['.te.txt']\r
759 elif '.pic.txt' in MatchDict:\r
760 FileList = MatchDict['.pic.txt']\r
761 elif '.raw.txt' in MatchDict:\r
762 FileList = MatchDict['.raw.txt']\r
763 elif '.ffs.txt' in MatchDict:\r
764 FileList = MatchDict['.ffs.txt']\r
765 else:\r
766 pass\r
767 for File in FileList:\r
768 with open(os.path.join(FfsPath[0], File), 'r') as F:\r
769 Name.append((F.read().split()[-1]))\r
770 if not Name:\r
771 continue\r
772\r
0d1f5b2b 773 Name = ' '.join(Name) if isinstance(Name, type([])) else Name\r
5e9256cd
YZ
774 GuidXRefFile.write("%s %s\n" %(FileStatementGuid, Name))\r
775\r
e4ac870f
LG
776 # Append GUIDs, Protocols, and PPIs to the Xref file\r
777 GuidXRefFile.write("\n")\r
778 for key, item in GuidDict.items():\r
779 GuidXRefFile.write("%s %s\n" % (GuidStructureStringToGuidString(item).upper(), key))\r
780\r
f51461c8
LG
781 if GuidXRefFile.getvalue():\r
782 SaveFileOnChange(GuidXRefFileName, GuidXRefFile.getvalue(), False)\r
783 GenFdsGlobalVariable.InfLogger("\nGUID cross reference file can be found at %s" % GuidXRefFileName)\r
784 elif os.path.exists(GuidXRefFileName):\r
785 os.remove(GuidXRefFileName)\r
786 GuidXRefFile.close()\r
787\r
b3497bad 788\r
f51461c8
LG
789if __name__ == '__main__':\r
790 r = main()\r
791 ## 0-127 is a safe return range, and 1 is a standard default error\r
9e47e6f9
CJ
792 if r < 0 or r > 127:\r
793 r = 1\r
794 exit(r)\r
f51461c8 795\r