Condividi tramite


Creare un file di progetto MSBuild da zero

I linguaggi di programmazione destinati a .NET Framework usano i file di progetto MSBuild per descrivere e controllare il processo di compilazione dell'applicazione. Quando si usa Visual Studio per creare un file di progetto MSBuild, il codice XML appropriato viene aggiunto automaticamente al file. Tuttavia, può risultare utile comprendere come è organizzato il codice XML e come modificarlo per controllare una compilazione.

Nota

Questo articolo è appropriato se si vogliono apprendere i concetti fondamentali di base del funzionamento di MSBuild indipendentemente da qualsiasi SDK. La compilazione con un SDK, ad esempio quando si usa dotnet build o si aggiunge l'attributo Sdk all'elemento del progetto radice, non viene trattato in questo articolo. Vedere SDK per progetti .NET.

La logica di compilazione importata dai file di .csproj standard supporta molte più opzioni e un processo di compilazione molto più complesso rispetto a questo esempio.

Per informazioni sulla creazione di un file di progetto per un progetto C++, vedere MSBuild (C++).

Questa esercitazione illustra come creare un file di progetto di base in modo incrementale usando solo un editor di testo. La procedura dettagliata segue questi passaggi:

  1. Estendere la variabile di ambiente PATH.

  2. Creare un file di origine dell'applicazione minimo.

  3. Creare un file di progetto MSBuild minimo.

  4. Compilare l'applicazione usando il file di progetto.

  5. Aggiungi proprietà per controllare la configurazione.

  6. Controllare il processo di compilazione modificando i valori delle proprietà.

  7. Aggiungere obiettivi alla compilazione.

  8. Controllare la compilazione specificando gli obiettivi.

  9. Compilare in modo incrementale.

Questa esercitazione illustra come compilare il progetto al prompt dei comandi ed esaminare i risultati. Per altre informazioni su MSBuild e su come eseguire MSBuild al prompt dei comandi, vedere Usare MSBuild.

Per completare l'esercitazione, è necessario che Visual Studio sia installato perché include MSBuild e il compilatore C#, necessari per la procedura dettagliata.

Estendere il percorso

Prima di poter usare MSBuild, è necessario estendere la variabile di ambiente PATH per includere tutti gli strumenti necessari.

Se si esegue in Windows, è possibile usare il prompt dei comandi per gli sviluppatori per Visual Studio. Cercarlo nella casella di ricerca di Windows nella barra delle applicazioni di Windows. Per configurare l'ambiente in un normale prompt dei comandi o in un ambiente di scripting, eseguire VSDevCmd.bat nella sottocartella Common7/Tools di un'installazione di Visual Studio.

Creare un'applicazione minima

Questa sezione illustra come creare un file di origine dell'applicazione C# minimo usando un editor di testo.

  1. Al prompt dei comandi passare alla cartella in cui si vuole creare l'applicazione, ad esempio \Documenti\ o \Desktop\.

  2. Creare una sottocartella denominata \HelloWorld\ e modificare la directory per passare all'interno di essa.

  3. In un editor di testo creare un nuovo file HelloWorld.cs e quindi copiare e incollare il codice seguente:

    using System;
    
    class HelloWorld
    {
        static void Main()
        {
    #if DebugConfig
            Console.WriteLine("WE ARE IN THE DEBUG CONFIGURATION");
    #endif
    
            Console.WriteLine("Hello, world!");
        }
    }
    
  4. Compilare l'applicazione digitando csc helloworld.cs al prompt dei comandi.

  5. Testare l'applicazione digitando helloworld al prompt dei comandi.

    Il Hello, world! messaggio deve essere visualizzato.

  6. Eliminare l'eseguibile.

Creare un file di progetto MSBuild minimo

Ora che si dispone di un file di origine dell'applicazione minimo, è possibile creare un file di progetto minimo per compilare l'applicazione. Questo file di progetto contiene gli elementi seguenti:

  • Nodo Project radice richiesto.

  • Nodo ItemGroup per contenere gli elementi degli articoli.

  • Elemento che fa riferimento al file di origine dell'applicazione.

  • Nodo Target che contiene attività necessarie per compilare l'applicazione.

  • Elemento Task per avviare il compilatore C# per compilare l'applicazione.

Per creare un file di progetto MSBuild minimo

  1. Nell'editor di testo creare un nuovo file HelloWorld.fromscratchproj e immettere il codice seguente:

    <Project>
      <ItemGroup>
        <Compile Include="helloworld.cs" />
      </ItemGroup>
    </Project>
    

    Questo ItemGroup contiene un elemento Compile e specifica un file di origine come elemento.

  2. Aggiungere un nodo Target come elemento figlio del nodo Project. Assegnare al nodo il nome Build.

    <Target Name="Build">
    </Target>
    
  3. Inserire questo elemento task come elemento figlio del nodo Target:

    <Csc Sources="@(Compile)"/>
    
  4. Salvare il file di progetto e denominarlo Helloworld.fromscratchproj.

Il file di progetto minimo dovrebbe essere simile al codice seguente:

