eclipse找不到cdt_将外部代码检查器集成到Eclipse CDT中

Codan是一个代码分析框架,可对C / C ++项目执行代码检查。 自2011年以来,Codan已成为Eclipse CDT(C / C ++开发工具)套件的一部分,它不仅提供执行静态代码分析所需的所有基础结构,而且还提供了一些有用的即用型问题检查器(请参阅参考资料 )。

Codan在2012年6月的Eclipse Juno版本中进行了更新,以使开发人员能够在Eclipse中自动执行外部代码分析工具。 对于Eclipse CDT和C / C ++开发人员而言,这是令人激动的进步。 尽管先前提供的问题检查器很好,但是需要更多的东西来使Codan与现有的外部代码分析工具保持功能相同。 Codan现在可以轻松地与成熟的外部工具(例如Cppcheck和clang_check)集成。

将外部代码分析工具与Eclipse CDT集成在一起,比开发人员仅使用Codan就能完成更多,更好的代码检查。 它还应该大大提高整体开发效率。 现在,我们可以从Codan的“首选项”页面配置外部代码分析工具。 与Codan集成后,将自动调用这些工具,并将其输出显示为编辑器标记。

在本文中,我将向您展示如何使用Java代码和一点点XML将您喜欢的代码分析工具集成到Eclipse C / C ++开发环境中。 我的示例将基于Cppcheck与Codan的集成,但是该过程应适用于您选择的工具。

安装Eclipse Juno和CDT

为了遵循本文中的示例,您将需要同时安装Eclipse Juno和CDT。 如果尚未安装Eclipse,则可以安装CDT附带的版本。 为此,只需从Eclipse下载页面中选择C / C ++开发人员的Eclipse IDE

如果您已经安装了不包含CDT的Eclipse,请按照以下说明更新您的开发环境:

  1. 在Eclipse中,选择菜单帮助>安装新软件...。
  2. 在“安装”对话框中,从下拉列表中选择Juno
  3. 在“编程语言”类别中,选择“ C / C ++开发工具SDK”
图1.安装CDT
Eclipse插件安装页面的屏幕快照。

除了CDT,您还需要标准的GNU C / C ++开发工具来编译,构建和调试代码。 请参阅相关主题有关如何安装这些工具的说明。

启动科丹

默认情况下,大多数Codan代码检查均处于启用状态。 您可以分别使用Eclipse的“首选项”或“项目属性”页面在工作区或项目级别分别配置Codan代码检查。

在Codan的Preferences页面(如图2所示)中,您可以看到所有可用的代码检查器以及每个报告的代码问题。

图2. Codan的Preferences页面上的代码检查器
Codan的“首选项”页面的屏幕截图。

在此页面上,您可以启用,禁用或更改问题的严重性。 如果要配置单个问题的其他属性,则可以选择一个问题,然后单击“ 定制选定的...”按钮。 图3显示了问题“函数的名称约定”的配置选项。

图3.配置问题
屏幕快照显示了使用Codan配置问题的路径。

图3中的第三个选项卡允许您指定应该如何启动问题检查:

  • 键入运行 :当用户在CDT编辑器中对文件进行更改时。
  • 在文件打开运行 :在CDT编辑器中打开文件时。
  • 在文件保存上运行 :保存CDT编辑器上未保存的更改时。
  • 在增量构建上运行 :发出增量构建时(通常在保存文件并启用项目级选项“自动构建”时)。 如果同时启用此选项和“在文件保存时运行”,则代码检查将运行两次。
  • 在完整版本上运行 :发出完整版本时(例如,在清理项目时)。
  • 按需运行 :当用户从上下文菜单项“运行C / C ++代码分析”手动触发代码检查时。

与Codan进行代码检查

为了让您看到Codan在工作,我将用一个简短的C ++文件创建一个C ++项目。 在此文件中,我将为其分配一个变量。 Codan包含代码检查“对自身的分配”,默认情况下,其严重性级别为“错误”启用。 它被配置为在您键入时运行,因此错误将立即弹出。

图4. Codan执行代码检查
屏幕快照显示了Codan正在执行代码检查。

图4中 ,您可以看到Codan在我有机会保存文件之前发现了自我分配错误并报告了该错误。 完善!

要了解有关使用Codan的更多信息,请访问项目的主页(请参阅参考资料 )。

将Cppcheck集成到Eclipse CDT中

为了将外部代码分析工具与Codan集成,我们需要编写一种特殊的检查程序,该检查程序知道如何调用该工具。 检查器是Codan IChecker接口的实现, IChecker接口对给定的IResource (通常是IFile )执行某种代码检查。

