Partilhar via


Compilações incrementais do MSBuild para alvos novos ou desatualizados

Quando você cria um projeto grande, é importante que as metas construídas que ainda estão up-todata não sejam reconstruídas. Se todos os alvos forem construídos sempre, cada compilação pode levar muito tempo para ser concluída.

Em uma compilação incremental, apenas os destinos não construídos do projeto ou os destinos obsoletos (desatualizados) são construídos. O Microsoft Build Engine (MSBuild) compara os carimbos de data/hora dos arquivos de entrada com os carimbos de data/hora dos arquivos de saída. O MSBuild determina se cada alvo deve ser ignorado, compilado ou parcialmente reconstruído.

O processo de compilação incremental requer uma correspondência um-a-um entre entradas e saídas para alvos. Você pode usar transformações para permitir que os destinos identifiquem o mapeamento de entrada para output. Para obter mais informações, consulte Transforms.

Especificar entradas e saídas

MSBuild pode criar um destino incrementalmente se as entradas e saídas no destino são especificadas no arquivo de projeto. Você especifica os valores com os atributos Inputs e Outputs do elemento Target.

O exemplo a seguir especifica a @(CSFile) lista de itens para o Inputs e o ficheiro hello.exe para o Outputs de um alvo:

<Target Name="Build"
    Inputs="@(CSFile)"
    Outputs="hello.exe">
    ...
</Target>

MSBuild compara os carimbos de data/hora das entradas e saídas para o alvo. No exemplo, se algum ficheiro na lista de @(CSFile) itens for mais recente do que o ficheiro hello.exe, o MSBuild compilará o alvo; caso contrário, o alvo será ignorado.

<Target Name="Build"
    Inputs="@(CSFile)"
    Outputs="hello.exe">

    <Csc
        Sources="@(CSFile)"
        OutputAssembly="hello.exe"/>
</Target>

Compare o mapeamento um-para-um versus nenhum mapeamento direto

Quando você especifica entradas e saídas em um destino, cada saída é mapeada para uma entrada diretamente ou não existe um mapeamento direto entre as saídas e as entradas. No exemplo, a tarefa Csc especifica um assembly de saída que não corresponde a uma única entrada. Para esta tarefa, a saída depende de todas as entradas.

Aqui estão algumas considerações sobre mapeamento um-para-um versus nenhum mapeamento direto:

  • Um alvo sem mapeamento direto entre entradas e saídas é sempre construído com mais frequência do que um alvo onde cada saída é mapeada para uma única entrada. Se um destino não tiver mapeamento direto, o MSBuild não poderá determinar as saídas específicas a serem reconstruídas quando apenas algumas entradas forem alteradas.

  • As tarefas que podem identificar um mapeamento direto entre as saídas e entradas são mais adequadas para compilações incrementais. Um exemplo é a tarefa LC , que gera um arquivo .license .

  • As tarefas que produzem um único assembly de saída a partir de várias entradas não são adequadas para compilações incrementais. Os exemplos incluem a tarefa Csc que encapsula o arquivo csc.exe e produz executáveis, bibliotecas e módulos, e a tarefa Vbc que encapsula o arquivo vbc.exe .

Usar transformações para criar um mapeamento um-para-um

O exemplo a seguir define um projeto que cria arquivos de conteúdo para um sistema de Ajuda. O projeto funciona convertendo arquivos de.txt de origem em arquivos .content intermediários, que são combinados com arquivos de metadados XML para produzir o arquivo .help final usado pelo sistema. O projeto inclui as seguintes tarefas:

  • GenerateContentFiles: Converte arquivos.txt em arquivos .content .
  • BuildHelp: Combina arquivos .content e arquivos de metadados XML para criar o arquivo .help final.

O projeto usa transformações para criar um mapeamento um-para-um entre entradas e saídas na GenerateContentFiles tarefa. O Output elemento é definido para usar automaticamente as saídas da GenerateContentFiles tarefa como entradas para a BuildHelp tarefa.

O arquivo de projeto contém Convert e Build destinos. As tarefas GenerateContentFiles e BuildHelp são colocadas nos alvos Convert e Build, respectivamente, para que cada alvo possa ser construído incrementalmente. A Output definição do elemento coloca as GenerateContentFiles saídas da tarefa na ContentFile lista de itens, para usar como entradas para a BuildHelp tarefa. Essa abordagem fornece automaticamente as saídas de uma tarefa como entradas para outra tarefa. Não é necessário listar os itens individuais ou as listas de itens manualmente em cada tarefa.

Observação

Embora o Convert destino possa ser construído incrementalmente, todas as saídas desse destino são sempre necessárias como entradas para o Build destino. MSBuild fornece automaticamente todas as saídas de um destino como entradas para outro destino quando você usa o Output elemento .

<Project DefaultTargets="Build">

    <ItemGroup>
        <TXTFile Include="*.txt"/>
        <XMLFiles Include="\metadata\*.xml"/>
    </ItemGroup>

    <Target Name = "Convert"
        Inputs="@(TXTFile)"
        Outputs="@(TXTFile->'%(Filename).content')">

        <GenerateContentFiles
            Sources = "@(TXTFile)">
            <Output TaskParameter = "OutputContentFiles"
                ItemName = "ContentFiles"/>
        </GenerateContentFiles>
    </Target>

    <Target Name = "Build" DependsOnTargets = "Convert"
        Inputs="@(ContentFiles);@(XMLFiles)"
        Outputs="$(MSBuildProjectName).help">

        <BuildHelp
            ContentFiles = "@(ContentFiles)"
            MetadataFiles = "@(XMLFiles)"
            OutputFileName = "$(MSBuildProjectName).help"/>
    </Target>
</Project>