1## @file
2# This file is used to be the main entrance of EOT tool
3#
4# Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
5# This program and the accompanying materials
6# are licensed and made available under the terms and conditions of the BSD License
7# which accompanies this distribution.  The full text of the license may be found at
8# http://opensource.org/licenses/bsd-license.php
9#
10# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12#
13
14##
15# Import Modules
16#
17import Common.LongFilePathOs as os, time, glob
18import Common.EdkLogger as EdkLogger
19import EotGlobalData
20from optparse import OptionParser
21from Common.String import NormPath
22from Common import BuildToolError
23from Common.Misc import GuidStructureStringToGuidString
24from InfParserLite import *
25import c
26import Database
27from FvImage import *
28from array import array
29from Report import Report
30from Common.Misc import ParseConsoleLog
31from Common.BuildVersion import gBUILD_VERSION
32from Parser import ConvertGuid
33from Common.LongFilePathSupport import OpenLongFilePath as open
34
35## Class Eot
36#
37# This class is used to define Eot main entrance
38#
39# @param object:          Inherited from object class
40#
41class Eot(object):
42    ## The constructor
43    #
44    #   @param  self:      The object pointer
45    #
46    def __init__(self, CommandLineOption=True, IsInit=True, SourceFileList=None, \
47                 IncludeDirList=None, DecFileList=None, GuidList=None, LogFile=None,
48                 FvFileList="", MapFileList="", Report='Report.html', Dispatch=None):
49        # Version and Copyright
50        self.VersionNumber = ("0.02" + " " + gBUILD_VERSION)
51        self.Version = "%prog Version " + self.VersionNumber
52        self.Copyright = "Copyright (c) 2008 - 2010, Intel Corporation  All rights reserved."
53        self.Report = Report
54
55        self.IsInit = IsInit
56        self.SourceFileList = SourceFileList
57        self.IncludeDirList = IncludeDirList
58        self.DecFileList = DecFileList
59        self.GuidList = GuidList
60        self.LogFile = LogFile
61        self.FvFileList = FvFileList
62        self.MapFileList = MapFileList
63        self.Dispatch = Dispatch
64
65        # Check workspace environment
66        if "EFI_SOURCE" not in os.environ:
67            if "EDK_SOURCE" not in os.environ:
68                pass
69            else:
70                EotGlobalData.gEDK_SOURCE = os.path.normpath(os.getenv("EDK_SOURCE"))
71        else:
72            EotGlobalData.gEFI_SOURCE = os.path.normpath(os.getenv("EFI_SOURCE"))
73            EotGlobalData.gEDK_SOURCE = os.path.join(EotGlobalData.gEFI_SOURCE, 'Edk')
74
75        if "WORKSPACE" not in os.environ:
76            EdkLogger.error("EOT", BuildToolError.ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found",
77                            ExtraData="WORKSPACE")
78        else:
79            EotGlobalData.gWORKSPACE = os.path.normpath(os.getenv("WORKSPACE"))
80
81        EotGlobalData.gMACRO['WORKSPACE'] = EotGlobalData.gWORKSPACE
82        EotGlobalData.gMACRO['EFI_SOURCE'] = EotGlobalData.gEFI_SOURCE
83        EotGlobalData.gMACRO['EDK_SOURCE'] = EotGlobalData.gEDK_SOURCE
84
85        # Parse the options and args
86        if CommandLineOption:
87            self.ParseOption()
88
89        if self.FvFileList:
90            for FvFile in GetSplitValueList(self.FvFileList, ' '):
91                FvFile = os.path.normpath(FvFile)
92                if not os.path.isfile(FvFile):
93                    EdkLogger.error("Eot", EdkLogger.EOT_ERROR, "Can not find file %s " % FvFile)
94                EotGlobalData.gFV_FILE.append(FvFile)
95        else:
96            EdkLogger.error("Eot", EdkLogger.EOT_ERROR, "The fv file list of target platform was not specified")
97
98        if self.MapFileList:
99            for MapFile in GetSplitValueList(self.MapFileList, ' '):
100                MapFile = os.path.normpath(MapFile)
101                if not os.path.isfile(MapFile):
102                    EdkLogger.error("Eot", EdkLogger.EOT_ERROR, "Can not find file %s " % MapFile)
103                EotGlobalData.gMAP_FILE.append(MapFile)
104
105        # Generate source file list
106        self.GenerateSourceFileList(self.SourceFileList, self.IncludeDirList)
107
108        # Generate guid list of dec file list
109        self.ParseDecFile(self.DecFileList)
110
111        # Generate guid list from GUID list file
112        self.ParseGuidList(self.GuidList)
113
114        # Init Eot database
115        EotGlobalData.gDb = Database.Database(Database.DATABASE_PATH)
116        EotGlobalData.gDb.InitDatabase(self.IsInit)
117
118        # Build ECC database
119        self.BuildDatabase()
120
121        # Parse Ppi/Protocol
122        self.ParseExecutionOrder()
123
124        # Merge Identifier tables
125        self.GenerateQueryTable()
126
127        # Generate report database
128        self.GenerateReportDatabase()
129
130        # Load Fv Info
131        self.LoadFvInfo()
132
133        # Load Map Info
134        self.LoadMapInfo()
135
136        # Generate Report
137        self.GenerateReport()
138
139        # Convert log file
140        self.ConvertLogFile(self.LogFile)
141
142        # DONE
143        EdkLogger.quiet("EOT FINISHED!")
144
145        # Close Database
146        EotGlobalData.gDb.Close()
147
148    ## ParseDecFile() method
149    #
150    #  parse DEC file and get all GUID names with GUID values as {GuidName : GuidValue}
151    #  The Dict is stored in EotGlobalData.gGuidDict
152    #
153    #  @param self: The object pointer
154    #  @param DecFileList: A list of all DEC files
155    #
156    def ParseDecFile(self, DecFileList):
157        if DecFileList:
158            path = os.path.normpath(DecFileList)
159            lfr = open(path, 'rb')
160            for line in lfr:
161                path = os.path.normpath(os.path.join(EotGlobalData.gWORKSPACE, line.strip()))
162                if os.path.exists(path):
163                    dfr = open(path, 'rb')
164                    for line in dfr:
165                        line = CleanString(line)
166                        list = line.split('=')
167                        if len(list) == 2:
168                            EotGlobalData.gGuidDict[list[0].strip()] = GuidStructureStringToGuidString(list[1].strip())
169
170
171    ## ParseGuidList() method
172    #
173    #  Parse Guid list and get all GUID names with GUID values as {GuidName : GuidValue}
174    #  The Dict is stored in EotGlobalData.gGuidDict
175    #
176    #  @param self: The object pointer
177    #  @param GuidList: A list of all GUID and its value
178    #
179    def ParseGuidList(self, GuidList):
180        Path = os.path.join(EotGlobalData.gWORKSPACE, GuidList)
181        if os.path.isfile(Path):
182            for Line in open(Path):
183                (GuidName, GuidValue) = Line.split()
184                EotGlobalData.gGuidDict[GuidName] = GuidValue
185
186    ## ConvertLogFile() method
187    #
188    #  Parse a real running log file to get real dispatch order
189    #  The result is saved to old file name + '.new'
190    #
191    #  @param self: The object pointer
192    #  @param LogFile: A real running log file name
193    #
194    def ConvertLogFile(self, LogFile):
195        newline = []
196        lfr = None
197        lfw = None
198        if LogFile:
199            lfr = open(LogFile, 'rb')
200            lfw = open(LogFile + '.new', 'wb')
201            for line in lfr:
202                line = line.strip()
203                line = line.replace('.efi', '')
204                index = line.find("Loading PEIM at ")
205                if index > -1:
206                    newline.append(line[index + 55 : ])
207                    continue
208                index = line.find("Loading driver at ")
209                if index > -1:
210                    newline.append(line[index + 57 : ])
211                    continue
212
213        for line in newline:
214            lfw.write(line + '\r\n')
215
216        if lfr:
217            lfr.close()
218        if lfw:
219            lfw.close()
220
221    ## GenerateSourceFileList() method
222    #
223    #  Generate a list of all source files
224    #  1. Search the file list one by one
225    #  2. Store inf file name with source file names under it like
226    #  { INF file name: [source file1, source file2, ...]}
227    #  3. Search the include list to find all .h files
228    #  4. Store source file list to EotGlobalData.gSOURCE_FILES
229    #  5. Store INF file list to EotGlobalData.gINF_FILES
230    #
231    #  @param self: The object pointer
232    #  @param SourceFileList: A list of all source files
233    #  @param IncludeFileList: A list of all include files
234    #
235    def GenerateSourceFileList(self, SourceFileList, IncludeFileList):
236        EdkLogger.quiet("Generating source files list ... ")
237        mSourceFileList = []
238        mInfFileList = []
239        mDecFileList = []
240        mFileList = {}
241        mCurrentInfFile = ''
242        mCurrentSourceFileList = []
243
244        if SourceFileList:
245            sfl = open(SourceFileList, 'rb')
246            for line in sfl:
247                line = os.path.normpath(os.path.join(EotGlobalData.gWORKSPACE, line.strip()))
248                if line[-2:].upper() == '.C' or  line[-2:].upper() == '.H':
249                    if line not in mCurrentSourceFileList:
250                        mCurrentSourceFileList.append(line)
251                        mSourceFileList.append(line)
252                        EotGlobalData.gOP_SOURCE_FILES.write('%s\n' % line)
253                if line[-4:].upper() == '.INF':
254                    if mCurrentInfFile != '':
255                        mFileList[mCurrentInfFile] = mCurrentSourceFileList
256                        mCurrentSourceFileList = []
257                    mCurrentInfFile = os.path.normpath(os.path.join(EotGlobalData.gWORKSPACE, line))
258                    EotGlobalData.gOP_INF.write('%s\n' % mCurrentInfFile)
259            if mCurrentInfFile not in mFileList:
260                mFileList[mCurrentInfFile] = mCurrentSourceFileList
261
262        # Get all include files from packages
263        if IncludeFileList:
264            ifl = open(IncludeFileList, 'rb')
265            for line in ifl:
266                if not line.strip():
267                    continue
268                newline = os.path.normpath(os.path.join(EotGlobalData.gWORKSPACE, line.strip()))
269                for Root, Dirs, Files in os.walk(str(newline)):
270                    for File in Files:
271                        FullPath = os.path.normpath(os.path.join(Root, File))
272                        if FullPath not in mSourceFileList and File[-2:].upper() == '.H':
273                            mSourceFileList.append(FullPath)
274                            EotGlobalData.gOP_SOURCE_FILES.write('%s\n' % FullPath)
275                        if FullPath not in mDecFileList and File.upper().find('.DEC') > -1:
276                            mDecFileList.append(FullPath)
277
278        EotGlobalData.gSOURCE_FILES = mSourceFileList
279        EotGlobalData.gOP_SOURCE_FILES.close()
280
281        EotGlobalData.gINF_FILES = mFileList
282        EotGlobalData.gOP_INF.close()
283
284        EotGlobalData.gDEC_FILES = mDecFileList
285
286
287    ## GenerateReport() method
288    #
289    #  Generate final HTML report
290    #
291    #  @param self: The object pointer
292    #
293    def GenerateReport(self):
294        EdkLogger.quiet("Generating report file ... ")
295        Rep = Report(self.Report, EotGlobalData.gFV, self.Dispatch)
296        Rep.GenerateReport()
297
298    ## LoadMapInfo() method
299    #
300    #  Load map files and parse them
301    #
302    #  @param self: The object pointer
303    #
304    def LoadMapInfo(self):
305        if EotGlobalData.gMAP_FILE != []:
306            EdkLogger.quiet("Parsing Map file ... ")
307            EotGlobalData.gMap = ParseMapFile(EotGlobalData.gMAP_FILE)
308
309    ## LoadFvInfo() method
310    #
311    #  Load FV binary files and parse them
312    #
313    #  @param self: The object pointer
314    #
315    def LoadFvInfo(self):
316        EdkLogger.quiet("Parsing FV file ... ")
317        EotGlobalData.gFV = MultipleFv(EotGlobalData.gFV_FILE)
318        EotGlobalData.gFV.Dispatch(EotGlobalData.gDb)
319
320        for Protocol in EotGlobalData.gProtocolList:
321            EotGlobalData.gOP_UN_MATCHED_IN_LIBRARY_CALLING.write('%s\n' %Protocol)
322
323    ## GenerateReportDatabase() method
324    #
325    #  Generate data for the information needed by report
326    #  1. Update name, macro and value of all found PPI/PROTOCOL GUID
327    #  2. Install hard coded PPI/PROTOCOL
328    #
329    #  @param self: The object pointer
330    #
331    def GenerateReportDatabase(self):
332        EdkLogger.quiet("Generating the cross-reference table of GUID for Ppi/Protocol ... ")
333
334        # Update Protocol/Ppi Guid
335        SqlCommand = """select DISTINCT GuidName from Report"""
336        RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
337        for Record in RecordSet:
338            GuidName = Record[0]
339            GuidMacro = ''
340            GuidMacro2 = ''
341            GuidValue = ''
342
343            # Find value for hardcode guid macro
344            if GuidName in EotGlobalData.gGuidMacroDict:
345                GuidMacro = EotGlobalData.gGuidMacroDict[GuidName][0]
346                GuidValue = EotGlobalData.gGuidMacroDict[GuidName][1]
347                SqlCommand = """update Report set GuidMacro = '%s', GuidValue = '%s' where GuidName = '%s'""" %(GuidMacro, GuidValue, GuidName)
348                EotGlobalData.gDb.TblReport.Exec(SqlCommand)
349                continue
350
351            # Find guid value defined in Dec file
352            if GuidName in EotGlobalData.gGuidDict:
353                GuidValue = EotGlobalData.gGuidDict[GuidName]
354                SqlCommand = """update Report set GuidMacro = '%s', GuidValue = '%s' where GuidName = '%s'""" %(GuidMacro, GuidValue, GuidName)
355                EotGlobalData.gDb.TblReport.Exec(SqlCommand)
356                continue
357
358            # Search defined Macros for guid name
359            SqlCommand ="""select DISTINCT Value, Modifier from Query where Name like '%s'""" % GuidName
360            GuidMacroSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
361            # Ignore NULL result
362            if not GuidMacroSet:
363                continue
364            GuidMacro = GuidMacroSet[0][0].strip()
365            if not GuidMacro:
366                continue
367            # Find Guid value of Guid Macro
368            SqlCommand ="""select DISTINCT Value from Query2 where Value like '%%%s%%' and Model = %s""" % (GuidMacro, MODEL_IDENTIFIER_MACRO_DEFINE)
369            GuidValueSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
370            if GuidValueSet != []:
371                GuidValue = GuidValueSet[0][0]
372                GuidValue = GuidValue[GuidValue.find(GuidMacro) + len(GuidMacro) :]
373                GuidValue = GuidValue.lower().replace('\\', '').replace('\r', '').replace('\n', '').replace('l', '').strip()
374                GuidValue = GuidStructureStringToGuidString(GuidValue)
375                SqlCommand = """update Report set GuidMacro = '%s', GuidValue = '%s' where GuidName = '%s'""" %(GuidMacro, GuidValue, GuidName)
376                EotGlobalData.gDb.TblReport.Exec(SqlCommand)
377                continue
378
379        # Update Hard Coded Ppi/Protocol
380        SqlCommand = """select DISTINCT GuidValue, ItemType from Report where ModuleID = -2 and ItemMode = 'Produced'"""
381        RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
382        for Record in RecordSet:
383            if Record[1] == 'Ppi':
384                EotGlobalData.gPpiList[Record[0].lower()] = -2
385            if Record[1] == 'Protocol':
386                EotGlobalData.gProtocolList[Record[0].lower()] = -2
387
388    ## GenerateQueryTable() method
389    #
390    #  Generate two tables improve query performance
391    #
392    #  @param self: The object pointer
393    #
394    def GenerateQueryTable(self):
395        EdkLogger.quiet("Generating temp query table for analysis ... ")
396        for Identifier in EotGlobalData.gIdentifierTableList:
397            SqlCommand = """insert into Query (Name, Modifier, Value, Model)
398                            select Name, Modifier, Value, Model from %s where (Model = %s or Model = %s)""" \
399                            % (Identifier[0], MODEL_IDENTIFIER_VARIABLE, MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION)
400            EotGlobalData.gDb.TblReport.Exec(SqlCommand)
401            SqlCommand = """insert into Query2 (Name, Modifier, Value, Model)
402                            select Name, Modifier, Value, Model from %s where Model = %s""" \
403                            % (Identifier[0], MODEL_IDENTIFIER_MACRO_DEFINE)
404            EotGlobalData.gDb.TblReport.Exec(SqlCommand)
405
406    ## ParseExecutionOrder() method
407    #
408    #  Get final execution order
409    #  1. Search all PPI
410    #  2. Search all PROTOCOL
411    #
412    #  @param self: The object pointer
413    #
414    def ParseExecutionOrder(self):
415        EdkLogger.quiet("Searching Ppi/Protocol ... ")
416        for Identifier in EotGlobalData.gIdentifierTableList:
417            ModuleID, ModuleName, ModuleGuid, SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, Enabled = \
418            -1, '', '', -1, '', '', '', '', '', '', '', '', 0
419
420            SourceFileID = Identifier[0].replace('Identifier', '')
421            SourceFileFullPath = Identifier[1]
422            Identifier = Identifier[0]
423
424            # Find Ppis
425            ItemMode = 'Produced'
426            SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s
427                            where (Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
428                            % (Identifier, '.InstallPpi', '->InstallPpi', 'PeiInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING)
429            SearchPpi(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode)
430
431            ItemMode = 'Produced'
432            SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s
433                            where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
434                            % (Identifier, '.ReInstallPpi', '->ReInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING)
435            SearchPpi(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode, 2)
436
437            SearchPpiCallFunction(Identifier, SourceFileID, SourceFileFullPath, ItemMode)
438
439            ItemMode = 'Consumed'
440            SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s
441                            where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
442                            % (Identifier, '.LocatePpi', '->LocatePpi', MODEL_IDENTIFIER_FUNCTION_CALLING)
443            SearchPpi(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode)
444
445            SearchFunctionCalling(Identifier, SourceFileID, SourceFileFullPath, 'Ppi', ItemMode)
446
447            ItemMode = 'Callback'
448            SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s
449                            where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
450                            % (Identifier, '.NotifyPpi', '->NotifyPpi', MODEL_IDENTIFIER_FUNCTION_CALLING)
451            SearchPpi(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode)
452
453            # Find Procotols
454            ItemMode = 'Produced'
455            SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s
456                            where (Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
457                            % (Identifier, '.InstallProtocolInterface', '.ReInstallProtocolInterface', '->InstallProtocolInterface', '->ReInstallProtocolInterface', MODEL_IDENTIFIER_FUNCTION_CALLING)
458            SearchProtocols(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode, 1)
459
460            SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s
461                            where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
462                            % (Identifier, '.InstallMultipleProtocolInterfaces', '->InstallMultipleProtocolInterfaces', MODEL_IDENTIFIER_FUNCTION_CALLING)
463            SearchProtocols(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode, 2)
464
465            SearchFunctionCalling(Identifier, SourceFileID, SourceFileFullPath, 'Protocol', ItemMode)
466
467            ItemMode = 'Consumed'
468            SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s
469                            where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
470                            % (Identifier, '.LocateProtocol', '->LocateProtocol', MODEL_IDENTIFIER_FUNCTION_CALLING)
471            SearchProtocols(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode, 0)
472
473            SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s
474                            where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
475                            % (Identifier, '.HandleProtocol', '->HandleProtocol', MODEL_IDENTIFIER_FUNCTION_CALLING)
476            SearchProtocols(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode, 1)
477
478            SearchFunctionCalling(Identifier, SourceFileID, SourceFileFullPath, 'Protocol', ItemMode)
479
480            ItemMode = 'Callback'
481            SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s
482                            where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
483                            % (Identifier, '.RegisterProtocolNotify', '->RegisterProtocolNotify', MODEL_IDENTIFIER_FUNCTION_CALLING)
484            SearchProtocols(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode, 0)
485
486            SearchFunctionCalling(Identifier, SourceFileID, SourceFileFullPath, 'Protocol', ItemMode)
487
488        # Hard Code
489        EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gEfiSecPlatformInformationPpiGuid', '', '', '', 0)
490        EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gEfiNtLoadAsDllPpiGuid', '', '', '', 0)
491        EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gNtPeiLoadFileGuid', '', '', '', 0)
492        EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiNtAutoScanPpiGuid', '', '', '', 0)
493        EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gNtFwhPpiGuid', '', '', '', 0)
494        EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiNtThunkPpiGuid', '', '', '', 0)
495        EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiPlatformTypePpiGuid', '', '', '', 0)
496        EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiFrequencySelectionCpuPpiGuid', '', '', '', 0)
497        EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiCachePpiGuid', '', '', '', 0)
498
499        EotGlobalData.gDb.Conn.commit()
500
501
502    ## BuildDatabase() methoc
503    #
504    #  Build the database for target
505    #
506    #  @param self: The object pointer
507    #
508    def BuildDatabase(self):
509        # Clean report table
510        EotGlobalData.gDb.TblReport.Drop()
511        EotGlobalData.gDb.TblReport.Create()
512
513        # Build database
514        if self.IsInit:
515            self.BuildMetaDataFileDatabase(EotGlobalData.gINF_FILES)
516            EdkLogger.quiet("Building database for source code ...")
517            c.CreateCCodeDB(EotGlobalData.gSOURCE_FILES)
518            EdkLogger.quiet("Building database for source code done!")
519
520        EotGlobalData.gIdentifierTableList = GetTableList((MODEL_FILE_C, MODEL_FILE_H), 'Identifier', EotGlobalData.gDb)
521
522    ## BuildMetaDataFileDatabase() method
523    #
524    #  Build the database for meta data files
525    #
526    #  @param self: The object pointer
527    #  @param Inf_Files: A list for all INF files
528    #
529    def BuildMetaDataFileDatabase(self, Inf_Files):
530        EdkLogger.quiet("Building database for meta data files ...")
531        for InfFile in Inf_Files:
532            EdkLogger.quiet("Parsing %s ..."  % str(InfFile))
533            EdkInfParser(InfFile, EotGlobalData.gDb, Inf_Files[InfFile], '')
534
535        EotGlobalData.gDb.Conn.commit()
536        EdkLogger.quiet("Building database for meta data files done!")
537
538    ## ParseOption() method
539    #
540    #  Parse command line options
541    #
542    #  @param self: The object pointer
543    #
544    def ParseOption(self):
545        (Options, Target) = self.EotOptionParser()
546
547        # Set log level
548        self.SetLogLevel(Options)
549
550        if Options.FvFileList:
551            self.FvFileList = Options.FvFileList
552
553        if Options.MapFileList:
554            self.MapFileList = Options.FvMapFileList
555
556        if Options.SourceFileList:
557            self.SourceFileList = Options.SourceFileList
558
559        if Options.IncludeDirList:
560            self.IncludeDirList = Options.IncludeDirList
561
562        if Options.DecFileList:
563            self.DecFileList = Options.DecFileList
564
565        if Options.GuidList:
566            self.GuidList = Options.GuidList
567
568        if Options.LogFile:
569            self.LogFile = Options.LogFile
570
571        if Options.keepdatabase:
572            self.IsInit = False
573
574    ## SetLogLevel() method
575    #
576    #  Set current log level of the tool based on args
577    #
578    #  @param self: The object pointer
579    #  @param Option: The option list including log level setting
580    #
581    def SetLogLevel(self, Option):
582        if Option.verbose != None:
583            EdkLogger.SetLevel(EdkLogger.VERBOSE)
584        elif Option.quiet != None:
585            EdkLogger.SetLevel(EdkLogger.QUIET)
586        elif Option.debug != None:
587            EdkLogger.SetLevel(Option.debug + 1)
588        else:
589            EdkLogger.SetLevel(EdkLogger.INFO)
590
591    ## EotOptionParser() method
592    #
593    #  Using standard Python module optparse to parse command line option of this tool.
594    #
595    #  @param self: The object pointer
596    #
597    #  @retval Opt   A optparse.Values object containing the parsed options
598    #  @retval Args  Target of build command
599    #
600    def EotOptionParser(self):
601        Parser = OptionParser(description = self.Copyright, version = self.Version, prog = "Eot.exe", usage = "%prog [options]")
602        Parser.add_option("-m", "--makefile filename", action="store", type="string", dest='MakeFile',
603            help="Specify a makefile for the platform.")
604        Parser.add_option("-c", "--dsc filename", action="store", type="string", dest="DscFile",
605            help="Specify a dsc file for the platform.")
606        Parser.add_option("-f", "--fv filename", action="store", type="string", dest="FvFileList",
607            help="Specify fv file list, quoted by \"\".")
608        Parser.add_option("-a", "--map filename", action="store", type="string", dest="MapFileList",
609            help="Specify map file list, quoted by \"\".")
610        Parser.add_option("-s", "--source files", action="store", type="string", dest="SourceFileList",
611            help="Specify source file list by a file")
612        Parser.add_option("-i", "--include dirs", action="store", type="string", dest="IncludeDirList",
613            help="Specify include dir list by a file")
614        Parser.add_option("-e", "--dec files", action="store", type="string", dest="DecFileList",
615            help="Specify dec file list by a file")
616        Parser.add_option("-g", "--guid list", action="store", type="string", dest="GuidList",
617            help="Specify guid file list by a file")
618        Parser.add_option("-l", "--log filename", action="store", type="string", dest="LogFile",
619            help="Specify real execution log file")
620
621        Parser.add_option("-k", "--keepdatabase", action="store_true", type=None, help="The existing Eot database will not be cleaned except report information if this option is specified.")
622
623        Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")
624        Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed, "\
625                                                                                   "including library instances selected, final dependency expression, "\
626                                                                                   "and warning messages, etc.")
627        Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")
628
629        (Opt, Args)=Parser.parse_args()
630
631        return (Opt, Args)
632
633##
634#
635# This acts like the main() function for the script, unless it is 'import'ed into another
636# script.
637#
638if __name__ == '__main__':
639    # Initialize log system
640    EdkLogger.Initialize()
641    EdkLogger.IsRaiseError = False
642    EdkLogger.quiet(time.strftime("%H:%M:%S, %b.%d %Y ", time.localtime()) + "[00:00]" + "\n")
643
644    StartTime = time.clock()
645    Eot = Eot()
646    FinishTime = time.clock()
647
648    BuildDuration = time.strftime("%M:%S", time.gmtime(int(round(FinishTime - StartTime))))
649    EdkLogger.quiet("\n%s [%s]" % (time.strftime("%H:%M:%S, %b.%d %Y", time.localtime()), BuildDuration))
650