Passo a passo: Criar um arquivo de projeto do MSBuild do zero

As linguagens de programação que tenham como destino o .NET Framework usam arquivos de projetos do MSBuild para descrever e controlar o processo de compilação de aplicativos. Quando você usa o Visual Studio para criar um arquivo de projeto do MSBuild, o XML apropriado é adicionado ao arquivo automaticamente. Entretanto, talvez você ache útil compreender como o XML é organizado e como é possível alterá-lo para controlar uma compilação.

Observação

Este artigo é apropriado se você quer aprender os conceitos básicos de como o MSBuild funciona independentemente de qualquer SDK. A criação com um SDK, por exemplo, quando você usa dotnet build ou adiciona o atributo Sdk ao elemento raiz do projeto, não é abordada neste artigo. Confira SDKs de projeto do .NET.

Para obter informações sobre como criar um arquivo de projeto para um projeto em C++, consulte MSBuild (C++).

Este passo a passo mostra como criar um arquivo de projeto básico de forma incremental, usando somente um editor de texto. Este passo a passo possui as seguintes etapas:

  1. Estenda a variável de ambiente PATH.

  2. Criar um arquivo de origem de aplicativo mínimo.

  3. Criar um arquivo de projeto MSBuild mínimo.

  4. Compilar o aplicativo usando o arquivo de projeto.

  5. Adicionar propriedades para controlar a compilação.

  6. Controlar a compilação alterando os valores de propriedade.

  7. Adicionar destinos à compilação.

  8. Controlar a compilação especificando destinos.

  9. Compilar de forma incremental.

Este passo a passo mostra como compilar o projeto no prompt de comando e como examinar os resultados. Para saber mais sobre o MSBuild e como executá-lo no prompt de comandos, confira Passo a passo: Usar o MSBuild.

Para concluir este passo a passo, você precisa ter o Visual Studio instalado, pois ele inclui o MSBuild e o compilador de C#, que são necessários para o passo a passo.

Estender o caminho

Para usar o MSBuild, você precisa estender a variável de ambiente PATH para incluir todas as ferramentas necessárias. Você pode usar o Prompt de Comando do Desenvolvedor para o Visual Studio. Pesquise por ele no Windows 10 na caixa de pesquisa na barra de tarefas do Windows. Para configurar o ambiente em um prompt de comando comum ou em um ambiente de script, execute VSDevCmd.bat na subpasta Common7/Tools de uma instalação do Visual Studio.

Criar um aplicativo mínimo

Esta seção mostra como criar um arquivo de origem de aplicativo mínimo do C# usando um editor de texto.

  1. No prompt de comando, navegue até a pasta onde deseja criar o aplicativo, por exemplo, \Meus Documentos\ ou \Área de Trabalho\.

  2. Crie uma subpasta chamada \HelloWorld\ e altere o diretório para entrar nela.

  3. Em um editor de texto, crie um arquivo HelloWorld.cs e copie e cole o seguinte código:

    using System;
    
    class HelloWorld
    {
        static void Main()
        {
    #if DebugConfig
            Console.WriteLine("WE ARE IN THE DEBUG CONFIGURATION");
    #endif
    
            Console.WriteLine("Hello, world!");
        }
    }
    
  4. Compile o aplicativo digitando csc helloworld.cs no prompt de comando.

  5. Teste o aplicativo digitando helloworld no prompt de comando.

    A mensagem Olá, mundo! deve ser exibida.

  6. Exclua o executável.

Criar um arquivo de projeto MSBuild mínimo

Agora que você possui um arquivo de origem de aplicativo mínimo, poderá criar um arquivo de projeto mínimo para compilar o aplicativo. Esse arquivo de projeto contém os seguintes elementos:

  • O nó raiz Project necessário.

  • Um nó ItemGroup para conter elementos do item.

  • Um elemento do item que se refere ao arquivo de origem do aplicativo.

  • Um nó Target para conter tarefas que são necessárias para compilar o aplicativo.

  • Um elemento Task para iniciar o compilador de C# para compilar o aplicativo.

Para criar um arquivo de projeto MSBuild mínimo

  1. No editor de texto, crie um arquivo HelloWorld.csproj e insira o seguinte código:

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

    Esse ItemGroup contém um elemento de item Compile e especifica um arquivo de origem como item.

  2. Adicione um nó Target como um elemento filho do nó Project. Nomeie o nó Build.

    <Target Name="Build">
    </Target>
    
  3. Insira este elemento da tarefa como um elemento filho do nó Target:

    <Csc Sources="@(Compile)"/>
    
  4. Salve esse arquivo de projeto e o nomeie como Helloworld.csproj.