为了证明它是多么容易地创建一个基于外部工具检查,我们将创建一个调用常用的工具Cppcheck(见检查相关主题 )。 这是我们要做的:

  • 创建一个Eclipse插件项目,并将Codan添加为依赖项。
  • 创建一个错误分析器以分析Cppcheck的输出,并在必要时创建编辑器标记。
  • 创建代码检查器,它是负责调用Cppcheck的类。

步骤1.创建一个Eclipse插件项目

要创建Codan检查器,我们首先创建一个新的Eclipse插件项目:

  1. 选择菜单文件>新建>项目...。
  2. 在“插件开发”类别中,选择“ 插件项目”
  3. 输入项目的名称(我的名称为“ CppcheckChecker”),然后单击“ 下一步”
  4. 接受默认值,然后单击完成
图5.创建一个插件项目
屏幕截图显示了如何创建一个插件项目。

创建新的插件项目后,Eclipse将立即自动打开MANIFEST.MF文件。 这是我们将添加Codan依赖项的文件。

在编辑器中,选择“依赖关系”选项卡,并将以下内容添加到“必需的插件”列表中:

org.eclipse.cdt.codan.core
org.eclipse.cdt.codan.core.cxx
org.eclipse.cdt.codan.ui
org.eclipse.cdt.codan.ui.cxx
org.eclipse.cdt.core
org.eclipse.cdt.ui
org.eclipse.core.resources
org.eclipse.core.runtime
org.eclipse.ui

步骤2.创建一个错误解析器

我们将需要一个错误解析器来根据Cppcheck的输出创建编辑器标记,因此下一步是使用插件扩展Eclipse的C / C ++工具。我们将为此目的使用Java代码,因为Eclipse本身就是Java应用程序。

首先,我们将创建一个实现org.eclipse.cdt.core.IErrorParser的类CppcheckErrorParser 。 我们首先找到在报告代码问题时Cppcheck使用的模式。 错误分析器将使用此模式来识别代表问题报告的输出行,然后从该输出中提取创建编辑器标记所需的信息。

清单1.与Cppcheck的输出匹配的模式
// sample line to parse:
  //
  // [/src/HelloWorld.cpp:19]: (style) The scope of the variable 'i' can be reduced
  // ----------1--------- -2    --3--  ------------------4-------------------------
  //
  // groups:
  // 1: file path and name
  // 2: line where problem was found
  // 3: problem severity
  // 4: problem description
  private static Pattern pattern = 
      Pattern.compile("\\[(.*):(\\d+)\\]:\\s*\\((.*)\\)\\s*(.*)");

清单2显示了错误解析器如何使用该模式提取要检查的文件的路径和名称,以及找到的错误的位置,描述和严重性。 利用此信息,错误分析器将创建一个新的ProblemMarkerInfo并将其传递给给定的ErrorParserManagerErrorParserManager是负责创建编辑器标记的类。

清单2.处理Cppcheck的输出
@Override
  public boolean processLine(String line, ErrorParserManager parserManager) {
    Matcher matcher = pattern.matcher(line);
    if (!matcher.matches()) {
      return false;
    }
    IFile fileName = parserManager.findFileName(matcher.group(1));
    if (fileName != null) {
      int lineNumber = Integer.parseInt(matcher.group(2));
      String description = matcher.group(4);
      int severity = findSeverityCode(matcher.group(3));
      ProblemMarkerInfo info = 
          new ProblemMarkerInfo(fileName, lineNumber, description, severity, null);
      parserManager.addProblemMarker(info);
      return true;
    }
    return false;
  }
}

映射问题严重性

Cppcheck定义了自己的问题严重性,与编辑器标记使用的严重性不同。 例如,Cppcheck严重性“样式”在Eclipse世界中没有对应的严重性。 为了克服这个问题,我们需要在两种问题严重性之间建立映射。 方法findSeverityCode (如清单3所示)演示了实现此映射的直接方法:

清单3.映射问题严重性
private static Map<String, Integer> SEVERITY_MAPPING = new HashMap<String, Integer>();
  
  static {
    SEVERITY_MAPPING.put("error", IMarkerGenerator.SEVERITY_ERROR_RESOURCE);
    SEVERITY_MAPPING.put("warning", IMarkerGenerator.SEVERITY_WARNING);
    SEVERITY_MAPPING.put("style", IMarkerGenerator.SEVERITY_INFO);
  }
  
  private int findSeverityCode(String text) {
    Integer code = SEVERITY_MAPPING.get(text);
    if (code != null) {
      return code;
    }
    return IMarkerGenerator.SEVERITY_INFO;
  }