<Project>
  <ItemGroup>
    <Compile Include="helloworld.cs"/>
  </ItemGroup>
  <Target Name="Build">
    <Csc Sources="@(Compile)"/>
  </Target>
</Project>

Le attività nel processo di compilazione vengono eseguite in sequenza. In questo caso, il task del compilatore C# Csc è l'unica attività. Si prevede che venga compilato un elenco di file di origine, dato dal valore dell'elemento Compile. L'elemento Compile fa riferimento a un solo file di origine, Helloworld.cs.

Nota

Nell'elemento item è possibile usare il carattere jolly asterisco (*) per fare riferimento a tutti i file con estensione .cs nome file, come indicato di seguito:

<Compile Include="*.cs" />

Compilare l'applicazione

A questo punto, per compilare l'applicazione, usare il file di progetto appena creato.

  1. Al prompt dei comandi digitare msbuild helloworld.fromscratchproj -t:Build.

    Si costruisce il target Build del file di progetto Helloworld richiamando il compilatore C# per creare l'applicazione Helloworld.

  2. Testare l'applicazione digitando helloworld.

    Il Hello, world! messaggio deve essere visualizzato.

Nota

È possibile visualizzare ulteriori dettagli sulla compilazione aumentando il livello di verbosità. Per impostare il livello di verbosità su "dettagliato", digitare questo comando al prompt dei comandi:

msbuild helloworld.fromscratchproj -t:Build -verbosity:detailed

Aggiungere proprietà di compilazione

È possibile aggiungere proprietà di compilazione al file di progetto per controllare ulteriormente la compilazione. Aggiungere ora queste proprietà:

  • Proprietà AssemblyName per specificare il nome dell'applicazione.

  • Proprietà OutputPath per specificare una cartella in cui contenere l'applicazione.

Per aggiungere proprietà di compilazione

  1. Eliminare il file eseguibile dell'applicazione esistente (in un secondo momento si aggiungerà una destinazione Clean per gestire l'eliminazione dei file di output precedenti).

  2. Nel file di progetto inserire questo elemento PropertyGroup subito dopo l'elemento Project di apertura:

    <PropertyGroup>
      <AssemblyName>MSBuildSample</AssemblyName>
      <OutputPath>Bin\</OutputPath>
    </PropertyGroup>
    
  3. Aggiungere questo task al target di Build, subito prima del task Csc.

    <MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')" />
    

    L'attività MakeDir crea una cartella denominata dalla proprietà OutputPath, purché non esista alcuna cartella con tale nome.

  4. Aggiungere questo attributo OutputAssembly all'attività Csc:

    <Csc Sources="@(Compile)" OutputAssembly="$(OutputPath)$(AssemblyName).exe" />
    

    In questo modo il compilatore C# deve produrre un assembly denominato dalla proprietà AssemblyName e inserirlo nella cartella denominata dalla proprietà OutputPath.

  5. Salvare le modifiche.

Il file di progetto dovrebbe ora essere simile al codice seguente:

<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>

Nota

È consigliabile aggiungere il delimitatore di percorso barra rovesciata (\) alla fine del nome della cartella quando lo si specifica nell'elemento OutputPath, anziché aggiungerlo nell'attributo OutputAssembly dell'attività Csc. Pertanto

<OutputPath>Bin\</OutputPath>

OutputAssembly="$(OutputPath)$(AssemblyName).exe" />

è meglio di

<OutputPath>Bin</OutputPath>

OutputAssembly="$(OutputPath)\$(AssemblyName).exe" />

Testare le proprietà di compilazione

A questo punto è possibile compilare l'applicazione usando il file di progetto in cui sono state usate le proprietà di compilazione per specificare la cartella di output e il nome dell'applicazione.

  1. Nel prompt dei comandi, digitare msbuild helloworld.fromscratchproj -t:Build.

    Verrà creata la cartella \Bin\ e quindi richiamato il compilatore C# per creare l'applicazione MSBuildSample e la inserisce nella cartella \Bin\.

  2. Per verificare che la cartella \Bin\ sia stata creata e che contenga l'applicazione MSBuildSample, digitare dir Bin.

  3. Testare l'applicazione digitando Bin\MSBuildSample per eseguire il file eseguibile.

    Il Hello, world! messaggio deve essere visualizzato.

Aggiungere obiettivi di compilazione

Aggiungere quindi altre due destinazioni al file di progetto, come indicato di seguito:

  • Destinazione pulita che elimina i file precedenti.

  • Destinazione Ricompila che usa l'attributo DependsOnTargets per forzare l'esecuzione dell'attività Pulisci prima dell'attività Compila.

Ora che hai più obiettivi, puoi impostare l'obiettivo di compilazione come obiettivo predefinito.

