From d0b64b21a3fb71a10f15987c73c135b9069bdd69 Mon Sep 17 00:00:00 2001 From: Ray Ni Date: Wed, 26 Mar 2025 17:30:08 +0800 Subject: BaseTools: Dump library dependency chain on build failure When a module M depends on L1, which depends on L2, which depends on L3, the build fails when the library instance of L3 cannot be found according to the library class-instance mapping configuration specified in the DSC file. When such failure happens, the build tool only prints that the instance of L3 required by module M cannot be found. But it does not tell how L3 is required by M. The change enhances build tool to print the entire dependency chain when such failure happens. With the change, the new error message will be as follows: (...): error 4000: Instance of library class [L3] is not found for module [M], [L3] is: consumed by consumed by Signed-off-by: Ray Ni --- BaseTools/Source/Python/Workspace/WorkspaceCommon.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'BaseTools/Source') diff --git a/BaseTools/Source/Python/Workspace/WorkspaceCommon.py b/BaseTools/Source/Python/Workspace/WorkspaceCommon.py index 7ac3b5b..1bfd137 100644 --- a/BaseTools/Source/Python/Workspace/WorkspaceCommon.py +++ b/BaseTools/Source/Python/Workspace/WorkspaceCommon.py @@ -90,6 +90,16 @@ def GetDeclaredPcd(Platform, BuildDatabase, Arch, Target, Toolchain, additionalP def GetLibraryInstances(Module, Platform, BuildDatabase, Arch, Target, Toolchain): return GetModuleLibInstances(Module, Platform, BuildDatabase, Arch, Target, Toolchain,Platform.MetaFile,EdkLogger) +def GenerateDependencyDump(ConsumedByList, M, Level, Visited): + if M in Visited: + return [] + Visited.add(M) + Indentation = "\t" * Level + DependencyDump = [f"{Indentation}consumed by {M}"] + for m in ConsumedByList[M]: + DependencyDump.extend(GenerateDependencyDump(ConsumedByList, m, Level + 1, Visited)) + return DependencyDump + def GetModuleLibInstances(Module, Platform, BuildDatabase, Arch, Target, Toolchain, FileName = '', EdkLogger = None): if Module.LibInstances: return Module.LibInstances @@ -133,9 +143,11 @@ def GetModuleLibInstances(Module, Platform, BuildDatabase, Arch, Target, Toolcha if LibraryPath is None: if not Module.LibraryClass: EdkLogger.error("build", RESOURCE_NOT_AVAILABLE, - "Instance of library class [%s] is not found" % LibraryClassName, + f"Instance of library class [{LibraryClassName}] is not found for" + f" module [{Module}], [{LibraryClassName}] is:", File=FileName, - ExtraData="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M), Arch, str(Module))) + ExtraData="\n\t".join(GenerateDependencyDump(ConsumedByList, M, 0, set())) + ) else: return [] -- cgit v1.1