From a357637fdc2219759ae5535f5c6e5be6581b31ef Mon Sep 17 00:00:00 2001 From: Sergey Chumakov Date: Tue, 17 Oct 2023 14:16:57 +0300 Subject: [PATCH] Support for nmake based projects --- CPPCheckPlugin/CPPCheckPluginPackage.cs | 74 ++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 8 deletions(-) diff --git a/CPPCheckPlugin/CPPCheckPluginPackage.cs b/CPPCheckPlugin/CPPCheckPluginPackage.cs index 5e75875..ea1e9eb 100644 --- a/CPPCheckPlugin/CPPCheckPluginPackage.cs +++ b/CPPCheckPlugin/CPPCheckPluginPackage.cs @@ -690,6 +690,37 @@ private static void recursiveAddToolDetails(SourceFile sourceForAnalysis, VCConf } } + private static void recursiveAddToolDetails(SourceFile sourceForAnalysis, VCConfiguration projectConfig, VCNMakeTool tool, dynamic propertySheets, ref bool bInheritDefs, ref bool bInheritUndefs) + { + // TODO: If the special keyword "\\\"$(INHERIT)\\\"" appears, we should inherit at that specific point. + if (bInheritDefs) + { + string[] macrosToDefine = tool.PreprocessorDefinitions.Split(';'); + bInheritDefs = !macrosToDefine.Contains("\\\"$(NOINHERIT)\\\""); + for (int i = 0; i < macrosToDefine.Length; ++i) + { + macrosToDefine[i] = Environment.ExpandEnvironmentVariables(projectConfig.Evaluate(macrosToDefine[i])); + } + + sourceForAnalysis.addMacros(macrosToDefine); + } + + if (propertySheets != null && (bInheritDefs || bInheritUndefs)) + { + // Scan any inherited property sheets. + foreach (var propSheet in propertySheets) + { + VCNMakeTool propSheetTool = (VCNMakeTool)propSheet.Tools.Item("VCNMakeTool"); + if (propSheetTool != null) + { + // When looping over the inherited property sheets, don't allow rules to filter back up the way. + bool bInheritDefs1 = bInheritDefs, bInheritUndefs1 = bInheritUndefs; + recursiveAddToolDetails(sourceForAnalysis, projectConfig, propSheetTool, propSheet.PropertySheets, ref bInheritDefs1, ref bInheritUndefs1); + } + } + } + } + private static async Task createSourceFileAsync(ProjectItem item) { try @@ -715,15 +746,23 @@ private static async Task createSourceFileAsync(ProjectItem item) bool bInheritDefs = true, bInheritUndefs = true; string[] includePaths = { }; - // Do the file-level first in case it disables inheritance. Include files don't have file-level config. - if (implementsInterface(fileConfig.Tool, "Microsoft.VisualStudio.VCProjectEngine.VCCLCompilerTool")) + // Possible exception thrown for nmake based project + try + { + // Do the file-level first in case it disables inheritance. Include files don't have file-level config. + if (implementsInterface(fileConfig.Tool, "Microsoft.VisualStudio.VCProjectEngine.VCCLCompilerTool")) + { + VCCLCompilerTool vcTool = (VCCLCompilerTool)fileConfig.Tool; + sourceForAnalysis = new SourceFile(item.FileNames[1], projectDirectory, projectName, toolSetName); + includePaths = vcTool.FullIncludePath.Split(';'); + string macros = vcTool.PreprocessorDefinitions; + // Other details may be gathered from the file, project or any inherited property sheets. + recursiveAddToolDetails(sourceForAnalysis, vcconfig, vcTool, null, ref bInheritDefs, ref bInheritUndefs); + } + } + catch (Exception ex) { - VCCLCompilerTool vcTool = (VCCLCompilerTool)fileConfig.Tool; - sourceForAnalysis = new SourceFile(item.FileNames[1], projectDirectory, projectName, toolSetName); - includePaths = vcTool.FullIncludePath.Split(';'); - string macros = vcTool.PreprocessorDefinitions; - // Other details may be gathered from the file, project or any inherited property sheets. - recursiveAddToolDetails(sourceForAnalysis, vcconfig, vcTool, null, ref bInheritDefs, ref bInheritUndefs); + DebugTracer.Trace(ex); } // Now get the full include path @@ -746,6 +785,25 @@ private static async Task createSourceFileAsync(ProjectItem item) recursiveAddToolDetails(sourceForAnalysis, vcconfig, projectTool, vcconfig.PropertySheets, ref bInheritDefs, ref bInheritUndefs); } + + VCNMakeTool nmakeTool = (VCNMakeTool)vcconfigTools.Item("VCNMakeTool"); + if (null != nmakeTool && implementsInterface(nmakeTool, "Microsoft.VisualStudio.VCProjectEngine.VCNMakeTool")) + { + if (sourceForAnalysis == null) + { + sourceForAnalysis = new SourceFile(item.FileNames[1], projectDirectory, projectName, toolSetName); + includePaths = nmakeTool.IncludeSearchPath.Split(';'); + } + + // Take the full include path from file level, which is already fully resolved. + for (int i = 0; i < includePaths.Length; ++i) + { + includePaths[i] = Environment.ExpandEnvironmentVariables(vcconfig.Evaluate(includePaths[i])); + } + sourceForAnalysis.addIncludePaths(includePaths); + + recursiveAddToolDetails(sourceForAnalysis, vcconfig, nmakeTool, vcconfig.PropertySheets, ref bInheritDefs, ref bInheritUndefs); + } } return sourceForAnalysis;