2010-07-16 3 views
4

Il existe de nombreux guides qui vous aident à reproduire le "Custom Build Step" de VS2008 dans VS2010 avec MSBuild. Cependant, j'aimerais que mon build soit plus intelligent et utilise MSBuild. J'ai écrit a little MSBuild task qui appelle le générateur d'analyseur ANTLR. Cette tâche de construction fonctionne parfaitement lorsque je l'exécute dans un simple fichier MSBuild de test. Cependant, lorsque j'essaie d'ajouter ma tâche à un projet C++, je rencontre des problèmes. Essentiellement, je l'ai ajouté à la partie supérieure de mon dossier de projet (Juste après l'élément <project>):Comment ajouter une cible de génération personnalisée à un projet Visual C++ 2010?

<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> 

Cependant, mon objectif n'est pas appelée avant la construction. Comment puis-je ajouter ma tâche à une construction C++?

Répondre

8

Avant de lire cette réponse, vous aurez probablement envie de voir:

L'ancienne façon d'étendre MSBuild, et celui mentionné par le livre de référence I ont, essentiellement, basé sur la substitution de cibles vides par défaut fournies par Microsoft. La nouvelle méthode, comme indiqué dans le deuxième lien ci-dessus, consiste à définir votre propre cible arbitraire et à utiliser les propriétés "BeforeTargets" et "AfterTargets" pour forcer votre cible à s'exécuter avant ou après la cible voulue.

Dans mon cas spécifique, j'avais besoin que la tâche ANTLR Grammars soit exécutée avant la cible CLCompile, qui génère réellement les fichiers C++, car la tâche GRAPHIQUES ANTLR génère des fichiers .cpp. Par conséquent, le XML ressemble à ceci:

<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> 

Quant à savoir pourquoi cela est supérieur à un PreBuildEvent et/ou PostBuildEvent; c'est assez intelligent pour ne pas reconstruire le .cpps lorsque la grammaire elle-même n'est pas mise à jour. Vous obtiendrez quelque chose comme:

 
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. 

Ce également réduit au silence incessant de Visual Studio se plaindre à chaque fois que vous exécutez le programme dont il a besoin pour reconstruire les choses, comme il le fait avec pré et post-plaine construire étapes.

Espérons que cela aide quelqu'un - m'a pris frickin forever pour comprendre.

+1

Merci! Cela me prenait pour toujours à comprendre, aussi bien. –

Questions connexes