Procedura dettagliata: utilizzo di MSBuild
MSBuild è la piattaforma di compilazione per Microsoft e Visual Studio. Questa procedura dettagliata introduce i concetti di base di MSBuild e mostra come scrivere e modificare progetti MSBuild nonché come eseguirne il debug. Verranno fornite informazioni sugli argomenti seguenti:
Creazione e modifica di un file di progetto
Utilizzo delle proprietà di compilazione
Utilizzo degli elementi di compilazione
MSBuild può essere eseguito tramite Visual Studio o mediante la finestra di comando. Questa procedura dettagliata illustra la creazione di un file di progetto di MSBuild utilizzando Visual Studio. Illustra inoltre la modifica del file di progetto in Visual Studio nonché l'utilizzo di una finestra di comando per compilare il progetto ed esaminare i risultati.
Creazione di un progetto MSBuild
Il sistema dei progetti di Visual Studio si basa su MSBuild. Ciò semplifica la creazione di un nuovo file di progetto utilizzando Visual Studio. In questa sezione viene descritta la creazione di un file di progetto di Visual C#. È possibile tuttavia scegliere di creare un file di progetto di Visual Basic. Nel contesto di questa procedura dettagliata, le differenze tra i due file di progetto sono trascurabili.
Per creare un file di progetto
Aprire Visual Studio.
Scegliere Nuovo dal menu File, quindi fare clic su Progetto.
Nella finestra di dialogo Nuovo progetto, selezionare il tipo di progetto Visual C# e quindi scegliere il modello Applicazione Windows Form. Nella casella Nome digitare BuildApp. Immettere un Percorso per la soluzione, ad esempio D:\. Accettare le impostazioni predefinite Crea directory per soluzione (selezionato), Aggiungi al controllo del codice sorgente (non selezionato) e Nome soluzione (BuildApp).
Scegliere OK per creare il file di progetto.
Esame del file di progetto
Nella sezione precedente si è utilizzato Visual Studio per creare un file di progetto di Visual C#. Il file di progetto viene rappresentato in Esplora soluzioni dal nodo di progetto denominato BuildApp. Per esaminare il file di progetto è possibile utilizzare l'editor del codice di Visual Studio.
Per esaminare il file di progetto
In Esplora soluzioni fare clic sul nodo di progetto BuildApp.
Nel browser Proprietà, notare che la proprietà File di progetto è BuildApp.csproj. Tutti i file di progetto sono denominati con il suffisso "proj". Se invece si creasse un progetto Visual Basic, il nome del file di progetto sarebbe BuildApp.vbproj.
Fare clic con il pulsante destro del mouse sul nodo di progetto, quindi scegliere Scarica progetto.
Fare nuovamente clic con il pulsante destro del mouse sul nodo di progetto, quindi scegliere Modifica BuildApp.csproj.
Il file di progetto verrà visualizzato nell'editor del codice.
Destinazioni e attività
I file di progetto sono file in formato XML con il nodo radice Project.
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
È necessario specificare lo spazio dei nomi xmlns nell'elemento Project.
Per eseguire le operazioni di compilazione di un'applicazione vengono utilizzati gli elementi Target (destinazione) e Task (attività).
Un'attività è l'unità più piccola di lavoro, in altre parole un "atomo" di compilazione. Le attività sono componenti eseguibili indipendenti che possono presentare input e output. Al momento il file di progetto non contiene alcuna attività definita o a cui si fa riferimento. Per aggiungere attività nel file di progetto si utilizzano le sezioni seguenti. Per ulteriori informazioni, vedere l'argomento Attività di MSBuild.
Una destinazione è una sequenza denominata di attività. Alla fine del file di progetto sono presenti due destinazioni attualmente racchiuse fra commenti HTML: BeforeBuild e AfterBuild.
<Target Name="BeforeBuild"> </Target> <Target Name="AfterBuild"> </Target>
Per ulteriori informazioni, vedere l'argomento Destinazioni di MSBuild.
Il nodo Project presenta un attributo DefaultTargets facoltativo che seleziona la destinazione predefinita da compilare, in questo caso Build.
<Project ToolsVersion="12.0" DefaultTargets="Build" ...
La destinazione di compilazione non viene definita nel file di progetto, ma viene importata dal file Microsoft.CSharp.targets tramite l'elemento Import.
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
I file importati vengono di fatto inseriti nel file di progetto in ogni punto in cui si fa riferimento ad essi.
MSBuild tiene traccia delle destinazioni di una build e garantisce che ogni destinazione venga compilata soltanto una volta.
Aggiunta di una destinazione e di un'attività
Aggiungere una destinazione al file di progetto. Aggiungere un'attività alla destinazione che stampa un messaggio.
Per aggiungere una destinazione e un'attività
Aggiungere le righe seguenti al file di progetto, subito dopo l'istruzione Import:
<Target Name="HelloWorld"> </Target>
In questo modo viene creata una destinazione denominata HelloWorld. Notare che si dispone del supporto IntelliSense durante la modifica del file di progetto.
Aggiungere righe alla destinazione HelloWorld in modo che la sezione così ottenuta risulti uguale a quanto segue:
<Target Name="HelloWorld"> <Message Text="Hello"></Message> <Message Text="World"></Message> </Target>
Salvare il file di progetto.
L'attività Message è una delle molte attività incluse in MSBuild. Per un elenco completo delle attività disponibili e per informazioni sul relativo utilizzo, vedere Riferimenti delle attività MSBuild.
L'attività Message accetta il valore stringa dell'attributo Text come input e lo visualizza nel dispositivo di output. La destinazione HelloWorld esegue due volte l'attività Message: prima per visualizzare "Hello" e quindi per visualizzare "World".
Compilazione della destinazione
Eseguire MSBuild dal prompt dei comandi di Visual Studio per compilare la destinazione HelloWorld sopra definita. Per selezionare la destinazione, utilizzare l'opzione della riga di comando /target o /t.
Nota
Nelle sezioni seguenti, con prompt dei comandi di Visual Studio si intenderà la finestra di comando.
Per compilare la destinazione
Fare clic sul pulsante Start, quindi scegliere Tutti i programmi. Individuare e scegliere il prompt dei comandi di Visual Studio nella cartella Visual Studio Tools.
Dalla finestra di comando, passare alla cartella che contiene il file di progetto. In questo caso, D:\BuildApp\BuildApp.
Eseguire msbuild con l'opzione di comando /t:HelloWorld. Quanto segue consente di selezionare e compilare la destinazione HelloWorld:
msbuild buildapp.csproj /t:HelloWorld
Esaminare l'output nella finestra di comando. Dovrebbero essere visualizzate le due righe "Hello" e "World":
Hello World
Nota
Se invece viene visualizzato il messaggio The target "HelloWorld" does not exist in the project probabilmente il file di progetto non è stato salvato nell'editor del codice.Salvare il file e provare nuovamente.
Se si passa alternativamente fra l'editor del codice e la finestra di comando è possibile modificare il file di progetto e visualizzare rapidamente i risultati.
Nota
Se si esegue msbuild senza l'opzione di comando /t, msbuild compila la destinazione specificata dall'attributo DefaultTarget dell'elemento Project, in questo caso "Build".Ciò comporta la compilazione dell'applicazione Windows Form BuildApp.exe.
Proprietà di compilazione
Le proprietà di compilazione sono coppie nome/valore che determinano la compilazione. Diverse proprietà di compilazione sono già definite all'inizio del file di progetto:
<PropertyGroup>
...
<ProductVersion>10.0.11107</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{30E3C9D5-FD86-4691-A331-80EA5BA7E571}</ProjectGuid>
<OutputType>WinExe</OutputType>
...
</PropertyGroup>
Tutte le proprietà sono elementi figlio di elementi PropertyGroup. Il nome della proprietà è il nome dell'elemento figlio e il valore della proprietà è l'elemento di testo dell'elemento figlio. Di seguito è riportato un esempio:
<TargetFrameworkVersion>v12.0</TargetFrameworkVersion>
definisce la proprietà denominata TargetFrameworkVersion, assegnandogli il valore stringa "v12.0".
Le proprietà di compilazione possono essere ridefinite in qualsiasi momento. Se il parametro
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
viene incluso successivamente nel file di progetto o se è presente in un file importato in un secondo momento nel file di progetto, TargetFrameworkVersion assume il nuovo valore "v3.5".
Esame del valore di una proprietà
Per ottenere il valore di una proprietà è possibile utilizzare la sintassi seguente, dove PropertyName indica il nome della proprietà:
$(PropertyName)
Utilizzare questa sintassi per esaminare alcune delle proprietà nel file di progetto.
Per esaminare il valore di una proprietà
Tramite l'editor del codice, sostituire la destinazione HelloWorld con il codice seguente:
<Target Name="HelloWorld"> <Message Text="Configuration is $(Configuration)" /> <Message Text="MSBuildToolsPath is $(MSBuildToolsPath)" /> </Target>
Salvare il file di progetto.
Nella finestra di comando immettere ed eseguire la riga seguente:
msbuild buildapp.csproj /t:HelloWorld
Esaminare l'output. Verranno visualizzate le due righe riportate di seguito. Tuttavia, è possibile che la versione di .NET Framework risulti diversa.
Configuration is Debug MSBuildToolsPath is C:\Program Files\MSBuild\12.0\bin
Nota
Se queste due righe non vengono visualizzate, probabilmente il file di progetto non è stato salvato nell'editor del codice.Salvare il file e provare nuovamente.
Proprietà condizionali
Molte proprietà, ad esempio Configuration, sono definite in base a determinate condizioni. Questa situazione si verifica quando l'elemento della proprietà contiene l'attributo Condition. Le proprietà condizionali vengono definite o ridefinite solo se la condizione risulta essere "true". Notare che alle proprietà non definite viene assegnato il valore predefinito di una stringa vuota. Di seguito è riportato un esempio:
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
significa: "Se la proprietà Configuration non è stata ancora definita, definiscila e assegnale il valore Debug".
Quasi tutti gli elementi MSBuild possono presentare un attributo Condition. Per ulteriori informazioni sull'utilizzo dell'attributo Condition, vedere Condizioni di MSBuild.
Proprietà riservate
MSBuild riserva alcuni nomi di proprietà per archiviare le informazioni relative al file di progetto e ai file binari di MSBuild. MSBuildToolsPath è un esempio di proprietà riservata. Per fare riferimento alle proprietà riservate si utilizza la notazione $, come per qualsiasi altra proprietà. Per ulteriori informazioni, vedere Procedura: fare riferimento al nome o al percorso del file di progetto e Proprietà riservate e note MSBuild.
Variabili di ambiente
Per fare riferimento alle variabili di ambiente nei file di progetto si procede nello stesso modo utilizzato per fare riferimento alle proprietà di compilazione. Per utilizzare ad esempio la variabile di ambiente PATH nel file di progetto, ricorrere a $(Path). Se il progetto contiene una definizione di proprietà che possiede lo stesso nome della variabile di ambiente, tale proprietà esegue l'override del valore della variabile. Per ulteriori informazioni, vedere Procedura: utilizzare le variabili di ambiente in una compilazione.
Impostazione delle proprietà dalla riga di comando
Le proprietà possono essere definite nella riga di comando utilizzando l'opzione della riga di comando /property o /p. I valori delle proprietà ricevuti dalla riga di comando eseguono l'override dei valori delle proprietà impostati nel file di progetto e delle variabili di ambiente.
Per impostare un valore di proprietà tramite la riga di comando
Nella finestra di comando immettere ed eseguire la riga seguente:
msbuild buildapp.csproj /t:HelloWorld /p:Configuration=Release
Esaminare l'output. Verrà visualizzata la riga seguente:
Configuration is Release.
MSBuild crea la proprietà Configuration e vi assegna il valore "Release".
Caratteri speciali
Alcuni caratteri hanno un significato speciale nei file di progetto di MSBuild. Esempi di questi caratteri sono il punto e virgola (;) e l'asterisco (*). Per utilizzare questi caratteri speciali come valori letterali in un file di progetto, è necessario specificarli utilizzando la sintassi %xx, dove xx rappresenta il valore ASCII esadecimale del carattere.
Modificare l'attività Message affinché mostri il valore della proprietà Configuration con i caratteri speciali, in modo da renderlo più leggibile.
Per utilizzare i caratteri speciali nell'attività Message
Tramite l'editor del codice, sostituire entrambe le attività Message con la riga seguente:
<Message Text="%24(Configuration) is %22$(Configuration)%22" />
Salvare il file di progetto.
Nella finestra di comando immettere ed eseguire la riga seguente:
msbuild buildapp.csproj /t:HelloWorld
Esaminare l'output. Verrà visualizzata la riga seguente:
$(Configuration) is "Debug"
Per ulteriori informazioni, vedere Caratteri speciali di MSBuild.
Elementi di compilazione
Un elemento è un'informazione, in genere un nome file, utilizzata come un input al sistema di compilazione. Ad esempio, una raccolta di elementi che rappresentano file di origine può essere passata a un'attività denominata Compile per compilare gli elementi in un assembly.
Tutti gli elementi sono elementi figlio di elementi ItemGroup. Il nome dell'elemento è il nome dell'elemento figlio e il valore dell'elemento è il valore dell'attributo Include dell'elemento figlio. I valori degli elementi aventi lo stesso nome vengono raggruppati in tipi di elemento con tale nome. Di seguito è riportato un esempio:
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
definisce un gruppo di elementi contenente due elementi. Il tipo di elemento Compile presenta due valori: "Program.cs" e "Properties\AssemblyInfo.cs".
Il codice seguente crea lo stesso tipo di elementi dichiarando entrambi i file in un unico attributo Include, separati da un punto e virgola.
<ItemGroup>
<Compile Include="Program.cs;Properties\AssemblyInfo.cs" />
</ItemGroup>
Per ulteriori informazioni, vedere Elementi MSBuild.
Nota
I percorsi dei file sono relativi alla cartella contenente il file di progetto di MSBuild.
Esame dei valori del tipo di elemento
Per ottenere i valori di un tipo di elemento è possibile utilizzare la sintassi seguente, dove ItemType è il nome del tipo di elemento:
@(ItemType)
Utilizzare questa sintassi per esaminare il tipo di elemento Compile nel file di progetto.
Per esaminare i valori del tipo di elemento
Tramite l'editor del codice, sostituire l'attività di destinazione HelloWorld con il codice seguente:
<Target Name="HelloWorld"> <Message Text="Compile item type contains @(Compile)" /> </Target>
Salvare il file di progetto.
Nella finestra di comando immettere ed eseguire la riga seguente:
msbuild buildapp.csproj /t:HelloWorld
Esaminare l'output. Verrà visualizzata la riga lunga seguente:
Compile item type contains Form1.cs;Form1.Designer.cs;Program.cs;Properties\AssemblyInfo.cs;Properties\Resources.Designer.cs;Properties\Settings.Designer.cs
Per impostazione predefinita, i valori di un tipo di elemento sono separati da punti e virgola.
Per modificare il separatore di un tipo di elemento è possibile utilizzare la sintassi seguente, dove ItemType è il tipo di elemento e Separator è una stringa di uno o più caratteri di separazione:
@(ItemType, Separator)
Modificare l'attività Message affinché utilizzi ritorni a capo e avanzamenti riga (%0A%0D) per visualizzare un elemento Compile per riga.
Per visualizzare un valore del tipo di elemento per riga
Tramite l'editor del codice, sostituire l'attività Message con la riga seguente:
<Message Text="Compile item type contains @(Compile, '%0A%0D')" />
Salvare il file di progetto.
Nella finestra di comando immettere ed eseguire la riga seguente:
msbuild buildapp.csproj /t:HelloWorld
Esaminare l'output. Verranno visualizzate le righe seguenti:
Compile item type contains Form1.cs Form1.Designer.cs Program.cs Properties\AssemblyInfo.cs Properties\Resources.Designer.cs Properties\Settings.Designer.cs
Include, Exclude e caratteri jolly
È possibile utilizzare i caratteri jolly "*", "**" e "?" con l'attributo Include per aggiungere elementi a un tipo di elemento. Di seguito è riportato un esempio:
<Photos Include="images\*.jpeg" />
aggiunge al tipo di elemento Photos tutti i file con estensione ".jpeg" nella cartella delle immagini, mentre
<Photos Include="images\**.jpeg" />
aggiunge al tipo di elemento Photos tutti i file con estensione ".jpeg" nella cartella delle immagini e tutte le relative sottocartelle. Per ulteriori esempi, vedere Procedura: selezionare i file da compilare.
Notare che ogni volta che viene dichiarato un elemento, questo viene aggiunto al tipo di elemento. Di seguito è riportato un esempio:
<Photos Include="images\*.jpeg" />
<Photos Include="images\*.gif" />
crea un tipo di elemento denominato Photo contenente tutti i file nella cartella delle immagini aventi l'estensione ".jpeg" o ".gif". Questa riga è equivalente alla riga seguente:
<Photos Include="images\*.jpeg;images\*.gif" />
Per escludere un elemento da un tipo di elemento è possibile utilizzare l'attributo Exclude. Di seguito è riportato un esempio:
<Compile Include="*.cs" Exclude="*Designer*">
aggiunge al tipo di elemento Compile tutti i file con estensione ".cs", a eccezione dei file i cui nomi contengono la stringa "Designer". Per ulteriori esempi, vedere Procedura: escludere file dalla compilazione.
L'attributo Exclude influisce solo sugli elementi aggiunti dall'attributo Include nell'elemento Item che contiene entrambi gli attributi. Di seguito è riportato un esempio:
<Compile Include="*.cs" />
<Compile Include="*.res" Exclude="Form1.cs">
non escluderebbe il file Form1.cs, aggiunto nell'elemento Item precedente.
Per includere ed escludere elementi
Tramite l'editor del codice, sostituire l'attività Message con la riga seguente:
<Message Text="Compile item type contains @(XFiles)" />
Aggiungere subito dopo l'elemento Import il gruppo di elementi seguente:
<ItemGroup> <XFiles Include="*.cs;properties/*.resx" Exclude="*Designer*" /> </ItemGroup>
Salvare il file di progetto.
Nella finestra di comando immettere ed eseguire la riga seguente:
msbuild buildapp.csproj /t:HelloWorld
Esaminare l'output. Verrà visualizzata la riga seguente:
Compile item type contains Form1.cs;Program.cs;Properties/Resources.resx
Metadati degli elementi
Oltre alle informazioni raccolte dagli attributi Include ed Exclude, gli elementi possono contenere metadati. Questi metadati possono essere utilizzati dalle attività che richiedono informazioni aggiuntive sugli elementi in quanto il semplice valore degli elementi risulta insufficiente.
Per dichiarare i metadati di elemento nel file di progetto, è necessario creare, come figlio di un elemento, un elemento con lo stesso nome dei metadati. Un elemento può contenere zero o più valori di metadati. Ad esempio, l'elemento CSFile seguente contiene metadati Culture con il valore "Fr":
<ItemGroup>
<CSFile Include="main.cs">
<Culture>Fr</Culture>
</CSFile>
</ItemGroup>
Per ottenere il valore dei metadati di un tipo di elemento è possibile utilizzare la sintassi seguente, dove ItemType è il nome del tipo di elemento e MetaDataName è il nome dei metadati:
%(ItemType.MetaDataName)
Per esaminare i metadati dell'elemento
Tramite l'editor del codice, sostituire l'attività Message con la riga seguente:
<Message Text="Compile.DependentUpon: %(Compile.DependentUpon)" />
Salvare il file di progetto.
Nella finestra di comando immettere ed eseguire la riga seguente:
msbuild buildapp.csproj /t:HelloWorld
Esaminare l'output. Verranno visualizzate le righe seguenti:
Compile.DependentUpon: Compile.DependentUpon: Form1.cs Compile.DependentUpon: Resources.resx Compile.DependentUpon: Settings.settings
Notare che la frase "Compile.DependentUpon" viene visualizzata molte volte. L'utilizzo di metadati con questa sintassi all'interno di una destinazione comporta la "divisione in batch". Ciò significa che le attività all'interno della destinazione vengono eseguite una volta per ogni valore di metadati univoco. Si tratta dell'equivalente script in MSBuild del costrutto di programmazione "ciclo for" di uso comune. Per ulteriori informazioni, vedere Batch MSBuild.
Metadati noti
Ogni volta che un elemento viene aggiunto a un elenco di elementi, a tale elemento vengono assegnati metadati noti. Ad esempio, %(Filename) restituisce il nome file di qualsiasi elemento. Per un elenco completo di tutti i metadati noti, vedere Metadati noti degli elementi di MSBuild.
Per esaminare metadati noti
Tramite l'editor del codice, sostituire l'attività Message con la riga seguente:
<Message Text="Compile Filename: %(Compile.Filename)" />
Salvare il file di progetto.
Nella finestra di comando immettere ed eseguire la riga seguente:
msbuild buildapp.csproj /t:HelloWorld
Esaminare l'output. Verranno visualizzate le righe seguenti:
Compile Filename: Form1 Compile Filename: Form1.Designer Compile Filename: Program Compile Filename: AssemblyInfo Compile Filename: Resources.Designer Compile Filename: Settings.Designer
Confrontando i due esempi appena forniti, è possibile vedere che benché nel tipo di elemento Compile esistano elementi senza metadati DependentUpon, tutti gli elementi presentano metadati noti Filename.
Trasformazioni dei metadati
Gli elenchi di elementi possono essere trasformati in nuovi elenchi di elementi. Per trasformare un elenco di elementi è possibile utilizzare la sintassi seguente, in cui ItemType è il nome del tipo di elemento e MetaDataName è il nome dei metadati:
@(ItemType -> '%(MetadataName)')
Un elenco di elementi di file di origine può ad esempio essere trasformato in una raccolta di file oggetto utilizzando un'espressione quale @(SourceFiles -> '%(Filename).obj'). Per ulteriori informazioni, vedere Trasformazioni di MSBuild.
Per trasformare gli elementi tramite i metadati
Tramite l'editor del codice, sostituire l'attività Message con la riga seguente:
<Message Text="Backup files: @(Compile->'%(filename).bak')" />
Salvare il file di progetto.
Nella finestra di comando immettere ed eseguire la riga seguente:
msbuild buildapp.csproj /t:HelloWorld
Esaminare l'output. Verrà visualizzata la riga seguente:
Backup files: Form1.bak;Form1.Designer.bak;Program.bak;AssemblyInfo.bak;Resources.Designer.bak;Settings.Designer.bak
Notare che i metadati espressi in questa sintassi non comportano la divisione in batch.
Argomenti successivi
Per una procedura dettagliata su come creare un file di progetto semplice, vedere Procedura dettagliata: creazione di un nuovo file di progetto MSBuild.