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