Partilhar via


Compilações incrementais

As compilações incrementais do MSBuild são compilações otimizadas para que os destinos com arquivos de saída up-toem relação aos arquivos de entrada correspondentes não sejam executados.

Um elemento de destino pode ter um atributo Inputs, que indica quais itens o destino espera como entrada, e um atributo Outputs, que indica quais itens ele produz como saída. O MSBuild tenta encontrar um mapeamento um-para-um entre os valores desses atributos. Se esse mapeamento existir, o MSBuild compara o carimbo de data/hora de cada item de entrada com o carimbo de data/hora do item de saída correspondente. Os arquivos de saída que não têm um mapeamento um-para-um são comparados a todos os arquivos de entrada. Um item é considerado up-to-date se seu arquivo de saída tiver a mesma idade ou for mais recente do que seu arquivo ou arquivos de entrada.

Observação

Quando o MSBuild avalia os arquivos de entrada, somente o conteúdo da lista na execução atual é considerado. As alterações na lista na última compilação não tornam automaticamente um alvo desatualizado.

Se todos os itens de saída estiverem up-to-date, o MSBuild ignorará o alvo. Esta construção incremental do alvo pode melhorar significativamente a velocidade de compilação. Se apenas alguns ficheiros estiverem up-to-date, o MSBuild executa o alvo mas ignora os itens up-to-date e, assim, atualiza todos os itens para up-to-date. Esse processo é conhecido como uma compilação incremental parcial .

Os mapeamentos um-para-um só podem ser produzidos tornando o atributo Outputs uma transformação do atributo Inputs. Para obter mais informações, consulte transformações do MSBuild.

Considere o seguinte alvo:

<Target Name="Backup" Inputs="@(Compile)"
    Outputs="@(Compile->'$(BackupFolder)%(Identity).bak')">
    <Copy SourceFiles="@(Compile)" DestinationFiles=
        "@(Compile->'$(BackupFolder)%(Identity).bak')" />
</Target>

O conjunto de arquivos representado pelo tipo de item Compile é copiado para um diretório de backup. Os arquivos de backup têm a extensão de nome de arquivo .bak. Se os arquivos representados pelo tipo de item Compile, ou os arquivos de backup correspondentes, não forem excluídos ou modificados depois que o destino Backup for executado, o destino Backup será ignorado nas compilações subsequentes.

Inferência de saída

O MSBuild compara os atributos Inputs e Outputs de um destino para determinar se o destino precisa ser executado. Idealmente, o conjunto de arquivos que existe após a conclusão de uma compilação incremental deve permanecer o mesmo, independentemente de os destinos associados serem executados ou não. Como as propriedades e os itens que as tarefas criam ou alteram podem afetar a compilação, MSBuild deve inferir seus valores mesmo se o alvo que os afeta for ignorado. Este processo é conhecido como inferência de saída .

Existem três casos:

  • O destino tem um atributo Condition que é avaliado como false. Nesse caso, o destino não é executado e não tem efeito sobre a compilação.

  • O alvo tem saídas desatualizadas e é executado para trazê-las up-toatualizadas.

  • O alvo não tem saídas desatualizadas e é ignorado. O MSBuild avalia o alvo e faz alterações em itens e propriedades como se o alvo tivesse sido executado.

Para dar suporte à compilação incremental, as tarefas devem garantir que o valor do atributo TaskParameter de qualquer elemento Output seja igual a um parâmetro de entrada de tarefa. Por exemplo:

<CreateProperty Value="123">
    <Output PropertyName="Easy" TaskParameter="Value" />
</CreateProperty>

Esse código cria a propriedade Easy, que tem o valor 123 se o destino é executado ou ignorado.

A partir do MSBuild 3.5, a inferência de saída é executada automaticamente em grupos de itens e propriedades em um destino. CreateItem tarefas não são necessárias num destino e devem ser evitadas. Tarefas CreateProperty devem ser usadas num alvo somente para determinar se um alvo foi executado.

Antes do MSBuild 3.5, pode usar a tarefa CreateItem.

Determinar se um alvo é executado

Devido à inferência de saída, deve-se examinar as propriedades e os itens de um alvo para determinar se este foi executado. Para fazer isso, adicione a tarefa CreateProperty ao destino e dê-lhe um elemento Output cujo atributo TaskParameter é ValueSetByTask. Por exemplo:

<CreateProperty Value="true">
    <Output TaskParameter="ValueSetByTask" PropertyName="CompileRan" />
</CreateProperty>

Este código cria a propriedade CompileRan e dá-lhe o valor true, mas apenas se o destino for executado. Se o destino for ignorado, CompileRan não será criado.