O seu arquivo de projeto mínimo deve se assemelhar ao seguinte código:

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

As tarefas no destino Compilar são executadas em sequência. Nesse caso, a tarefa Csc do compilador de C# é a única tarefa. Ela espera que uma lista de arquivos de origem seja compilada e isso ocorre pelo valor do item Compile. O item Compile faz referências a apenas um arquivo de origem, Helloworld.cs.

Observação

No elemento de item, você pode usar o caractere curinga de asterisco (*) para fazer referência a todos os arquivos que tenham a extensão de nome de arquivo .cs, da seguinte maneira:

<Compile Include="*.cs" />

Compilar o aplicativo

Agora, para compilar o aplicativo, use o arquivo de projeto recém-criado.

  1. No prompt de comando, digite msbuild helloworld.csproj -t:Build.

    Isso compila o destino de Build do arquivo de projeto Helloworld invocando o compilador de C# para criar o aplicativo Helloworld.

  2. Teste o aplicativo digitando helloworld.

    A mensagem Olá, mundo! deve ser exibida.

Observação

Você pode ver mais detalhes sobre a compilação aumentando o nível de detalhamento. Para configurar o nível de detalhamento como "detalhado", digite este comando no prompt de comando:

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

Adicionar propriedades de compilação

Você pode adicionar propriedades de compilação ao arquivo de projeto para controlar ainda mais a compilação. Agora, adicione estas propriedades:

  • Uma propriedade AssemblyName para especificar o nome do aplicativo.

  • Uma propriedade OutputPath para especificar uma pasta para conter o aplicativo.

Para adicionar propriedades de compilação

  1. Exclua o executável do aplicativo existente (posteriormente, você adicionará um Clean de destino para lidar com a exclusão de arquivos de saída antigos).

  2. No arquivo de projeto, insira este elemento PropertyGroup imediatamente depois de abrir o elemento Project:

    <PropertyGroup>
      <AssemblyName>MSBuildSample</AssemblyName>
      <OutputPath>Bin\</OutputPath>
    </PropertyGroup>
    
  3. Adicione esta tarefa no destino Compilar, imediatamente antes da tarefa Csc:

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

    A tarefa MakeDir cria uma pasta que é chamada pela propriedade OutputPath, contanto que não exista atualmente nenhuma pasta com esse nome.

  4. Adicione esse atributo OutputAssembly à tarefa Csc:

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

    Isso instrui o compilador de C# a produzir um assembly que é nomeado pela propriedade AssemblyName e para colocá-lo na pasta que é nomeada pela propriedade OutputPath.

  5. Salve suas alterações.

O seu arquivo de projeto deve agora se assemelhar ao seguinte código:

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

Observação

Recomendamos que você adicione um delimitador de caminho de barra invertida (\) no final do nome da pasta quando especificá-lo no elemento OutputPath, em vez de adicioná-lo ao atributo OutputAssembly da tarefa Csc. Portanto,

<OutputPath>Bin\</OutputPath>

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

é melhor que

<OutputPath>Bin</OutputPath>

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

Testar as propriedades de compilação

Agora, você pode compilar o aplicativo usando o arquivo de projeto no qual usou as propriedades de compilação para especificar a pasta de saída e o nome do aplicativo.

  1. No prompt de comando, digite msbuild helloworld.csproj -t:Build.

    Isso cria a pasta \Bin\ e invoca o compilador de C# para criar o aplicativo MSBuildSample e colocá-lo na pasta \Bin\.

  2. Para verificar se a pasta \Bin\ foi criada e se ela contém o aplicativo MSBuildSample, digite dir Bin.

  3. Teste o aplicativo digitando Bin\MSBuildSample para executar o executável.

    A mensagem Olá, mundo! deve ser exibida.

Adicionar destinos de compilação

Em seguida, adicione mais dois destinos ao arquivo de projeto, como a seguir:

  • Um destino Limpar que exclui arquivos antigos.

  • Um destino Recompilar que usa o atributo DependsOnTargets para forçar a tarefa Limpar a executar a tarefa Compilar.

Agora que você tem vários destinos, poderá configurar o destino Compilar como o destino padrão.

Para adicionar destinos de compilação

  1. No arquivo de projeto, adicione esses dois destinos imediatamente após o destino Compilar:

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

    O destino Limpar chama a tarefa Excluir para excluir o aplicativo. O destino Recompilar não é executado até que o destino Limpar e o destino Compilar tenham sido executados. Embora o destino Recompilar não tenha tarefas, ele faz com que o destino Limpar seja executado antes do destino Compilar.

  2. Adicione esse atributo DefaultTargets ao elemento Project inicial:

    <Project DefaultTargets="Build">
    

    Isso configura o destino Compilar como o destino padrão.

