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