Per aggiungere target di compilazione

  1. Nel file di progetto aggiungere queste due destinazioni subito dopo la destinazione di compilazione:

    <Target Name="Clean" >
      <Delete Files="$(OutputPath)$(AssemblyName).exe" />
    </Target>
    <Target Name="Rebuild" DependsOnTargets="Clean;Build" />
    

    La destinazione Pulisci richiama l'attività Elimina per eliminare l'applicazione. La destinazione Ricompila non viene eseguita fino a quando non vengono eseguiti sia la destinazione Pulisci che la destinazione di compilazione. Anche se la destinazione Ricompila non ha attività, la destinazione Pulisci viene eseguita prima della destinazione di compilazione.

  2. Aggiungere questo attributo DefaultTargets all'elemento Project di apertura:

    <Project DefaultTargets="Build">
    

    In questo modo, la destinazione di compilazione viene impostata come destinazione predefinita.

Il file di progetto dovrebbe ora essere simile al codice seguente:

<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>

Testare i target di compilazione

È possibile utilizzare i nuovi target di build per testare queste funzionalità del file di progetto.

  • Compilazione della build predefinita.

  • Impostazione del nome dell'applicazione al prompt dei comandi.

  • Eliminazione dell'applicazione prima della compilazione di un'altra applicazione.

  • Eliminazione dell'applicazione senza compilare un'altra applicazione.

Per testare gli obiettivi di build

  1. Nel prompt dei comandi, digitare msbuild helloworld.fromscratchproj -p:AssemblyName=Greetings.

    Poiché non è stata usata l'opzione -t per impostare in modo esplicito la destinazione, MSBuild esegue la destinazione di compilazione predefinita. L'opzione -p esegue l'override della proprietà AssemblyName e assegna il nuovo valore Greetings. In questo modo viene creata una nuova applicazione, Greetings.exe, nella cartella \Bin\.

  2. Per verificare che la cartella \Bin\ contenga sia l'applicazione MSBuildSample che la nuova applicazione Greetings, digitare dir Bin.

  3. Testare l'applicazione Greetings (ad esempio, digitando Bin\Greetings in Windows).

    Il Hello, world! messaggio deve essere visualizzato.

  4. Eliminare l'applicazione MSBuildSample digitando msbuild helloworld.fromscratchproj -t:clean.

    Viene eseguita l'attività di pulizia per rimuovere l'applicazione che ha il valore predefinito della proprietà AssemblyName, MSBuildSample.

  5. Eliminare l'applicazione Greetings digitando msbuild helloworld.fromscratchproj -t:clean -p:AssemblyName=Greetings.

    Viene eseguita l'attività Pulisci per rimuovere l'applicazione con il valore specificato della proprietà AssemblyName Greetings.

  6. Per verificare che la cartella \Bin\ sia ora vuota, digitare bin.

  7. Digitare msbuild.

    Sebbene non sia specificato un file di progetto, MSBuild compila il file helloworld.fromscratchproj perché è presente un solo file di progetto nella cartella corrente. In questo modo, l'applicazione MSBuildSample verrà creata nella cartella \Bin\.

    Per verificare che la cartella \Bin\ contenga l'applicazione MSBuildSample, digitare bin.

Compilare in modo incrementale

È possibile indicare a MSBuild di compilare una destinazione solo se i file di origine o i file di destinazione da cui dipende la destinazione sono stati modificati. MSBuild usa il timestamp di un file per determinare se è stato modificato.

Per compilare in modo incrementale

  1. Nel file di progetto, aggiungere questi attributi all'elemento di compilazione iniziale.

    Inputs="@(Compile)" Outputs="$(OutputPath)$(AssemblyName).exe"
    

    Specifica che la destinazione di compilazione dipende dai file di input specificati nel gruppo di elementi Compile e che la destinazione di output è il file dell'applicazione.

    La destinazione di compilazione risultante dovrebbe essere simile al codice seguente:

    <Target Name="Build" Inputs="@(Compile)" Outputs="$(OutputPath)$(AssemblyName).exe">
      <MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')" />
      <Csc Sources="@(Compile)" OutputAssembly="$(OutputPath)$(AssemblyName).exe" />
    </Target>
    
  2. Testare la destinazione di compilazione digitando msbuild -v:d al prompt dei comandi.

    Tenere presente che helloworld.fromscratchproj è il file di progetto predefinito e che Build è la destinazione predefinita.

    L'opzione -v:d è un'abbreviazione di -verbosity:detailed usata in precedenza.

    Se l'output è già stato compilato, verranno visualizzate le righe seguenti:

    Stiamo saltando la destinazione "Build" perché tutti i file di output sono up-toaggiornati rispetto ai file di input.

    MSBuild ignora la destinazione di compilazione perché nessuno dei file di origine è stato modificato dall'ultima compilazione dell'applicazione.

Esempio di C#

L'esempio seguente mostra un file di progetto che compila un'applicazione C# e registra un messaggio contenente il nome del file di output.

Codice

<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>

Esempio di Visual Basic

Nell'esempio seguente viene illustrato un file di progetto che compila un'applicazione Visual Basic e registra un messaggio contenente il nome del file di output.

Codice

<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>

E adesso?

Visual Studio può eseguire automaticamente gran parte del lavoro illustrato in questa procedura dettagliata. Per informazioni su come usare Visual Studio per creare, modificare, compilare e testare i file di progetto MSBuild, vedere Usare MSBuild.