]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/GenFds/GenFds.py
BaseTools: GlobalData.gConfDirectory is None when run 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
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
6b17c11b 41from Common.Misc import CheckPcdDatum\r
db55dac7 42from Common.Misc import BuildOptionPcdValueFormat\r
f51461c8 43from Common.BuildVersion import gBUILD_VERSION\r
05cc51ad 44from Common.MultipleWorkspace import MultipleWorkspace as mws\r
5e9256cd
YZ
45import FfsFileStatement\r
46import glob\r
47from struct import unpack\r
f51461c8
LG
48\r
49## Version and Copyright\r
50versionNumber = "1.0" + ' ' + gBUILD_VERSION\r
51__version__ = "%prog Version " + versionNumber\r
95816356 52__copyright__ = "Copyright (c) 2007 - 2017, Intel Corporation All rights reserved."\r
f51461c8
LG
53\r
54## Tool entrance method\r
55#\r
56# This method mainly dispatch specific methods per the command line options.\r
57# If no error found, return zero value so the caller of this tool can know\r
58# if it's executed successfully or not.\r
59#\r
60# @retval 0 Tool was successful\r
61# @retval 1 Tool failed\r
62#\r
63def main():\r
64 global Options\r
65 Options = myOptionParser()\r
66\r
67 global Workspace\r
68 Workspace = ""\r
69 ArchList = None\r
70 ReturnCode = 0\r
71\r
72 EdkLogger.Initialize()\r
73 try:\r
74 if Options.verbose != None:\r
75 EdkLogger.SetLevel(EdkLogger.VERBOSE)\r
76 GenFdsGlobalVariable.VerboseMode = True\r
77 \r
78 if Options.FixedAddress != None:\r
79 GenFdsGlobalVariable.FixedLoadAddress = True\r
80 \r
81 if Options.quiet != None:\r
82 EdkLogger.SetLevel(EdkLogger.QUIET)\r
83 if Options.debug != None:\r
84 EdkLogger.SetLevel(Options.debug + 1)\r
85 GenFdsGlobalVariable.DebugLevel = Options.debug\r
86 else:\r
87 EdkLogger.SetLevel(EdkLogger.INFO)\r
88\r
89 if (Options.Workspace == None):\r
90 EdkLogger.error("GenFds", OPTION_MISSING, "WORKSPACE not defined",\r
91 ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")\r
92 elif not os.path.exists(Options.Workspace):\r
93 EdkLogger.error("GenFds", PARAMETER_INVALID, "WORKSPACE is invalid",\r
94 ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")\r
95 else:\r
96 Workspace = os.path.normcase(Options.Workspace)\r
97 GenFdsGlobalVariable.WorkSpaceDir = Workspace\r
98 if 'EDK_SOURCE' in os.environ.keys():\r
99 GenFdsGlobalVariable.EdkSourceDir = os.path.normcase(os.environ['EDK_SOURCE'])\r
100 if (Options.debug):\r
47fea6af 101 GenFdsGlobalVariable.VerboseLogger("Using Workspace:" + Workspace)\r
37de70b7
YZ
102 if Options.GenfdsMultiThread:\r
103 GenFdsGlobalVariable.EnableGenfdsMultiThread = True\r
f51461c8 104 os.chdir(GenFdsGlobalVariable.WorkSpaceDir)\r
05cc51ad
LY
105 \r
106 # set multiple workspace\r
107 PackagesPath = os.getenv("PACKAGES_PATH")\r
108 mws.setWs(GenFdsGlobalVariable.WorkSpaceDir, PackagesPath)\r
f51461c8
LG
109\r
110 if (Options.filename):\r
111 FdfFilename = Options.filename\r
112 FdfFilename = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdfFilename)\r
113\r
114 if FdfFilename[0:2] == '..':\r
115 FdfFilename = os.path.realpath(FdfFilename)\r
47fea6af 116 if not os.path.isabs(FdfFilename):\r
05cc51ad 117 FdfFilename = mws.join(GenFdsGlobalVariable.WorkSpaceDir, FdfFilename)\r
f51461c8
LG
118 if not os.path.exists(FdfFilename):\r
119 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=FdfFilename)\r
f51461c8
LG
120\r
121 GenFdsGlobalVariable.FdfFile = FdfFilename\r
122 GenFdsGlobalVariable.FdfFileTimeStamp = os.path.getmtime(FdfFilename)\r
123 else:\r
124 EdkLogger.error("GenFds", OPTION_MISSING, "Missing FDF filename")\r
125\r
126 if (Options.BuildTarget):\r
127 GenFdsGlobalVariable.TargetName = Options.BuildTarget\r
f51461c8
LG
128\r
129 if (Options.ToolChain):\r
130 GenFdsGlobalVariable.ToolChainTag = Options.ToolChain\r
f51461c8
LG
131\r
132 if (Options.activePlatform):\r
133 ActivePlatform = Options.activePlatform\r
134 ActivePlatform = GenFdsGlobalVariable.ReplaceWorkspaceMacro(ActivePlatform)\r
135\r
136 if ActivePlatform[0:2] == '..':\r
137 ActivePlatform = os.path.realpath(ActivePlatform)\r
138\r
139 if not os.path.isabs (ActivePlatform):\r
05cc51ad 140 ActivePlatform = mws.join(GenFdsGlobalVariable.WorkSpaceDir, ActivePlatform)\r
f51461c8
LG
141\r
142 if not os.path.exists(ActivePlatform) :\r
143 EdkLogger.error("GenFds", FILE_NOT_FOUND, "ActivePlatform doesn't exist!")\r
f51461c8
LG
144 else:\r
145 EdkLogger.error("GenFds", OPTION_MISSING, "Missing active platform")\r
146\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
00bcb5c2
YZ
161 if "CONF_PATH" in os.environ.keys():\r
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
183 if ToolChainList == None or len(ToolChainList) == 0:\r
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
YZ
220 # Use the -t and -b option as gGlobalDefines's TOOLCHAIN and TARGET if they are not defined\r
221 if "TARGET" not in GlobalData.gGlobalDefines.keys():\r
222 GlobalData.gGlobalDefines["TARGET"] = GenFdsGlobalVariable.TargetName\r
223 if "TOOLCHAIN" not in GlobalData.gGlobalDefines.keys():\r
224 GlobalData.gGlobalDefines["TOOLCHAIN"] = GenFdsGlobalVariable.ToolChainTag\r
225 if "TOOL_CHAIN_TAG" not in GlobalData.gGlobalDefines.keys():\r
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
LG
231 BuildWorkSpace.InitDatabase()\r
232 \r
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
243 ArchList = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON', Options.BuildTarget, Options.ToolChain].SupArchList\r
244\r
245 TargetArchList = set(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON', Options.BuildTarget, Options.ToolChain].SupArchList) & set(ArchList)\r
246 if len(TargetArchList) == 0:\r
247 EdkLogger.error("GenFds", GENFDS_ERROR, "Target ARCH %s not in platform supported ARCH %s" % (str(ArchList), str(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON'].SupArchList)))\r
248 \r
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
283 if Options.uiFdName.upper() in FdfParserObj.Profile.FdDict.keys():\r
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
290 if Options.uiFvName.upper() in FdfParserObj.Profile.FvDict.keys():\r
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
297 if Options.uiCapName.upper() in FdfParserObj.Profile.CapsuleDict.keys():\r
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
YZ
303 GenFdsGlobalVariable.WorkSpace = BuildWorkSpace\r
304 if ArchList != None:\r
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
320 if RegionObj.RegionType != 'FV':\r
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
0a57a978 331 GlobalData.BuildOptionPcd = Options.OptionPcd if Options.OptionPcd else {}\r
f51461c8
LG
332 """Call GenFds"""\r
333 GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList)\r
334\r
335 """Generate GUID cross reference file"""\r
5e9256cd 336 GenFds.GenerateGuidXRefFile(BuildWorkSpace, ArchList, FdfParserObj)\r
f51461c8
LG
337\r
338 """Display FV space info."""\r
339 GenFds.DisplayFvSpaceInfo(FdfParserObj)\r
340\r
341 except FdfParser.Warning, X:\r
47fea6af 342 EdkLogger.error(X.ToolName, FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError=False)\r
f51461c8
LG
343 ReturnCode = FORMAT_INVALID\r
344 except FatalError, X:\r
345 if Options.debug != None:\r
346 import traceback\r
347 EdkLogger.quiet(traceback.format_exc())\r
348 ReturnCode = X.args[0]\r
349 except:\r
350 import traceback\r
351 EdkLogger.error(\r
352 "\nPython",\r
353 CODE_ERROR,\r
354 "Tools code failure",\r
3a0f8bde 355 ExtraData="Please send email to edk2-devel@lists.01.org for help, attaching following call stack trace!\n",\r
f51461c8
LG
356 RaiseError=False\r
357 )\r
358 EdkLogger.quiet(traceback.format_exc())\r
359 ReturnCode = CODE_ERROR\r
97fa0ee9
YL
360 finally:\r
361 ClearDuplicatedInf()\r
f51461c8
LG
362 return ReturnCode\r
363\r
364gParamCheck = []\r
365def SingleCheckCallback(option, opt_str, value, parser):\r
366 if option not in gParamCheck:\r
367 setattr(parser.values, option.dest, value)\r
368 gParamCheck.append(option)\r
369 else:\r
370 parser.error("Option %s only allows one instance in command line!" % option)\r
6b17c11b
YZ
371\r
372def CheckBuildOptionPcd():\r
373 for Arch in GenFdsGlobalVariable.ArchList:\r
374 PkgList = GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag)\r
375 for i, pcd in enumerate(GlobalData.BuildOptionPcd):\r
376 if type(pcd) is tuple:\r
377 continue\r
378 (pcdname, pcdvalue) = pcd.split('=')\r
379 if not pcdvalue:\r
380 EdkLogger.error('GenFds', OPTION_MISSING, "No Value specified for the PCD %s." % (pcdname))\r
381 if '.' in pcdname:\r
382 (TokenSpaceGuidCName, TokenCName) = pcdname.split('.')\r
383 HasTokenSpace = True\r
384 else:\r
385 TokenCName = pcdname\r
386 TokenSpaceGuidCName = ''\r
387 HasTokenSpace = False\r
388 TokenSpaceGuidCNameList = []\r
389 FoundFlag = False\r
390 PcdDatumType = ''\r
391 NewValue = ''\r
392 for package in PkgList:\r
393 for key in package.Pcds:\r
394 PcdItem = package.Pcds[key]\r
395 if HasTokenSpace:\r
396 if (PcdItem.TokenCName, PcdItem.TokenSpaceGuidCName) == (TokenCName, TokenSpaceGuidCName):\r
397 PcdDatumType = PcdItem.DatumType\r
398 NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)\r
399 FoundFlag = True\r
400 else:\r
401 if PcdItem.TokenCName == TokenCName:\r
402 if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:\r
403 if len (TokenSpaceGuidCNameList) < 1:\r
404 TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)\r
405 PcdDatumType = PcdItem.DatumType\r
406 TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName\r
407 NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)\r
408 FoundFlag = True\r
409 else:\r
410 EdkLogger.error(\r
411 'GenFds',\r
412 PCD_VALIDATION_INFO_ERROR,\r
413 "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (TokenCName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])\r
414 )\r
415\r
416 GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, NewValue)\r
417\r
6b17c11b 418\r
91ae2988
YZ
419## FindExtendTool()\r
420#\r
421# Find location of tools to process data\r
422#\r
423# @param KeyStringList Filter for inputs of section generation\r
424# @param CurrentArchList Arch list\r
425# @param NameGuid The Guid name\r
426#\r
427def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):\r
95816356 428 ToolDb = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDatabase\r
91ae2988
YZ
429 # if user not specify filter, try to deduce it from global data.\r
430 if KeyStringList == None or KeyStringList == []:\r
431 Target = GenFdsGlobalVariable.TargetName\r
432 ToolChain = GenFdsGlobalVariable.ToolChainTag\r
91ae2988
YZ
433 if ToolChain not in ToolDb['TOOL_CHAIN_TAG']:\r
434 EdkLogger.error("GenFds", GENFDS_ERROR, "Can not find external tool because tool tag %s is not defined in tools_def.txt!" % ToolChain)\r
435 KeyStringList = [Target + '_' + ToolChain + '_' + CurrentArchList[0]]\r
436 for Arch in CurrentArchList:\r
437 if Target + '_' + ToolChain + '_' + Arch not in KeyStringList:\r
438 KeyStringList.append(Target + '_' + ToolChain + '_' + Arch)\r
439\r
440 if GenFdsGlobalVariable.GuidToolDefinition:\r
441 if NameGuid in GenFdsGlobalVariable.GuidToolDefinition.keys():\r
442 return GenFdsGlobalVariable.GuidToolDefinition[NameGuid]\r
443\r
444 ToolDefinition = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDictionary\r
445 ToolPathTmp = None\r
446 ToolOption = None\r
95816356
YZ
447 ToolPathKey = None\r
448 ToolOptionKey = None\r
449 KeyList = None\r
91ae2988
YZ
450 for ToolDef in ToolDefinition.items():\r
451 if NameGuid == ToolDef[1]:\r
452 KeyList = ToolDef[0].split('_')\r
453 Key = KeyList[0] + \\r
454 '_' + \\r
455 KeyList[1] + \\r
456 '_' + \\r
457 KeyList[2]\r
458 if Key in KeyStringList and KeyList[4] == 'GUID':\r
95816356
YZ
459 ToolPathKey = Key + '_' + KeyList[3] + '_PATH'\r
460 ToolOptionKey = Key + '_' + KeyList[3] + '_FLAGS'\r
461 ToolPath = ToolDefinition.get(ToolPathKey)\r
462 ToolOption = ToolDefinition.get(ToolOptionKey)\r
91ae2988
YZ
463 if ToolPathTmp == None:\r
464 ToolPathTmp = ToolPath\r
465 else:\r
466 if ToolPathTmp != ToolPath:\r
467 EdkLogger.error("GenFds", GENFDS_ERROR, "Don't know which tool to use, %s or %s ?" % (ToolPathTmp, ToolPath))\r
468\r
95816356
YZ
469 BuildOption = {}\r
470 for Arch in CurrentArchList:\r
471 Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
472 # key is (ToolChainFamily, ToolChain, CodeBase)\r
473 for item in Platform.BuildOptions:\r
474 if '_PATH' in item[1] or '_FLAGS' in item[1] or '_GUID' in item[1]:\r
475 if not item[0] or (item[0] and GenFdsGlobalVariable.ToolChainFamily== item[0]):\r
476 if item[1] not in BuildOption:\r
477 BuildOption[item[1]] = Platform.BuildOptions[item]\r
478 if BuildOption:\r
479 ToolList = [TAB_TOD_DEFINES_TARGET, TAB_TOD_DEFINES_TOOL_CHAIN_TAG, TAB_TOD_DEFINES_TARGET_ARCH]\r
480 for Index in range(2, -1, -1):\r
481 for Key in dict(BuildOption):\r
482 List = Key.split('_')\r
483 if List[Index] == '*':\r
484 for String in ToolDb[ToolList[Index]]:\r
485 if String in [Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]:\r
486 List[Index] = String\r
487 NewKey = '%s_%s_%s_%s_%s' % tuple(List)\r
488 if NewKey not in BuildOption:\r
489 BuildOption[NewKey] = BuildOption[Key]\r
490 continue\r
491 del BuildOption[Key]\r
492 elif List[Index] not in ToolDb[ToolList[Index]]:\r
493 del BuildOption[Key]\r
494 if BuildOption:\r
495 if not KeyList:\r
496 for Op in BuildOption:\r
497 if NameGuid == BuildOption[Op]:\r
498 KeyList = Op.split('_')\r
499 Key = KeyList[0] + '_' + KeyList[1] +'_' + KeyList[2]\r
500 if Key in KeyStringList and KeyList[4] == 'GUID':\r
501 ToolPathKey = Key + '_' + KeyList[3] + '_PATH'\r
502 ToolOptionKey = Key + '_' + KeyList[3] + '_FLAGS'\r
503 if ToolPathKey in BuildOption.keys():\r
504 ToolPathTmp = BuildOption.get(ToolPathKey)\r
505 if ToolOptionKey in BuildOption.keys():\r
506 ToolOption = BuildOption.get(ToolOptionKey)\r
507\r
91ae2988
YZ
508 GenFdsGlobalVariable.GuidToolDefinition[NameGuid] = (ToolPathTmp, ToolOption)\r
509 return ToolPathTmp, ToolOption\r
510\r
f51461c8
LG
511## Parse command line options\r
512#\r
513# Using standard Python module optparse to parse command line option of this tool.\r
514#\r
515# @retval Opt A optparse.Values object containing the parsed options\r
516# @retval Args Target of build command\r
517#\r
518def myOptionParser():\r
519 usage = "%prog [options] -f input_file -a arch_list -b build_target -p active_platform -t tool_chain_tag -D \"MacroName [= MacroValue]\""\r
47fea6af 520 Parser = OptionParser(usage=usage, description=__copyright__, version="%prog " + str(versionNumber))\r
f51461c8
LG
521 Parser.add_option("-f", "--file", dest="filename", type="string", help="Name of FDF file to convert", action="callback", callback=SingleCheckCallback)\r
522 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
523 Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")\r
524 Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed.")\r
525 Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")\r
526 Parser.add_option("-p", "--platform", type="string", dest="activePlatform", help="Set the ACTIVE_PLATFORM, overrides target.txt ACTIVE_PLATFORM setting.",\r
527 action="callback", callback=SingleCheckCallback)\r
528 Parser.add_option("-w", "--workspace", type="string", dest="Workspace", default=os.environ.get('WORKSPACE'), help="Set the WORKSPACE",\r
529 action="callback", callback=SingleCheckCallback)\r
530 Parser.add_option("-o", "--outputDir", type="string", dest="outputDir", help="Name of Build Output directory",\r
531 action="callback", callback=SingleCheckCallback)\r
532 Parser.add_option("-r", "--rom_image", dest="uiFdName", help="Build the image using the [FD] section named by FdUiName.")\r
533 Parser.add_option("-i", "--FvImage", dest="uiFvName", help="Build the FV image using the [FV] section named by UiFvName")\r
534 Parser.add_option("-C", "--CapsuleImage", dest="uiCapName", help="Build the Capsule image using the [Capsule] section named by UiCapName")\r
535 Parser.add_option("-b", "--buildtarget", type="string", dest="BuildTarget", help="Set the build TARGET, overrides target.txt TARGET setting.",\r
536 action="callback", callback=SingleCheckCallback)\r
537 Parser.add_option("-t", "--tagname", type="string", dest="ToolChain", help="Using the tools: TOOL_CHAIN_TAG name to build the platform.",\r
538 action="callback", callback=SingleCheckCallback)\r
539 Parser.add_option("-D", "--define", action="append", type="string", dest="Macros", help="Macro: \"Name [= Value]\".")\r
540 Parser.add_option("-s", "--specifyaddress", dest="FixedAddress", action="store_true", type=None, help="Specify driver load address.")\r
97fa0ee9
YL
541 Parser.add_option("--conf", action="store", type="string", dest="ConfDirectory", help="Specify the customized Conf directory.")\r
542 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 543 Parser.add_option("--pcd", action="append", dest="OptionPcd", help="Set PCD value by command line. Format: \"PcdName=Value\" ")\r
37de70b7 544 Parser.add_option("--genfds-multi-thread", action="store_true", dest="GenfdsMultiThread", default=False, help="Enable GenFds multi thread to generate ffs file.")\r
97fa0ee9 545\r
f51461c8
LG
546 (Options, args) = Parser.parse_args()\r
547 return Options\r
548\r
549## The class implementing the EDK2 flash image generation process\r
550#\r
551# This process includes:\r
552# 1. Collect workspace information, includes platform and module information\r
553# 2. Call methods of Fd class to generate FD\r
554# 3. Call methods of Fv class to generate FV that not belong to FD\r
555#\r
556class GenFds :\r
557 FdfParsef = None\r
558 # FvName, FdName, CapName in FDF, Image file name\r
559 ImageBinDict = {}\r
560 OnlyGenerateThisFd = None\r
561 OnlyGenerateThisFv = None\r
562 OnlyGenerateThisCap = None\r
563\r
564 ## GenFd()\r
565 #\r
566 # @param OutputDir Output directory\r
567 # @param FdfParser FDF contents parser\r
568 # @param Workspace The directory of workspace\r
569 # @param ArchList The Arch list of platform\r
570 #\r
571 def GenFd (OutputDir, FdfParser, WorkSpace, ArchList):\r
572 GenFdsGlobalVariable.SetDir ('', FdfParser, WorkSpace, ArchList)\r
573\r
574 GenFdsGlobalVariable.VerboseLogger(" Generate all Fd images and their required FV and Capsule images!")\r
575 if GenFds.OnlyGenerateThisCap != None and GenFds.OnlyGenerateThisCap.upper() in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.keys():\r
576 CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.get(GenFds.OnlyGenerateThisCap.upper())\r
577 if CapsuleObj != None:\r
578 CapsuleObj.GenCapsule()\r
579 return\r
580\r
581 if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
582 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(GenFds.OnlyGenerateThisFd.upper())\r
583 if FdObj != None:\r
584 FdObj.GenFd()\r
585 return\r
586 elif GenFds.OnlyGenerateThisFd == None and GenFds.OnlyGenerateThisFv == None:\r
587 for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
588 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName]\r
589 FdObj.GenFd()\r
590\r
591 GenFdsGlobalVariable.VerboseLogger("\n Generate other FV images! ")\r
592 if GenFds.OnlyGenerateThisFv != None and GenFds.OnlyGenerateThisFv.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():\r
593 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(GenFds.OnlyGenerateThisFv.upper())\r
594 if FvObj != None:\r
595 Buffer = StringIO.StringIO()\r
596 FvObj.AddToBuffer(Buffer)\r
597 Buffer.close()\r
598 return\r
599 elif GenFds.OnlyGenerateThisFv == None:\r
600 for FvName in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():\r
601 Buffer = StringIO.StringIO('')\r
602 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[FvName]\r
603 FvObj.AddToBuffer(Buffer)\r
604 Buffer.close()\r
605 \r
606 if GenFds.OnlyGenerateThisFv == None and GenFds.OnlyGenerateThisFd == None and GenFds.OnlyGenerateThisCap == None:\r
607 if GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict != {}:\r
608 GenFdsGlobalVariable.VerboseLogger("\n Generate other Capsule images!")\r
609 for CapsuleName in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.keys():\r
610 CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict[CapsuleName]\r
611 CapsuleObj.GenCapsule()\r
612\r
613 if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:\r
614 GenFdsGlobalVariable.VerboseLogger("\n Generate all Option ROM!")\r
615 for DriverName in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.keys():\r
616 OptRomObj = GenFdsGlobalVariable.FdfParser.Profile.OptRomDict[DriverName]\r
617 OptRomObj.AddToBuffer(None)\r
37de70b7
YZ
618 @staticmethod\r
619 def GenFfsMakefile(OutputDir, FdfParser, WorkSpace, ArchList, GlobalData):\r
620 GenFdsGlobalVariable.SetEnv(FdfParser, WorkSpace, ArchList, GlobalData)\r
621 for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
622 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName]\r
623 FdObj.GenFd(Flag=True)\r
624\r
625 for FvName in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():\r
626 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[FvName]\r
627 FvObj.AddToBuffer(Buffer=None, Flag=True)\r
628\r
629 if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:\r
630 for DriverName in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.keys():\r
631 OptRomObj = GenFdsGlobalVariable.FdfParser.Profile.OptRomDict[DriverName]\r
632 OptRomObj.AddToBuffer(Buffer=None, Flag=True)\r
633\r
634 return GenFdsGlobalVariable.FfsCmdDict\r
f51461c8
LG
635\r
636 ## GetFvBlockSize()\r
637 #\r
638 # @param FvObj Whose block size to get\r
639 # @retval int Block size value\r
640 #\r
641 def GetFvBlockSize(FvObj):\r
642 DefaultBlockSize = 0x1\r
643 FdObj = None\r
644 if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
645 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()]\r
646 if FdObj == None:\r
647 for ElementFd in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():\r
648 for ElementRegion in ElementFd.RegionList:\r
649 if ElementRegion.RegionType == 'FV':\r
650 for ElementRegionData in ElementRegion.RegionDataList:\r
651 if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName:\r
652 if FvObj.BlockSizeList != []:\r
653 return FvObj.BlockSizeList[0][0]\r
654 else:\r
655 return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)\r
656 if FvObj.BlockSizeList != []:\r
657 return FvObj.BlockSizeList[0][0]\r
658 return DefaultBlockSize\r
659 else:\r
660 for ElementRegion in FdObj.RegionList:\r
661 if ElementRegion.RegionType == 'FV':\r
662 for ElementRegionData in ElementRegion.RegionDataList:\r
663 if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName:\r
664 if FvObj.BlockSizeList != []:\r
665 return FvObj.BlockSizeList[0][0]\r
666 else:\r
667 return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)\r
668 return DefaultBlockSize\r
669\r
670 ## DisplayFvSpaceInfo()\r
671 #\r
672 # @param FvObj Whose block size to get\r
673 # @retval None\r
674 #\r
675 def DisplayFvSpaceInfo(FdfParser):\r
676 \r
677 FvSpaceInfoList = []\r
678 MaxFvNameLength = 0\r
679 for FvName in FdfParser.Profile.FvDict:\r
680 if len(FvName) > MaxFvNameLength:\r
681 MaxFvNameLength = len(FvName)\r
682 FvSpaceInfoFileName = os.path.join(GenFdsGlobalVariable.FvDir, FvName.upper() + '.Fv.map')\r
683 if os.path.exists(FvSpaceInfoFileName):\r
684 FileLinesList = linecache.getlines(FvSpaceInfoFileName)\r
685 TotalFound = False\r
686 Total = ''\r
687 UsedFound = False\r
688 Used = ''\r
689 FreeFound = False\r
690 Free = ''\r
691 for Line in FileLinesList:\r
692 NameValue = Line.split('=')\r
693 if len(NameValue) == 2:\r
694 if NameValue[0].strip() == 'EFI_FV_TOTAL_SIZE':\r
695 TotalFound = True\r
696 Total = NameValue[1].strip()\r
697 if NameValue[0].strip() == 'EFI_FV_TAKEN_SIZE':\r
698 UsedFound = True\r
699 Used = NameValue[1].strip()\r
700 if NameValue[0].strip() == 'EFI_FV_SPACE_SIZE':\r
701 FreeFound = True\r
702 Free = NameValue[1].strip()\r
703 \r
704 if TotalFound and UsedFound and FreeFound:\r
705 FvSpaceInfoList.append((FvName, Total, Used, Free))\r
706 \r
707 GenFdsGlobalVariable.InfLogger('\nFV Space Information')\r
708 for FvSpaceInfo in FvSpaceInfoList:\r
709 Name = FvSpaceInfo[0]\r
710 TotalSizeValue = long(FvSpaceInfo[1], 0)\r
711 UsedSizeValue = long(FvSpaceInfo[2], 0)\r
712 FreeSizeValue = long(FvSpaceInfo[3], 0)\r
713 if UsedSizeValue == TotalSizeValue:\r
714 Percentage = '100'\r
715 else:\r
47fea6af
YZ
716 Percentage = str((UsedSizeValue + 0.0) / TotalSizeValue)[0:4].lstrip('0.')\r
717\r
f51461c8
LG
718 GenFdsGlobalVariable.InfLogger(Name + ' ' + '[' + Percentage + '%Full] ' + str(TotalSizeValue) + ' total, ' + str(UsedSizeValue) + ' used, ' + str(FreeSizeValue) + ' free')\r
719\r
720 ## PreprocessImage()\r
721 #\r
722 # @param BuildDb Database from build meta data files\r
723 # @param DscFile modules from dsc file will be preprocessed\r
724 # @retval None\r
725 #\r
726 def PreprocessImage(BuildDb, DscFile):\r
727 PcdDict = BuildDb.BuildObject[DscFile, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Pcds\r
728 PcdValue = ''\r
729 for Key in PcdDict:\r
730 PcdObj = PcdDict[Key]\r
731 if PcdObj.TokenCName == 'PcdBsBaseAddress':\r
732 PcdValue = PcdObj.DefaultValue\r
733 break\r
734 \r
735 if PcdValue == '':\r
736 return\r
737 \r
738 Int64PcdValue = long(PcdValue, 0)\r
739 if Int64PcdValue == 0 or Int64PcdValue < -1: \r
740 return\r
741 \r
742 TopAddress = 0\r
743 if Int64PcdValue > 0:\r
744 TopAddress = Int64PcdValue\r
745 \r
746 ModuleDict = BuildDb.BuildObject[DscFile, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Modules\r
747 for Key in ModuleDict:\r
748 ModuleObj = BuildDb.BuildObject[Key, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
749 print ModuleObj.BaseName + ' ' + ModuleObj.ModuleType\r
750\r
5e9256cd 751 def GenerateGuidXRefFile(BuildDb, ArchList, FdfParserObj):\r
f51461c8
LG
752 GuidXRefFileName = os.path.join(GenFdsGlobalVariable.FvDir, "Guid.xref")\r
753 GuidXRefFile = StringIO.StringIO('')\r
e4ac870f 754 GuidDict = {}\r
5e9256cd
YZ
755 ModuleList = []\r
756 FileGuidList = []\r
f51461c8
LG
757 for Arch in ArchList:\r
758 PlatformDataBase = BuildDb.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
759 for ModuleFile in PlatformDataBase.Modules:\r
760 Module = BuildDb.BuildObject[ModuleFile, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
5e9256cd
YZ
761 if Module in ModuleList:\r
762 continue\r
763 else:\r
764 ModuleList.append(Module)\r
f51461c8 765 GuidXRefFile.write("%s %s\n" % (Module.Guid, Module.BaseName))\r
e4ac870f
LG
766 for key, item in Module.Protocols.items():\r
767 GuidDict[key] = item\r
768 for key, item in Module.Guids.items():\r
769 GuidDict[key] = item\r
770 for key, item in Module.Ppis.items():\r
771 GuidDict[key] = item\r
5e9256cd
YZ
772 for FvName in FdfParserObj.Profile.FvDict:\r
773 for FfsObj in FdfParserObj.Profile.FvDict[FvName].FfsList:\r
774 if not isinstance(FfsObj, FfsFileStatement.FileStatement):\r
775 InfPath = PathClass(NormPath(mws.join(GenFdsGlobalVariable.WorkSpaceDir, FfsObj.InfFileName)))\r
776 FdfModule = BuildDb.BuildObject[InfPath, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
777 if FdfModule in ModuleList:\r
778 continue\r
779 else:\r
780 ModuleList.append(FdfModule)\r
781 GuidXRefFile.write("%s %s\n" % (FdfModule.Guid, FdfModule.BaseName))\r
782 for key, item in FdfModule.Protocols.items():\r
783 GuidDict[key] = item\r
784 for key, item in FdfModule.Guids.items():\r
785 GuidDict[key] = item\r
786 for key, item in FdfModule.Ppis.items():\r
787 GuidDict[key] = item\r
788 else:\r
789 FileStatementGuid = FfsObj.NameGuid\r
790 if FileStatementGuid in FileGuidList:\r
791 continue\r
792 else:\r
793 FileGuidList.append(FileStatementGuid)\r
794 Name = []\r
795 FfsPath = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')\r
796 FfsPath = glob.glob(os.path.join(FfsPath, FileStatementGuid) + '*')\r
797 if not FfsPath:\r
798 continue\r
799 if not os.path.exists(FfsPath[0]):\r
800 continue\r
801 MatchDict = {}\r
802 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
803 FileList = os.listdir(FfsPath[0])\r
804 for File in FileList:\r
805 Match = ReFileEnds.search(File)\r
806 if Match:\r
807 for Index in range(1, 8):\r
808 if Match.group(Index) and Match.group(Index) in MatchDict:\r
809 MatchDict[Match.group(Index)].append(File)\r
810 elif Match.group(Index):\r
811 MatchDict[Match.group(Index)] = [File]\r
812 if not MatchDict:\r
813 continue\r
814 if '.ui' in MatchDict:\r
815 for File in MatchDict['.ui']:\r
816 with open(os.path.join(FfsPath[0], File), 'rb') as F:\r
817 F.read()\r
818 length = F.tell()\r
819 F.seek(4)\r
820 TmpStr = unpack('%dh' % ((length - 4) / 2), F.read())\r
821 Name = ''.join([chr(c) for c in TmpStr[:-1]])\r
822 else:\r
823 FileList = []\r
824 if 'fv.sec.txt' in MatchDict:\r
825 FileList = MatchDict['fv.sec.txt']\r
826 elif '.pe32.txt' in MatchDict:\r
827 FileList = MatchDict['.pe32.txt']\r
828 elif '.te.txt' in MatchDict:\r
829 FileList = MatchDict['.te.txt']\r
830 elif '.pic.txt' in MatchDict:\r
831 FileList = MatchDict['.pic.txt']\r
832 elif '.raw.txt' in MatchDict:\r
833 FileList = MatchDict['.raw.txt']\r
834 elif '.ffs.txt' in MatchDict:\r
835 FileList = MatchDict['.ffs.txt']\r
836 else:\r
837 pass\r
838 for File in FileList:\r
839 with open(os.path.join(FfsPath[0], File), 'r') as F:\r
840 Name.append((F.read().split()[-1]))\r
841 if not Name:\r
842 continue\r
843\r
844 Name = ' '.join(Name) if type(Name) == type([]) else Name\r
845 GuidXRefFile.write("%s %s\n" %(FileStatementGuid, Name))\r
846\r
e4ac870f
LG
847 # Append GUIDs, Protocols, and PPIs to the Xref file\r
848 GuidXRefFile.write("\n")\r
849 for key, item in GuidDict.items():\r
850 GuidXRefFile.write("%s %s\n" % (GuidStructureStringToGuidString(item).upper(), key))\r
851\r
f51461c8
LG
852 if GuidXRefFile.getvalue():\r
853 SaveFileOnChange(GuidXRefFileName, GuidXRefFile.getvalue(), False)\r
854 GenFdsGlobalVariable.InfLogger("\nGUID cross reference file can be found at %s" % GuidXRefFileName)\r
855 elif os.path.exists(GuidXRefFileName):\r
856 os.remove(GuidXRefFileName)\r
857 GuidXRefFile.close()\r
858\r
859 ##Define GenFd as static function\r
860 GenFd = staticmethod(GenFd)\r
861 GetFvBlockSize = staticmethod(GetFvBlockSize)\r
862 DisplayFvSpaceInfo = staticmethod(DisplayFvSpaceInfo)\r
863 PreprocessImage = staticmethod(PreprocessImage)\r
864 GenerateGuidXRefFile = staticmethod(GenerateGuidXRefFile)\r
865\r
866if __name__ == '__main__':\r
867 r = main()\r
868 ## 0-127 is a safe return range, and 1 is a standard default error\r
869 if r < 0 or r > 127: r = 1\r
870 sys.exit(r)\r
871\r