如何将自定义生成目标添加到Visual C++ 2010项目?

Bil*_*eal 4 c++ msbuild visual-c++

有很多指南可以帮助你在VS2010中使用MSBuild模仿VS2008的"自定义构建步骤".但是,我希望我的构建更智能并使用MSBuild.我写了一个MSBuild任务,它调用了ANTLR解析器生成器.当我在一个简单的测试MSBuild文件中运行它时,该构建任务完美无缺.但是,当我尝试将我的任务添加到C++项目时,我遇到了问题.基本上我已经将它添加到我的项目文件的顶部(在<project>元素之后):

  <UsingTask TaskName="ANTLR.MSBuild.AntlrGrammar"
        AssemblyName = "ANTLR.MSBuild, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d50cc80512acc876" />
  <Target Name="BeforeBuild"
    Inputs="ConfigurationParser.g"
    Outputs="ConfigurationParserParser.h;ConfigurationParserParser.cpp;ConfigurationParserLexer.h;ConfigurationParserLexer.cpp">
    <AntlrGrammar
      AntlrLocation="$(MSBuildProjectDirectory)Antlr.jar"
      Grammar="ConfigurationParser.g"
      RenameToCpp="true" />
  </Target>
Run Code Online (Sandbox Code Playgroud)

但是,我的目标在构建之前没有被调用.

如何将我的任务添加到C++构建中?

Bil*_*eal 8

在阅读本答案之前,您可能希望看到:

扩展MSBuild的旧方法,以及我所拥有的参考书中提到的方法,基本上是基于覆盖Microsoft提供的默认空目标.上面第二个链接中指定的新方法是定义您自己的任意目标,并使用"BeforeTargets"和"AfterTargets"属性强制您的目标在预期目标之前或之后运行.

在我的特定情况下,我需要在CLCompile目标之前运行ANTLR Grammars任务,该目标实际构建C++文件,因为ANTLR Grammars任务构建.cpp文件.因此,XML看起来像这样:

<Project ...
  <!-- Other things put in by VS2010 ... this is the bottom of the file -->
  <UsingTask TaskName="ANTLR.MSBuild.AntlrGrammar"
  AssemblyName = "ANTLR.MSBuild, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d50cc80512acc876" />
    <Target Name="AntlrGrammars"
      Inputs="Configuration.g"
      Outputs="ConfigurationParser.h;ConfigurationParser.cpp;ConfigurationLexer.h;ConfigurationLexer.cpp"
      BeforeTargets="ClCompile">
      <AntlrGrammar
        AntlrLocation="$(MSBuildProjectDirectory)\Antlr.jar"
        Grammar="Configuration.g"
        RenameToCpp="true" />
    </Target>
  <ImportGroup Label="ExtensionTargets">
  </ImportGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
Run Code Online (Sandbox Code Playgroud)

至于为什么它优于PreBuildEvent和/或PostBuildEvent; 这很聪明,当语法本身没有更新时,不能重建.cpps.你会得到类似的东西:

1>AntlrGrammars:
1>Skipping target "AntlrGrammars" because all output files are up-to-date with respect to the input files.
1>ClCompile:
1>  All outputs are up-to-date.
1>  All outputs are up-to-date.

这也使Visual Studio不断抱怨每次运行它需要重建事物的程序,就像使用简单的预建和后构建步骤一样.

希望这有助于某人 - 永远把我带走了.