Comment : effectuer des générations incrémentielles
Mise à jour : novembre 2007
Lorsque vous générez un gros projet, il importe que les composants déjà générés et qui demeurent à jour ne soient pas générés à nouveau. Si toutes les cibles sont générées à chaque fois, chaque génération nécessitera un temps plus long. Pour activer les générations incrémentielles (générations dans lesquelles seules les cibles obsolètes ou n'ayant pas été déjà générées sont régénérées), Microsoft Build Engine (MSBuild) peut comparer les horodatages des fichiers d'entrée avec les horodatages des fichiers de sortie et déterminer si la cible doit être ignorée, générée intégralement ou régénérée partiellement. Toutefois, il doit exister un mappage un-à-un entre les entrées et les sorties. Vous pouvez utiliser des transformations pour permettre aux cibles d'identifier ce mappage direct. Pour plus d'informations sur les transformations, consultez Transformations MSBuild.
Spécification des entrées et des sorties
Une cible peut être générée de façon incrémentielle si les entrées et les sorties sont spécifiées dans le fichier projet.
Pour spécifier les entrées et les sorties d'une cible
Utilisez les attributs Inputs et Outputs de l'élément Target. Par exemple :
<Target Name="Build" Inputs="@(CSFile)" Outputs="hello.exe">
MSBuild peut comparer les horodatages des fichiers d'entrée avec ceux des fichiers de sortie et déterminer s'il faut ignorer, générer ou régénérer partiellement la cible. Dans l'exemple suivant, si un fichier de la collection d'éléments @(CSFile) est plus récent que le fichier hello.exe, MSBuild exécute la cible ; sinon, il l'ignore :
<Target Name="Build"
Inputs="@(CSFile)"
Outputs="hello.exe">
<Csc
Sources="@(CSFile)"
OutputAssembly="hello.exe"/>
</Target>
Lorsque les entrées et sorties sont spécifiées dans une cible, chaque sortie est mappée avec une seule entrée ou il n'existe pas de mappage direct entre les sorties et entrées. Dans la tâche Csc, tâche précédente, par exemple, la sortie hello.exe ne peut pas être mappée avec une entrée unique – elle dépend de fait de toutes les entrées.
Remarque : |
---|
Une cible dans laquelle il n'existe pas de mappage direct entre les entrées et les sorties sera toujours générée plus fréquemment qu'une cible dans laquelle chaque sortie ne peut être mappée qu'avec une seule entrée, parce que MSBuild ne peut pas déterminer les sorties qui doivent être régénérées si certaines des entrées ont changé. |
Les tâches dans lesquelles vous pouvez identifier un mappage direct entre les sorties et les entrées, comme LC, tâche, sont mieux adaptées aux générations incrémentielles, à l'inverse des tâches telles que Csc et Vbc, qui produisent un seul assembly de sortie à partir de plusieurs entrées.
Exemple
L'exemple suivant utilise un projet qui génère des fichiers d'aide pour un système d'aide éventuel. Le projet fonctionne en convertissant les fichiers source .txt en fichiers .content intermédiaires, qui sont ensuite combinés avec les fichiers de métadonnées XML pour produire le dernier fichier .help utilisé par le système d'aide. Le projet utilise les tâches hypothétiques suivantes :
GenerateContentFiles : convertit des fichiers .txt en fichiers .content.
BuildHelp : combine des fichiers .content et des fichiers de métadonnées XML pour générer le dernier fichier .help.
Le projet utilise les transformations pour créer un mappage univoque entre les entrées et les sorties de la tâche GenerateContentFiles. Pour plus d'informations, consultez Transformations MSBuild. De même, l'élément Output est défini de façon à utiliser automatiquement les sorties de la tâche GenerateContentFiles comme entrées de la tâche BuildHelp.
Ce fichier projet contient à la fois les cibles Convert et Build. Les tâches GenerateContentFiles et BuildHelp sont placées respectivement dans les cibles Convert et Build afin que chaque cible puisse être générée de façon incrémentielle. En utilisant l'élément Output, les sorties de la tâche GenerateContentFiles sont placées dans la collection d'éléments ContentFile, puis utilisées ensuite comme entrées de la tâche BuildHelp. En utilisant l'élément Output de cette façon, vous pouvez utiliser automatiquement les sorties d'une tâche comme entrées d'une autre tâche – vous n'avez pas à répertorier les éléments ou les collections d'éléments dans chaque tâche.
Remarque : |
---|
Bien que la cible GenerateContentFiles puisse être générée de façon incrémentielle, toutes les sorties de cette cible sont toujours requises comme entrées de la cible BuildHelp. MSBuild fournit automatiquement toutes les sorties d'une cible comme entrées d'une autre cible lorsque vous utilisez l'élément Output. |
<Project DefaultTargets="Build"
xmlns="https://schemas.microsoft.com/developer/msbuild/2003" >
<ItemGroup>
<TXTFile Include="*.txt"/>
<XMLFile Include="\metadata\*.xml"/>
</ItemGroup>
<Target Name = "Convert"
Inputs="@(TXTFile)"
Outputs="@(TXTFile->'%(Filename).content')">
<GenerateContentFiles
Sources = "@(TXTFile)">
<Output TaskParameter = "OutputContentFiles"
ItemName = "ContentFiles"/>
</GenerateContentFiles>
</Target>
<Target Name = "Build" DependsOnTargets = "Convert"
Inputs="@(ContentFiles);@(XMLFiles)"
Outputs="$(MSBuildProjectName).help">
<BuildHelp
ContentFiles = "@(ContentFiles)"
MetadataFiles = "@(XMLFile)"
OutputFileName = "$(MSBuildProjectName).help"/>
</Target>
</Project>