Personnaliser votre buildCustomize your build

Les projets MSBuild qui utilisent le processus de génération standard (importation de Microsoft.Common.props et Microsoft.Common.targets) ont plusieurs crochets d’extensibilité qui permettent de personnaliser le processus.MSBuild projects that use the standard build process (importing Microsoft.Common.props and Microsoft.Common.targets) have several extensibility hooks that can be used to customize your build process.

Ajout d’arguments aux appels MSBuild de ligne de commande pour votre projetAdding arguments to command-line MSBuild invocations for your project

Un fichier Directory.Build.rsp dans ou au-dessus de votre répertoire source est appliqué aux générations de ligne de commande de votre projet.A Directory.Build.rsp file in or above your source directory will be applied to command-line builds of your project. Pour plus d’informations, consultez Fichiers réponse MSBuild.For details, see MSBuild Response Files.

Directory.Build.props et Directory.Build.targetsDirectory.Build.props and Directory.Build.targets

Dans les versions de MSBuild antérieures à la version 15, si vous souhaitiez fournir une nouvelle propriété personnalisée aux projets de votre solution, vous deviez ajouter manuellement une référence à cette propriété pour chaque fichier projet de la solution.In versions of MSBuild prior to version 15, if you wanted to provide a new, custom property to projects in your solution, you had to manually add a reference to that property to every project file in the solution. Ou vous deviez définir la propriété dans un fichier .props, puis importer explicitement le fichier .props dans chaque projet de la solution, entre autres.Or, you had to define the property in a .props file and then explicitly import the .props file in every project in the solution, among other things.

Maintenant, vous pouvez ajouter une nouvelle propriété à chaque projet en une seule étape en la définissant dans un seul fichier appelé Directory.Build.props dans le dossier racine contenant votre source.However, now you can add a new property to every project in one step by defining it in a single file called Directory.Build.props in the root folder that contains your source. Quand MSBuild s’exécute, Microsoft.Common.props recherche le fichier Directory.Build.props dans votre structure de répertoire (et Microsoft.Common.targets recherche Directory.Build.targets).When MSBuild runs, Microsoft.Common.props searches your directory structure for the Directory.Build.props file (and Microsoft.Common.targets looks for Directory.Build.targets). S’il en trouve un, il importe la propriété.If it finds one, it imports the property. Directory.Build.props est un fichier défini par l’utilisateur qui fournit des personnalisations aux projets situés dans un répertoire.Directory.Build.props is a user-defined file that provides customizations to projects under a directory.

Exemple avec Directory.Build.propsDirectory.Build.props example

Par exemple, si vous souhaitez permettre à l’ensemble de vos projets d’accéder à la nouvelle fonctionnalité Roslyn /deterministic (qui est exposée dans la cible CoreCompile de Roslyn par la propriété $(Deterministic)), vous pouvez procéder comme suit.For example, if you wanted to enable all of your projects to access the new Roslyn /deterministic feature (which is exposed in the Roslyn CoreCompile target by the property $(Deterministic)), you could do the following.

  1. Créez un nouveau fichier à la racine de votre référentiel appelé Directory.Build.props.Create a new file in the root of your repo called Directory.Build.props.
  2. Ajoutez le code XML suivant au fichier.Add the following XML to the file.

    <Project>
     <PropertyGroup>
       <Deterministic>true</Deterministic>
     </PropertyGroup>
    </Project>
    
  3. Exécutez MSBuild.Run MSBuild. Les importations existantes de votre projet de Microsoft.Common.props et Microsoft.Common.targets trouvent le fichier et l’importent.Your project’s existing imports of Microsoft.Common.props and Microsoft.Common.targets find the file and import it.

Étendue de la rechercheSearch scope

Lorsque vous recherchez un fichier Directory.Build.props, MSBuild remonte dans la structure de répertoire par rapport à l’emplacement de votre projet ($(MSBuildProjectFullPath)) et s’arrête après avoir localisé un fichier Directory.Build.props.When searching for a Directory.Build.props file, MSBuild walks the directory structure upwards from your project location ($(MSBuildProjectFullPath)), stopping after it locates a Directory.Build.props file. Par exemple, si votre $(MSBuildProjectFullPath) était c:\users\username\code\test\case1, MSBuild commencerait à rechercher ici, puis remonterait dans la structure de répertoire jusqu’à ce qu’il trouve un fichier Directory.Build.props, comme dans la structure de répertoire suivante.For example, if your $(MSBuildProjectFullPath) was c:\users\username\code\test\case1, MSBuild would start searching there and then search the directory structure upward until it located a Directory.Build.props file, as in the following directory structure.

c:\users\username\code\test\case1
c:\users\username\code\test
c:\users\username\code
c:\users\username
c:\users
c:\

L’emplacement du fichier solution est sans importance pour Directory.Build.props.The location of the solution file is irrelevant to Directory.Build.props.

Ordre d’importationImport order

Directory.Build.props est importé très tôt dans Microsoft.Common.props, donc les propriétés définies ultérieurement ne sont pas disponibles pour ce dernier.Directory.Build.props is imported very early in Microsoft.Common.props, so properties defined later are unavailable to it. Par conséquent, évitez de faire référence aux propriétés qui ne sont pas encore définies (et qui seront évaluées comme vides).So, avoid referring to properties that are not yet defined (and will thus evaluate to empty).

Directory.Build.targets est importé à partir de Microsoft.Common.targets après l’importation des fichiers .targets à partir des packages NuGet.Directory.Build.targets is imported from Microsoft.Common.targets after importing .targets files from NuGet packages. Il peut donc être utilisé pour remplacer les propriétés et les cibles définies dans la quasi-totalité de la logique de build. Dans certains cas toutefois, il peut être nécessaire d’effectuer des personnalisations dans le fichier projet après l’importation finale.So, it can be used to override properties and targets defined in most of the build logic, but at times it may be necessary to do customizations within the project file after the final import.

Cas d’utilisation : Fusion à plusieurs niveauxUse case: multi-level merging

Supposons que vous ayez la structure de solution standard suivante :Suppose you have this standard solution structure:

\
  MySolution.sln
  Directory.Build.props     (1)
  \src
    Directory.Build.props   (2-src)
    \Project1
    \Project2
  \test
    Directory.Build.props   (2-test)
    \Project1Tests
    \Project2Tests

Il peut être souhaitable d’avoir des propriétés communes pour tous les projets (1), des propriétés communes pour les projets src (2-src) et des propriétés communes pour les projets test (2-test).It might be desirable to have common properties for all projects (1), common properties for src projects (2-src), and common properties for test projects (2-test).

Pour que MSBuild fusionne correctement les fichiers « internes » (2-src et 2-test) avec le fichier « externe » (1), vous devez prendre en compte le fait qu’une fois que MSBuild a trouvé un fichier Directory.Build.props, il arrête sa recherche.For MSBuild to correctly merge the "inner" files (2-src and 2-test) with the "outer" file (1), you must take into account that once MSBuild finds a Directory.Build.props file, it stops further scanning. Pour poursuivre la recherche et fusionner les fichiers internes avec le fichier externe, placez ce qui suit dans les deux fichiers internes :To continue scanning, and merge into the outer file, place this into both inner files:

<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />

Voici un résumé de l’approche générale MSBuild :A summary of MSBuild's general approach is as follows:

  • Pour un projet donné, MSBuild recherche le premier Directory.Build.props vers le haut de la structure de la solution, le fusionne avec les valeurs par défaut et arrête la rechercheFor any given project, MSBuild finds the first Directory.Build.props upward in the solution structure, merges it with defaults, and stops scanning for more
  • Si vous souhaitez rechercher et fusionner plusieurs niveaux, importez (<Import...>, ci-dessus) le fichier « externe » à partir du fichier « interne ».If you want multiple levels to be found and merged, then <Import...> (shown above) the "outer" file from the "inner" file
  • Si le fichier « externe » n’importe pas également un élément situé au-dessus, la recherche s’arrête.If the "outer" file does not itself also import something above it, then scanning stops there
  • Pour contrôler le processus de recherche et de fusion, utilisez $(DirectoryBuildPropsPath) et $(ImportDirectoryBuildProps).To control the scanning/merging process, use $(DirectoryBuildPropsPath) and $(ImportDirectoryBuildProps)

Ou plus simplement : MSBuild s’arrête au premier Directory.Build.props qui n’importe aucun élément.Or more simply: the first Directory.Build.props which doesn't import anything, is where MSBuild stops.

MSBuildProjectExtensionsPathMSBuildProjectExtensionsPath

Par défaut, Microsoft.Common.props importe $(MSBuildProjectExtensionsPath)$(MSBuildProjectFile).*.props et Microsoft.Common.targets importe $(MSBuildProjectExtensionsPath)$(MSBuildProjectFile).*.targets.By default, Microsoft.Common.props imports $(MSBuildProjectExtensionsPath)$(MSBuildProjectFile).*.props and Microsoft.Common.targets imports $(MSBuildProjectExtensionsPath)$(MSBuildProjectFile).*.targets. La valeur par défaut de MSBuildProjectExtensionsPath est $(BaseIntermediateOutputPath), obj/.The default value of MSBuildProjectExtensionsPath is $(BaseIntermediateOutputPath), obj/. Il s’agit du mécanisme qu’utilise NuGet pour faire référence à la logique de génération fournie avec les packages ; autrement dit, au moment de la restauration, il crée les fichiers {project}.nuget.g.props qui font référence au contenu des packages.This is the mechanism that NuGet uses to refer to build logic delivered with packages, that is, at restore time, it creates {project}.nuget.g.props files that refer to the package contents.

Vous pouvez désactiver ce mécanisme d’extensibilité en définissant la propriété ImportProjectExtensionProps sur false dans un fichier Directory.Build.props ou avant d’importer Microsoft.Common.props.This extensibility mechanism can be disabled by setting the property ImportProjectExtensionProps to false in a Directory.Build.props or before importing Microsoft.Common.props.

Note

La désactivation de MSBuildProjectExtensionsPath empêche d’appliquer à votre projet la logique de génération fournie dans les packages NuGet.Disabling MSBuildProjectExtensionsPath imports will prevent build logic delivered in NuGet packages from applying to your project. Certains packages NuGet nécessitent la logique de génération pour effectuer leur fonction et sont rendus inutiles quand ce mécanisme est désactivé.Some NuGet packages require build logic to perform their function and will be rendered useless when this is disabled.

Fichier .user.user file

Microsoft.Common.CurrentVersion.targets importe $(MSBuildProjectFullPath).user s’il existe, afin que vous puissiez créer un fichier à côté de votre projet avec cette extension supplémentaire.Microsoft.Common.CurrentVersion.targets imports $(MSBuildProjectFullPath).user if it exists, so you can create a file next to your project with that additional extension. Pour les changements à long terme que vous envisagez d’archiver dans le contrôle de code source, préférez la modification du projet proprement dit, afin que les futurs responsables de la maintenance n’aient pas à connaître ce mécanisme d’extension.For long-term changes you plan to check into source control, prefer changing the project itself, so that future maintainers do not have to know about this extension mechanism.

MSBuildExtensionsPath et MSBuildUserExtensionsPathMSBuildExtensionsPath and MSBuildUserExtensionsPath

Avertissement

L’utilisation de ces mécanismes d’extension rend très difficile la répétition de générations d’une machine à l’autre.Using these extension mechanisms makes it harder to get repeatable builds across machines. Essayez d’utiliser une configuration qui puisse être archivée dans votre système de contrôle de code source et partagée entre tous les développeurs de votre code base.Try to use a configuration that can be checked into your source control system and shared among all developers of your codebase.

Par convention, de nombreux fichiers de logique de génération de base importentBy convention, many core build logic files import

$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\{TargetFileName}\ImportBefore\*.targets

avant leur contenu, etbefore their contents, and

$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\{TargetFileName}\ImportAfter\*.targets

après.afterward. Ainsi, les kits SDK installés peuvent renforcer la logique de génération des types de projets courants.This allows installed SDKs to augment the build logic of common project types.

La même structure de répertoire est recherchée dans $(MSBuildUserExtensionsPath), qui est le dossier par utilisateur %LOCALAPPDATA%\Microsoft\MSBuild.The same directory structure is searched in $(MSBuildUserExtensionsPath), which is the per-user folder %LOCALAPPDATA%\Microsoft\MSBuild. Les fichiers placés dans ce dossier sont importés pour toutes les générations du type de projet correspondant exécutées sous les informations d’identification de l’utilisateur concerné.Files placed in that folder will be imported for all builds of the corresponding project type run under that user's credentials. Vous pouvez désactiver les extensions utilisateur en définissant les propriétés nommées d’après le fichier d’importation selon le modèle ImportUserLocationsByWildcardBefore{ImportingFileNameWithNoDots}.The user extensions can be disabled by setting properties named after the importing file in the pattern ImportUserLocationsByWildcardBefore{ImportingFileNameWithNoDots}. Par exemple, si vous définissez ImportUserLocationsByWildcardBeforeMicrosoftCommonProps avec la valeur false, vous empêchez l’importation de $(MSBuildUserExtensionsPath)\$(MSBuildToolsVersion)\Imports\Microsoft.Common.props\ImportBefore\*.For example, setting ImportUserLocationsByWildcardBeforeMicrosoftCommonProps to false would prevent importing $(MSBuildUserExtensionsPath)\$(MSBuildToolsVersion)\Imports\Microsoft.Common.props\ImportBefore\*.

Personnalisation de la génération de la solutionCustomizing the solution build

Important

La personnalisation de la génération de la solution de cette façon s’applique uniquement aux générations de ligne de commande avec MSBuild.exe.Customizing the solution build in this way applies only to command-line builds with MSBuild.exe. Elle ne s’applique pas aux générations à l’intérieur de Visual Studio.It does not apply to builds inside Visual Studio.

Quand MSBuild génère un fichier solution, il le convertit en interne en fichier projet, puis génère ce dernier.When MSBuild builds a solution file, it first translates it internally into a project file and then builds that. Le fichier projet généré importe before.{solutionname}.sln.targets avant de définir des cibles et after.{solutionname}.sln.targets après avoir importé les cibles, notamment les cibles installées dans les répertoires $(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\SolutionFile\ImportBefore et $(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\SolutionFile\ImportAfter.The generated project file imports before.{solutionname}.sln.targets before defining any targets and after.{solutionname}.sln.targets after importing targets, including targets installed to the $(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\SolutionFile\ImportBefore and $(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\SolutionFile\ImportAfter directories.

Par exemple, vous pouvez définir une nouvelle cible pour écrire un message de journal personnalisé après avoir généré MyCustomizedSolution.sln en créant un fichier dans le même répertoire que celui nommé after.MyCustomizedSolution.sln.targets qui contientFor example, you could define a new target to write a custom log message after building MyCustomizedSolution.sln by creating a file in the same directory named after.MyCustomizedSolution.sln.targets that contains

<Project>
 <Target Name="EmitCustomMessage" AfterTargets="Build">
   <Message Importance="High" Text="The solution has completed the Build target" />
 </Target>
</Project>

Voir aussiSee Also

Concepts MSBuild Référence MSBuildMSBuild Concepts MSBuild Reference