O seu arquivo de projeto deve agora se assemelhar ao seguinte código:

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

Testar os destinos de compilação

Você pode experimentar os novos destinos de compilação para testar esses recursos do arquivo de projeto:

  • Compilando a compilação padrão.

  • Configurando o nome do aplicativo no prompt de comando.

  • Excluindo o aplicativo antes de outro aplicativo ser compilado.

  • Excluindo o aplicativo sem compilar outro aplicativo.

Para testar os destinos de compilação

  1. No prompt de comando, digite msbuild helloworld.csproj -p:AssemblyName=Greetings.

    Como você não usou a opção -t para configurar de forma explícita o destino, o MSBuild executa o destino de build padrão. A opção -p substitui a propriedade AssemblyName e dá a ela o novo valor, Greetings. Isso faz com que um aplicativo, Greetings.exe, seja criado na pasta \Bin\.

  2. Para verificar se a pasta \Bin\ contém o aplicativo MSBuildSample e o novo aplicativo Greetings, digite dir Bin.

  3. Teste o aplicativo Greetings (por exemplo, digitando Bin\Greetings no Windows).

    A mensagem Olá, mundo! deve ser exibida.

  4. Exclua o aplicativo MSBuildSample digitando msbuild helloworld.csproj -t:clean.

    Isso executa a tarefa Limpar para remover o aplicativo que tem o AssemblyName valor da propriedade MSBuildSample padrão.

  5. Exclua o aplicativo Greetings digitando msbuild helloworld.csproj -t:clean -p:AssemblyName=Greetings.

    Isso executa a tarefa Limpar para remover o aplicativo que tem o valor da propriedade especificado AssemblyName, Greetings.

  6. Para verificar se a pasta \Bin\ está vazia, digite dir Bin.

  7. Digite msbuild.

    Embora um arquivo de projeto não esteja especificado, o MSBuild compila o arquivo helloworld.csproj, pois há somente um arquivo na pasta atual. Isso faz com que um aplicativo MSBuildSample seja criado na pasta \Bin\.

    Para verificar se a pasta \Bin\ contém o aplicativo MSBuildSample, digite dir Bin.

Compilar de forma incremental

Você pode informar ao MSBuild para compilar um destino somente se os arquivos de origem ou os arquivos de destino do qual dependem o destino tiverem sido alterados. O MSBuild usa o carimbo de data/hora de um arquivo para determinar se ele foi alterado.

Para compilar de forma incremental

  1. No arquivo de projeto, adicione esses atributos ao destino Compilar inicial:

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

    Isso especifica que o destino Compilar depende dos arquivos de entrada especificados no grupo de itens Compile e que o destino de saída é o arquivo de aplicativo.

    O destino Compilar resultante deve se assemelhar ao seguinte código:

    <Target Name="Build" Inputs="@(Compile)" Outputs="$(OutputPath)$(AssemblyName).exe">
      <MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')" />
      <Csc Sources="@(Compile)" OutputAssembly="$(OutputPath)$(AssemblyName).exe" />
    </Target>
    
  2. Teste o destino de build digitando msbuild -v:d no prompt de comando.

    Lembre-se de que helloworld.csproj é o arquivo de projeto padrão e de que Compilar é o destino padrão.

    A opção -v:d é uma abreviação de -verbosity:detailed que você usou anteriormente.

    Se você já compilou a saída, estas linhas devem ser exibidas:

    Ignorando o destino de "Build" porque todos os arquivos de saída estão atualizados em relação aos arquivos de entrada.

    O MSBuild ignora o destino Compilar, pois nenhum dos arquivos de origem foi alterado desde a última compilação do aplicativo.

Exemplo de C#

O exemplo a seguir mostra um arquivo de projeto que compila um aplicativo C# e registra uma mensagem que contém o nome do arquivo de saída.

Código

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

Exemplo do Visual Basic

O exemplo a seguir mostra um arquivo de projeto que compila um aplicativo Visual Basic e registra uma mensagem que contém o nome do arquivo de saída.

Código

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

O que vem a seguir?

O Visual Studio pode fazer automaticamente muito do trabalho que é mostrado neste passo a passo. Para saber como usar o Visual Studio para criar, editar, compilar e testar arquivos de projeto MSBuild, confira Passo a passo: Usar o MSBuild.