]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/build/BuildReport.py
BaseTools: PcdDataBase Optimization for multiple SkuIds
[mirror_edk2.git] / BaseTools / Source / Python / build / BuildReport.py
index 27a5d9736efa32d5f1b7645adb38f5facb356ade..6a4d7e099b69806f631d6dea6b5f37a79ca0126d 100644 (file)
@@ -4,7 +4,7 @@
 # This module contains the functionality to generate build report after\r
 # build all target completes successfully.\r
 #\r
-# Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2010 - 2017, 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
@@ -47,6 +47,9 @@ from Common.DataType import TAB_BACK_SLASH
 from Common.LongFilePathSupport import OpenLongFilePath as open\r
 from Common.MultipleWorkspace import MultipleWorkspace as mws\r
 import Common.GlobalData as GlobalData\r
+from AutoGen.AutoGen import ModuleAutoGen\r
+from Common.Misc import PathClass\r
+from Common.String import NormPath\r
 \r
 ## Pattern to extract contents in EDK DXS files\r
 gDxsDependencyPattern = re.compile(r"DEPENDENCY_START(.+)DEPENDENCY_END", re.DOTALL)\r
@@ -120,6 +123,8 @@ gDriverTypeMap = {
   'UEFI_APPLICATION'  : '0x9 (APPLICATION)',\r
   'SMM_CORE'          : '0xD (SMM_CORE)',\r
   'SMM_DRIVER'        : '0xA (SMM)', # Extension of module type to support PI 1.1 SMM drivers\r
+  'MM_STANDALONE'     : '0xE (MM_STANDALONE)',\r
+  'MM_CORE_STANDALONE' : '0xF (MM_CORE_STANDALONE)'\r
   }\r
 \r
 ## The look up table of the supported opcode in the dependency expression binaries\r
@@ -302,7 +307,11 @@ class LibraryReport(object):
             LibConstructorList = Lib.ConstructorList\r
             LibDesstructorList = Lib.DestructorList\r
             LibDepexList = Lib.DepexExpression[M.Arch, M.ModuleType]\r
-            self.LibraryList.append((LibInfPath, LibClassList, LibConstructorList, LibDesstructorList, LibDepexList))\r
+            for LibAutoGen in M.LibraryAutoGenList:\r
+                if LibInfPath == LibAutoGen.MetaFile.Path:\r
+                    LibTime = LibAutoGen.BuildTime\r
+                    break\r
+            self.LibraryList.append((LibInfPath, LibClassList, LibConstructorList, LibDesstructorList, LibDepexList, LibTime))\r
 \r
     ##\r
     # Generate report for module library information\r
@@ -315,9 +324,9 @@ class LibraryReport(object):
     # @param File            The file object for report\r
     #\r
     def GenerateReport(self, File):\r
-        FileWrite(File, gSubSectionStart)\r
-        FileWrite(File, TAB_BRG_LIBRARY)\r
         if len(self.LibraryList) > 0:\r
+            FileWrite(File, gSubSectionStart)\r
+            FileWrite(File, TAB_BRG_LIBRARY)\r
             FileWrite(File, gSubSectionSep)\r
             for LibraryItem in self.LibraryList:\r
                 LibInfPath = LibraryItem[0]\r
@@ -339,12 +348,14 @@ class LibraryReport(object):
                     LibDepex = " ".join(LibraryItem[4])\r
                     if LibDepex:\r
                         EdkIILibInfo += " Depex = " + LibDepex\r
+                    if LibraryItem[5]:\r
+                        EdkIILibInfo += " Time = " + LibraryItem[5]\r
                     if EdkIILibInfo:\r
                         FileWrite(File, "{%s: %s}" % (LibClass, EdkIILibInfo))\r
                     else:\r
                         FileWrite(File, "{%s}" % LibClass)\r
 \r
-        FileWrite(File, gSubSectionEnd)\r
+            FileWrite(File, gSubSectionEnd)\r
 \r
 ##\r
 # Reports dependency expression information\r
@@ -371,7 +382,7 @@ class DepexReport(object):
         if not ModuleType:\r
             ModuleType = gComponentType2ModuleType.get(M.ComponentType, "")\r
 \r
-        if ModuleType in ["SEC", "PEI_CORE", "DXE_CORE", "SMM_CORE", "UEFI_APPLICATION"]:\r
+        if ModuleType in ["SEC", "PEI_CORE", "DXE_CORE", "SMM_CORE", "MM_CORE_STANDALONE", "UEFI_APPLICATION"]:\r
             return\r
       \r
         for Source in M.SourceFileList:\r
