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