Builds incrémentielles
Les builds incrémentielles sont des builds optimisées qui permettent de ne pas exécuter les cibles dont les fichiers de sortie sont à jour par rapport à leurs fichiers d’entrée correspondants. Un élément cible peut avoir à la fois un attribut Inputs
, qui indique les éléments que la cible attend comme entrée, et un attribut Outputs
qui indique les éléments qu’il produit comme sortie. MSBuild tente de trouver une correspondance « 1 à 1 » entre les valeurs de ces attributs. Si une correspondance « 1 à 1 » existe, MSBuild compare l’horodatage de chaque élément d’entrée avec celui de l’élément de sortie correspondant. Les fichiers de sortie sans correspondance « 1 à 1 » sont comparés à tous les fichiers d’entrée. Un élément est considéré comme à jour si son fichier de sortie a une date de création identique ou antérieure à celle du ou des fichiers d’entrée.
Notes
Lorsque MSBuild évalue les fichiers d’entrée, seul le contenu de la liste dans l’exécution actuelle est pris en compte. Les modifications apportées à la liste de la dernière build ne rendent pas automatiquement une cible obsolète.
Si tous les éléments de sortie sont à jour, MSBuild ignore la cible. Cette build incrémentielle de la cible peut améliorer considérablement la vitesse de génération. Si seuls certains fichiers sont à jour, MSBuild exécute la cible en ignorant les éléments à jour, pour que tous les éléments soient à jour. Ce processus est appelé « build incrémentielle partielle ».
Les mappages 1-à-1 ne peuvent être produits qu’en faisant de l’attribut Outputs
une transformation de l’attribut Inputs
. Pour plus d’informations, consultez l’article Transforms (Transformations MSBuild).
Examinons la cible suivante.
<Target Name="Backup" Inputs="@(Compile)"
Outputs="@(Compile->'$(BackupFolder)%(Identity).bak')">
<Copy SourceFiles="@(Compile)" DestinationFiles=
"@(Compile->'$(BackupFolder)%(Identity).bak')" />
</Target>
Le jeu de fichiers représenté par le type d’élément Compile
est copié dans un répertoire de sauvegarde. Les fichiers de sauvegarde ont l’extension de nom de fichier .bak. Si les fichiers représentés par le type d’élément Compile
, ou les fichiers de sauvegarde correspondants, ne sont pas supprimés ou modifiés après l’exécution de la cible de sauvegarde, celle-ci est ignorée dans les builds suivantes.
Inférence de sortie
MSBuild compare les attributs Inputs
et Outputs
d’une cible pour déterminer si celle-ci doit être exécutée. Dans l’idéal, le jeu de fichiers qui existe après une build incrémentielle doit rester le même, que les cibles associées soient exécutées ou non. Étant donné que les propriétés et les éléments qui sont créés ou modifiés par les tâches peuvent affecter la build, MSBuild doit déduire leurs valeurs, même si la cible associée est ignorée. Ce processus est appelé « inférence de sortie ».
Celle-ci s’utilise dans trois cas :
La cible a un attribut
Condition
dont la valeur estfalse
. Dans ce cas, la cible n’est pas exécutée et n’a aucun effet sur la build.La cible comprend des sorties obsolètes, et est donc exécutée pour les mettre à jour.
La cible ne comprend aucune sortie obsolète, et est donc ignorée. MSBuild évalue la cible et apporte des modifications aux éléments et aux propriétés comme si la cible avait été exécutée.
Pour que la compilation incrémentielle soit prise en charge, les tâches doivent vérifier que la valeur de l’attribut TaskParameter
d’un élément Output
est égale à un paramètre d’entrée de tâche. Voici quelques exemples :
<CreateProperty Value="123">
<Output PropertyName="Easy" TaskParameter="Value" />
</CreateProperty>
Ce code crée la propriété Easy, dont la valeur est « 123 », que la cible ait été ou non exécutée ou ignorée.
À compter de MSBuild 3.5, l’inférence de sortie est exécutée automatiquement sur les groupes de propriétés et d’éléments de la cible. Les tâches CreateItem
ne sont pas obligatoires dans la cible et doivent être évitées. De plus, les tâches CreateProperty
ne doivent être utilisées dans une cible que pour déterminer si celle-ci a été exécutée.
Avant MSBuild 3.5, vous pouvez utiliser la tâche CreateItem.
Déterminer si une cible a été exécutée
En raison de l’inférence de sortie, vous devez ajouter une tâche CreateProperty
à une cible pour examiner les propriétés et les éléments, et ainsi, déterminer si la cible a été exécutée. Ajoutez la tâche CreateProperty
à la cible et attribuez-lui un élément Output
dont le TaskParameter
est défini sur « ValueSetByTask ».
<CreateProperty Value="true">
<Output TaskParameter="ValueSetByTask" PropertyName="CompileRan" />
</CreateProperty>
Ce code crée la propriété CompileRan et lui attribue la valeur true
, mais uniquement si la cible est exécutée. Si la cible est ignorée, CompileRan n’est pas créé.