@@ -408,9 +419,6 @@ class DepexReport(object):
     #\r
     def GenerateReport(self, File, GlobalDepexParser):\r
         if not self.Depex:\r
-            FileWrite(File, gSubSectionStart)\r
-            FileWrite(File, TAB_DEPEX)\r
-            FileWrite(File, gSubSectionEnd)\r
             return\r
         FileWrite(File, gSubSectionStart)\r
         if os.path.isfile(self._DepexFileName):\r
@@ -551,6 +559,7 @@ class ModuleReport(object):
         self.PciDeviceId = M.Module.Defines.get("PCI_DEVICE_ID", "")\r
         self.PciVendorId = M.Module.Defines.get("PCI_VENDOR_ID", "")\r
         self.PciClassCode = M.Module.Defines.get("PCI_CLASS_CODE", "")\r
+        self.BuildTime = M.BuildTime\r
 \r
         self._BuildDir = M.BuildDir\r
         self.ModulePcdSet = {}\r
@@ -646,6 +655,8 @@ class ModuleReport(object):
             FileWrite(File, "SHA1 HASH:            %s *%s" % (self.Hash, self.ModuleName + ".efi"))\r
         if self.BuildTimeStamp:\r
             FileWrite(File, "Build Time Stamp:     %s" % self.BuildTimeStamp)\r
+        if self.BuildTime:\r
+            FileWrite(File, "Module Build Time:    %s" % self.BuildTime)\r
         if self.DriverType:\r
             FileWrite(File, "Driver Type:          %s" % self.DriverType)\r
         if self.UefiSpecVersion:\r
@@ -735,6 +746,13 @@ class PcdReport(object):
             UnusedPcdFullList = []\r
             for item in Pa.Platform.Pcds:\r
                 Pcd = Pa.Platform.Pcds[item]\r
+                if not Pcd.Type:\r
+                    # check the Pcd in FDF file, whether it is used in module first\r
+                    for T in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:\r
+                        PcdList = self.AllPcds.setdefault(Pcd.TokenSpaceGuidCName, {}).setdefault(T, [])\r
+                        if Pcd in PcdList:\r
+                            Pcd.Type = T\r
+                            break\r
                 if not Pcd.Type:\r
                     PcdTypeFlag = False\r
                     for package in Pa.PackageList:\r
@@ -815,7 +833,7 @@ class PcdReport(object):
         for Arch in Wa.ArchList:\r
             Platform = Wa.BuildDatabase[Wa.MetaFile, Arch, Wa.BuildTarget, Wa.ToolChain]\r
             for (TokenCName, TokenSpaceGuidCName) in Platform.Pcds:\r
-                DscDefaultValue = Platform.Pcds[(TokenCName, TokenSpaceGuidCName)].DefaultValue\r
+                DscDefaultValue = Platform.Pcds[(TokenCName, TokenSpaceGuidCName)].DscDefaultValue\r
                 if DscDefaultValue:\r
                     self.DscPcdDefault[(TokenCName, TokenSpaceGuidCName)] = DscDefaultValue\r
 \r
@@ -863,7 +881,7 @@ class PcdReport(object):
                 FileWrite(File, "  *M  - Module scoped PCD override")\r
             FileWrite(File, gSectionSep)\r
         else:\r
-            if not ReportSubType:\r
+            if not ReportSubType and ModulePcdSet:\r
                 #\r
                 # For module PCD sub-section\r
                 #\r
@@ -882,11 +900,21 @@ class PcdReport(object):
                 #\r
                 TypeName, DecType = gPcdTypeMap.get(Type, ("", Type))\r
                 for Pcd in PcdDict[Key][Type]:\r
+                    PcdTokenCName = Pcd.TokenCName\r
+                    MixedPcdFlag = False\r
+                    if GlobalData.MixedPcd:\r
+                        for PcdKey in GlobalData.MixedPcd:\r
+                            if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdKey]:\r
+                                PcdTokenCName = PcdKey[0]\r
+                                MixedPcdFlag = True\r
+                        if MixedPcdFlag and not ModulePcdSet:\r
+                            continue\r
                     #\r
                     # Get PCD default value and their override relationship\r
                     #\r
                     DecDefaultValue = self.DecPcdDefault.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, DecType))\r
                     DscDefaultValue = self.DscPcdDefault.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName))\r
