Condividi tramite


Compilazioni incrementali

Le compilazioni incrementali di MSBuild sono compilazioni ottimizzate in modo che le destinazioni con file di output up-to-date rispetto ai file di input corrispondenti non vengano eseguite.

Un elemento di destinazione può avere sia un attributo Inputs, che indica gli elementi previsti dalla destinazione come input e un attributo Outputs, che indica quali elementi produce come output. MSBuild tenta di trovare una corrispondenza uno-a-uno tra i valori di questi attributi. Se esiste un mapping di questo tipo, MSBuild confronta il timestamp di ogni elemento di input con il timestamp dell'elemento di output corrispondente. I file di output che non hanno un mapping uno-a-uno vengono confrontati con tutti i file di input. Un elemento viene considerato up-to-date se il file di output è la stessa età o più recente rispetto al file o ai file di input.

Nota

Quando MSBuild valuta i file di input, vengono considerati solo i contenuti dell'elenco nell'esecuzione corrente. Le modifiche nell'elenco dell'ultima compilazione non rendono automaticamente obsoleta una destinazione.

Se tutti gli elementi di output sono up-to-date, MSBuild ignora l'obiettivo. Questa build incrementale del target può migliorare significativamente la velocità di compilazione. Se solo alcuni file sono up-to-date, MSBuild esegue la destinazione, ma ignora gli elementi up-to-date e quindi porta tutti gli elementi up-to-date. Questo processo è noto come compilazione incrementale parziale .

I mapping uno-a-uno possono essere prodotti solo rendendo l'attributo Outputs una trasformazione dell'attributo Inputs. Per ulteriori informazioni, vedere le trasformazioni di MSBuild .

Si consideri la destinazione seguente:

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

Il set di file rappresentato dal tipo di elemento Compile viene copiato in una directory di backup. I file di backup hanno l'estensione .bak nome file. Se i file rappresentati dal tipo di elemento Compile o dai file di backup corrispondenti non vengono eliminati o modificati dopo l'esecuzione della destinazione Backup, la destinazione Backup viene ignorata nelle compilazioni successive.

Inferenza di output

MSBuild confronta gli attributi Inputs e Outputs di una destinazione per determinare se la destinazione deve essere eseguita. Idealmente, il set di file esistenti dopo il completamento di una compilazione incrementale deve rimanere invariato se le destinazioni associate vengono eseguite o meno. Poiché le proprietà e gli elementi creati o modificati dalle attività possono influire sulla compilazione, MSBuild deve dedurre i valori anche se la destinazione che li interessa viene ignorata. Questo processo è noto come inferenza dell'output .

Esistono tre casi:

  • La destinazione ha un attributo Condition che restituisce false. In questo caso, la destinazione non viene eseguita e non ha alcun effetto sulla compilazione.

  • L'obiettivo include degli output obsoleti ed è in esecuzione per portarli up-to-date.

  • La destinazione non ha output non aggiornati e viene ignorata. MSBuild valuta il target e apporta modifiche a elementi e proprietà come se il target fosse stato eseguito.

Per supportare la compilazione incrementale, le attività devono assicurarsi che il valore dell'attributo TaskParameter di qualsiasi elemento Output sia uguale a un parametro di input dell'attività. Per esempio:

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

Questo codice crea la proprietà Easy, che ha il valore 123 se la destinazione viene eseguita o ignorata.

A partire da MSBuild 3.5, l'inferenza di output viene eseguita automaticamente sui gruppi di elementi e proprietà in un obiettivo. CreateItem le attività non sono necessarie in una destinazione e devono essere evitate. Inoltre, i compiti CreateProperty devono essere usati in una destinazione solo per determinare se un obiettivo è stato eseguito.

Prima di MSBuild 3.5, è possibile usare l'attività CreateItem.

Determinare se un obiettivo viene eseguito

A causa dell'inferenza dell'output, è necessario esaminare le proprietà e gli elementi di una destinazione per determinare se la destinazione è stata eseguita. A tale scopo, aggiungere l'attività CreateProperty al target e assegnargli un elemento Output il cui TaskParameter è ValueSetByTask. Per esempio:

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

Questo codice crea la proprietà CompileRan e assegna il valore true, ma solo se viene eseguita la destinazione. Se la destinazione viene ignorata, CompileRan non viene creata.