]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/build/BuildReport.py
BaseTools: Clean some coding style issues
[mirror_edk2.git] / BaseTools / Source / Python / build / BuildReport.py
index 13d28ff3bad73996982ef75e301907164fbf7772..722d8b7f458cbec76d46412f57eda0944d191119 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 - 2011, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2010 - 2014, 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
@@ -16,7 +16,7 @@
 \r
 ## Import Modules\r
 #\r
-import os\r
+import Common.LongFilePathOs as os\r
 import re\r
 import platform\r
 import textwrap\r
@@ -33,7 +33,15 @@ from Common.Misc import GuidStructureStringToGuidString
 from Common.InfClassObject import gComponentType2ModuleType\r
 from Common.BuildToolError import FILE_WRITE_FAILURE\r
 from Common.BuildToolError import CODE_ERROR\r
-\r
+from Common.DataType import TAB_LINE_BREAK\r
+from Common.DataType import TAB_DEPEX\r
+from Common.DataType import TAB_SLASH\r
+from Common.DataType import TAB_SPACE_SPLIT\r
+from Common.DataType import TAB_BRG_PCD\r
+from Common.DataType import TAB_BRG_LIBRARY\r
+from Common.DataType import TAB_BACK_SLASH\r
+from Common.LongFilePathSupport import OpenLongFilePath as open\r
+from Common.MultipleWorkspace import MultipleWorkspace as mws\r
 \r
 ## Pattern to extract contents in EDK DXS files\r
 gDxsDependencyPattern = re.compile(r"DEPENDENCY_START(.+)DEPENDENCY_END", re.DOTALL)\r
@@ -63,15 +71,22 @@ gIncludePattern2 = re.compile(r"#include\s+EFI_([A-Z_]+)\s*[(]\s*(\w+)\s*[)]")
 ## Pattern to find the entry point for EDK module using EDKII Glue library\r
 gGlueLibEntryPoint = re.compile(r"__EDKII_GLUE_MODULE_ENTRY_POINT__\s*=\s*(\w+)")\r
 \r
+## Tags for MaxLength of line in report\r
+gLineMaxLength = 120\r
+\r
+## Tags for end of line in report\r
+gEndOfLine = "\r\n"\r
+\r
 ## Tags for section start, end and separator\r
-gSectionStart = ">" + "=" * 118 + "<"\r
-gSectionEnd = "<" + "=" * 118 + ">" + "\n"\r
-gSectionSep = "=" * 120\r
+gSectionStart = ">" + "=" * (gLineMaxLength - 2) + "<"\r
+gSectionEnd = "<" + "=" * (gLineMaxLength - 2) + ">" + "\n"\r
+gSectionSep = "=" * gLineMaxLength\r
 \r
 ## Tags for subsection start, end and separator\r