创建映射后,由Cppcheck报告的严重性为“样式”的任何问题都将使用严重性SEVERITY_INFO在Eclipse中显示。 此映射仅定义问题严重性的默认值。 如您将在后面看到的,可以从“ Codan首选项”页面配置此映射。

为了使CppcheckErrorParser能够识别CppcheckErrorParser ,需要使用扩展点org.eclipse.cdt.core.ErrorParser将其注册在plugin.xml文件中:

清单4.注册错误解析器
<extension id="com.developerworks.cdt.checkers" name="Cppcheck error parsers" 
      point="org.eclipse.cdt.core.ErrorParser">
    <errorparser class="cppcheckchecker.CppcheckErrorParser" 
        id="com.dw.cdt.checkers.CppcheckErrorParser"
        name="Cppcheck">
      <context type="codan" />
    </errorparser>
  </extension>

请注意,在清单4中, ErrorParser扩展点最初是为注册CDT的构建工具的解析器而创建的。 它不特定于Codan。 为了表明CppcheckErrorParser应与Codan一起使用,我们添加上下文“ codan

步骤3.创建代码检查器

AbstractExternalToolBasedChecker是任何基于外部工具的Codan代码检查器的超类。 它提供了调用外部代码分析工具所需的大多数基础结构。 因为我们正在集成Cppcheck,所以我们将其称为CppcheckChecker类。

我们需要做的第一件事是为信息指定与外部工具有关的默认值,该默认值将显示在“ Codan首选项”页面上。

该信息应传递给检查器的构造函数,包括以下内容:

  • 外部代码分析工具的名称,在本例中为Cppcheck。
  • 工具可执行文件的名称,即cppcheck 。 我们不需要为可执行文件指定路径,因为我们假设它位于系统的PATH
  • 传递给可执行文件的参数,包含在单个String 。 我们指定“ --enable=all ”以启用所有Cppcheck的检查。
清单5.默认的Cppcheck信息
public CppCheckChecker() {
    super(new ConfigurationSettings("Cppcheck", new File("cppcheck"), "--enable=all"));
  }

请注意,Codan的“首选项”页面允许我们修改可执行路径和要传递的参数。

将问题严重性映射到问题ID

接下来,我们要指定将要使用的错误解析器的ID,如清单6所示。这些ID必须与plugin.xml文件中使用的ID相同。

清单6.指定要使用的错误解析器的ID
@Override
  protected String[] getParserIDs() {
    return new String[] { "com.dw.cdt.checkers.CppcheckErrorParser" };
  }

返回清单2 ,我们创建了ProblemMarkerInfo并将其传递给给定的ErrorParserManager ,以创建编辑器标记。 ErrorParserManager将把编辑器标记的创建委派给我们新创建的检查器。

要使检查器创建编辑器标记,我们需要重写addMarker(ProblemMarkerInfo)方法(其工作是查找另一种不匹配类型)。 Codan检查器无法直接从ProblemMarkerInfo创建编辑器标记。 他们有自己的机制,该机制使用问题ID来为创建的编辑器标记找出适当的严重性。

问题ID是Codan用来标识代码检查程序报告的代码问题的唯一ID。 所有代码问题都显示在Codan的“首选项”页面上(请参见图2 )。

清单7.创建错误标记
@Override
  public void addMarker(ProblemMarkerInfo info) {
    String problemId = PROBLEM_IDS.get(info.severity);
    String description = String.format("[cppcheck] %s", info.description);
    reportProblem(problemId, createProblemLocation(info), description);
  }

为了找到与ProblemMarkerInfo的严重性相对应的问题ID,我们需要在严重性和问题ID之间创建映射。 清单8显示了如何实现映射:

清单8.将问题严重性映射到问题ID
private static final String ERROR_PROBLEM_ID = 
      "com.dw.cdt.checkers.cppcheck.error";

  private static final Map<Integer, String> PROBLEM_IDS = 
      new HashMap<Integer, String>();

  static {
    PROBLEM_IDS.put(
        IMarkerGenerator.SEVERITY_ERROR_RESOURCE, ERROR_PROBLEM_ID);
    PROBLEM_IDS.put(
        IMarkerGenerator.SEVERITY_WARNING, "com.dw.cdt.checkers.cppcheck.warning");
    PROBLEM_IDS.put(
        IMarkerGenerator.SEVERITY_INFO, "com.dw.cdt.checkers.cppcheck.style");
  }