+                    DscDefaultValBak= DscDefaultValue\r
                     DscDefaultValue = self.FdfPcdSet.get((Pcd.TokenCName, Key), DscDefaultValue)\r
                     InfDefaultValue = None\r
                     \r
@@ -953,18 +981,18 @@ class PcdReport(object):
                     #\r
                     # Report PCD item according to their override relationship\r
                     #\r
-                    if BuildOptionMatch:\r
-                        FileWrite(File, ' *B %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '(' + Pcd.DatumType + ')', PcdValue.strip()))\r
-                    elif DecMatch and InfMatch:\r
-                        FileWrite(File, '    %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '(' + Pcd.DatumType + ')', PcdValue.strip()))\r
+                    if DecMatch and InfMatch:\r
+                        FileWrite(File, '    %-*s: %6s %10s = %-22s' % (self.MaxLen, PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', PcdValue.strip()))\r
+                    elif BuildOptionMatch:\r
+                        FileWrite(File, ' *B %-*s: %6s %10s = %-22s' % (self.MaxLen, PcdTokenCName, 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.strip()))\r
+                                FileWrite(File, ' *F %-*s: %6s %10s = %-22s' % (self.MaxLen, PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', PcdValue.strip()))\r
                             else:\r
-                                FileWrite(File, ' *P %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '(' + Pcd.DatumType + ')', PcdValue.strip()))\r
+                                FileWrite(File, ' *P %-*s: %6s %10s = %-22s' % (self.MaxLen, PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', PcdValue.strip()))\r
                         else:\r
-                            FileWrite(File, ' *M %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '(' + Pcd.DatumType + ')', PcdValue.strip()))\r
+                            FileWrite(File, ' *M %-*s: %6s %10s = %-22s' % (self.MaxLen, PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', PcdValue.strip()))\r
 \r
                     if TypeName in ('DYNHII', 'DEXHII', 'DYNVPD', 'DEXVPD'):\r
                         for SkuInfo in Pcd.SkuInfoList.values():\r
@@ -973,8 +1001,8 @@ class PcdReport(object):
                             else:\r
                                 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.strip()))\r
+                    if not DscMatch and DscDefaultValBak != None:\r
+                        FileWrite(File, '    %*s = %s' % (self.MaxLen + 19, 'DSC DEFAULT', DscDefaultValBak.strip()))\r
 \r
                     if not InfMatch and InfDefaultValue != None:\r
                         FileWrite(File, '    %*s = %s' % (self.MaxLen + 19, 'INF DEFAULT', InfDefaultValue.strip()))\r
@@ -999,7 +1027,7 @@ class PcdReport(object):
         if ModulePcdSet == None:\r
             FileWrite(File, gSectionEnd)\r
         else:\r
-            if not ReportSubType:\r
+            if not ReportSubType and ModulePcdSet:\r
                 FileWrite(File, gSubSectionEnd)\r
 \r
 \r
@@ -1557,7 +1585,10 @@ class FdReport(object):
                 try:\r
                     PcdName, SkuId, Offset, Size, Value = Line.split("#")[0].split("|")\r
                     PcdName, SkuId, Offset, Size, Value = PcdName.strip(), SkuId.strip(), Offset.strip(), Size.strip(), Value.strip()\r
-                    Offset = '0x%08X' % (int(Offset, 16) + self.VPDBaseAddress)\r
+                    if Offset.lower().startswith('0x'):\r
+                        Offset = '0x%08X' % (int(Offset, 16) + self.VPDBaseAddress)\r
+                    else:\r
+                        Offset = '0x%08X' % (int(Offset, 10) + self.VPDBaseAddress)\r
                     self.VPDInfoList.append("%s | %s | %s | %s | %s" % (PcdName, SkuId, Offset, Size, Value))\r
                 except:\r
                     EdkLogger.error("BuildReport", CODE_ERROR, "Fail to parse VPD information file %s" % self.VpdFilePath)\r
@@ -1647,8 +1678,21 @@ class PlatformReport(object):
         else:\r
             self._IsModuleBuild = False\r
             for Pa in Wa.AutoGenObjectList:\r
+                ModuleAutoGenList = []\r
                 for ModuleKey in Pa.Platform.Modules:\r
-                    self.ModuleReportList.append(ModuleReport(Pa.Platform.Modules[ModuleKey].M, ReportType))\r
+                    ModuleAutoGenList.append(Pa.Platform.Modules[ModuleKey].M)\r
+                if GlobalData.gFdfParser != None:\r
+                    if Pa.Arch in GlobalData.gFdfParser.Profile.InfDict:\r
+                        INFList = GlobalData.gFdfParser.Profile.InfDict[Pa.Arch]\r
+                        for InfName in INFList:\r
+                            InfClass = PathClass(NormPath(InfName), Wa.WorkspaceDir, Pa.Arch)\r
+                            Ma = ModuleAutoGen(Wa, InfClass, Pa.BuildTarget, Pa.ToolChain, Pa.Arch, Wa.MetaFile)\r
+                            if Ma == None:\r
+                                continue\r
+                            if Ma not in ModuleAutoGenList:\r
+                                ModuleAutoGenList.append(Ma)\r
+                for MGen in ModuleAutoGenList:\r
+                    self.ModuleReportList.append(ModuleReport(MGen, ReportType))\r
 \r
 \r
 \r
@@ -1662,9 +1706,12 @@ class PlatformReport(object):
     # @param self            The object pointer\r
     # @param File            The file object for report\r
     # @param BuildDuration   The total time to build the modules\r
+    # @param AutoGenTime     The total time of AutoGen Phase\r
+    # @param MakeTime        The total time of Make Phase\r
+    # @param GenFdsTime      The total time of GenFds Phase\r
     # @param ReportType      The kind of report items in the final report file\r
     #\r
-    def GenerateReport(self, File, BuildDuration, ReportType):\r
+    def GenerateReport(self, File, BuildDuration, AutoGenTime, MakeTime, GenFdsTime, ReportType):\r
         FileWrite(File, "Platform Summary")\r
         FileWrite(File, "Platform Name:        %s" % self.PlatformName)\r
         FileWrite(File, "Platform DSC Path:    %s" % self.PlatformDscPath)\r
@@ -1674,8 +1721,22 @@ class PlatformReport(object):
         FileWrite(File, "Output Path:          %s" % self.OutputPath)\r
         FileWrite(File, "Build Environment:    %s" % self.BuildEnvironment)\r
         FileWrite(File, "Build Duration:       %s" % BuildDuration)\r
+        if AutoGenTime:\r
+            FileWrite(File, "AutoGen Duration:     %s" % AutoGenTime)\r
+        if MakeTime:\r
+            FileWrite(File, "Make Duration:        %s" % MakeTime)\r
+        if GenFdsTime:\r
+            FileWrite(File, "GenFds Duration:      %s" % GenFdsTime)\r
         FileWrite(File, "Report Content:       %s" % ", ".join(ReportType))\r
 \r
+        if GlobalData.MixedPcd:\r
+            FileWrite(File, gSectionStart)\r
+            FileWrite(File, "The following PCDs use different access methods:")\r
+            FileWrite(File, gSectionSep)\r
+            for PcdItem in GlobalData.MixedPcd:\r
+                FileWrite(File, "%s.%s" % (str(PcdItem[1]), str(PcdItem[0])))\r
+            FileWrite(File, gSectionEnd)\r
+\r
         if not self._IsModuleBuild:\r
             if "PCD" in ReportType:\r
                 self.PcdReport.GenerateReport(File, None)\r
@@ -1740,13 +1801,16 @@ class BuildReport(object):
     #\r
     # @param self            The object pointer\r
     # @param BuildDuration   The total time to build the modules\r
+    # @param AutoGenTime     The total time of AutoGen phase\r
+    # @param MakeTime        The total time of Make phase\r
+    # @param GenFdsTime      The total time of GenFds phase\r
     #\r
-    def GenerateReport(self, BuildDuration):\r
+    def GenerateReport(self, BuildDuration, AutoGenTime, MakeTime, GenFdsTime):\r
         if self.ReportFile:\r
             try:\r
                 File = StringIO('')\r
                 for (Wa, MaList) in self.ReportList:\r
-                    PlatformReport(Wa, MaList, self.ReportType).GenerateReport(File, BuildDuration, self.ReportType)\r
+                    PlatformReport(Wa, MaList, self.ReportType).GenerateReport(File, BuildDuration, AutoGenTime, MakeTime, GenFdsTime, self.ReportType)\r
                 Content = FileLinesSplit(File.getvalue(), gLineMaxLength)\r
                 SaveFileOnChange(self.ReportFile, Content, True)\r
                 EdkLogger.quiet("Build report can be found at %s" % os.path.abspath(self.ReportFile))\r