]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Ecc/Ecc.py
BaseTools: Clean up source files
[mirror_edk2.git] / BaseTools / Source / Python / Ecc / Ecc.py
CommitLineData
30fdf114
LG
1## @file\r
2# This file is used to be the main entrance of ECC tool\r
3#\r
f7496d71 4# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
40d841f6 5# This program and the accompanying materials\r
30fdf114
LG
6# are licensed and made available under the terms and conditions of the BSD License\r
7# which accompanies this distribution. The full text of the license may be found at\r
8# http://opensource.org/licenses/bsd-license.php\r
9#\r
10# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12#\r
13\r
14##\r
15# Import Modules\r
16#\r
1be2ed90 17import Common.LongFilePathOs as os, time, glob, sys\r
30fdf114
LG
18import Common.EdkLogger as EdkLogger\r
19import Database\r
20import EccGlobalData\r
21from MetaDataParser import *\r
22from optparse import OptionParser\r
23from Configuration import Configuration\r
24from Check import Check\r
9508d0fa 25import Common.GlobalData as GlobalData\r
d0acc87a 26\r
5a57246e 27from Common.StringUtils import NormPath\r
b36d134f 28from Common.BuildVersion import gBUILD_VERSION\r
30fdf114 29from Common import BuildToolError\r
9508d0fa 30from Common.Misc import PathClass\r
64b2609f 31from Common.Misc import DirCache\r
d0acc87a
LG
32from MetaFileWorkspace.MetaFileParser import DscParser\r
33from MetaFileWorkspace.MetaFileParser import DecParser\r
34from MetaFileWorkspace.MetaFileParser import InfParser\r
35from MetaFileWorkspace.MetaFileParser import Fdf\r
36from MetaFileWorkspace.MetaFileTable import MetaFileStorage\r
30fdf114 37import c\r
fd171542 38import re, string\r
30fdf114 39from Exception import *\r
1be2ed90 40from Common.LongFilePathSupport import OpenLongFilePath as open\r
c4f52e12 41from Common.MultipleWorkspace import MultipleWorkspace as mws\r
30fdf114
LG
42\r
43## Ecc\r
44#\r
45# This class is used to define Ecc main entrance\r
46#\r
47# @param object: Inherited from object class\r
48#\r
49class Ecc(object):\r
50 def __init__(self):\r
51 # Version and Copyright\r
45258285 52 self.VersionNumber = ("1.0" + " Build " + gBUILD_VERSION)\r
30fdf114 53 self.Version = "%prog Version " + self.VersionNumber\r
f7496d71 54 self.Copyright = "Copyright (c) 2009 - 2018, Intel Corporation All rights reserved."\r
30fdf114
LG
55\r
56 self.InitDefaultConfigIni()\r
57 self.OutputFile = 'output.txt'\r
58 self.ReportFile = 'Report.csv'\r
59 self.ExceptionFile = 'exception.xml'\r
60 self.IsInit = True\r
61 self.ScanSourceCode = True\r
62 self.ScanMetaData = True\r
d0acc87a 63 self.MetaFile = ''\r
e4ac870f 64 self.OnlyScan = None\r
fd171542 65\r
30fdf114
LG
66 # Parse the options and args\r
67 self.ParseOption()\r
45258285 68 EdkLogger.info(time.strftime("%H:%M:%S, %b.%d %Y ", time.localtime()) + "[00:00]" + "\n")\r
f7496d71 69\r
9508d0fa
LG
70 #\r
71 # Check EFI_SOURCE (Edk build convention). EDK_SOURCE will always point to ECP\r
72 #\r
73 WorkspaceDir = os.path.normcase(os.path.normpath(os.environ["WORKSPACE"]))\r
74 os.environ["WORKSPACE"] = WorkspaceDir\r
f7496d71 75\r
c4f52e12
LY
76 # set multiple workspace\r
77 PackagesPath = os.getenv("PACKAGES_PATH")\r
78 mws.setWs(WorkspaceDir, PackagesPath)\r
f7496d71 79\r
9508d0fa 80 if "ECP_SOURCE" not in os.environ:\r
c4f52e12 81 os.environ["ECP_SOURCE"] = mws.join(WorkspaceDir, GlobalData.gEdkCompatibilityPkg)\r
9508d0fa
LG
82 if "EFI_SOURCE" not in os.environ:\r
83 os.environ["EFI_SOURCE"] = os.environ["ECP_SOURCE"]\r
84 if "EDK_SOURCE" not in os.environ:\r
85 os.environ["EDK_SOURCE"] = os.environ["ECP_SOURCE"]\r
86\r
87 #\r
88 # Unify case of characters on case-insensitive systems\r
89 #\r
90 EfiSourceDir = os.path.normcase(os.path.normpath(os.environ["EFI_SOURCE"]))\r
91 EdkSourceDir = os.path.normcase(os.path.normpath(os.environ["EDK_SOURCE"]))\r
92 EcpSourceDir = os.path.normcase(os.path.normpath(os.environ["ECP_SOURCE"]))\r
f7496d71 93\r
9508d0fa
LG
94 os.environ["EFI_SOURCE"] = EfiSourceDir\r
95 os.environ["EDK_SOURCE"] = EdkSourceDir\r
96 os.environ["ECP_SOURCE"] = EcpSourceDir\r
f7496d71 97\r
9508d0fa
LG
98 GlobalData.gWorkspace = WorkspaceDir\r
99 GlobalData.gEfiSource = EfiSourceDir\r
100 GlobalData.gEdkSource = EdkSourceDir\r
101 GlobalData.gEcpSource = EcpSourceDir\r
102\r
103 GlobalData.gGlobalDefines["WORKSPACE"] = WorkspaceDir\r
104 GlobalData.gGlobalDefines["EFI_SOURCE"] = EfiSourceDir\r
105 GlobalData.gGlobalDefines["EDK_SOURCE"] = EdkSourceDir\r
106 GlobalData.gGlobalDefines["ECP_SOURCE"] = EcpSourceDir\r
f7496d71 107\r
45258285 108 EdkLogger.info("Loading ECC configuration ... done")\r
30fdf114
LG
109 # Generate checkpoints list\r
110 EccGlobalData.gConfig = Configuration(self.ConfigFile)\r
fd171542 111\r
30fdf114
LG
112 # Generate exception list\r
113 EccGlobalData.gException = ExceptionCheck(self.ExceptionFile)\r
fd171542 114\r
30fdf114
LG
115 # Init Ecc database\r
116 EccGlobalData.gDb = Database.Database(Database.DATABASE_PATH)\r
117 EccGlobalData.gDb.InitDatabase(self.IsInit)\r
fd171542 118\r
64b2609f
LG
119 #\r
120 # Get files real name in workspace dir\r
121 #\r
122 GlobalData.gAllFiles = DirCache(GlobalData.gWorkspace)\r
f7496d71 123\r
30fdf114 124 # Build ECC database\r
e4ac870f
LG
125# self.BuildDatabase()\r
126 self.DetectOnlyScanDirs()\r
f7496d71 127\r
30fdf114
LG
128 # Start to check\r
129 self.Check()\r
fd171542 130\r
30fdf114
LG
131 # Show report\r
132 self.GenReport()\r
fd171542 133\r
30fdf114
LG
134 # Close Database\r
135 EccGlobalData.gDb.Close()\r
136\r
137 def InitDefaultConfigIni(self):\r
138 paths = map(lambda p: os.path.join(p, 'Ecc', 'config.ini'), sys.path)\r
139 paths = (os.path.realpath('config.ini'),) + tuple(paths)\r
140 for path in paths:\r
141 if os.path.exists(path):\r
142 self.ConfigFile = path\r
143 return\r
144 self.ConfigFile = 'config.ini'\r
145\r
e4ac870f
LG
146\r
147 ## DetectOnlyScan\r
148 #\r
149 # Detect whether only scanned folders have been enabled\r
150 #\r
151 def DetectOnlyScanDirs(self):\r
152 if self.OnlyScan == True:\r
153 OnlyScanDirs = []\r
154 # Use regex here if multiple spaces or TAB exists in ScanOnlyDirList in config.ini file\r
155 for folder in re.finditer(r'\S+', EccGlobalData.gConfig.ScanOnlyDirList):\r
156 OnlyScanDirs.append(folder.group())\r
157 if len(OnlyScanDirs) != 0:\r
158 self.BuildDatabase(OnlyScanDirs)\r
159 else:\r
160 EdkLogger.error("ECC", BuildToolError.OPTION_VALUE_INVALID, ExtraData="Use -f option need to fill specific folders in config.ini file")\r
161 else:\r
162 self.BuildDatabase()\r
f7496d71
LG
163\r
164\r
30fdf114
LG
165 ## BuildDatabase\r
166 #\r
167 # Build the database for target\r
168 #\r
e4ac870f 169 def BuildDatabase(self, SpeciDirs = None):\r
30fdf114
LG
170 # Clean report table\r
171 EccGlobalData.gDb.TblReport.Drop()\r
172 EccGlobalData.gDb.TblReport.Create()\r
fd171542 173\r
30fdf114 174 # Build database\r
f7496d71 175 if self.IsInit:\r
30fdf114 176 if self.ScanMetaData:\r
64b2609f 177 EdkLogger.quiet("Building database for Meta Data File ...")\r
e4ac870f 178 self.BuildMetaDataFileDatabase(SpeciDirs)\r
64b2609f
LG
179 if self.ScanSourceCode:\r
180 EdkLogger.quiet("Building database for Meta Data File Done!")\r
4231a819 181 if SpeciDirs is None:\r
e4ac870f
LG
182 c.CollectSourceCodeDataIntoDB(EccGlobalData.gTarget)\r
183 else:\r
184 for specificDir in SpeciDirs:\r
185 c.CollectSourceCodeDataIntoDB(os.path.join(EccGlobalData.gTarget, specificDir))\r
fd171542 186\r
30fdf114 187 EccGlobalData.gIdentifierTableList = GetTableList((MODEL_FILE_C, MODEL_FILE_H), 'Identifier', EccGlobalData.gDb)\r
e56468c0 188 EccGlobalData.gCFileList = GetFileList(MODEL_FILE_C, EccGlobalData.gDb)\r
189 EccGlobalData.gHFileList = GetFileList(MODEL_FILE_H, EccGlobalData.gDb)\r
b3d07ff8 190 EccGlobalData.gUFileList = GetFileList(MODEL_FILE_UNI, EccGlobalData.gDb)\r
fd171542 191\r
30fdf114
LG
192 ## BuildMetaDataFileDatabase\r
193 #\r
194 # Build the database for meta data files\r
195 #\r
e4ac870f
LG
196 def BuildMetaDataFileDatabase(self, SpecificDirs = None):\r
197 ScanFolders = []\r
4231a819 198 if SpecificDirs is None:\r
e4ac870f
LG
199 ScanFolders.append(EccGlobalData.gTarget)\r
200 else:\r
f7496d71 201 for specificDir in SpecificDirs:\r
e4ac870f 202 ScanFolders.append(os.path.join(EccGlobalData.gTarget, specificDir))\r
30fdf114
LG
203 EdkLogger.quiet("Building database for meta data files ...")\r
204 Op = open(EccGlobalData.gConfig.MetaDataFileCheckPathOfGenerateFileList, 'w+')\r
205 #SkipDirs = Read from config file\r
206 SkipDirs = EccGlobalData.gConfig.SkipDirList\r
fd171542 207 SkipDirString = string.join(SkipDirs, '|')\r
e4ac870f
LG
208# p = re.compile(r'.*[\\/](?:%s)[\\/]?.*' % SkipDirString)\r
209 p = re.compile(r'.*[\\/](?:%s^\S)[\\/]?.*' % SkipDirString)\r
210 for scanFolder in ScanFolders:\r
211 for Root, Dirs, Files in os.walk(scanFolder):\r
212 if p.match(Root.upper()):\r
30fdf114 213 continue\r
e4ac870f
LG
214 for Dir in Dirs:\r
215 Dirname = os.path.join(Root, Dir)\r
216 if os.path.islink(Dirname):\r
217 Dirname = os.path.realpath(Dirname)\r
218 if os.path.isdir(Dirname):\r
219 # symlinks to directories are treated as directories\r
220 Dirs.remove(Dir)\r
221 Dirs.append(Dirname)\r
f7496d71 222\r
e4ac870f
LG
223 for File in Files:\r
224 if len(File) > 4 and File[-4:].upper() == ".DEC":\r
225 Filename = os.path.normpath(os.path.join(Root, File))\r
226 EdkLogger.quiet("Parsing %s" % Filename)\r
227 Op.write("%s\r" % Filename)\r
228 #Dec(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)\r
229 self.MetaFile = DecParser(Filename, MODEL_FILE_DEC, EccGlobalData.gDb.TblDec)\r
230 self.MetaFile.Start()\r
231 continue\r
232 if len(File) > 4 and File[-4:].upper() == ".DSC":\r
233 Filename = os.path.normpath(os.path.join(Root, File))\r
234 EdkLogger.quiet("Parsing %s" % Filename)\r
235 Op.write("%s\r" % Filename)\r
236 #Dsc(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)\r
237 self.MetaFile = DscParser(PathClass(Filename, Root), MODEL_FILE_DSC, MetaFileStorage(EccGlobalData.gDb.TblDsc.Cur, Filename, MODEL_FILE_DSC, True))\r
238 # alwasy do post-process, in case of macros change\r
239 self.MetaFile.DoPostProcess()\r
240 self.MetaFile.Start()\r
241 self.MetaFile._PostProcess()\r
242 continue\r
243 if len(File) > 4 and File[-4:].upper() == ".INF":\r
244 Filename = os.path.normpath(os.path.join(Root, File))\r
245 EdkLogger.quiet("Parsing %s" % Filename)\r
246 Op.write("%s\r" % Filename)\r
247 #Inf(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)\r
248 self.MetaFile = InfParser(Filename, MODEL_FILE_INF, EccGlobalData.gDb.TblInf)\r
249 self.MetaFile.Start()\r
250 continue\r
251 if len(File) > 4 and File[-4:].upper() == ".FDF":\r
252 Filename = os.path.normpath(os.path.join(Root, File))\r
253 EdkLogger.quiet("Parsing %s" % Filename)\r
254 Op.write("%s\r" % Filename)\r
255 Fdf(Filename, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)\r
256 continue\r
b3d07ff8
HC
257 if len(File) > 4 and File[-4:].upper() == ".UNI":\r
258 Filename = os.path.normpath(os.path.join(Root, File))\r
259 EdkLogger.quiet("Parsing %s" % Filename)\r
260 Op.write("%s\r" % Filename)\r
1b2467c5
HC
261 FileID = EccGlobalData.gDb.TblFile.InsertFile(Filename, MODEL_FILE_UNI)\r
262 EccGlobalData.gDb.TblReport.UpdateBelongsToItemByFile(FileID, File)\r
b3d07ff8
HC
263 continue\r
264\r
30fdf114 265 Op.close()\r
fd171542 266\r
30fdf114
LG
267 # Commit to database\r
268 EccGlobalData.gDb.Conn.commit()\r
fd171542 269\r
30fdf114 270 EdkLogger.quiet("Building database for meta data files done!")\r
fd171542 271\r
30fdf114
LG
272 ##\r
273 #\r
274 # Check each checkpoint\r
275 #\r
276 def Check(self):\r
277 EdkLogger.quiet("Checking ...")\r
278 EccCheck = Check()\r
279 EccCheck.Check()\r
280 EdkLogger.quiet("Checking done!")\r
fd171542 281\r
30fdf114
LG
282 ##\r
283 #\r
284 # Generate the scan report\r
285 #\r
286 def GenReport(self):\r
287 EdkLogger.quiet("Generating report ...")\r
288 EccGlobalData.gDb.TblReport.ToCSV(self.ReportFile)\r
289 EdkLogger.quiet("Generating report done!")\r
fd171542 290\r
30fdf114
LG
291 def GetRealPathCase(self, path):\r
292 TmpPath = path.rstrip(os.sep)\r
293 PathParts = TmpPath.split(os.sep)\r
294 if len(PathParts) == 0:\r
295 return path\r
296 if len(PathParts) == 1:\r
297 if PathParts[0].strip().endswith(':'):\r
298 return PathParts[0].upper()\r
299 # Relative dir, list . current dir\r
300 Dirs = os.listdir('.')\r
301 for Dir in Dirs:\r
302 if Dir.upper() == PathParts[0].upper():\r
303 return Dir\r
fd171542 304\r
30fdf114
LG
305 if PathParts[0].strip().endswith(':'):\r
306 PathParts[0] = PathParts[0].upper()\r
307 ParentDir = PathParts[0]\r
308 RealPath = ParentDir\r
309 if PathParts[0] == '':\r
310 RealPath = os.sep\r
311 ParentDir = os.sep\r
fd171542 312\r
30fdf114
LG
313 PathParts.remove(PathParts[0]) # need to remove the parent\r
314 for Part in PathParts:\r
315 Dirs = os.listdir(ParentDir + os.sep)\r
316 for Dir in Dirs:\r
317 if Dir.upper() == Part.upper():\r
318 RealPath += os.sep\r
319 RealPath += Dir\r
320 break\r
321 ParentDir += os.sep\r
322 ParentDir += Dir\r
fd171542 323\r
30fdf114 324 return RealPath\r
fd171542 325\r
30fdf114
LG
326 ## ParseOption\r
327 #\r
328 # Parse options\r
329 #\r
330 def ParseOption(self):\r
30fdf114 331 (Options, Target) = self.EccOptionParser()\r
fd171542 332\r
52302d4d
LG
333 if Options.Workspace:\r
334 os.environ["WORKSPACE"] = Options.Workspace\r
e56468c0 335\r
30fdf114
LG
336 # Check workspace envirnoment\r
337 if "WORKSPACE" not in os.environ:\r
fd171542 338 EdkLogger.error("ECC", BuildToolError.ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found",\r
30fdf114
LG
339 ExtraData="WORKSPACE")\r
340 else:\r
341 EccGlobalData.gWorkspace = os.path.normpath(os.getenv("WORKSPACE"))\r
342 if not os.path.exists(EccGlobalData.gWorkspace):\r
343 EdkLogger.error("ECC", BuildToolError.FILE_NOT_FOUND, ExtraData="WORKSPACE = %s" % EccGlobalData.gWorkspace)\r
344 os.environ["WORKSPACE"] = EccGlobalData.gWorkspace\r
345 # Set log level\r
346 self.SetLogLevel(Options)\r
fd171542 347\r
30fdf114 348 # Set other options\r
4231a819 349 if Options.ConfigFile is not None:\r
30fdf114 350 self.ConfigFile = Options.ConfigFile\r
4231a819 351 if Options.OutputFile is not None:\r
30fdf114 352 self.OutputFile = Options.OutputFile\r
4231a819 353 if Options.ReportFile is not None:\r
30fdf114 354 self.ReportFile = Options.ReportFile\r
4231a819 355 if Options.ExceptionFile is not None:\r
52302d4d 356 self.ExceptionFile = Options.ExceptionFile\r
4231a819 357 if Options.Target is not None:\r
30fdf114
LG
358 if not os.path.isdir(Options.Target):\r
359 EdkLogger.error("ECC", BuildToolError.OPTION_VALUE_INVALID, ExtraData="Target [%s] does NOT exist" % Options.Target)\r
360 else:\r
361 EccGlobalData.gTarget = self.GetRealPathCase(os.path.normpath(Options.Target))\r
362 else:\r
363 EdkLogger.warn("Ecc", EdkLogger.ECC_ERROR, "The target source tree was not specified, using current WORKSPACE instead!")\r
364 EccGlobalData.gTarget = os.path.normpath(os.getenv("WORKSPACE"))\r
4231a819 365 if Options.keepdatabase is not None:\r
30fdf114 366 self.IsInit = False\r
4231a819 367 if Options.metadata is not None and Options.sourcecode is not None:\r
30fdf114 368 EdkLogger.error("ECC", BuildToolError.OPTION_CONFLICT, ExtraData="-m and -s can't be specified at one time")\r
4231a819 369 if Options.metadata is not None:\r
30fdf114 370 self.ScanSourceCode = False\r
4231a819 371 if Options.sourcecode is not None:\r
30fdf114 372 self.ScanMetaData = False\r
4231a819 373 if Options.folders is not None:\r
e4ac870f 374 self.OnlyScan = True\r
fd171542 375\r
30fdf114
LG
376 ## SetLogLevel\r
377 #\r
378 # Set current log level of the tool based on args\r
379 #\r
fd171542 380 # @param Option: The option list including log level setting\r
30fdf114
LG
381 #\r
382 def SetLogLevel(self, Option):\r
4231a819 383 if Option.verbose is not None:\r
30fdf114 384 EdkLogger.SetLevel(EdkLogger.VERBOSE)\r
4231a819 385 elif Option.quiet is not None:\r
30fdf114 386 EdkLogger.SetLevel(EdkLogger.QUIET)\r
4231a819 387 elif Option.debug is not None:\r
30fdf114
LG
388 EdkLogger.SetLevel(Option.debug + 1)\r
389 else:\r
390 EdkLogger.SetLevel(EdkLogger.INFO)\r
391\r
392 ## Parse command line options\r
393 #\r
394 # Using standard Python module optparse to parse command line option of this tool.\r
395 #\r
396 # @retval Opt A optparse.Values object containing the parsed options\r
397 # @retval Args Target of build command\r
398 #\r
399 def EccOptionParser(self):\r
400 Parser = OptionParser(description = self.Copyright, version = self.Version, prog = "Ecc.exe", usage = "%prog [options]")\r
401 Parser.add_option("-t", "--target sourcepath", action="store", type="string", dest='Target',\r
402 help="Check all files under the target workspace.")\r
403 Parser.add_option("-c", "--config filename", action="store", type="string", dest="ConfigFile",\r
404 help="Specify a configuration file. Defaultly use config.ini under ECC tool directory.")\r
405 Parser.add_option("-o", "--outfile filename", action="store", type="string", dest="OutputFile",\r
406 help="Specify the name of an output file, if and only if one filename was specified.")\r
407 Parser.add_option("-r", "--reportfile filename", action="store", type="string", dest="ReportFile",\r
408 help="Specify the name of an report file, if and only if one filename was specified.")\r
52302d4d
LG
409 Parser.add_option("-e", "--exceptionfile filename", action="store", type="string", dest="ExceptionFile",\r
410 help="Specify the name of an exception file, if and only if one filename was specified.")\r
30fdf114
LG
411 Parser.add_option("-m", "--metadata", action="store_true", type=None, help="Only scan meta-data files information if this option is specified.")\r
412 Parser.add_option("-s", "--sourcecode", action="store_true", type=None, help="Only scan source code files information if this option is specified.")\r
413 Parser.add_option("-k", "--keepdatabase", action="store_true", type=None, help="The existing Ecc database will not be cleaned except report information if this option is specified.")\r
fd171542 414 Parser.add_option("-l", "--log filename", action="store", dest="LogFile", help="""If specified, the tool should emit the changes that\r
415 were made by the tool after printing the result message.\r
416 If filename, the emit to the file, otherwise emit to\r
417 standard output. If no modifications were made, then do not\r
30fdf114
LG
418 create a log file, or output a log message.""")\r
419 Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")\r
420 Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed, "\\r
421 "including library instances selected, final dependency expression, "\\r
422 "and warning messages, etc.")\r
423 Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")\r
52302d4d 424 Parser.add_option("-w", "--workspace", action="store", type="string", dest='Workspace', help="Specify workspace.")\r
e4ac870f 425 Parser.add_option("-f", "--folders", action="store_true", type=None, help="Only scanning specified folders which are recorded in config.ini file.")\r
fd171542 426\r
30fdf114 427 (Opt, Args)=Parser.parse_args()\r
fd171542 428\r
30fdf114
LG
429 return (Opt, Args)\r
430\r
431##\r
432#\r
433# This acts like the main() function for the script, unless it is 'import'ed into another\r
434# script.\r
435#\r
436if __name__ == '__main__':\r
437 # Initialize log system\r
438 EdkLogger.Initialize()\r
439 EdkLogger.IsRaiseError = False\r
30fdf114
LG
440\r
441 StartTime = time.clock()\r
442 Ecc = Ecc()\r
443 FinishTime = time.clock()\r
444\r
445 BuildDuration = time.strftime("%M:%S", time.gmtime(int(round(FinishTime - StartTime))))\r
446 EdkLogger.quiet("\n%s [%s]" % (time.strftime("%H:%M:%S, %b.%d %Y", time.localtime()), BuildDuration))\r