Dela via


Inkrementella versioner

MSBuild-inkrementella versioner är versioner som är optimerade så att mål som har utdatafiler som up-to-date med avseende på motsvarande indatafiler inte körs.

Ett målelement kan ha både ett Inputs-attribut, vilket anger vilka objekt som målet förväntar sig som indata och ett Outputs attribut som anger vilka objekt det producerar som utdata. MSBuild försöker hitta en en-till-en-mappning mellan värdena för dessa attribut. Om en sådan mappning finns jämför MSBuild tidsstämpeln för varje indataobjekt med tidsstämpeln för motsvarande utdataobjekt. Utdatafiler som inte har en en-till-en-mappning jämförs med alla indatafiler. Ett objekt anses up-to-date om dess utdatafil är samma ålder eller senare än dess indatafil eller filer.

Obs

När MSBuild utvärderar indatafilerna beaktas endast innehållet i listan under den pågående körningen. Ändringar i listan från den senaste versionen gör inte automatiskt ett mål inaktuellt.

Om alla utdataobjekt är (up-to-date), hoppar MSBuild över målet. Den här inkrementella versionen av målet kan avsevärt förbättra kompileringens hastighet. Om bara vissa filer är up-to-date kör MSBuild målet men hoppar över up-to-date-objekten och tar därför med alla objekt up-to-date. Den här processen kallas för en partiell stegvis kompilering.

En-till-en-mappningar kan endast skapas genom att göra attributet Outputs till en transformering av Inputs-attributet. Mer information finns i MSBuild-transformeringar.

Överväg följande mål:

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

Uppsättningen filer som representeras av Compile objekttyp kopieras till en säkerhetskopieringskatalog. Säkerhetskopiorna har filnamnstillägget .bak. Om filerna som representeras av Compile objekttyp eller motsvarande säkerhetskopieringsfiler inte tas bort eller ändras efter att Backup målet har körts, hoppas Backup målet över i kommande kompileringar.

Slutsatsdragning av utdata

MSBuild jämför attributen Inputs och Outputs för ett mål för att avgöra om målet behöver köras. Helst bör den uppsättning filer som finns efter att en inkrementell version har slutförts förbli densamma oavsett om de associerade målen körs eller inte. Eftersom egenskaper och objekt som uppgifter skapar eller ändrar kan påverka bygget måste MSBuild härleda deras värden även om målet som påverkar dem skippas. Den här processen kallas utdatainferens.

Det finns tre fall:

  • Målet har ett Condition-attribut som utvärderas till false. I det här fallet körs inte målet och påverkar inte bygget.

  • Målet har inaktuella utdata och körs för att få dem up-to-date.

  • Målet har inga inaktuella utdata och hoppas över. MSBuild utvärderar målet och gör ändringar i objekt och egenskaper som om målet kördes.

För att stöda inkrementell kompilering måste uppgifter se till att TaskParameter attributvärdet för alla Output element är lika med en aktivitetsindataparameter. Till exempel:

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

Den här koden skapar egenskapen Easy, som har värdet 123 oavsett om målet körs eller hoppar över.

Från och med MSBuild 3.5 utförs utdatainferens automatiskt på objekt- och egenskapsgrupper i ett mål. CreateItem uppgifter krävs inte i ett mål och bör undvikas. Dessutom bör CreateProperty tasker endast användas i ett mål för att avgöra om en process har körts.

Innan MSBuild 3.5 kan du använda uppgiften CreateItem.

Kontrollera om ett målobjekt körs

På grund av utdatainferensen måste du undersöka egenskaperna och objekten i ett mål för att avgöra om målet kördes. Om du vill göra det lägger du till den CreateProperty uppgiften till målet och ger den ett Output element vars TaskParameter är ValueSetByTask. Till exempel:

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

Den här koden skapar egenskapen CompileRan och ger den värdet true, men bara om målet körs. Om målet hoppas över skapas inte CompileRan.