]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/GenFds/GenFds.py
NetworkPkg/IpSecDxe: Fix wrong IKE header "FLAG" update
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / GenFds.py
CommitLineData
f51461c8
LG
1## @file\r
2# generate flash image\r
3#\r
3a0f8bde 4# Copyright (c) 2007 - 2016, 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
33import Common.DataType\r
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
f51461c8 42from Common.BuildVersion import gBUILD_VERSION\r
05cc51ad 43from Common.MultipleWorkspace import MultipleWorkspace as mws\r
f51461c8
LG
44\r
45## Version and Copyright\r
46versionNumber = "1.0" + ' ' + gBUILD_VERSION\r
47__version__ = "%prog Version " + versionNumber\r
6b17c11b 48__copyright__ = "Copyright (c) 2007 - 2016, Intel Corporation All rights reserved."\r
f51461c8
LG
49\r
50## Tool entrance method\r
51#\r
52# This method mainly dispatch specific methods per the command line options.\r
53# If no error found, return zero value so the caller of this tool can know\r
54# if it's executed successfully or not.\r
55#\r
56# @retval 0 Tool was successful\r
57# @retval 1 Tool failed\r
58#\r
59def main():\r
60 global Options\r
61 Options = myOptionParser()\r
62\r
63 global Workspace\r
64 Workspace = ""\r
65 ArchList = None\r
66 ReturnCode = 0\r
67\r
68 EdkLogger.Initialize()\r
69 try:\r
70 if Options.verbose != None:\r
71 EdkLogger.SetLevel(EdkLogger.VERBOSE)\r
72 GenFdsGlobalVariable.VerboseMode = True\r
73 \r
74 if Options.FixedAddress != None:\r
75 GenFdsGlobalVariable.FixedLoadAddress = True\r
76 \r
77 if Options.quiet != None:\r
78 EdkLogger.SetLevel(EdkLogger.QUIET)\r
79 if Options.debug != None:\r
80 EdkLogger.SetLevel(Options.debug + 1)\r
81 GenFdsGlobalVariable.DebugLevel = Options.debug\r
82 else:\r
83 EdkLogger.SetLevel(EdkLogger.INFO)\r
84\r
85 if (Options.Workspace == None):\r
86 EdkLogger.error("GenFds", OPTION_MISSING, "WORKSPACE not defined",\r
87 ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")\r
88 elif not os.path.exists(Options.Workspace):\r
89 EdkLogger.error("GenFds", PARAMETER_INVALID, "WORKSPACE is invalid",\r
90 ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")\r
91 else:\r
92 Workspace = os.path.normcase(Options.Workspace)\r
93 GenFdsGlobalVariable.WorkSpaceDir = Workspace\r
94 if 'EDK_SOURCE' in os.environ.keys():\r
95 GenFdsGlobalVariable.EdkSourceDir = os.path.normcase(os.environ['EDK_SOURCE'])\r
96 if (Options.debug):\r
47fea6af 97 GenFdsGlobalVariable.VerboseLogger("Using Workspace:" + Workspace)\r
f51461c8 98 os.chdir(GenFdsGlobalVariable.WorkSpaceDir)\r
05cc51ad
LY
99 \r
100 # set multiple workspace\r
101 PackagesPath = os.getenv("PACKAGES_PATH")\r
102 mws.setWs(GenFdsGlobalVariable.WorkSpaceDir, PackagesPath)\r
f51461c8
LG
103\r
104 if (Options.filename):\r
105 FdfFilename = Options.filename\r
106 FdfFilename = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdfFilename)\r
107\r
108 if FdfFilename[0:2] == '..':\r
109 FdfFilename = os.path.realpath(FdfFilename)\r
47fea6af 110 if not os.path.isabs(FdfFilename):\r
05cc51ad 111 FdfFilename = mws.join(GenFdsGlobalVariable.WorkSpaceDir, FdfFilename)\r
f51461c8
LG
112 if not os.path.exists(FdfFilename):\r
113 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=FdfFilename)\r
f51461c8
LG
114\r
115 GenFdsGlobalVariable.FdfFile = FdfFilename\r
116 GenFdsGlobalVariable.FdfFileTimeStamp = os.path.getmtime(FdfFilename)\r
117 else:\r
118 EdkLogger.error("GenFds", OPTION_MISSING, "Missing FDF filename")\r
119\r
120 if (Options.BuildTarget):\r
121 GenFdsGlobalVariable.TargetName = Options.BuildTarget\r
f51461c8
LG
122\r
123 if (Options.ToolChain):\r
124 GenFdsGlobalVariable.ToolChainTag = Options.ToolChain\r
f51461c8
LG
125\r
126 if (Options.activePlatform):\r
127 ActivePlatform = Options.activePlatform\r
128 ActivePlatform = GenFdsGlobalVariable.ReplaceWorkspaceMacro(ActivePlatform)\r
129\r
130 if ActivePlatform[0:2] == '..':\r
131 ActivePlatform = os.path.realpath(ActivePlatform)\r
132\r
133 if not os.path.isabs (ActivePlatform):\r
05cc51ad 134 ActivePlatform = mws.join(GenFdsGlobalVariable.WorkSpaceDir, ActivePlatform)\r
f51461c8
LG
135\r
136 if not os.path.exists(ActivePlatform) :\r
137 EdkLogger.error("GenFds", FILE_NOT_FOUND, "ActivePlatform doesn't exist!")\r
f51461c8
LG
138 else:\r
139 EdkLogger.error("GenFds", OPTION_MISSING, "Missing active platform")\r
140\r
e642ceb8 141 GenFdsGlobalVariable.ActivePlatform = PathClass(NormPath(ActivePlatform))\r
f51461c8 142\r
97fa0ee9
YL
143 if (Options.ConfDirectory):\r
144 # Get alternate Conf location, if it is absolute, then just use the absolute directory name\r
145 ConfDirectoryPath = os.path.normpath(Options.ConfDirectory)\r
146 if ConfDirectoryPath.startswith('"'):\r
147 ConfDirectoryPath = ConfDirectoryPath[1:]\r
148 if ConfDirectoryPath.endswith('"'):\r
149 ConfDirectoryPath = ConfDirectoryPath[:-1]\r
150 if not os.path.isabs(ConfDirectoryPath):\r
151 # Since alternate directory name is not absolute, the alternate directory is located within the WORKSPACE\r
152 # This also handles someone specifying the Conf directory in the workspace. Using --conf=Conf\r
153 ConfDirectoryPath = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, ConfDirectoryPath)\r
154 else:\r
155 # Get standard WORKSPACE/Conf, use the absolute path to the WORKSPACE/Conf\r
05cc51ad 156 ConfDirectoryPath = mws.join(GenFdsGlobalVariable.WorkSpaceDir, 'Conf')\r
97fa0ee9
YL
157 GenFdsGlobalVariable.ConfDir = ConfDirectoryPath\r
158 BuildConfigurationFile = os.path.normpath(os.path.join(ConfDirectoryPath, "target.txt"))\r
f51461c8 159 if os.path.isfile(BuildConfigurationFile) == True:\r
e4979bee
YZ
160 TargetTxt = TargetTxtClassObject.TargetTxtClassObject()\r
161 TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)\r
162 # if no build target given in command line, get it from target.txt\r
163 if not GenFdsGlobalVariable.TargetName:\r
164 BuildTargetList = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TARGET]\r
165 if len(BuildTargetList) != 1:\r
166 EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="Only allows one instance for Target.")\r
167 GenFdsGlobalVariable.TargetName = BuildTargetList[0]\r
168\r
169 # if no tool chain given in command line, get it from target.txt\r
170 if not GenFdsGlobalVariable.ToolChainTag:\r
171 ToolChainList = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_TAG]\r
172 if ToolChainList == None or len(ToolChainList) == 0:\r
173 EdkLogger.error("GenFds", RESOURCE_NOT_AVAILABLE, ExtraData="No toolchain given. Don't know how to build.")\r
174 if len(ToolChainList) != 1:\r
175 EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="Only allows one instance for ToolChain.")\r
176 GenFdsGlobalVariable.ToolChainTag = ToolChainList[0]\r
f51461c8
LG
177 else:\r
178 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=BuildConfigurationFile)\r
179\r
97fa0ee9
YL
180 #Set global flag for build mode\r
181 GlobalData.gIgnoreSource = Options.IgnoreSources\r
182\r
f51461c8
LG
183 if Options.Macros:\r
184 for Pair in Options.Macros:\r
97fa0ee9
YL
185 if Pair.startswith('"'):\r
186 Pair = Pair[1:]\r
187 if Pair.endswith('"'):\r
188 Pair = Pair[:-1]\r
f51461c8
LG
189 List = Pair.split('=')\r
190 if len(List) == 2:\r
e4979bee
YZ
191 if not List[1].strip():\r
192 EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="No Value given for Macro %s" %List[0])\r
f51461c8
LG
193 if List[0].strip() == "EFI_SOURCE":\r
194 GlobalData.gEfiSource = List[1].strip()\r
195 GlobalData.gGlobalDefines["EFI_SOURCE"] = GlobalData.gEfiSource\r
196 continue\r
197 elif List[0].strip() == "EDK_SOURCE":\r
198 GlobalData.gEdkSource = List[1].strip()\r
199 GlobalData.gGlobalDefines["EDK_SOURCE"] = GlobalData.gEdkSource\r
200 continue\r
201 elif List[0].strip() in ["WORKSPACE", "TARGET", "TOOLCHAIN"]:\r
202 GlobalData.gGlobalDefines[List[0].strip()] = List[1].strip()\r
203 else:\r
204 GlobalData.gCommandLineDefines[List[0].strip()] = List[1].strip()\r
205 else:\r
206 GlobalData.gCommandLineDefines[List[0].strip()] = "TRUE"\r
207 os.environ["WORKSPACE"] = Workspace\r
208\r
e4979bee
YZ
209 # Use the -t and -b option as gGlobalDefines's TOOLCHAIN and TARGET if they are not defined\r
210 if "TARGET" not in GlobalData.gGlobalDefines.keys():\r
211 GlobalData.gGlobalDefines["TARGET"] = GenFdsGlobalVariable.TargetName\r
212 if "TOOLCHAIN" not in GlobalData.gGlobalDefines.keys():\r
213 GlobalData.gGlobalDefines["TOOLCHAIN"] = GenFdsGlobalVariable.ToolChainTag\r
214 if "TOOL_CHAIN_TAG" not in GlobalData.gGlobalDefines.keys():\r
215 GlobalData.gGlobalDefines['TOOL_CHAIN_TAG'] = GenFdsGlobalVariable.ToolChainTag\r
216\r
f51461c8 217 """call Workspace build create database"""\r
97fa0ee9
YL
218 GlobalData.gDatabasePath = os.path.normpath(os.path.join(ConfDirectoryPath, GlobalData.gDatabasePath))\r
219 BuildWorkSpace = WorkspaceDatabase(GlobalData.gDatabasePath)\r
f51461c8
LG
220 BuildWorkSpace.InitDatabase()\r
221 \r
222 #\r
223 # Get files real name in workspace dir\r
224 #\r
225 GlobalData.gAllFiles = DirCache(Workspace)\r
226 GlobalData.gWorkspace = Workspace\r
227\r
228 if (Options.archList) :\r
229 ArchList = Options.archList.split(',')\r
230 else:\r
231# EdkLogger.error("GenFds", OPTION_MISSING, "Missing build ARCH")\r
232 ArchList = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON', Options.BuildTarget, Options.ToolChain].SupArchList\r
233\r
234 TargetArchList = set(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON', Options.BuildTarget, Options.ToolChain].SupArchList) & set(ArchList)\r
235 if len(TargetArchList) == 0:\r
236 EdkLogger.error("GenFds", GENFDS_ERROR, "Target ARCH %s not in platform supported ARCH %s" % (str(ArchList), str(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON'].SupArchList)))\r
237 \r
238 for Arch in ArchList:\r
239 GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = NormPath(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, Options.BuildTarget, Options.ToolChain].OutputDirectory)\r
240 GenFdsGlobalVariable.PlatformName = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, Options.BuildTarget, Options.ToolChain].PlatformName\r
241\r
242 if (Options.outputDir):\r
243 OutputDirFromCommandLine = GenFdsGlobalVariable.ReplaceWorkspaceMacro(Options.outputDir)\r
244 if not os.path.isabs (OutputDirFromCommandLine):\r
245 OutputDirFromCommandLine = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, OutputDirFromCommandLine)\r
246 for Arch in ArchList:\r
247 GenFdsGlobalVariable.OutputDirDict[Arch] = OutputDirFromCommandLine\r
248 else:\r
249 for Arch in ArchList:\r
250 GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.join(GenFdsGlobalVariable.OutputDirFromDscDict[Arch], GenFdsGlobalVariable.TargetName + '_' + GenFdsGlobalVariable.ToolChainTag)\r
251\r
252 for Key in GenFdsGlobalVariable.OutputDirDict:\r
253 OutputDir = GenFdsGlobalVariable.OutputDirDict[Key]\r
254 if OutputDir[0:2] == '..':\r
255 OutputDir = os.path.realpath(OutputDir)\r
256\r
257 if OutputDir[1] != ':':\r
258 OutputDir = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, OutputDir)\r
259\r
260 if not os.path.exists(OutputDir):\r
261 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=OutputDir)\r
262 GenFdsGlobalVariable.OutputDirDict[Key] = OutputDir\r
263\r
264 """ Parse Fdf file, has to place after build Workspace as FDF may contain macros from DSC file """\r
265 FdfParserObj = FdfParser.FdfParser(FdfFilename)\r
266 FdfParserObj.ParseFile()\r
267\r
268 if FdfParserObj.CycleReferenceCheck():\r
269 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Cycle Reference Detected in FDF file")\r
270\r
271 if (Options.uiFdName) :\r
272 if Options.uiFdName.upper() in FdfParserObj.Profile.FdDict.keys():\r
273 GenFds.OnlyGenerateThisFd = Options.uiFdName\r
274 else:\r
275 EdkLogger.error("GenFds", OPTION_VALUE_INVALID,\r
276 "No such an FD in FDF file: %s" % Options.uiFdName)\r
277\r
278 if (Options.uiFvName) :\r
279 if Options.uiFvName.upper() in FdfParserObj.Profile.FvDict.keys():\r
280 GenFds.OnlyGenerateThisFv = Options.uiFvName\r
281 else:\r
282 EdkLogger.error("GenFds", OPTION_VALUE_INVALID,\r
283 "No such an FV in FDF file: %s" % Options.uiFvName)\r
284\r
285 if (Options.uiCapName) :\r
286 if Options.uiCapName.upper() in FdfParserObj.Profile.CapsuleDict.keys():\r
287 GenFds.OnlyGenerateThisCap = Options.uiCapName\r
288 else:\r
289 EdkLogger.error("GenFds", OPTION_VALUE_INVALID,\r
290 "No such a Capsule in FDF file: %s" % Options.uiCapName)\r
291\r
6b17c11b
YZ
292 GenFdsGlobalVariable.WorkSpace = BuildWorkSpace\r
293 if ArchList != None:\r
294 GenFdsGlobalVariable.ArchList = ArchList\r
295\r
296 if Options.OptionPcd:\r
297 GlobalData.BuildOptionPcd = Options.OptionPcd\r
298 CheckBuildOptionPcd()\r
299\r
f51461c8
LG
300 """Modify images from build output if the feature of loading driver at fixed address is on."""\r
301 if GenFdsGlobalVariable.FixedLoadAddress:\r
302 GenFds.PreprocessImage(BuildWorkSpace, GenFdsGlobalVariable.ActivePlatform)\r
303 """Call GenFds"""\r
304 GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList)\r
305\r
306 """Generate GUID cross reference file"""\r
307 GenFds.GenerateGuidXRefFile(BuildWorkSpace, ArchList)\r
308\r
309 """Display FV space info."""\r
310 GenFds.DisplayFvSpaceInfo(FdfParserObj)\r
311\r
312 except FdfParser.Warning, X:\r
47fea6af 313 EdkLogger.error(X.ToolName, FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError=False)\r
f51461c8
LG
314 ReturnCode = FORMAT_INVALID\r
315 except FatalError, X:\r
316 if Options.debug != None:\r
317 import traceback\r
318 EdkLogger.quiet(traceback.format_exc())\r
319 ReturnCode = X.args[0]\r
320 except:\r
321 import traceback\r
322 EdkLogger.error(\r
323 "\nPython",\r
324 CODE_ERROR,\r
325 "Tools code failure",\r
3a0f8bde 326 ExtraData="Please send email to edk2-devel@lists.01.org for help, attaching following call stack trace!\n",\r
f51461c8
LG
327 RaiseError=False\r
328 )\r
329 EdkLogger.quiet(traceback.format_exc())\r
330 ReturnCode = CODE_ERROR\r
97fa0ee9
YL
331 finally:\r
332 ClearDuplicatedInf()\r
f51461c8
LG
333 return ReturnCode\r
334\r
335gParamCheck = []\r
336def SingleCheckCallback(option, opt_str, value, parser):\r
337 if option not in gParamCheck:\r
338 setattr(parser.values, option.dest, value)\r
339 gParamCheck.append(option)\r
340 else:\r
341 parser.error("Option %s only allows one instance in command line!" % option)\r
6b17c11b
YZ
342\r
343def CheckBuildOptionPcd():\r
344 for Arch in GenFdsGlobalVariable.ArchList:\r
345 PkgList = GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag)\r
346 for i, pcd in enumerate(GlobalData.BuildOptionPcd):\r
347 if type(pcd) is tuple:\r
348 continue\r
349 (pcdname, pcdvalue) = pcd.split('=')\r
350 if not pcdvalue:\r
351 EdkLogger.error('GenFds', OPTION_MISSING, "No Value specified for the PCD %s." % (pcdname))\r
352 if '.' in pcdname:\r
353 (TokenSpaceGuidCName, TokenCName) = pcdname.split('.')\r
354 HasTokenSpace = True\r
355 else:\r
356 TokenCName = pcdname\r
357 TokenSpaceGuidCName = ''\r
358 HasTokenSpace = False\r
359 TokenSpaceGuidCNameList = []\r
360 FoundFlag = False\r
361 PcdDatumType = ''\r
362 NewValue = ''\r
363 for package in PkgList:\r
364 for key in package.Pcds:\r
365 PcdItem = package.Pcds[key]\r
366 if HasTokenSpace:\r
367 if (PcdItem.TokenCName, PcdItem.TokenSpaceGuidCName) == (TokenCName, TokenSpaceGuidCName):\r
368 PcdDatumType = PcdItem.DatumType\r
369 NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)\r
370 FoundFlag = True\r
371 else:\r
372 if PcdItem.TokenCName == TokenCName:\r
373 if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:\r
374 if len (TokenSpaceGuidCNameList) < 1:\r
375 TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)\r
376 PcdDatumType = PcdItem.DatumType\r
377 TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName\r
378 NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)\r
379 FoundFlag = True\r
380 else:\r
381 EdkLogger.error(\r
382 'GenFds',\r
383 PCD_VALIDATION_INFO_ERROR,\r
384 "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (TokenCName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])\r
385 )\r
386\r
387 GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, NewValue)\r
388\r
389def BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, Value):\r
390 if PcdDatumType == 'VOID*':\r
391 if Value.startswith('L'):\r
392 if not Value[1]:\r
393 EdkLogger.error('GenFds', OPTION_VALUE_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"')\r
394 Value = Value[0] + '"' + Value[1:] + '"'\r
395 elif Value.startswith('B'):\r
396 if not Value[1]:\r
397 EdkLogger.error('GenFds', OPTION_VALUE_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"')\r
398 Value = Value[1:]\r
399 else:\r
400 if not Value[0]:\r
401 EdkLogger.error('GenFds', OPTION_VALUE_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"')\r
402 Value = '"' + Value + '"'\r
403\r
404 IsValid, Cause = CheckPcdDatum(PcdDatumType, Value)\r
405 if not IsValid:\r
406 EdkLogger.error('build', FORMAT_INVALID, Cause, ExtraData="%s.%s" % (TokenSpaceGuidCName, TokenCName))\r
407 if PcdDatumType == 'BOOLEAN':\r
408 Value = Value.upper()\r
409 if Value == 'TRUE' or Value == '1':\r
410 Value = '1'\r
411 elif Value == 'FALSE' or Value == '0':\r
412 Value = '0'\r
413 return Value\r
414\r
f51461c8
LG
415 \r
416## Parse command line options\r
417#\r
418# Using standard Python module optparse to parse command line option of this tool.\r
419#\r
420# @retval Opt A optparse.Values object containing the parsed options\r
421# @retval Args Target of build command\r
422#\r
423def myOptionParser():\r
424 usage = "%prog [options] -f input_file -a arch_list -b build_target -p active_platform -t tool_chain_tag -D \"MacroName [= MacroValue]\""\r
47fea6af 425 Parser = OptionParser(usage=usage, description=__copyright__, version="%prog " + str(versionNumber))\r
f51461c8
LG
426 Parser.add_option("-f", "--file", dest="filename", type="string", help="Name of FDF file to convert", action="callback", callback=SingleCheckCallback)\r
427 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
428 Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")\r
429 Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed.")\r
430 Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")\r
431 Parser.add_option("-p", "--platform", type="string", dest="activePlatform", help="Set the ACTIVE_PLATFORM, overrides target.txt ACTIVE_PLATFORM setting.",\r
432 action="callback", callback=SingleCheckCallback)\r
433 Parser.add_option("-w", "--workspace", type="string", dest="Workspace", default=os.environ.get('WORKSPACE'), help="Set the WORKSPACE",\r
434 action="callback", callback=SingleCheckCallback)\r
435 Parser.add_option("-o", "--outputDir", type="string", dest="outputDir", help="Name of Build Output directory",\r
436 action="callback", callback=SingleCheckCallback)\r
437 Parser.add_option("-r", "--rom_image", dest="uiFdName", help="Build the image using the [FD] section named by FdUiName.")\r
438 Parser.add_option("-i", "--FvImage", dest="uiFvName", help="Build the FV image using the [FV] section named by UiFvName")\r
439 Parser.add_option("-C", "--CapsuleImage", dest="uiCapName", help="Build the Capsule image using the [Capsule] section named by UiCapName")\r
440 Parser.add_option("-b", "--buildtarget", type="string", dest="BuildTarget", help="Set the build TARGET, overrides target.txt TARGET setting.",\r
441 action="callback", callback=SingleCheckCallback)\r
442 Parser.add_option("-t", "--tagname", type="string", dest="ToolChain", help="Using the tools: TOOL_CHAIN_TAG name to build the platform.",\r
443 action="callback", callback=SingleCheckCallback)\r
444 Parser.add_option("-D", "--define", action="append", type="string", dest="Macros", help="Macro: \"Name [= Value]\".")\r
445 Parser.add_option("-s", "--specifyaddress", dest="FixedAddress", action="store_true", type=None, help="Specify driver load address.")\r
97fa0ee9
YL
446 Parser.add_option("--conf", action="store", type="string", dest="ConfDirectory", help="Specify the customized Conf directory.")\r
447 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 448 Parser.add_option("--pcd", action="append", dest="OptionPcd", help="Set PCD value by command line. Format: \"PcdName=Value\" ")\r
97fa0ee9 449\r
f51461c8
LG
450 (Options, args) = Parser.parse_args()\r
451 return Options\r
452\r
453## The class implementing the EDK2 flash image generation process\r
454#\r
455# This process includes:\r
456# 1. Collect workspace information, includes platform and module information\r
457# 2. Call methods of Fd class to generate FD\r
458# 3. Call methods of Fv class to generate FV that not belong to FD\r
459#\r
460class GenFds :\r
461 FdfParsef = None\r
462 # FvName, FdName, CapName in FDF, Image file name\r
463 ImageBinDict = {}\r
464 OnlyGenerateThisFd = None\r
465 OnlyGenerateThisFv = None\r
466 OnlyGenerateThisCap = None\r
467\r
468 ## GenFd()\r
469 #\r
470 # @param OutputDir Output directory\r
471 # @param FdfParser FDF contents parser\r
472 # @param Workspace The directory of workspace\r
473 # @param ArchList The Arch list of platform\r
474 #\r
475 def GenFd (OutputDir, FdfParser, WorkSpace, ArchList):\r
476 GenFdsGlobalVariable.SetDir ('', FdfParser, WorkSpace, ArchList)\r
477\r
478 GenFdsGlobalVariable.VerboseLogger(" Generate all Fd images and their required FV and Capsule images!")\r
479 if GenFds.OnlyGenerateThisCap != None and GenFds.OnlyGenerateThisCap.upper() in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.keys():\r
480 CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.get(GenFds.OnlyGenerateThisCap.upper())\r
481 if CapsuleObj != None:\r
482 CapsuleObj.GenCapsule()\r
483 return\r
484\r
485 if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
486 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(GenFds.OnlyGenerateThisFd.upper())\r
487 if FdObj != None:\r
488 FdObj.GenFd()\r
489 return\r
490 elif GenFds.OnlyGenerateThisFd == None and GenFds.OnlyGenerateThisFv == None:\r
491 for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
492 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName]\r
493 FdObj.GenFd()\r
494\r
495 GenFdsGlobalVariable.VerboseLogger("\n Generate other FV images! ")\r
496 if GenFds.OnlyGenerateThisFv != None and GenFds.OnlyGenerateThisFv.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():\r
497 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(GenFds.OnlyGenerateThisFv.upper())\r
498 if FvObj != None:\r
499 Buffer = StringIO.StringIO()\r
500 FvObj.AddToBuffer(Buffer)\r
501 Buffer.close()\r
502 return\r
503 elif GenFds.OnlyGenerateThisFv == None:\r
504 for FvName in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():\r
505 Buffer = StringIO.StringIO('')\r
506 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[FvName]\r
507 FvObj.AddToBuffer(Buffer)\r
508 Buffer.close()\r
509 \r
510 if GenFds.OnlyGenerateThisFv == None and GenFds.OnlyGenerateThisFd == None and GenFds.OnlyGenerateThisCap == None:\r
511 if GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict != {}:\r
512 GenFdsGlobalVariable.VerboseLogger("\n Generate other Capsule images!")\r
513 for CapsuleName in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.keys():\r
514 CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict[CapsuleName]\r
515 CapsuleObj.GenCapsule()\r
516\r
517 if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:\r
518 GenFdsGlobalVariable.VerboseLogger("\n Generate all Option ROM!")\r
519 for DriverName in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.keys():\r
520 OptRomObj = GenFdsGlobalVariable.FdfParser.Profile.OptRomDict[DriverName]\r
521 OptRomObj.AddToBuffer(None)\r
522\r
523 ## GetFvBlockSize()\r
524 #\r
525 # @param FvObj Whose block size to get\r
526 # @retval int Block size value\r
527 #\r
528 def GetFvBlockSize(FvObj):\r
529 DefaultBlockSize = 0x1\r
530 FdObj = None\r
531 if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
532 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()]\r
533 if FdObj == None:\r
534 for ElementFd in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():\r
535 for ElementRegion in ElementFd.RegionList:\r
536 if ElementRegion.RegionType == 'FV':\r
537 for ElementRegionData in ElementRegion.RegionDataList:\r
538 if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName:\r
539 if FvObj.BlockSizeList != []:\r
540 return FvObj.BlockSizeList[0][0]\r
541 else:\r
542 return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)\r
543 if FvObj.BlockSizeList != []:\r
544 return FvObj.BlockSizeList[0][0]\r
545 return DefaultBlockSize\r
546 else:\r
547 for ElementRegion in FdObj.RegionList:\r
548 if ElementRegion.RegionType == 'FV':\r
549 for ElementRegionData in ElementRegion.RegionDataList:\r
550 if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName:\r
551 if FvObj.BlockSizeList != []:\r
552 return FvObj.BlockSizeList[0][0]\r
553 else:\r
554 return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)\r
555 return DefaultBlockSize\r
556\r
557 ## DisplayFvSpaceInfo()\r
558 #\r
559 # @param FvObj Whose block size to get\r
560 # @retval None\r
561 #\r
562 def DisplayFvSpaceInfo(FdfParser):\r
563 \r
564 FvSpaceInfoList = []\r
565 MaxFvNameLength = 0\r
566 for FvName in FdfParser.Profile.FvDict:\r
567 if len(FvName) > MaxFvNameLength:\r
568 MaxFvNameLength = len(FvName)\r
569 FvSpaceInfoFileName = os.path.join(GenFdsGlobalVariable.FvDir, FvName.upper() + '.Fv.map')\r
570 if os.path.exists(FvSpaceInfoFileName):\r
571 FileLinesList = linecache.getlines(FvSpaceInfoFileName)\r
572 TotalFound = False\r
573 Total = ''\r
574 UsedFound = False\r
575 Used = ''\r
576 FreeFound = False\r
577 Free = ''\r
578 for Line in FileLinesList:\r
579 NameValue = Line.split('=')\r
580 if len(NameValue) == 2:\r
581 if NameValue[0].strip() == 'EFI_FV_TOTAL_SIZE':\r
582 TotalFound = True\r
583 Total = NameValue[1].strip()\r
584 if NameValue[0].strip() == 'EFI_FV_TAKEN_SIZE':\r
585 UsedFound = True\r
586 Used = NameValue[1].strip()\r
587 if NameValue[0].strip() == 'EFI_FV_SPACE_SIZE':\r
588 FreeFound = True\r
589 Free = NameValue[1].strip()\r
590 \r
591 if TotalFound and UsedFound and FreeFound:\r
592 FvSpaceInfoList.append((FvName, Total, Used, Free))\r
593 \r
594 GenFdsGlobalVariable.InfLogger('\nFV Space Information')\r
595 for FvSpaceInfo in FvSpaceInfoList:\r
596 Name = FvSpaceInfo[0]\r
597 TotalSizeValue = long(FvSpaceInfo[1], 0)\r
598 UsedSizeValue = long(FvSpaceInfo[2], 0)\r
599 FreeSizeValue = long(FvSpaceInfo[3], 0)\r
600 if UsedSizeValue == TotalSizeValue:\r
601 Percentage = '100'\r
602 else:\r
47fea6af
YZ
603 Percentage = str((UsedSizeValue + 0.0) / TotalSizeValue)[0:4].lstrip('0.')\r
604\r
f51461c8
LG
605 GenFdsGlobalVariable.InfLogger(Name + ' ' + '[' + Percentage + '%Full] ' + str(TotalSizeValue) + ' total, ' + str(UsedSizeValue) + ' used, ' + str(FreeSizeValue) + ' free')\r
606\r
607 ## PreprocessImage()\r
608 #\r
609 # @param BuildDb Database from build meta data files\r
610 # @param DscFile modules from dsc file will be preprocessed\r
611 # @retval None\r
612 #\r
613 def PreprocessImage(BuildDb, DscFile):\r
614 PcdDict = BuildDb.BuildObject[DscFile, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Pcds\r
615 PcdValue = ''\r
616 for Key in PcdDict:\r
617 PcdObj = PcdDict[Key]\r
618 if PcdObj.TokenCName == 'PcdBsBaseAddress':\r
619 PcdValue = PcdObj.DefaultValue\r
620 break\r
621 \r
622 if PcdValue == '':\r
623 return\r
624 \r
625 Int64PcdValue = long(PcdValue, 0)\r
626 if Int64PcdValue == 0 or Int64PcdValue < -1: \r
627 return\r
628 \r
629 TopAddress = 0\r
630 if Int64PcdValue > 0:\r
631 TopAddress = Int64PcdValue\r
632 \r
633 ModuleDict = BuildDb.BuildObject[DscFile, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Modules\r
634 for Key in ModuleDict:\r
635 ModuleObj = BuildDb.BuildObject[Key, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
636 print ModuleObj.BaseName + ' ' + ModuleObj.ModuleType\r
637\r
638 def GenerateGuidXRefFile(BuildDb, ArchList):\r
639 GuidXRefFileName = os.path.join(GenFdsGlobalVariable.FvDir, "Guid.xref")\r
640 GuidXRefFile = StringIO.StringIO('')\r
e4ac870f 641 GuidDict = {}\r
f51461c8
LG
642 for Arch in ArchList:\r
643 PlatformDataBase = BuildDb.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
644 for ModuleFile in PlatformDataBase.Modules:\r
645 Module = BuildDb.BuildObject[ModuleFile, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
646 GuidXRefFile.write("%s %s\n" % (Module.Guid, Module.BaseName))\r
e4ac870f
LG
647 for key, item in Module.Protocols.items():\r
648 GuidDict[key] = item\r
649 for key, item in Module.Guids.items():\r
650 GuidDict[key] = item\r
651 for key, item in Module.Ppis.items():\r
652 GuidDict[key] = item\r
653 # Append GUIDs, Protocols, and PPIs to the Xref file\r
654 GuidXRefFile.write("\n")\r
655 for key, item in GuidDict.items():\r
656 GuidXRefFile.write("%s %s\n" % (GuidStructureStringToGuidString(item).upper(), key))\r
657\r
f51461c8
LG
658 if GuidXRefFile.getvalue():\r
659 SaveFileOnChange(GuidXRefFileName, GuidXRefFile.getvalue(), False)\r
660 GenFdsGlobalVariable.InfLogger("\nGUID cross reference file can be found at %s" % GuidXRefFileName)\r
661 elif os.path.exists(GuidXRefFileName):\r
662 os.remove(GuidXRefFileName)\r
663 GuidXRefFile.close()\r
664\r
665 ##Define GenFd as static function\r
666 GenFd = staticmethod(GenFd)\r
667 GetFvBlockSize = staticmethod(GetFvBlockSize)\r
668 DisplayFvSpaceInfo = staticmethod(DisplayFvSpaceInfo)\r
669 PreprocessImage = staticmethod(PreprocessImage)\r
670 GenerateGuidXRefFile = staticmethod(GenerateGuidXRefFile)\r
671\r
672if __name__ == '__main__':\r
673 r = main()\r
674 ## 0-127 is a safe return range, and 1 is a standard default error\r
675 if r < 0 or r > 127: r = 1\r
676 sys.exit(r)\r
677\r