From c8d07c5eeb481e777ad48dc1737d1ab1be67bd44 Mon Sep 17 00:00:00 2001 From: Yonghong Zhu Date: Wed, 23 Mar 2016 17:34:13 +0800 Subject: [PATCH] BaseTools: Add two new sections for PCD in the build report Build Spec updated to add two new sections for PCD in the build report. 1.Conditional directives section:If the DSC or FDF file contains conditional directive statements. 2.Unused PCDs section: If the DSC or FDF file define values for PCDs that are not used by any module and are not used in conditional directive statements. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Yonghong Zhu Reviewed-by: Liming Gao --- BaseTools/Source/Python/Common/Expression.py | 6 +- BaseTools/Source/Python/Common/GlobalData.py | 3 + BaseTools/Source/Python/build/BuildReport.py | 112 ++++++++++++++++--- 3 files changed, 104 insertions(+), 17 deletions(-) diff --git a/BaseTools/Source/Python/Common/Expression.py b/BaseTools/Source/Python/Common/Expression.py index 3c8d14e6ce..7b3030c5fa 100644 --- a/BaseTools/Source/Python/Common/Expression.py +++ b/BaseTools/Source/Python/Common/Expression.py @@ -1,7 +1,7 @@ ## @file # This file is used to parse and evaluate expression in directive or PCD value. # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 2016, 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 @@ -76,6 +76,10 @@ def ReplaceExprMacro(String, Macros, ExceptionList = None): InQuote = True MacroStartPos = String.find('$(') if MacroStartPos < 0: + for Pcd in gPlatformPcds.keys(): + if Pcd in String: + if Pcd not in gConditionalPcds: + gConditionalPcds.append(Pcd) continue RetStr = '' while MacroStartPos >= 0: diff --git a/BaseTools/Source/Python/Common/GlobalData.py b/BaseTools/Source/Python/Common/GlobalData.py index 8f544bd1b2..c3439ebbfc 100644 --- a/BaseTools/Source/Python/Common/GlobalData.py +++ b/BaseTools/Source/Python/Common/GlobalData.py @@ -78,3 +78,6 @@ gFdfParser = None gTempInfs = [] BuildOptionPcd = [] + +# Pcd name for the Pcd which used in the Conditional directives +gConditionalPcds = [] diff --git a/BaseTools/Source/Python/build/BuildReport.py b/BaseTools/Source/Python/build/BuildReport.py index 2dc02c2c4e..aee50fb3a2 100644 --- a/BaseTools/Source/Python/build/BuildReport.py +++ b/BaseTools/Source/Python/build/BuildReport.py @@ -658,6 +658,8 @@ class PcdReport(object): # def __init__(self, Wa): self.AllPcds = {} + self.UnusedPcds = {} + self.ConditionalPcds = {} self.MaxLen = 0 if Wa.FdfProfile: self.FdfPcdSet = Wa.FdfProfile.PcdDict @@ -676,6 +678,63 @@ class PcdReport(object): PcdList.append(Pcd) if len(Pcd.TokenCName) > self.MaxLen: self.MaxLen = len(Pcd.TokenCName) + # + # Collect the PCD defined in DSC/FDF file, but not used in module + # + UnusedPcdFullList = [] + for item in Pa.Platform.Pcds: + Pcd = Pa.Platform.Pcds[item] + if not Pcd.Type: + PcdTypeFlag = False + for package in Pa.PackageList: + for T in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]: + if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, T) in package.Pcds: + Pcd.Type = T + PcdTypeFlag = True + if not Pcd.DatumType: + Pcd.DatumType = package.Pcds[(Pcd.TokenCName, Pcd.TokenSpaceGuidCName, T)].DatumType + break + if PcdTypeFlag: + break + if not Pcd.DatumType: + PcdType = Pcd.Type + # Try to remove Hii and Vpd suffix + if PcdType.startswith("DynamicEx"): + PcdType = "DynamicEx" + elif PcdType.startswith("Dynamic"): + PcdType = "Dynamic" + for package in Pa.PackageList: + if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, PcdType) in package.Pcds: + Pcd.DatumType = package.Pcds[(Pcd.TokenCName, Pcd.TokenSpaceGuidCName, PcdType)].DatumType + break + + PcdList = self.AllPcds.setdefault(Pcd.TokenSpaceGuidCName, {}).setdefault(Pcd.Type, []) + if Pcd not in PcdList and Pcd not in UnusedPcdFullList: + UnusedPcdFullList.append(Pcd) + if len(Pcd.TokenCName) > self.MaxLen: + self.MaxLen = len(Pcd.TokenCName) + + if GlobalData.gConditionalPcds: + for PcdItem in GlobalData.gConditionalPcds: + if '.' in PcdItem: + (TokenSpaceGuidCName, TokenCName) = PcdItem.split('.') + if (TokenCName, TokenSpaceGuidCName) in Pa.Platform.Pcds.keys(): + Pcd = Pa.Platform.Pcds[(TokenCName, TokenSpaceGuidCName)] + PcdList = self.ConditionalPcds.setdefault(Pcd.TokenSpaceGuidCName, {}).setdefault(Pcd.Type, []) + if Pcd not in PcdList: + PcdList.append(Pcd) + + UnusedPcdList = [] + if UnusedPcdFullList: + for Pcd in UnusedPcdFullList: + if Pcd.TokenSpaceGuidCName + '.' + Pcd.TokenCName in GlobalData.gConditionalPcds: + continue + UnusedPcdList.append(Pcd) + + for Pcd in UnusedPcdList: + PcdList = self.UnusedPcds.setdefault(Pcd.TokenSpaceGuidCName, {}).setdefault(Pcd.Type, []) + if Pcd not in PcdList: + PcdList.append(Pcd) for Module in Pa.Platform.Modules.values(): # @@ -709,6 +768,13 @@ class PcdReport(object): if DscDefaultValue: self.DscPcdDefault[(TokenCName, TokenSpaceGuidCName)] = DscDefaultValue + def GenerateReport(self, File, ModulePcdSet): + if self.ConditionalPcds: + self.GenerateReportDetail(File, ModulePcdSet, 1) + if self.UnusedPcds: + self.GenerateReportDetail(File, ModulePcdSet, 2) + self.GenerateReportDetail(File, ModulePcdSet) + ## # Generate report for PCD information # @@ -719,39 +785,52 @@ class PcdReport(object): # @param File The file object for report # @param ModulePcdSet Set of all PCDs referenced by module or None for # platform PCD report + # @param ReportySubType 0 means platform/module PCD report, 1 means Conditional + # directives section report, 2 means Unused Pcds section report # @param DscOverridePcds Module DSC override PCDs set # - def GenerateReport(self, File, ModulePcdSet): + def GenerateReportDetail(self, File, ModulePcdSet, ReportSubType = 0): + PcdDict = self.AllPcds + if ReportSubType == 1: + PcdDict = self.ConditionalPcds + elif ReportSubType == 2: + PcdDict = self.UnusedPcds + if ModulePcdSet == None: - # - # For platform global PCD section - # FileWrite(File, gSectionStart) - FileWrite(File, "Platform Configuration Database Report") + if ReportSubType == 1: + FileWrite(File, "Conditional Directives used by the build system") + elif ReportSubType == 2: + FileWrite(File, "PCDs not used by modules or in conditional directives") + else: + FileWrite(File, "Platform Configuration Database Report") + FileWrite(File, " *B - PCD override in the build option") 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") + if not ReportSubType: + FileWrite(File, " *M - Module scoped PCD override") FileWrite(File, gSectionSep) else: - # - # For module PCD sub-section - # - FileWrite(File, gSubSectionStart) - FileWrite(File, TAB_BRG_PCD) - FileWrite(File, gSubSectionSep) + if not ReportSubType: + # + # For module PCD sub-section + # + FileWrite(File, gSubSectionStart) + FileWrite(File, TAB_BRG_PCD) + FileWrite(File, gSubSectionSep) - for Key in self.AllPcds: + for Key in PcdDict: # # Group PCD by their token space GUID C Name # First = True - for Type in self.AllPcds[Key]: + for Type in PcdDict[Key]: # # Group PCD by their usage type # TypeName, DecType = gPcdTypeMap.get(Type, ("", Type)) - for Pcd in self.AllPcds[Key][Type]: + for Pcd in PcdDict[Key][Type]: # # Get PCD default value and their override relationship # @@ -869,7 +948,8 @@ class PcdReport(object): if ModulePcdSet == None: FileWrite(File, gSectionEnd) else: - FileWrite(File, gSubSectionEnd) + if not ReportSubType: + FileWrite(File, gSubSectionEnd) -- 2.39.2