-gSubSectionStart = ">" + "-" * 118 + "<"\r
-gSubSectionEnd = "<" + "-" * 118 + ">"\r
-gSubSectionSep = "-" * 120\r
+gSubSectionStart = ">" + "-" * (gLineMaxLength - 2) + "<"\r
+gSubSectionEnd = "<" + "-" * (gLineMaxLength - 2) + ">"\r
+gSubSectionSep = "-" * gLineMaxLength\r
+\r
 \r
 ## The look up table to map PCD type to pair of report display type and DEC type\r
 gPcdTypeMap = {\r
@@ -81,9 +96,9 @@ gPcdTypeMap = {
   'Dynamic'          : ('DYN',    'Dynamic'),\r
   'DynamicHii'       : ('DYNHII', 'Dynamic'),\r
   'DynamicVpd'       : ('DYNVPD', 'Dynamic'),\r
-  'DynamicEx'        : ('DEX',    'Dynamic'),\r
-  'DynamicExHii'     : ('DEXHII', 'Dynamic'),\r
-  'DynamicExVpd'     : ('DEXVPD', 'Dynamic'),\r
+  'DynamicEx'        : ('DEX',    'DynamicEx'),\r
+  'DynamicExHii'     : ('DEXHII', 'DynamicEx'),\r
+  'DynamicExVpd'     : ('DEXVPD', 'DynamicEx'),\r
   }\r
 \r
 ## The look up table to map module type to driver type\r
@@ -118,7 +133,7 @@ gOpCodeList = ["BEFORE", "AFTER", "PUSH", "AND", "OR", "NOT", "TRUE", "FALSE", "
 def FileWrite(File, String, Wrapper=False):\r
     if Wrapper:\r
         String = textwrap.fill(String, 120)\r
-    File.write(String + "\r\n")\r
+    File.write(String + gEndOfLine)\r
 \r
 ##\r
 # Find all the header file that the module source directly includes.\r
@@ -166,6 +181,39 @@ def FindIncludeFiles(Source, IncludePathList, IncludeFiles):
                 IncludeFiles[FullFileName.lower().replace("\\", "/")] = FullFileName\r
                 break\r
 \r
+## Split each lines in file\r
+#\r
+#  This method is used to split the lines in file to make the length of each line \r
+#  less than MaxLength.\r
+#\r
+#  @param      Content           The content of file\r
+#  @param      MaxLength         The Max Length of the line\r
+#\r
+def FileLinesSplit(Content=None, MaxLength=None):\r
+    ContentList = Content.split(TAB_LINE_BREAK)\r
+    NewContent = ''\r
+    NewContentList = []\r
+    for Line in ContentList:\r
+        while len(Line.rstrip()) > MaxLength:\r
+            LineSpaceIndex = Line.rfind(TAB_SPACE_SPLIT, 0, MaxLength)\r
+            LineSlashIndex = Line.rfind(TAB_SLASH, 0, MaxLength)\r
+            LineBackSlashIndex = Line.rfind(TAB_BACK_SLASH, 0, MaxLength)\r
+            if max(LineSpaceIndex, LineSlashIndex, LineBackSlashIndex) > 0:\r
+                LineBreakIndex = max(LineSpaceIndex, LineSlashIndex, LineBackSlashIndex)\r
+            else:\r
+                LineBreakIndex = MaxLength\r
+            NewContentList.append(Line[:LineBreakIndex])\r
+            Line = Line[LineBreakIndex:]\r
+        if Line:\r
+            NewContentList.append(Line)\r
+    for NewLine in NewContentList:\r
+        NewContent += NewLine + TAB_LINE_BREAK\r
+    \r
+    NewContent = NewContent.replace(TAB_LINE_BREAK, gEndOfLine).replace('\r\r\n', gEndOfLine)\r
+    return NewContent\r
+    \r
+    \r
+    \r
 ##\r
 # Parse binary dependency expression section\r
 #\r
@@ -184,16 +232,17 @@ class DepexParser(object):
     #\r
     def __init__(self, Wa):\r
         self._GuidDb = {}\r
-        for Package in Wa.BuildDatabase.WorkspaceDb.PackageList:\r
-            for Protocol in Package.Protocols:\r
-                GuidValue = GuidStructureStringToGuidString(Package.Protocols[Protocol])\r
-                self._GuidDb[GuidValue.upper()] = Protocol\r
-            for Ppi in Package.Ppis:\r
-                GuidValue = GuidStructureStringToGuidString(Package.Ppis[Ppi])\r
-                self._GuidDb[GuidValue.upper()] = Ppi\r
-            for Guid in Package.Guids:\r
-                GuidValue = GuidStructureStringToGuidString(Package.Guids[Guid])\r
-                self._GuidDb[GuidValue.upper()] = Guid\r
+        for Pa in Wa.AutoGenObjectList:\r
+            for Package in Pa.PackageList:\r
+                for Protocol in Package.Protocols:\r
+                    GuidValue = GuidStructureStringToGuidString(Package.Protocols[Protocol])\r
+                    self._GuidDb[GuidValue.upper()] = Protocol\r
+                for Ppi in Package.Ppis:\r
+                    GuidValue = GuidStructureStringToGuidString(Package.Ppis[Ppi])\r
+                    self._GuidDb[GuidValue.upper()] = Ppi\r
+                for Guid in Package.Guids:\r
+                    GuidValue = GuidStructureStringToGuidString(Package.Guids[Guid])\r
+                    self._GuidDb[GuidValue.upper()] = Guid\r
     \r
     ##\r
     # Parse the binary dependency expression files.\r
@@ -212,12 +261,12 @@ class DepexParser(object):
             Statement = gOpCodeList[struct.unpack("B", OpCode)[0]]\r
             if Statement in ["BEFORE", "AFTER", "PUSH"]:\r
                 GuidValue = "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X" % \\r
-                            struct.unpack("LHHBBBBBBBB", DepexFile.read(16))\r
+                            struct.unpack("=LHHBBBBBBBB", DepexFile.read(16))\r
                 GuidString = self._GuidDb.get(GuidValue, GuidValue)\r
                 Statement = "%s %s" % (Statement, GuidString)\r
             DepexStatement.append(Statement)\r
-            OpCode = DepexFile.read(1)     \r
-        \r
+            OpCode = DepexFile.read(1)\r
+\r
         return DepexStatement\r
     \r
 ##\r
@@ -262,7 +311,7 @@ class LibraryReport(object):
     #\r
     def GenerateReport(self, File):\r
         FileWrite(File, gSubSectionStart)\r
-        FileWrite(File, "Library")\r
+        FileWrite(File, TAB_BRG_LIBRARY)\r
         if len(self.LibraryList) > 0:\r
             FileWrite(File, gSubSectionSep)\r
             for LibraryItem in self.LibraryList:\r
@@ -312,7 +361,7 @@ class DepexReport(object):
     #\r
     def __init__(self, M):\r
         self.Depex = ""\r
-        self._DepexFileName = os.path.join(M.BuildDir, "OUTPUT", M.Module.BaseName + ".depex") \r
+        self._DepexFileName = os.path.join(M.BuildDir, "OUTPUT", M.Module.BaseName + ".depex")\r
         ModuleType = M.ModuleType\r
         if not ModuleType:\r
             ModuleType = gComponentType2ModuleType.get(M.ComponentType, "")\r
@@ -354,8 +403,10 @@ 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
-\r
         FileWrite(File, gSubSectionStart)\r
         if os.path.isfile(self._DepexFileName):\r
             try:\r
@@ -485,8 +536,8 @@ class ModuleReport(object):
             # 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, 16) >= 0x0001000A:\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
@@ -641,15 +692,17 @@ class PcdReport(object):
         # Collect PCD DEC default value.\r
         #\r
         self.DecPcdDefault = {}\r
-        for Package in Wa.BuildDatabase.WorkspaceDb.PackageList:\r
-            for (TokenCName, TokenSpaceGuidCName, DecType) in Package.Pcds:\r
-                DecDefaultValue = Package.Pcds[TokenCName, TokenSpaceGuidCName, DecType].DefaultValue\r
-                self.DecPcdDefault.setdefault((TokenCName, TokenSpaceGuidCName, DecType), DecDefaultValue)\r
+        for Pa in Wa.AutoGenObjectList:\r
+            for Package in Pa.PackageList:\r
+                for (TokenCName, TokenSpaceGuidCName, DecType) in Package.Pcds:\r
+                    DecDefaultValue = Package.Pcds[TokenCName, TokenSpaceGuidCName, DecType].DefaultValue\r
+                    self.DecPcdDefault.setdefault((TokenCName, TokenSpaceGuidCName, DecType), DecDefaultValue)\r
         #\r
         # Collect PCDs defined in DSC common section\r
         #\r
         self.DscPcdDefault = {}\r
-        for Platform in Wa.BuildDatabase.WorkspaceDb.PlatformList:\r
+        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
                 if DscDefaultValue:\r
@@ -683,7 +736,7 @@ class PcdReport(object):
             # For module PCD sub-section\r
             #\r
             FileWrite(File, gSubSectionStart)\r
-            FileWrite(File, "PCD")\r
+            FileWrite(File, TAB_BRG_PCD)\r
             FileWrite(File, gSubSectionSep)\r
 \r
         for Key in self.AllPcds:\r
@@ -760,20 +813,20 @@ class PcdReport(object):
                     # 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.strip()))\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.strip()))\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.strip()))\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.strip()))\r
-                    \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
                             if TypeName in ('DYNHII', 'DEXHII'):\r
-                                FileWrite(File, '%*s: %s: %s' % (self.MaxLen + 4, SkuInfo.VariableGuid, SkuInfo.VariableName, SkuInfo.VariableOffset))        \r
+                                FileWrite(File, '%*s: %s: %s' % (self.MaxLen + 4, SkuInfo.VariableGuid, SkuInfo.VariableName, SkuInfo.VariableOffset))\r
                             else:\r
                                 FileWrite(File, '%*s' % (self.MaxLen + 4, SkuInfo.VpdOffset))\r
                                \r
@@ -1174,18 +1227,19 @@ class FdRegionReport(object):
             self._DiscoverNestedFvList(FvName, Wa)\r
 \r
         PlatformPcds = {}\r
-        \r
         #\r
         # Collect PCDs declared in DEC files.\r
+        #        \r
+        for Pa in Wa.AutoGenObjectList:\r
+            for Package in Pa.PackageList:\r
+                for (TokenCName, TokenSpaceGuidCName, DecType) in Package.Pcds:\r
+                    DecDefaultValue = Package.Pcds[TokenCName, TokenSpaceGuidCName, DecType].DefaultValue\r
+                    PlatformPcds[(TokenCName, TokenSpaceGuidCName)] = DecDefaultValue\r
         #\r
-        for Package in Wa.BuildDatabase.WorkspaceDb.PackageList:\r
-            for (TokenCName, TokenSpaceGuidCName, DecType) in Package.Pcds:\r
-                DecDefaultValue = Package.Pcds[TokenCName, TokenSpaceGuidCName, DecType].DefaultValue\r
-                PlatformPcds[(TokenCName, TokenSpaceGuidCName)] = DecDefaultValue\r
-        #\r
-        # Collect PCDs defined in DSC common section\r
+        # Collect PCDs defined in DSC file\r
         #\r
-        for Platform in Wa.BuildDatabase.WorkspaceDb.PlatformList:\r
+        for arch in Wa.ArchList:\r
+            Platform = Wa.BuildDatabase[Wa.MetaFile, arch]\r
             for (TokenCName, TokenSpaceGuidCName) in Platform.Pcds:\r
                 DscDefaultValue = Platform.Pcds[(TokenCName, TokenSpaceGuidCName)].DefaultValue\r
                 PlatformPcds[(TokenCName, TokenSpaceGuidCName)] = DscDefaultValue\r
@@ -1203,7 +1257,7 @@ class FdRegionReport(object):
         for Pa in Wa.AutoGenObjectList:\r
             for ModuleKey in Pa.Platform.Modules:\r
                 M = Pa.Platform.Modules[ModuleKey].M\r
-                InfPath = os.path.join(Wa.WorkspaceDir, M.MetaFile.File)\r
+                InfPath = mws.join(Wa.WorkspaceDir, M.MetaFile.File)\r
                 self._GuidsDb[M.Guid.upper()] = "%s (%s)" % (M.Module.BaseName, InfPath)\r
 \r
         #\r
@@ -1225,7 +1279,7 @@ class FdRegionReport(object):
                             Guid = GuidStructureByteArrayToGuidString(GuidValue).upper()\r
                     for Section in Ffs.SectionList:\r
                         try:\r
-                            ModuleSectFile = os.path.join(Wa.WorkspaceDir, Section.SectFileName)\r
+                            ModuleSectFile = mws.join(Wa.WorkspaceDir, Section.SectFileName)\r
                             self._GuidsDb[Guid] = ModuleSectFile\r
                         except AttributeError:\r
                             pass\r
@@ -1256,7 +1310,7 @@ class FdRegionReport(object):
             FvTotalSize = 0\r
             FvTakenSize = 0\r
             FvFreeSize  = 0\r
-            FvReportFileName = os.path.join(self._FvDir, FvName + ".fv.txt")\r
+            FvReportFileName = os.path.join(self._FvDir, FvName + ".Fv.txt")\r
             try:\r
                 #\r
                 # Collect size info in the firmware volume.\r
@@ -1333,6 +1387,32 @@ class FdReport(object):
         self.BaseAddress = Fd.BaseAddress\r
         self.Size = Fd.Size\r
         self.FdRegionList = [FdRegionReport(FdRegion, Wa) for FdRegion in Fd.RegionList]\r
+        self.FvPath = os.path.join(Wa.BuildDir, "FV")\r
+        self.VpdFilePath = os.path.join(self.FvPath, "%s.map" % Wa.Platform.VpdToolGuid)\r
+        VpdPcdToken = 'gEfiMdeModulePkgTokenSpaceGuid'\r
+        VpdPcdName = 'PcdVpdBaseAddress'\r
+        self.VPDInfoList = []\r
+        for index, FdRegion in enumerate(Fd.RegionList):\r
+            if (VpdPcdName, VpdPcdToken) == FdRegion.PcdOffset:\r
+                self.VPDBaseAddress = self.FdRegionList[index].BaseAddress\r
+                self.VPDSize = self.FdRegionList[index].Size\r
+                break\r
+\r
+        if os.path.isfile(self.VpdFilePath):\r
+            fd = open(self.VpdFilePath, "r")\r
+            Lines = fd.readlines()\r
+            for Line in Lines:\r
+                Line = Line.strip()\r
+                if len(Line) == 0 or Line.startswith("#"):\r
+                    continue\r
+                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
+                    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
+            fd.close()\r
 \r
     ##\r
     # Generate report for the firmware device.\r
@@ -1353,6 +1433,15 @@ class FdReport(object):
             for FdRegionItem in self.FdRegionList:\r
                 FdRegionItem.GenerateReport(File)\r
 \r
+        if len(self.VPDInfoList) > 0:\r
+            FileWrite(File, gSubSectionStart)\r
+            FileWrite(File, "FD VPD Region")\r
+            FileWrite(File, "Base Address:       0x%X" % self.VPDBaseAddress)\r
+            FileWrite(File, "Size:               0x%X (%.0fK)" % (self.VPDSize, self.VPDSize / 1024.0))\r
+            FileWrite(File, gSubSectionSep)\r
+            for item in self.VPDInfoList:\r
+                FileWrite(File, item)\r
+            FileWrite(File, gSubSectionEnd)\r
         FileWrite(File, gSectionEnd)\r
 \r
 \r
@@ -1509,7 +1598,8 @@ class BuildReport(object):
                 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
+                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
             except IOError:\r
                 EdkLogger.error(None, FILE_WRITE_FAILURE, ExtraData=self.ReportFile)\r