Przewodnik: tworzenie pliku projektu MSBuild od podstaw

Języki programowania przeznaczone dla programu .NET Framework używają plików projektu MSBuild do opisywania i kontrolowania procesu kompilacji aplikacji. Gdy używasz programu Visual Studio do tworzenia pliku projektu MSBuild, odpowiedni kod XML jest dodawany automatycznie do pliku. Warto jednak zrozumieć, jak jest zorganizowany kod XML i jak można go zmienić w celu kontrolowania kompilacji.

Uwaga

Ten artykuł jest odpowiedni, jeśli chcesz poznać podstawowe podstawy działania programu MSBuild niezależnie od dowolnego zestawu SDK. Kompilowanie przy użyciu zestawu SDK, takiego jak w przypadku użycia dotnet build lub dodawania atrybutu Sdk do głównego elementu projektu, nie zostało omówione w tym artykule. Zobacz Zestawy SDK projektu .NET.

Aby uzyskać informacje na temat tworzenia pliku projektu dla projektu C++, zobacz MSBuild (C++).

W tym przewodniku pokazano, jak przyrostowo utworzyć podstawowy plik projektu przy użyciu tylko edytora tekstów. Przewodnik jest zgodny z następującymi krokami:

  1. Rozszerz zmienną środowiskową PATH.

  2. Utwórz minimalny plik źródłowy aplikacji.

  3. Utwórz minimalny plik projektu MSBuild.

  4. Skompiluj aplikację przy użyciu pliku projektu.

  5. Dodaj właściwości, aby kontrolować kompilację.

  6. Kontrolowanie kompilacji przez zmianę wartości właściwości.

  7. Dodaj elementy docelowe do kompilacji.

  8. Kontroluj kompilację, określając elementy docelowe.

  9. Kompiluj przyrostowo.

W tym przewodniku pokazano, jak skompilować projekt w wierszu polecenia i sprawdzić wyniki. Aby uzyskać więcej informacji o programie MSBuild i sposobie uruchamiania programu MSBuild w wierszu polecenia, zobacz Przewodnik: korzystanie z programu MSBuild.

Aby ukończyć przewodnik, musisz mieć zainstalowany program Visual Studio, ponieważ zawiera program MSBuild i kompilator języka C#, które są wymagane w przewodniku.

Rozszerzanie ścieżki

Przed rozpoczęciem korzystania z programu MSBuild należy rozszerzyć zmienną środowiskową PATH, aby uwzględnić wszystkie wymagane narzędzia. Możesz użyć wiersza polecenia dla deweloperów dla programu Visual Studio. Wyszukaj go w systemie Windows 10 w polu wyszukiwania na pasku zadań systemu Windows. Aby skonfigurować środowisko w zwykłym wierszu polecenia lub w środowisku skryptowym, uruchom plik VSDevCmd.bat w podfolderze Common7/Tools instalacji programu Visual Studio.

Tworzenie minimalnej aplikacji

W tej sekcji pokazano, jak utworzyć minimalny plik źródłowy aplikacji języka C# przy użyciu edytora tekstów.

  1. W wierszu polecenia przejdź do folderu, w którym chcesz utworzyć aplikację, na przykład \Moje dokumenty\ lub \Desktop\.

  2. Utwórz podfolder o nazwie \HelloWorld\ i zmień katalog, aby przejść do niego.

  3. W edytorze tekstów utwórz nowy plik HelloWorld.cs , a następnie skopiuj i wklej następujący kod:

    using System;
    
    class HelloWorld
    {
        static void Main()
        {
    #if DebugConfig
            Console.WriteLine("WE ARE IN THE DEBUG CONFIGURATION");
    #endif
    
            Console.WriteLine("Hello, world!");
        }
    }
    
  4. Skompiluj aplikację, wpisując csc helloworld.cs w wierszu polecenia.

  5. Przetestuj aplikację, wpisując helloworld w wierszu polecenia.

    Powinien zostać wyświetlony komunikat Witaj, świecie!

  6. Usuń plik wykonywalny.

