diff --git a/BaseTools/Source/Python/AutoGen/AutoGenWorker.py b/BaseTools/Source/Python/AutoGen/AutoGenWorker.py index b23363b3e83..819dc3a83e1 100755 --- a/BaseTools/Source/Python/AutoGen/AutoGenWorker.py +++ b/BaseTools/Source/Python/AutoGen/AutoGenWorker.py @@ -218,6 +218,7 @@ def run(self): GlobalData.gEnableGenfdsMultiThread = self.data_pipe.Get("EnableGenfdsMultiThread") GlobalData.gPlatformFinalPcds = self.data_pipe.Get("gPlatformFinalPcds") GlobalData.file_lock = self.file_lock + GlobalData.gLogLibraryMismatch = False # MU_CHANGE CommandTarget = self.data_pipe.Get("CommandTarget") pcd_from_build_option = [] for pcd_tuple in self.data_pipe.Get("BuildOptPcd"): diff --git a/BaseTools/Source/Python/Common/GlobalData.py b/BaseTools/Source/Python/Common/GlobalData.py index 43d3ff01545..b2833444952 100755 --- a/BaseTools/Source/Python/Common/GlobalData.py +++ b/BaseTools/Source/Python/Common/GlobalData.py @@ -123,6 +123,7 @@ # Common lock for the file access in multiple process AutoGens file_lock = None # MU_CHANGE [BEGIN]: Add build-time random stack cookie support +gLogLibraryMismatch = True gStackCookieValues32 = [] gStackCookieValues64 = [] # MU_CHANGE [END] diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py index d68971eec17..cebb9ca2370 100644 --- a/BaseTools/Source/Python/Workspace/DscBuildData.py +++ b/BaseTools/Source/Python/Workspace/DscBuildData.py @@ -40,6 +40,8 @@ import json import shutil +LoggedLibraryWarnings = [] # MU_CHANGE + def _IsFieldValueAnArray (Value): Value = Value.strip() if Value.startswith(TAB_GUID) and Value.endswith(')'): @@ -764,6 +766,14 @@ def Modules(self): LibraryPath = PathClass(NormPath(Record[1], Macros), GlobalData.gWorkspace, Arch=self._Arch) LineNo = Record[-1] + # MU_CHANGE begin + # Validate that the Library instance implements the Library Class + if not self._ValidateLibraryClass(LibraryClass, LibraryPath) and self._ShouldLogLibrary(LineNo): + EdkLogger.warn("build", + f"{str(LibraryPath)} does not support LIBRARY_CLASS {LibraryClass}", + File=self.MetaFile) + # MU_CHANGE end + # check the file validation ErrorCode, ErrorInfo = LibraryPath.Validate('.inf') if ErrorCode != 0: @@ -917,6 +927,15 @@ def LibraryClasses(self): EdkLogger.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch, LibraryInstance, LibraryClass)) LibraryClassSet.add(LibraryClass) LibraryInstance = PathClass(NormPath(LibraryInstance, Macros), GlobalData.gWorkspace, Arch=self._Arch) + + # MU_CHANGE begin + # Validate that the Library instance implements the Library Class + if not self._ValidateLibraryClass(LibraryClass, LibraryInstance) and self._ShouldLogLibrary(LineNo): + EdkLogger.warn("build", + f"{str(LibraryInstance)} does not support LIBRARY_CLASS {LibraryClass}", + File=self.MetaFile) + # MU_CHANGE end + # check the file validation ErrorCode, ErrorInfo = LibraryInstance.Validate('.inf') if ErrorCode != 0: @@ -1187,6 +1206,29 @@ def __ParsePcdFromCommandLine(self): for item in delete_assign: GlobalData.BuildOptionPcd.remove(item) + # MU_CHANGE begin + def _ValidateLibraryClass(self, LibraryClass: str, LibraryInstance: PathClass) -> bool: + if LibraryClass.upper().startswith('NULL'): + return True + + ParsedLibraryInfo = self._Bdb[LibraryInstance, self._Arch, self._Target, self._Toolchain] + + for LibraryClassObject in ParsedLibraryInfo.LibraryClass: + if LibraryClassObject.LibraryClass == LibraryClass: + return True + return False + + def _ShouldLogLibrary(self, LineNo) -> bool: + if not GlobalData.gLogLibraryMismatch: + return False + + if LineNo in LoggedLibraryWarnings: + return False + + LoggedLibraryWarnings.append(LineNo) + return True + # MU_CHANGE end + @staticmethod def HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, PcdValue, PcdDatumType, GuidDict, FieldName=''): if FieldName: