Procédure pas à pas : créer un fichier projet MSBuild en partant de zéro
Les langages de programmation qui ciblent .NET Framework utilisent des fichiers projet MSBuild pour décrire et contrôler le processus de génération d'application. Quand vous utilisez Visual Studio pour créer un fichier projet MSBuild, le code XML approprié est ajouté automatiquement au fichier. Il peut cependant être utile de comprendre comment le code XML est organisé et comment vous pouvez le modifier pour contrôler une build.
Notes
Cet article est approprié si vous souhaitez découvrir les bases du fonctionnement de MSBuild indépendamment de n’importe quel Kit SDK. La génération à l’aide d’un Kit SDK, par exemple lorsque vous utilisez dotnet build
ou lorsque vous ajoutez l’attribut Sdk
à l’élément de projet racine, n’est pas abordée dans cet article. Consultez SDK de projet .NET.
Pour plus d’informations sur la création d’un fichier projet pour un projet C++, consultez l’article MSBuild (C++).
Cette procédure pas à pas montre comment créer progressivement un fichier projet de base, en utilisant seulement un éditeur de texte. Cette procédure pas à pas comprend les étapes suivantes :
Étendez la variable d’environnement PATH.
Créer un fichier source d'application minimal.
Créer un fichier projet MSBuild minimal.
Générer l'application en utilisant le fichier projet.
Ajouter des propriétés pour contrôler la build.
Contrôler la build en changeant les valeurs de propriétés.
Ajouter des cibles à la build.
Contrôler la build en spécifiant des cibles.
Générer de façon incrémentielle.
Cette procédure pas à pas montre comment créer le projet sur l'invite de commandes et examiner les résultats. Pour plus d’informations sur MSBuild et son exécution à l’invite de commandes, consultez la Procédure pas à pas : utiliser MSBuild.
Pour effectuer la procédure pas à pas, vous devez disposer de Visual Studio, car il comprend MSBuild et le compilateur C#, qui sont requis pour cette procédure.
Étendre le chemin d’accès
Avant de pouvoir utiliser MSBuild, vous devez étendre la variable d'environnement PATH pour inclure tous les outils requis. Vous pouvez utiliser l’Invite de commandes développeur pour Visual Studio. Recherchez-la sur Windows 10 dans la zone de recherche de la barre des tâches Windows. Pour configurer l’environnement dans une invite de commandes ordinaire ou dans un environnement de script, exécutez VSDevCmd.bat dans le sous-dossier Common7/Tools d’une installation de Visual Studio.
Créer une application minimale
Cette section montre comment créer un fichier source d’application C# minimal en utilisant un éditeur de texte.
À l’invite de commandes, accédez au dossier où vous voulez créer l’application, par exemple, \Mes documents\ ou \Bureau\.
Créez un sous-dossier nommé \HelloWorld\ et modifiez le répertoire pour y accéder.
Dans un éditeur de texte, créez un fichier HelloWorld.cs, puis copiez et collez le code suivant :
using System; class HelloWorld { static void Main() { #if DebugConfig Console.WriteLine("WE ARE IN THE DEBUG CONFIGURATION"); #endif Console.WriteLine("Hello, world!"); } }
Générez l’application en entrant csc helloworld.cs à l’invite de commandes.
Testez l’application en entrant helloworld à l’invite de commandes.
Le message Hello, world! doit s’afficher.
Supprimez le fichier exécutable.
Créer un fichier projet MSBuild minimal
Maintenant que vous avez un fichier source d'application minimal, vous pouvez créer un fichier projet minimal pour générer l'application. Ce fichier projet contient les éléments suivants :
Le nœud
Project
racine requis.Un nœud
ItemGroup
pour contenir les éléments item.Un élément item qui référence le fichier source d'application.
Un nœud
Target
pour contenir les tâches requises pour générer l'application.Un élément
Task
pour démarrer le compilateur C# afin de générer l’application.
Pour créer un fichier projet MSBuild minimal
Dans l’éditeur de texte, créez un fichier HelloWorld.csproj et entrez le code suivant :
<Project> <ItemGroup> <Compile Include="helloworld.cs" /> </ItemGroup> </Project>
Ce
ItemGroup
contient un élément itemCompile
et spécifie un fichier source en tant qu’élément.Ajoutez un nœud
Target
comme élément enfant du nœudProject
. Nommez le nœudBuild
.<Target Name="Build"> </Target>
Insérez cet élément de tâche comme élément enfant du nœud
Target
:<Csc Sources="@(Compile)"/>
Enregistrez ce fichier projet et nommez-le Helloworld.csproj.
Votre fichier projet minimal doit ressembler au code suivant :
<Project>
<ItemGroup>
<Compile Include="helloworld.cs"/>
</ItemGroup>
<Target Name="Build">
<Csc Sources="@(Compile)"/>
</Target>
</Project>
Les tâches de la cible Build sont exécutées séquentiellement. Dans ce cas, la tâche Csc
du compilateur C# est la seule tâche. Elle attend une liste de fichiers source à compiler, qui lui est donnée par la valeur de l'élément Compile
. L'élément Compile
ne référence qu'un seul fichier source, Helloworld.cs.
Notes
Dans l’élément item, vous pouvez utiliser le caractère générique astérisque (*) pour référencer tous les fichiers ayant l’extension de nom de fichier .cs, comme ceci :
<Compile Include="*.cs" />
Créer l’application
Maintenant, pour créer l'application, utilisez le fichier projet que vous venez de créer.
Dans l’invite de commandes, tapez msbuild helloworld.csproj -t:Build.
Ceci crée la cible Build du fichier projet Helloworld en appelant le compilateur C# pour créer l’application Helloworld.
Testez l’application en entrant helloworld.
Le message Hello, world! doit s’afficher.
Notes
Vous pouvez afficher plus de détails sur la génération en augmentant le niveau de détail. Pour définir le niveau de détail sur « détaillé », entrez cette commande à l’invite de commandes :
msbuild helloworld.csproj -t:Build -verbosity:detailed
Ajouter des propriétés de build
Vous pouvez ajouter des propriétés de build au fichier projet pour contrôler davantage la génération. Ajoutez maintenant ces propriétés :
Une propriété
AssemblyName
pour spécifier le nom de l'application.Une propriété
OutputPath
pour spécifier un dossier destiné à contenir l'application.
Pour ajouter des propriétés de build
Supprimez le fichier exécutable de l’application existant (plus tard, vous ajouterez une cible
Clean
pour gérer la suppression des anciens fichiers de sortie).Dans le fichier projet, insérez cet élément
PropertyGroup
juste après l'élémentProject
du début :<PropertyGroup> <AssemblyName>MSBuildSample</AssemblyName> <OutputPath>Bin\</OutputPath> </PropertyGroup>
Ajoutez cette tâche à la cible Build, juste avant la tâche
Csc
:<MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')" />
La tâche
MakeDir
crée un dossier dont le nom est donné par la propriétéOutputPath
, à condition qu'aucun dossier de ce nom n'existe déjà.Ajoutez cet attribut
OutputAssembly
à la tâcheCsc
:<Csc Sources="@(Compile)" OutputAssembly="$(OutputPath)$(AssemblyName).exe" />
Ceci demande au compilateur C# de produire un assembly dont le nom est donné par la propriété
AssemblyName
et de le placer dans le dossier dont le nom est donné par la propriétéOutputPath
.Enregistrez vos modifications.
Votre fichier projet doit maintenant ressembler au code suivant :
<Project>
<PropertyGroup>
<AssemblyName>MSBuildSample</AssemblyName>
<OutputPath>Bin\</OutputPath>
</PropertyGroup>
<ItemGroup>
<Compile Include="helloworld.cs" />
</ItemGroup>
<Target Name="Build">
<MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')" />
<Csc Sources="@(Compile)" OutputAssembly="$(OutputPath)$(AssemblyName).exe" />
</Target>
</Project>
Notes
Nous vous recommandons d’ajouter le délimiteur de chemin (\) (barre oblique inverse) à la fin du nom du dossier quand vous le spécifiez dans l’élément OutputPath
, au lieu de l’ajouter dans l’attribut OutputAssembly
de la tâche Csc
. Par conséquent,
<OutputPath>Bin\</OutputPath>
OutputAssembly="$(OutputPath)$(AssemblyName).exe" />
est mieux que
<OutputPath>Bin</OutputPath>
OutputAssembly="$(OutputPath)\$(AssemblyName).exe" />
Tester les propriétés de build
Vous pouvez maintenant générer l'application en utilisant le fichier projet où vous avez utilisé des propriétés de build pour spécifier le dossier de sortie et le nom de l'application.
Dans l’invite de commandes, tapez msbuild helloworld.csproj -t:Build.
Ceci crée le dossier \Bin\, puis appelle le compilateur C# pour créer l’application MSBuildSample et la place dans le dossier \Bin\.
Pour vérifier que le dossier \Bin\ a été créé et qu’il contient l’application MSBuildSample, saisissez dir Bin.
Testez l’application en saisissant Bin\MSBuildSample pour exécuter le fichier exécutable.
Le message Hello, world! doit s’afficher.
Ajouter des cibles de génération
Ensuite, ajoutez deux cibles de plus au fichier projet, comme suit :
Une cible Clean qui supprime les anciens fichiers.
Une cible Rebuild qui utilise l'attribut
DependsOnTargets
pour forcer la tâche Clean à s'exécuter avant la tâche Build.
Maintenant que vous avez plusieurs cibles, vous pouvez définir la cible Build comme cible par défaut.
Pour ajouter des cibles de génération
Dans le fichier projet, ajoutez ces deux cibles juste après la cible Build :
<Target Name="Clean" > <Delete Files="$(OutputPath)$(AssemblyName).exe" /> </Target> <Target Name="Rebuild" DependsOnTargets="Clean;Build" />
La cible Clean appelle la tâche Delete pour supprimer l'application. La cible Rebuild ne s'exécute pas tant que la cible Clean et la cible Build n'ont pas été exécutées. Même si la cible Rebuild n'a pas de tâches, elle provoque l'exécution de la cible Clean avant l'exécution de la cible Build.
Ajoutez cet attribut
DefaultTargets
à l'élémentProject
du début :<Project DefaultTargets="Build">
Ceci définit la cible Build comme cible par défaut.
Votre fichier projet doit maintenant ressembler au code suivant :
<Project DefaultTargets="Build">
<PropertyGroup>
<AssemblyName>MSBuildSample</AssemblyName>
<OutputPath>Bin\</OutputPath>
</PropertyGroup>
<ItemGroup>
<Compile Include="helloworld.cs" />
</ItemGroup>
<Target Name="Build">
<MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')" />
<Csc Sources="@(Compile)" OutputAssembly="$(OutputPath)$(AssemblyName).exe" />
</Target>
<Target Name="Clean" >
<Delete Files="$(OutputPath)$(AssemblyName).exe" />
</Target>
<Target Name="Rebuild" DependsOnTargets="Clean;Build" />
</Project>
Tester les cibles de génération
Vous pouvez utiliser les nouvelles cibles de génération pour tester ces fonctionnalités dans le fichier projet :
Création de la génération par défaut
Définition du nom de l'application à l'invite de commandes
Suppression de l'application avant la génération d'une autre application
Suppression de l'application sans génération d'une autre application
Pour tester les cibles de génération
Dans l’invite de commandes, tapez msbuild helloworld.csproj -p:AssemblyName=Greetings.
Comme vous n’avez pas utilisé le commutateur - pour définir explicitement la cible, MSBuild exécute la cible Build par défaut. Le commutateur -p remplace la propriété
AssemblyName
et lui donne la nouvelle valeur,Greetings
. Ceci provoque la création d’une nouvelle application, Greetings.exe dans le dossier \Bin\.Pour vérifier que le dossier \Bin\ contient à la fois l’application MSBuildSample et la nouvelle application Greetings, saisissez dir Bin.
Testez l’application Greetings (par exemple, en saisissant Bin\Greetings sur Windows).
Le message Hello, world! doit s’afficher.
Supprimez l’application MSBuildSample en tapant msbuild helloworld.csproj -t:clean.
Cela exécute la tâche Clean pour supprimer l’application qui a la valeur de la propriété
AssemblyName
par défaut,MSBuildSample
.Supprimez l’application Greetings en tapant msbuild helloworld.csproj -t:clean -p:AssemblyName=Greetings.
Cela exécute la tâche Clean pour supprimer l’application qui a la valeur de la propriété AssemblyName spécifiée,
Greetings
.Pour vérifier que le dossier \Bin\ est maintenant vide, saisissez dir Bin.
Tapez msbuild.
Même si aucun fichier projet n’est spécifié, MSBuild génère le fichier helloworld.csproj, car il n’existe qu’un seul fichier projet dans le dossier actif. Ceci provoque la création de l’application MSBuildSample dans le dossier \Bin\.
Pour vérifier que le dossier \Bin\ contient l’application MSBuildSample, saisissez dir Bin.
Générer de façon incrémentielle
Vous pouvez indiquer à MSBuild de générer une cible seulement si les fichiers source ou les fichiers cible dont dépend la cible ont changé. MSBuild utilise l'horodatage d'un fichier pour déterminer s'il a changé.
Pour générer de façon incrémentielle
Dans le fichier projet, ajoutez ces attributs après la cible Build du début :
Inputs="@(Compile)" Outputs="$(OutputPath)$(AssemblyName).exe"
Ceci spécifie que la cible Build dépend des fichiers d'entrée qui sont spécifiés dans le groupe d'éléments
Compile
et que la cible en sortie est le fichier d'application.La cible Build résultante doit être similaire au code suivant :
<Target Name="Build" Inputs="@(Compile)" Outputs="$(OutputPath)$(AssemblyName).exe"> <MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')" /> <Csc Sources="@(Compile)" OutputAssembly="$(OutputPath)$(AssemblyName).exe" /> </Target>
Testez la cible Build en tapant msbuild -v:d dans l’invite de commandes.
Rappelez-vous que helloworld.csproj est le fichier projet par défaut et que Build est la cible par défaut.
Le commutateur -v:d est une abréviation de -verbosity:detailed que vous avez utilisée précédemment.
Si vous avez déjà généré la sortie, ces lignes doivent être affichées :
La cible est ignorée "Build", car tous les fichiers de sortie sont à jour par rapport aux fichiers d'entrée.
MSBuild ignore la cible Build, car aucun des fichiers source n'a changé depuis la dernière génération de l'application.
Exemple en code C#
L’exemple suivant montre un fichier de projet qui compile une application C# et consigne un message contenant le nom du fichier de sortie.
Code
<Project DefaultTargets = "Compile">
<!-- Set the application name as a property -->
<PropertyGroup>
<appname>HelloWorldCS</appname>
</PropertyGroup>
<!-- Specify the inputs by type and file name -->
<ItemGroup>
<CSFile Include = "*.cs"/>
</ItemGroup>
<Target Name="Compile">
<!-- Run the C# compilation using input files of type CSFile -->
<CSC
Sources = "@(CSFile)"
OutputAssembly = "$(appname).exe">
<!-- Set the OutputAssembly attribute of the CSC task
to the name of the executable file that is created -->
<Output
TaskParameter = "OutputAssembly"
ItemName = "EXEFile" />
</CSC>
<!-- Log the file name of the output file -->
<Message Text="The output file is @(EXEFile)"/>
</Target>
</Project>
Exemple Visual Basic
L’exemple suivant montre un fichier de projet qui compile une application Visual Basic et consigne un message contenant le nom du fichier de sortie.
Code
<Project DefaultTargets = "Compile">
<!-- Set the application name as a property -->
<PropertyGroup>
<appname>HelloWorldVB</appname>
</PropertyGroup>
<!-- Specify the inputs by type and file name -->
<ItemGroup>
<VBFile Include = "consolehwvb1.vb"/>
</ItemGroup>
<Target Name = "Compile">
<!-- Run the Visual Basic compilation using input files of type VBFile -->
<VBC
Sources = "@(VBFile)"
OutputAssembly= "$(appname).exe">
<!-- Set the OutputAssembly attribute of the VBC task
to the name of the executable file that is created -->
<Output
TaskParameter = "OutputAssembly"
ItemName = "EXEFile" />
</VBC>
<!-- Log the file name of the output file -->
<Message Text="The output file is @(EXEFile)"/>
</Target>
</Project>
Et ensuite ?
Visual Studio peut faire automatiquement la plus grande partie du travail qui est montré dans cette procédure pas à pas. Pour découvrir comment utiliser Visual Studio pour créer, modifier, générer et tester des fichiers projet MSBuild, consultez la Procédure pas à pas : utiliser MSBuild.