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