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