使用外部代码分析工具的代码检查器需要指出他们的哪个问题ID被视为“参考”。 参考问题ID用于获取检查器的首选项值(例如,外部工具的名称,如清单5所示)。 哪个问题ID是参考都没有关系,因为所有问题都将共享首选项。

清单9.指定参考问题ID
@Override
  protected String getReferenceProblemId() {
    return ERROR_PROBLEM_ID;
  }

清单8中定义了常量ERROR_PROBLEM_ID

注册检查器

为了使代码检查器及其报告的所有问题都显示在Codan的“首选项”页面上(因此用户可以访问),我们需要在Codan的plugin.xml文件中注册检查器。

因为我们不知道Cppcheck可以报告的所有问题,并且因为我们不能阻止Cppcheck在将来的版本中添加或删除代码检查,所以我们将无法注册每个问题。 相反,我们将按严重性对问题进行分组,并将每个组视为一个单独的问题。 在清单10中,我们将错误 , 警告和样式冲突注册为三个独立的问题:

清单10.注册检查器和问题报告
<extension point="org.eclipse.cdt.codan.core.checkers">
    <category id="cppcheckChecker.category" name="Cppcheck" />
    <checker class="cppcheckchecker.CppcheckChecker" id="cppcheckChecker.cppChecker"
      name="CppcheckChecker">
      <problem id="com.dw.cdt.checkers.cppcheck.error" name="Error" 
        defaultEnabled="true" defaultSeverity="Error" messagePattern="{0}"
        category="cppcheckChecker.category"/>
      <problem id="com.dw.cdt.checkers.cppcheck.warning" name="Warning" 
        defaultEnabled="true" defaultSeverity="Warning" messagePattern="{0}"
        category="cppcheckChecker.category"/>
      <problem id="com.dw.cdt.checkers.cppcheck.style" name="Style" 
        defaultEnabled="true" defaultSeverity="Info" messagePattern="{0}"
        category="cppcheckChecker.category"/>
    </checker>
  </extension>

我们在category元素中指定将显示给用户的检查器的名称。 问题的ID应该与检查器中使用的ID相同(请参见清单8 )。

在plugin.xml文件中,我们针对所有三个问题指定以下内容:

  • 默认情况下启用它们。
  • 它们分别具有默认严重性“错误”,“警告”和“信息”。
  • 它们具有消息模式:“ {0}, ”,它迫使Codan使用Cppcheck报告的问题描述。

在Codan中使用Cppcheck

现在,我们可以在Codan Preferences页面上看到CppcheckChecker如图6所示:

图6. Codan的Preferences页面上显示的Cppcheck
“ Codan首选项”页面上列出的CppcheckChecker的屏幕截图。

图7显示了用于配置Cppcheck如何报告代码错误的选项:

图7.配置Cppcheck的错误报告
用于配置Cppcheck错误的选项。

图8显示了Cppcheck如何报告代码问题。 请注意,保存文件后会自动调用Cppcheck。

图8. Cppcheck报告
Cppcheck报告代码问题的屏幕快照。

整合的弊端

将Codan与外部代码分析工具集成的局限性在于,当用户键入内容时,基于​​外部工具的检查器无法运行。 这仅仅是因为外部工具无法看到文件的未保存更改。 因此,当打开文件并保存文件时,需要运行外部检查器。

但是,使用成熟的代码分析工具所带来的好处却远远超过了这种限制。 与创建常规检查器相比,将外部工具与Codan集成起来也容易得多,也很简单,后者需要对C或C ++语言以及CDT的AST实现有深入的了解。 相比之下,我们能够用大约100行简单的Java代码(包含在两个类中)和30行XML来编写CppcheckChecker

结论

在Eclipse Juno发行版之前,为Codan创建自定义代码检查需要充分了解C / C ++语言和CDT自己的AST实现。 Eclipse CDT的Juno版本通过允许开发人员创建Codan代码检查器来解决此问题,然后将繁重的工作委托给外部代码分析工具。

在本文中,我们仅使用了少量Java代码和XML即可将Cppcheck与Codan集成在一起,将流行的C / C ++代码分析工具与Eclipse中C / C ++程序的内置代码分析框架结合在一起。 如前所述,您应该能够将此处演示的过程应用于您喜欢的代码分析工具。 请参阅相关主题 ,以了解更多信息。


翻译自: https://www.ibm.com/developerworks/java/library/j-codan/index.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值