Share via


Eseguire la compilazione incrementale

Quando si compila un progetto di grandi dimensioni, è importante che i componenti compilati precedentemente e ancora aggiornati non vengano ricompilati. Se vengono ricompilate tutte le destinazioni, ogni compilazione impiegherà molto tempo. Per abilitare compilazioni incrementali (compilazioni in cui vengono ricompilate solo le destinazioni che non sono state compilate prima o le destinazioni non aggiornate), Microsoft Build Engine (MSBuild) può confrontare i timestamp dei file di input con i timestamp dei file di output e determinare se ignorare, compilare o ricompilare parzialmente una destinazione. Per questa operazione di confronto, è necessario un mapping uno a uno tra input e output. È possibile usare le trasformazioni per consentire alle destinazioni di identificare tale mapping diretto. Per altre informazioni sulle trasformazioni, vedere Trasformazioni.

Specifica di input e output

Una destinazione può essere compilata in modo incrementale se gli input e gli output sono specificati nel file di progetto.

Per specificare input e output per una destinazione

  • Usare gli attributi Inputs e Outputs dell'elemento Target. Ad esempio:

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

MSBuild può confrontare i timestamp dei file di input con i timestamp dei file di output e determinare se ignorare, compilare o ricompilare parzialmente una destinazione. Nell'esempio seguente, se un file nell'elenco @(CSFile) di elementi è più recente del file hello.exe , MSBuild eseguirà la destinazione; in caso contrario, verrà ignorato:

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

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

Quando gli input e gli output sono specificati in una destinazione, ogni output può essere mappato solo a un input oppure potrebbe non esserci alcun mapping diretto tra gli output e gli input. Nell'attività Csc precedente, ad esempio, l'output hello.exe non può essere mappato a un singolo input, ma dipende da tutti gli elementi.

Nota

Una destinazione in cui non esiste alcun mapping diretto tra gli input e gli output verrà sempre compilata più spesso di una destinazione in cui ogni output può eseguire il mapping a un solo input perché MSBuild non è in grado di determinare quali output devono essere ricompilati se alcuni degli input sono stati modificati.

Le attività in cui è possibile identificare un mapping diretto tra output e input, ad esempio l'attività LC, sono più adatte per le compilazioni incrementali, a differenza delle attività Csc e Vbc, che producono un assembly di output da un numero di input.

Esempio

Nell'esempio seguente viene usato un progetto che compila file della Guida per un ipotetico sistema di Guida. Il progetto converte i file di origine con estensione txt in file con estensione content intermedi, che vengono quindi combinati con i file di metadati XML per generare il file con estensione help finale usato dal sistema della Guida. Il progetto usa le attività ipotetiche seguenti:

  • GenerateContentFiles: converte file txt in file content.

  • BuildHelp: combina i file content e i file di metadati XML per compilare il file help finale.

Il progetto usa trasformazioni per creare un mapping uno a uno tra input e output nell'attività GenerateContentFiles. Per altre informazioni, vedere Trasformazioni. L'elemento Output è impostato per usare automaticamente gli output dall'attività GenerateContentFiles come input per l'attività BuildHelp.

Questo file di progetto contiene le destinazioni Convert e Build. Le attività GenerateContentFiles e BuildHelp vengono inserite rispettivamente nelle destinazioni Convert e Build in modo che ogni destinazione possa essere compilata in modo incrementale. Tramite l'elemento Output, gli output dell'attività GenerateContentFiles vengono inseriti nell'elenco di elementi ContentFile dove possono essere usati come input per l'attività BuildHelp. L'uso dell'elemento Output in questo modo offre automaticamente gli output da un'attività come input per un'altra attività in modo che non sia necessario elencare manualmente i singoli elementi o elenchi di elementi in ogni attività.

Nota

Sebbene la destinazione Convert possa essere compilata in modo incrementale, tutti gli output di tale destinazione sono sempre necessari come input per la destinazione Build. MSBuild fornisce automaticamente tutti gli output di una destinazione come input per un'altra destinazione quando si usa l'elemento Output .

<Project DefaultTargets="Build"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >

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