BZ:https://bugzilla.tianocore.org/show_bug.cgi?id=2270 Currently a PCD (e.g. FeaturePCD) cannot be used in a conditional statement in a DSC/FDF file without a module in the build referencing the PCD package DEC file. An example implementation that to support this is to allow a [Packages] section in the DSC file to list additional package dependencies for PCD references in the package DSC/FDF files. this patch is going to add the ability to have the [packages] section defined in the DSC file Cc: Liming Gao Cc: Bob Feng Signed-off-by: Zhiju.Fan --- BaseTools/Source/Python/AutoGen/ModuleAutoGen.py | 28 +++++++++++++++++----- BaseTools/Source/Python/AutoGen/PlatformAutoGen.py | 1 + .../Source/Python/AutoGen/WorkspaceAutoGen.py | 1 + BaseTools/Source/Python/Common/DataType.py | 1 + BaseTools/Source/Python/Workspace/DscBuildData.py | 23 +++++++++++++++++- .../Source/Python/Workspace/MetaFileParser.py | 14 +++++++++++ .../Source/Python/Workspace/WorkspaceCommon.py | 2 ++ .../Source/Python/Workspace/WorkspaceDatabase.py | 5 ++++ 8 files changed, 68 insertions(+), 7 deletions(-) diff --git a/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py b/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py index f0812b6887..112707edb1 100755 --- a/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py +++ b/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py @@ -462,13 +462,29 @@ class ModuleAutoGen(AutoGen): def BuildCommand(self): return self.PlatformInfo.BuildCommand - ## Get object list of all packages the module and its dependent libraries belong to + ## Get Module package and Platform package + # + # @retval list The list of package object + # + @cached_property + def PackageList(self): + PkagList = [] + if self.Module.Packages: + PkagList.extend(self.Module.Packages) + Platform = self.BuildDatabase[self.PlatformInfo.MetaFile, self.Arch, self.BuildTarget, self.ToolChain] + for Package in Platform.Packages: + if Package in PkagList: + continue + PkagList.append(Package) + return PkagList + + ## Get object list of all packages the module and its dependent libraries belong to and the Platform depends on # # @retval list The list of package object # @cached_property def DerivedPackageList(self): - PackageList = [] + PackageList = self.PackageList for M in [self.Module] + self.DependentLibraryList: for Package in M.Packages: if Package in PackageList: @@ -938,13 +954,13 @@ class ModuleAutoGen(AutoGen): self.Targets return self._FileTypes - ## Get the list of package object the module depends on + ## Get the list of package object the module depends on and the Platform depends on # # @retval list The package object list # @cached_property def DependentPackageList(self): - return self.Module.Packages + return self.PackageList ## Return the list of auto-generated code file # @@ -1101,7 +1117,7 @@ class ModuleAutoGen(AutoGen): RetVal.append(self.MetaFile.Dir) RetVal.append(self.DebugDir) - for Package in self.Module.Packages: + for Package in self.PackageList: PackageDir = mws.join(self.WorkspaceDir, Package.MetaFile.Dir) if PackageDir not in RetVal: RetVal.append(PackageDir) @@ -1125,7 +1141,7 @@ class ModuleAutoGen(AutoGen): @cached_property def PackageIncludePathList(self): IncludesList = [] - for Package in self.Module.Packages: + for Package in self.PackageList: PackageDir = mws.join(self.WorkspaceDir, Package.MetaFile.Dir) IncludesList = Package.Includes if Package._PrivateIncludes: diff --git a/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py b/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py index debeb46f58..4c3cdf82d5 100644 --- a/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py +++ b/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py @@ -975,6 +975,7 @@ class PlatformAutoGen(AutoGen): continue ModuleData = self.BuildDatabase[ModuleFile, self.Arch, self.BuildTarget, self.ToolChain] RetVal.update(ModuleData.Packages) + RetVal.update(self.Platform.Packages) return list(RetVal) @cached_property diff --git a/BaseTools/Source/Python/AutoGen/WorkspaceAutoGen.py b/BaseTools/Source/Python/AutoGen/WorkspaceAutoGen.py index 9d8040905e..fde48b4b27 100644 --- a/BaseTools/Source/Python/AutoGen/WorkspaceAutoGen.py +++ b/BaseTools/Source/Python/AutoGen/WorkspaceAutoGen.py @@ -420,6 +420,7 @@ class WorkspaceAutoGen(AutoGen): continue ModuleData = self.BuildDatabase[ModuleFile, Arch, self.BuildTarget, self.ToolChain] PkgSet.update(ModuleData.Packages) + PkgSet.update(Platform.Packages) Pkgs[Arch] = list(PkgSet) return Pkgs diff --git a/BaseTools/Source/Python/Common/DataType.py b/BaseTools/Source/Python/Common/DataType.py index 5d49afb0a9..8d80b41089 100644 --- a/BaseTools/Source/Python/Common/DataType.py +++ b/BaseTools/Source/Python/Common/DataType.py @@ -519,6 +519,7 @@ SECTIONS_HAVE_ITEM_AFTER_ARCH_SET = {TAB_LIBRARY_CLASSES.upper(), TAB_DEPEX.uppe PCDS_DYNAMICEX_VPD.upper(), PCDS_DYNAMICEX_HII.upper(), TAB_BUILD_OPTIONS.upper(), + TAB_PACKAGES.upper(), TAB_INCLUDES.upper()} # diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py index 9192077f90..03a15bbf3e 100644 --- a/BaseTools/Source/Python/Workspace/DscBuildData.py +++ b/BaseTools/Source/Python/Workspace/DscBuildData.py @@ -719,6 +719,24 @@ class DscBuildData(PlatformBuildClassObject): self._RawData.DisableOverrideComponent(Components[(file_guid_str,str(ModuleFile))]) Components[(file_guid_str,str(ModuleFile))] = ModuleId self._RawData._PostProcessed = False + + ## Retrieve packages this Platform depends on + @cached_property + def Packages(self): + RetVal = set() + RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch] + Macros = self._Macros + for Record in RecordList: + File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch) + # check the file validation + ErrorCode, ErrorInfo = File.Validate('.dec') + if ErrorCode != 0: + LineNo = Record[-1] + EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo) + # parse this package now. we need it to get protocol/ppi/guid value + RetVal.add(self._Bdb[File, self._Arch, self._Target, self._Toolchain]) + return RetVal + ## Retrieve [Components] section information @property def Modules(self): @@ -896,7 +914,8 @@ class DscBuildData(PlatformBuildClassObject): continue ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain] PkgSet.update(ModuleData.Packages) - + if self.Packages: + PkgSet.update(self.Packages) self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain, PkgSet) self._GuidDict.update(GlobalData.gPlatformPcds) @@ -3320,6 +3339,8 @@ class DscBuildData(PlatformBuildClassObject): continue ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain] PkgSet.update(ModuleData.Packages) + if self.Packages: + PkgSet.update(self.Packages) self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain, PkgSet) self._GuidDict.update(GlobalData.gPlatformPcds) return self._DecPcds diff --git a/BaseTools/Source/Python/Workspace/MetaFileParser.py b/BaseTools/Source/Python/Workspace/MetaFileParser.py index 806fc322c5..3f96ce0564 100644 --- a/BaseTools/Source/Python/Workspace/MetaFileParser.py +++ b/BaseTools/Source/Python/Workspace/MetaFileParser.py @@ -160,6 +160,7 @@ class MetaFileParser(object): self.MetaFile = FilePath self._FileDir = self.MetaFile.Dir self._Defines = {} + self._Packages = [] self._FileLocalMacros = {} self._SectionsMacroDict = defaultdict(dict) @@ -351,6 +352,13 @@ class MetaFileParser(object): # If the section information is needed later, it should be stored in database self._ValueList[0] = self._SectionName + ## [packages] section parser + @ParseMacro + def _PackageParser(self): + self._CurrentLine = CleanString(self._CurrentLine) + self._Packages.append(self._CurrentLine) + self._ValueList[0] = self._CurrentLine + ## [defines] section parser @ParseMacro def _DefineParser(self): @@ -848,6 +856,7 @@ class DscParser(MetaFileParser): TAB_LIBRARIES.upper() : MODEL_EFI_LIBRARY_INSTANCE, TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS, TAB_BUILD_OPTIONS.upper() : MODEL_META_DATA_BUILD_OPTION, + TAB_PACKAGES.upper() : MODEL_META_DATA_PACKAGE, TAB_PCDS_FIXED_AT_BUILD_NULL.upper() : MODEL_PCD_FIXED_AT_BUILD, TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper() : MODEL_PCD_PATCHABLE_IN_MODULE, TAB_PCDS_FEATURE_FLAG_NULL.upper() : MODEL_PCD_FEATURE_FLAG, @@ -1339,6 +1348,7 @@ class DscParser(MetaFileParser): MODEL_META_DATA_DEFINE : self.__ProcessDefine, MODEL_META_DATA_GLOBAL_DEFINE : self.__ProcessDefine, MODEL_META_DATA_INCLUDE : self.__ProcessDirective, + MODEL_META_DATA_PACKAGE : self.__ProcessPackages, MODEL_META_DATA_CONDITIONAL_STATEMENT_IF : self.__ProcessDirective, MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE : self.__ProcessDirective, MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF : self.__ProcessDirective, @@ -1642,6 +1652,9 @@ class DscParser(MetaFileParser): self._ValueList = None self._ContentIndex -= 1 + def __ProcessPackages(self): + self._ValueList[0] = ReplaceMacro(self._ValueList[0], self._Macros) + def __ProcessSkuId(self): self._ValueList = [ReplaceMacro(Value, self._Macros, RaiseError=True) for Value in self._ValueList] @@ -1720,6 +1733,7 @@ class DscParser(MetaFileParser): MODEL_META_DATA_COMPONENT : _ComponentParser, MODEL_META_DATA_BUILD_OPTION : _BuildOptionParser, MODEL_UNKNOWN : MetaFileParser._Skip, + MODEL_META_DATA_PACKAGE : MetaFileParser._PackageParser, MODEL_META_DATA_USER_EXTENSION : MetaFileParser._SkipUserExtension, MODEL_META_DATA_SECTION_HEADER : MetaFileParser._SectionHeaderParser, MODEL_META_DATA_SUBSECTION_HEADER : _SubsectionHeaderParser, diff --git a/BaseTools/Source/Python/Workspace/WorkspaceCommon.py b/BaseTools/Source/Python/Workspace/WorkspaceCommon.py index 0b11ec2d59..913e710fd9 100644 --- a/BaseTools/Source/Python/Workspace/WorkspaceCommon.py +++ b/BaseTools/Source/Python/Workspace/WorkspaceCommon.py @@ -37,6 +37,8 @@ class OrderedListDict(OrderedDict): # def GetPackageList(Platform, BuildDatabase, Arch, Target, Toolchain): PkgSet = set() + if Platform.Packages: + PkgSet.update(Platform.Packages) for ModuleFile in Platform.Modules: Data = BuildDatabase[ModuleFile, Arch, Target, Toolchain] PkgSet.update(Data.Packages) diff --git a/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py b/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py index ab7b4506c1..37a6f9f7be 100644 --- a/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py +++ b/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py @@ -186,6 +186,11 @@ class WorkspaceDatabase(object): for Package in LibObj.Packages: if Package not in PackageList: PackageList.append(Package) + DscPlatform = self.BuildObject[self.Platform, Arch, TargetName, ToolChainTag] + for Package in DscPlatform.Packages: + if Package in PackageList: + continue + PackageList.append(Package) return PackageList -- 2.14.1.windows.1