Tworzenie minimalnego pliku projektu MSBuild

Teraz, gdy masz minimalny plik źródłowy aplikacji, możesz utworzyć minimalny plik projektu w celu skompilowania aplikacji. Ten plik projektu zawiera następujące elementy:

  • Wymagany węzeł główny Project .

  • Węzeł ItemGroup zawierający elementy elementu.

  • Element, który odwołuje się do pliku źródłowego aplikacji.

  • Target Węzeł zawierający zadania wymagane do skompilowania aplikacji.

  • Element Task umożliwiający uruchomienie kompilatora języka C# w celu skompilowania aplikacji.

Aby utworzyć minimalny plik projektu MSBuild

  1. W edytorze tekstów utwórz nowy plik HelloWorld.csproj i wprowadź następujący kod:

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

    Zawiera element ItemGroup elementu Compile i określa jeden plik źródłowy jako element.

  2. Target Dodaj węzeł jako element podrzędny węzłaProject. Nadaj węzłowi Buildnazwę .

    <Target Name="Build">
    </Target>
    
  3. Wstaw ten element zadania jako element podrzędny węzła Target :

    <Csc Sources="@(Compile)"/>
    
  4. Zapisz ten plik projektu i nadaj mu nazwę Helloworld.csproj.

Minimalny plik projektu powinien przypominać następujący kod:

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

Zadania w obiekcie docelowym kompilacji są wykonywane sekwencyjnie. W tym przypadku jedynym zadaniem kompilatora Csc języka C# jest. Oczekuje ona, że lista plików źródłowych zostanie skompilowana i zostanie podana przez wartość Compile elementu. Element Compile odwołuje się tylko do jednego pliku źródłowego Helloworld.cs.

Uwaga

W elemencie elementu można użyć symbolu wieloznacznego gwiazdki (*), aby odwołać się do wszystkich plików, które mają rozszerzenie nazwy pliku cs w następujący sposób:

<Compile Include="*.cs" />

Kompilowanie aplikacji

Teraz, aby skompilować aplikację, użyj właśnie utworzonego pliku projektu.

  1. W wierszu polecenia wpisz msbuild helloworld.csproj -t:Build.

    Spowoduje to skompilowanie elementu docelowego kompilacji pliku projektu Helloworld przez wywołanie kompilatora języka C#w celu utworzenia aplikacji Helloworld.

  2. Przetestuj aplikację, wpisując helloworld.

    Powinien zostać wyświetlony komunikat Witaj, świecie!

Uwaga

Więcej szczegółów dotyczących kompilacji można wyświetlić, zwiększając poziom szczegółowości. Aby ustawić poziom szczegółowości na "szczegółowy", wpisz to polecenie w wierszu polecenia:

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

Dodawanie właściwości kompilacji

Możesz dodać właściwości kompilacji do pliku projektu, aby dokładniej kontrolować kompilację. Teraz dodaj następujące właściwości:

  • Właściwość AssemblyName określająca nazwę aplikacji.

  • Właściwość określająca OutputPath folder, który ma zawierać aplikację.

Aby dodać właściwości kompilacji

  1. Usuń istniejący plik wykonywalny aplikacji (później dodasz Clean element docelowy do obsługi usuwania starych plików wyjściowych).

  2. W pliku projektu wstaw ten PropertyGroup element tuż po elemercie otwierającym Project :

    <PropertyGroup>
      <AssemblyName>MSBuildSample</AssemblyName>
      <OutputPath>Bin\</OutputPath>
    </PropertyGroup>
    
  3. Dodaj to zadanie do obiektu docelowego kompilacji tuż przed Csc zadaniem:

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

    Zadanie MakeDir tworzy folder o nazwie według OutputPath właściwości, pod warunkiem, że żaden folder o tej nazwie obecnie nie istnieje.

  4. Dodaj ten OutputAssembly atrybut do Csc zadania:

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

    Spowoduje to, że kompilator języka C# utworzy zestaw o nazwie przez AssemblyName właściwość i umieścić go w folderze, który jest nazwany przez OutputPath właściwość .

  5. Zapisz zmiany.

