Compartilhar via


Criar um arquivo de projeto do MSBuild do zero

As linguagens de programação direcionadas ao .NET Framework usam arquivos de projeto do MSBuild para descrever e controlar o processo de build do aplicativo. Quando você usa o Visual Studio para criar um arquivo de projeto do MSBuild, o XML apropriado é adicionado ao arquivo automaticamente. No entanto, você pode achar útil entender como o XML é organizado e como você pode alterá-lo para controlar um build.

Nota

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

A lógica de build importada por arquivos de .csproj padrão dá suporte a muito mais opções e a um processo de build muito mais complexo do que este exemplo.

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

Este tutorial mostra como criar um arquivo de projeto básico de forma incremental usando apenas um editor de texto. O passo a passo segue estas etapas:

  1. Estenda a variável de ambiente PATH.

  2. Crie um arquivo de origem mínimo do aplicativo.

  3. Crie um arquivo de projeto mínimo do MSBuild.

  4. Crie o aplicativo usando o arquivo de projeto.

  5. Adicione 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 alvos.

  9. Construa incrementalmente.

Este tutorial mostra como criar o projeto no prompt de comando e examinar os resultados. Para obter mais informações sobre o MSBuild e como executar o MSBuild no prompt de comando, consulte Usar o MSBuild.

Para concluir o tutorial, você deve ter o Visual Studio instalado porque ele inclui o MSBuild e o compilador C#, que são necessários para o passo a passo.

Estender o caminho

Antes de usar o MSBuild, você deve estender a variável de ambiente PATH para incluir todas as ferramentas necessárias.

Se você estiver utilizando o Windows, poderá usar o Prompt de Comando do Desenvolvedor para o Visual Studio. Pesquise-o na caixa de pesquisa do Windows 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 C# mínimo usando um editor de texto.

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

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

  3. Em um editor de texto, crie um novo 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. Crie o aplicativo digitando csc helloworld.cs no prompt de comando.

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

    A Olá, mundo! mensagem deve ser exibida.

  6. Exclua o executável.

Criar um arquivo de projeto mínimo do MSBuild

Agora que você tem um arquivo de origem mínimo do aplicativo, você pode criar um arquivo de projeto mínimo para criar o aplicativo. Este arquivo de projeto contém os seguintes elementos:

  • O nó raiz Project necessário.

  • Um nó ItemGroup para conter elementos do item.

  • Um elemento de 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 C# para criar o aplicativo.

Para criar um arquivo de projeto mínimo do MSBuild

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

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

    Este ItemGroup contém um elemento de item Compile e especifica um arquivo de origem como um 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 de tarefa como um elemento filho do nó Target:

    <Csc Sources="@(Compile)"/>
    
  4. Salve este arquivo de projeto e nomeie-o Helloworld.fromscratchproj.

Seu arquivo de projeto mínimo deve ser semelhante ao seguinte código:

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

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

Nota

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

<Compile Include="*.cs" />

Compilar o aplicativo

Agora, para criar o aplicativo, use o arquivo de projeto que você acabou de criar.

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

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

  2. Teste o aplicativo digitando helloworld.

    A Olá, mundo! mensagem deve ser exibida.

Nota

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

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

Adicionar propriedades de compilação

Você pode adicionar propriedades de build ao arquivo de projeto para controlar ainda mais o build. 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 destino Clean para lidar com a exclusão de arquivos de saída antigos).

  2. No arquivo de projeto, insira este elemento PropertyGroup logo após o elemento Project de abertura.

    <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 nomeada pela propriedade OutputPath, desde que nenhuma pasta com esse nome exista no momento.

  4. Adicione este atributo OutputAssembly à tarefa Csc:

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

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

  5. Salve suas alterações.

O arquivo de projeto agora deve ser semelhante 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>

Nota

Recomendamos que você adicione o delimitador de caminho de barra invertida (\) no final do nome da pasta ao especificá-lo no elemento OutputPath, em vez de adicioná-lo no 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 criar o aplicativo usando o arquivo de projeto no qual você usou propriedades de build para especificar a pasta de saída e o nome do aplicativo.

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

    Isso cria a pasta \Bin\ e, em seguida, invoca o compilador C# para criar o aplicativo MSBuildSample e o coloca 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, da seguinte maneira:

  • 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, você pode definir o destino Build como o destino padrão.

Para adicionar destinos de compilação

  1. No arquivo de projeto, adicione estes dois destinos logo após o destino build:

    <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 este atributo DefaultTargets ao elemento de abertura Project:

    <Project DefaultTargets="Build">
    

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

O arquivo de projeto agora deve ser semelhante 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 utilizar os novos alvos de compilação para testar estes recursos do arquivo de projeto.

  • Compilando o build padrão.

  • Configurando o nome do aplicativo no prompt de comando.

  • Excluindo o aplicativo antes que outro aplicativo seja criado.

  • Excluindo o aplicativo sem criar outro aplicativo.

Para testar os destinos de compilação

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

    Como você não usou a opção -t para definir explicitamente o destino, o MSBuild executa o destino de Build padrão. A opção -p substitui a propriedade AssemblyName e fornece o novo valor, Greetings. Isso faz com que um novo aplicativo, Greetings.exe, seja criado na pasta \Bin\.

  2. Para verificar se a pasta \Bin\ contém o aplicativo "MSBuildSample" e o novo aplicativo "Saudações", 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.fromscratchproj -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.fromscratchproj -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\ agora está vazia, digite dir Bin.

  7. Digite msbuild.

    Embora um arquivo de projeto não seja especificado, o MSBuild cria o arquivo helloworld.fromscratchproj porque há apenas um arquivo de projeto na pasta atual. Isso faz com que o aplicativo MSBuildSample seja criado na pasta \Bin\.

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

Construir de forma incremental

Você pode dizer ao MSBuild para criar um destino somente se os arquivos de origem ou arquivos de destino dos quais o destino depende 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 estes atributos ao alvo de build inicial.

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

    Isso especifica que o destino build 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 alvo de compilação digitando msbuild -v:d no prompt de comando.

    Lembre-se de que helloworld.fromscratchproj é o arquivo de projeto padrão e que Build é o destino padrão.

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

    Se você já tiver criado a saída, essas linhas deverão 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 build porque 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 do 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 realizar automaticamente grande parte do trabalho mostrado neste passo a passo. Para saber como usar o Visual Studio para criar, editar, compilar e testar arquivos de projeto do MSBuild, consulte Usar o MSBuild.