X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2Fbuild%2FBuildReport.py;h=af03e1f982d04291f4b94e6702dce847e30e47df;hp=23e819e5cab1a9d01aded9624e7551137292295f;hb=40d841f6a8f84e75409178e19e69b95e01bada0f;hpb=52302d4dee589a5df43a464420c9fe68ba83937d diff --git a/BaseTools/Source/Python/build/BuildReport.py b/BaseTools/Source/Python/build/BuildReport.py index 23e819e5ca..af03e1f982 100644 --- a/BaseTools/Source/Python/build/BuildReport.py +++ b/BaseTools/Source/Python/build/BuildReport.py @@ -4,8 +4,8 @@ # This module contains the functionality to generate build report after # build all target completes successfully. # -# Copyright (c) 2010, Intel Corporation -# All rights reserved. This program and the accompanying materials +# Copyright (c) 2010, Intel Corporation. All rights reserved.
+# This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License # which accompanies this distribution. The full text of the license may be found at # http://opensource.org/licenses/bsd-license.php @@ -22,12 +22,14 @@ import platform import textwrap import traceback import sys +import time from datetime import datetime +from StringIO import StringIO from Common import EdkLogger +from Common.Misc import SaveFileOnChange from Common.Misc import GuidStructureByteArrayToGuidString from Common.Misc import GuidStructureStringToGuidString from Common.InfClassObject import gComponentType2ModuleType -from Common.BuildToolError import FILE_OPEN_FAILURE from Common.BuildToolError import FILE_WRITE_FAILURE from Common.BuildToolError import CODE_ERROR @@ -221,7 +223,7 @@ class LibraryReport(object): EdkIILibInfo += " C = " + LibConstructor LibDestructor = " ".join(LibraryItem[3]) if LibDestructor: - EdkIILibInfo += " D = " + LibConstructor + EdkIILibInfo += " D = " + LibDestructor LibDepex = " ".join(LibraryItem[4]) if LibDepex: EdkIILibInfo += " Depex = " + LibDepex @@ -255,7 +257,8 @@ class DepexReport(object): ModuleType = M.ModuleType if not ModuleType: ModuleType = gComponentType2ModuleType.get(M.ComponentType, "") - if ModuleType in ["SEC", "PEI_CORE", "DXE_CORE"]: + + if ModuleType in ["SEC", "PEI_CORE", "DXE_CORE", "SMM_CORE", "UEFI_APPLICATION"]: return for Source in M.SourceFileList: @@ -404,17 +407,18 @@ class ModuleReport(object): self.Size = 0 self.BuildTimeStamp = None self.DriverType = "" - ModuleType = M.ModuleType - if not ModuleType: - ModuleType = gComponentType2ModuleType.get(M.ComponentType, "") - # - # If a module complies to PI 1.1, promote Module type to "SMM_DRIVER" - # - if ModuleType == "DXE_SMM_DRIVER": - PiSpec = M.Module.Specification.get("PI_SPECIFICATION_VERSION", "0x00010000") - if int(PiSpec, 0) >= 0x0001000A: - ModuleType = "SMM_DRIVER" - self.DriverType = gDriverTypeMap.get(ModuleType, "") + if not M.IsLibrary: + ModuleType = M.ModuleType + if not ModuleType: + ModuleType = gComponentType2ModuleType.get(M.ComponentType, "") + # + # If a module complies to PI 1.1, promote Module type to "SMM_DRIVER" + # + if ModuleType == "DXE_SMM_DRIVER": + PiSpec = M.Module.Specification.get("PI_SPECIFICATION_VERSION", "0x00010000") + if int(PiSpec, 0) >= 0x0001000A: + ModuleType = "SMM_DRIVER" + self.DriverType = gDriverTypeMap.get(ModuleType, "0x2 (FREE_FORM)") self.UefiSpecVersion = M.Module.Specification.get("UEFI_SPECIFICATION_VERSION", "") self.PiSpecVersion = M.Module.Specification.get("PI_SPECIFICATION_VERSION", "") self.PciDeviceId = M.Module.Defines.get("PCI_DEVICE_ID", "") @@ -576,7 +580,8 @@ class PcdReport(object): for Platform in Wa.BuildDatabase.WorkspaceDb.PlatformList: for (TokenCName, TokenSpaceGuidCName) in Platform.Pcds: DscDefaultValue = Platform.Pcds[(TokenCName, TokenSpaceGuidCName)].DefaultValue - self.DscPcdDefault[(TokenCName, TokenSpaceGuidCName)] = DscDefaultValue + if DscDefaultValue: + self.DscPcdDefault[(TokenCName, TokenSpaceGuidCName)] = DscDefaultValue ## # Generate report for PCD information @@ -599,7 +604,7 @@ class PcdReport(object): FileWrite(File, "Platform Configuration Database Report") FileWrite(File, " *P - Platform scoped PCD override in DSC file") FileWrite(File, " *F - Platform scoped PCD override in FDF file") - FileWrite(File, " *M - Module scoped PCD override in DSC file") + FileWrite(File, " *M - Module scoped PCD override") FileWrite(File, gSectionSep) else: # @@ -667,31 +672,31 @@ class PcdReport(object): if DecDefaultValue == None: DecMatch = True else: - DecMatch = (DecDefaultValue == PcdValue) + DecMatch = (DecDefaultValue.strip() == PcdValue.strip()) if InfDefaultValue == None: InfMatch = True else: - InfMatch = (InfDefaultValue == PcdValue) + InfMatch = (InfDefaultValue.strip() == PcdValue.strip()) if DscDefaultValue == None: DscMatch = True else: - DscMatch = (DscDefaultValue == PcdValue) + DscMatch = (DscDefaultValue.strip() == PcdValue.strip()) # # Report PCD item according to their override relationship # if DecMatch and InfMatch: - FileWrite(File, ' %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', PcdValue)) + FileWrite(File, ' %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', PcdValue.strip())) else: if DscMatch: if (Pcd.TokenCName, Key) in self.FdfPcdSet: - FileWrite(File, ' *F %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', PcdValue)) + FileWrite(File, ' *F %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', PcdValue.strip())) else: - FileWrite(File, ' *P %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', PcdValue)) + FileWrite(File, ' *P %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', PcdValue.strip())) else: - FileWrite(File, ' *M %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', PcdValue)) + FileWrite(File, ' *M %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', PcdValue.strip())) if TypeName in ('DYNHII', 'DEXHII', 'DYNVPD', 'DEXVPD'): for SkuInfo in Pcd.SkuInfoList.values(): @@ -701,13 +706,13 @@ class PcdReport(object): FileWrite(File, '%*s' % (self.MaxLen + 4, SkuInfo.VpdOffset)) if not DscMatch and DscDefaultValue != None: - FileWrite(File, ' %*s = %s' % (self.MaxLen + 19, 'DSC DEFAULT', DscDefaultValue)) + FileWrite(File, ' %*s = %s' % (self.MaxLen + 19, 'DSC DEFAULT', DscDefaultValue.strip())) if not InfMatch and InfDefaultValue != None: - FileWrite(File, ' %*s = %s' % (self.MaxLen + 19, 'INF DEFAULT', InfDefaultValue)) + FileWrite(File, ' %*s = %s' % (self.MaxLen + 19, 'INF DEFAULT', InfDefaultValue.strip())) if not DecMatch and DecDefaultValue != None: - FileWrite(File, ' %*s = %s' % (self.MaxLen + 19, 'DEC DEFAULT', DecDefaultValue)) + FileWrite(File, ' %*s = %s' % (self.MaxLen + 19, 'DEC DEFAULT', DecDefaultValue.strip())) if ModulePcdSet == None: ModuleOverride = self.ModulePcdOverride.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName), {}) @@ -717,10 +722,10 @@ class PcdReport(object): ModulePcdDefaultValueNumber = int(ModuleDefault.strip(), 0) Match = (ModulePcdDefaultValueNumber == PcdValueNumber) else: - Match = (ModuleDefault == PcdValue) + Match = (ModuleDefault.strip() == PcdValue.strip()) if Match: continue - FileWrite(File, ' *M %-*s = %s' % (self.MaxLen + 19, ModulePath, ModuleDefault)) + FileWrite(File, ' *M %-*s = %s' % (self.MaxLen + 19, ModulePath, ModuleDefault.strip())) if ModulePcdSet == None: FileWrite(File, gSectionEnd) @@ -763,6 +768,13 @@ class PredictionReport(object): for Pa in Wa.AutoGenObjectList: for Module in Pa.LibraryAutoGenList + Pa.ModuleAutoGenList: # + # BASE typed modules are EFI agnostic, so we need not scan + # their source code to find PPI/Protocol produce or consume + # information. + # + if Module.ModuleType == "BASE": + continue + # # Add module referenced source files # self._SourceList.append(str(Module)) @@ -887,12 +899,17 @@ class PredictionReport(object): try: from Eot.Eot import Eot + # - # Invoke EOT tool + # Invoke EOT tool and echo its runtime performance # + EotStartTime = time.time() Eot(CommandLineOption=False, SourceFileList=SourceList, GuidList=GuidList, FvFileList=' '.join(FvFileList), Dispatch=DispatchList, IsInit=True) - + EotEndTime = time.time() + EotDuration = time.strftime("%H:%M:%S", time.gmtime(int(round(EotEndTime - EotStartTime)))) + EdkLogger.quiet("EOT run time: %s\n" % EotDuration) + # # Parse the output of EOT tool # @@ -1283,8 +1300,9 @@ class PlatformReport(object): # # @param self The object pointer # @param Wa Workspace context information + # @param MaList The list of modules in the platform build # - def __init__(self, Wa, ReportType): + def __init__(self, Wa, MaList, ReportType): self._WorkspaceDir = Wa.WorkspaceDir self.PlatformName = Wa.Name self.PlatformDscPath = Wa.Platform @@ -1299,7 +1317,7 @@ class PlatformReport(object): self.PcdReport = PcdReport(Wa) self.FdReportList = [] - if "FLASH" in ReportType and Wa.FdfProfile: + if "FLASH" in ReportType and Wa.FdfProfile and MaList == None: for Fd in Wa.FdfProfile.FdDict: self.FdReportList.append(FdReport(Wa.FdfProfile.FdDict[Fd], Wa)) @@ -1308,9 +1326,15 @@ class PlatformReport(object): self.PredictionReport = PredictionReport(Wa) self.ModuleReportList = [] - for Pa in Wa.AutoGenObjectList: - for ModuleKey in Pa.Platform.Modules: - self.ModuleReportList.append(ModuleReport(Pa.Platform.Modules[ModuleKey].M, ReportType)) + if MaList != None: + self._IsModuleBuild = True + for Ma in MaList: + self.ModuleReportList.append(ModuleReport(Ma, ReportType)) + else: + self._IsModuleBuild = False + for Pa in Wa.AutoGenObjectList: + for ModuleKey in Pa.Platform.Modules: + self.ModuleReportList.append(ModuleReport(Pa.Platform.Modules[ModuleKey].M, ReportType)) @@ -1338,18 +1362,20 @@ class PlatformReport(object): FileWrite(File, "Build Duration: %s" % BuildDuration) FileWrite(File, "Report Content: %s" % ", ".join(ReportType)) - if "PCD" in ReportType: - self.PcdReport.GenerateReport(File, None) - - if "FLASH" in ReportType: - for FdReportListItem in self.FdReportList: - FdReportListItem.GenerateReport(File) + if not self._IsModuleBuild: + if "PCD" in ReportType: + self.PcdReport.GenerateReport(File, None) + + if "FLASH" in ReportType: + for FdReportListItem in self.FdReportList: + FdReportListItem.GenerateReport(File) for ModuleReportItem in self.ModuleReportList: ModuleReportItem.GenerateReport(File, self.PcdReport, self.PredictionReport, ReportType) - if "EXECUTION_ORDER" in ReportType: - self.PredictionReport.GenerateReport(File, None) + if not self._IsModuleBuild: + if "EXECUTION_ORDER" in ReportType: + self.PredictionReport.GenerateReport(File, None) ## BuildReport class # @@ -1386,10 +1412,11 @@ class BuildReport(object): # # @param self The object pointer # @param Wa Workspace context information + # @param MaList The list of modules in the platform build # - def AddPlatformReport(self, Wa): + def AddPlatformReport(self, Wa, MaList=None): if self.ReportFile: - self.ReportList.append(Wa) + self.ReportList.append((Wa, MaList)) ## # Generates the final report. @@ -1403,20 +1430,18 @@ class BuildReport(object): def GenerateReport(self, BuildDuration): if self.ReportFile: try: - File = open(self.ReportFile, "w+") - except IOError: - EdkLogger.error(None, FILE_OPEN_FAILURE, ExtraData=self.ReportFile) - try: - for Wa in self.ReportList: - PlatformReport(Wa, self.ReportType).GenerateReport(File, BuildDuration, self.ReportType) - EdkLogger.quiet("Report successfully saved to %s" % os.path.abspath(self.ReportFile)) + File = StringIO('') + for (Wa, MaList) in self.ReportList: + PlatformReport(Wa, MaList, self.ReportType).GenerateReport(File, BuildDuration, self.ReportType) + SaveFileOnChange(self.ReportFile, File.getvalue(), False) + EdkLogger.quiet("Build report can be found at %s" % os.path.abspath(self.ReportFile)) except IOError: EdkLogger.error(None, FILE_WRITE_FAILURE, ExtraData=self.ReportFile) except: EdkLogger.error("BuildReport", CODE_ERROR, "Unknown fatal error when generating build report", ExtraData=self.ReportFile, RaiseError=False) EdkLogger.quiet("(Python %s on %s\n%s)" % (platform.python_version(), sys.platform, traceback.format_exc())) File.close() - + # This acts like the main() function for the script, unless it is 'import'ed into another script. if __name__ == '__main__': pass