Plik projektu powinien teraz wyglądać podobnie do następującego kodu:

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

Uwaga

Zalecamy dodanie ogranicznika ścieżki odwrotnej (\) na końcu nazwy folderu po określeniu go w OutputPath elemecie , zamiast dodawać go w OutputAssembly atrybucie Csc zadania. Zatem

<OutputPath>Bin\</OutputPath>

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

jest lepszy niż

<OutputPath>Bin</OutputPath>

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

Testowanie właściwości kompilacji

Teraz możesz skompilować aplikację przy użyciu pliku projektu, w którym użyto właściwości kompilacji do określenia folderu wyjściowego i nazwy aplikacji.

  1. W wierszu polecenia wpisz msbuild helloworld.csproj -t:Build.

    Spowoduje to utworzenie folderu \Bin\ , a następnie wywoła kompilator języka C#, aby utworzyć aplikację MSBuildSample i umieścić ją w folderze \Bin\ .

  2. Aby sprawdzić, czy folder \Bin\ został utworzony i czy zawiera aplikację MSBuildSample , wpisz dir Bin.

  3. Przetestuj aplikację, wpisując bin\MSBuildSample , aby uruchomić plik wykonywalny.

    Powinien zostać wyświetlony komunikat Witaj, świecie!

Dodawanie obiektów docelowych kompilacji

Następnie dodaj dwa kolejne elementy docelowe do pliku projektu w następujący sposób:

  • Czysty element docelowy, który usuwa stare pliki.

  • Rekompiluj element docelowy, który używa atrybutu DependsOnTargets , aby wymusić uruchomienie zadania Clean przed zadaniem kompilacji.

Teraz, gdy masz wiele obiektów docelowych, możesz ustawić element docelowy kompilacji jako domyślny element docelowy.

Aby dodać obiekty docelowe kompilacji

  1. W pliku projektu dodaj te dwa obiekty docelowe tuż po obiekcie docelowym kompilacji:

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

    Obiekt docelowy Clean wywołuje zadanie Usuń, aby usunąć aplikację. Cel ponownego kompiluj nie jest uruchamiany, dopóki nie zostanie uruchomiony zarówno cel Clean, jak i element docelowy kompilacji. Mimo że cel ponownej kompilacji nie ma żadnych zadań, powoduje uruchomienie elementu docelowego Clean przed obiektem docelowym kompilacji.

  2. Dodaj ten DefaultTargets atrybut do elementu otwierającego Project :

    <Project DefaultTargets="Build">
    

    Spowoduje to ustawienie elementu docelowego kompilacji jako domyślnego elementu docelowego.

Plik projektu powinien teraz wyglądać podobnie do następującego kodu:

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

Testowanie miejsc docelowych kompilacji

Nowe cele kompilacji można wykonać, aby przetestować te funkcje pliku projektu:

  • Kompilowanie kompilacji domyślnej.

  • Ustawianie nazwy aplikacji w wierszu polecenia.

  • Usuwanie aplikacji przed skompilowaniem innej aplikacji.

  • Usuwanie aplikacji bez kompilowania innej aplikacji.

Aby przetestować cele kompilacji

  1. W wierszu polecenia wpisz msbuild helloworld.csproj -p:AssemblyName=Greetings.

    Ponieważ nie użyto przełącznika -t , aby jawnie ustawić obiekt docelowy, program MSBuild uruchamia domyślny element docelowy kompilacji. Przełącznik -p zastępuje AssemblyName właściwość i nadaje jej nową wartość . Greetings Spowoduje to utworzenie nowej aplikacji Greetings.exe w folderze \Bin\ .

  2. Aby sprawdzić, czy folder \Bin\ zawiera zarówno aplikację MSBuildSample , jak i nową aplikację Greetings , wpisz dir Bin.

  3. Przetestuj aplikację Greetings (na przykład wpisując Bin\Greetings w systemie Windows).

    Powinien zostać wyświetlony komunikat Witaj, świecie!

  4. Usuń aplikację MSBuildSample, wpisując msbuild helloworld.csproj -t:clean.

    Spowoduje to uruchomienie zadania Clean w celu usunięcia aplikacji, która ma domyślną AssemblyName wartość właściwości . MSBuildSample

  5. Usuń aplikację Greetings, wpisując msbuild helloworld.csproj -t:clean -p:AssemblyName=Greetings.

    Spowoduje to uruchomienie zadania Clean w celu usunięcia aplikacji, która ma daną wartość właściwości AssemblyName , Greetings.

  6. Aby sprawdzić, czy folder \Bin\ jest teraz pusty, wpisz dir Bin.

  7. Wpisz msbuild.

    Mimo że plik projektu nie jest określony, program MSBuild kompiluje plik helloworld.csproj , ponieważ w bieżącym folderze znajduje się tylko jeden plik projektu. Powoduje to utworzenie aplikacji MSBuildSample w folderze \Bin\.

    Aby sprawdzić, czy folder \Bin\ zawiera aplikację MSBuildSample , wpisz dir Bin.

Kompilacja przyrostowa

Program MSBuild może skompilować element docelowy tylko wtedy, gdy pliki źródłowe lub pliki docelowe, od których zależy element docelowy, uległy zmianie. Program MSBuild używa sygnatury czasowej pliku, aby określić, czy został zmieniony.

Aby kompilować przyrostowo

  1. W pliku projektu dodaj następujące atrybuty do otwierającego elementu docelowego kompilacji:

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

    Określa to, że element docelowy kompilacji zależy od plików wejściowych określonych w Compile grupie elementów, a element docelowy danych wyjściowych jest plikiem aplikacji.

    Wynikowy element docelowy kompilacji powinien przypominać następujący kod:

    <Target Name="Build" Inputs="@(Compile)" Outputs="$(OutputPath)$(AssemblyName).exe">
      <MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')" />
      <Csc Sources="@(Compile)" OutputAssembly="$(OutputPath)$(AssemblyName).exe" />
    </Target>
    
  2. Przetestuj element docelowy kompilacji, wpisując msbuild -v:d w wierszu polecenia.

    Pamiętaj, że helloworld.csproj jest domyślnym plikiem projektu i że kompilacja jest domyślnym obiektem docelowym.

    Przełącznik -v:d jest skrótem -verbosity:detailed , który został użyty wcześniej.

    Jeśli dane wyjściowe zostały już skompilowane, powinny zostać wyświetlone następujące wiersze:

    Pomijanie docelowego elementu "Kompilacja", ponieważ wszystkie pliki wyjściowe są aktualne w odniesieniu do plików wejściowych.

    Program MSBuild pomija element docelowy kompilacji, ponieważ żaden z plików źródłowych nie zmienił się od czasu ostatniej kompilacji aplikacji.

Przykład w języku C#

Poniższy przykład przedstawia plik projektu, który kompiluje aplikację języka C# i rejestruje komunikat zawierający nazwę pliku wyjściowego.

Kod

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

Przykład języka Visual Basic

Poniższy przykład przedstawia plik projektu, który kompiluje aplikację języka Visual Basic i rejestruje komunikat zawierający nazwę pliku wyjściowego.

Kod

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

Co dalej?

Program Visual Studio może automatycznie wykonać większość pracy, która jest wyświetlana w tym przewodniku. Aby dowiedzieć się, jak używać programu Visual Studio do tworzenia, edytowania, kompilowania i testowania plików projektów MSBuild, zobacz Przewodnik: używanie programu MSBuild.