2009-06-02 10 views
28

Qual è la differenza tra la creazione di un oggetto all'interno di un obiettivo come questo:CreateItem vs ItemGroup

<Target Name="DoStuff"> 
    <CreateItem Include="@(IntermediateAssembly)" > 
     <Output TaskParameter="Include" ItemName="FileWrites"/> 
    </CreateItem> 
</Target> 

e in questo modo:

<Target Name="DoStuff"> 
    <ItemGroup> 
     <FileWrites Include="@(IntermediateAssembly)" /> 
    </ItemGroup> 
</Target> 

cui si deve utilizzare uno o l'altro e perché?

risposta

27

Nelle versioni di MSBuild precedenti alla 3.5 non è possibile definire proprietà o elementi all'interno di destinazioni (come nel secondo esempio). È stato quindi utilizzato un task (CreateItem e CreateProperty)

Se si utilizza ToolsVersion 3.5, non è più necessario utilizzare CreateItem (anche se è ancora possibile se si preferisce).

Alla fine entrambi creano l'articolo allo stesso modo, con lo stesso scopo. L'utilizzo della seconda sintassi è più leggibile e l'impostazione di metadati personalizzati è molto più semplice (secondo me).

NOTA: la versione 3.5 di MSBuild è installata con .NET 3.5. Sebbene sia necessario definire ToolsVersion="3.5" nel tag Project del file MSBuild per utilizzare le funzionalità 3.5.

Nel caso ve lo stiate chiedendo, ho ottenuto la maggior parte di queste informazioni dal libro Inside the Microsoft® Build Engine: Using MSBuild and Team Foundation Build che mi è piaciuto molto (ma non sono affiliato in alcun modo).

+0

Grazie mille, questo è proprio quello che volevo sapere! Dovrò controllare quel libro. – Jake

+2

Sì, quel libro è fantastico, lo adoro :) :) :) Grazie per il rec. –

+5

Tuttavia ho trovato una grande differenza: CreateItem espande i caratteri jolly dati in Includi tramite un'operazione di trasformazione come mentre una dichiarazione ItemGroup non la espande . –

7

Non penso che la risposta accettata abbia definito la differenza.

La differenza è:

  • ItemGroup viene valutata quando lo script MSBuild viene caricato.
  • CreateItem viene valutata quando il target viene eseguito

Questo può portare a differenti valori della voce all'interno dello script.

Prendi l'esempio di un'attività che fa qualcosa con tutti i file che corrispondono a "* .txt" in una directory. Se il tuo script MSBuild è caricato in Visual Studio, solo i file esistenti all'avvio di VS saranno nell'articolo se usi ItemGroup.

Se si utilizza CreateItem, eseguirà una ricerca per tutti i file * .txt quando viene eseguito il target.

+10

Il richiedente indica che entrambi vengono chiamati dall'interno di un bersaglio. Dalla tua risposta, sembra che tu stia pensando in termini pre-MSBuild 3.5. (Quando ItemGroup non può essere inserito all'interno di una destinazione). Se ItemGroup si trova all'interno di una destinazione, è dinamico come se fosse stato dichiarato tramite CreateItem. (cioè viene valutato quando viene eseguito il target.) (Vedere Pagina 51 di "Inside the Microsoft Build Engine: Utilizzo di MSBuild e Team Foundation Build" come riferimento (o semplicemente provarlo)). – Vaccano

+0

@Vaccano: Un Itemgroup è "altrettanto dinamico" all'interno di un target con l'eccezione menzionata da Johannes Rudolph in un commento alla risposta scelta - "CreateItem espande i caratteri jolly dati in Include tramite un'operazione di trasformazione" ... mentre un La dichiarazione del gruppo di oggetti non lo farà. – CyberMonk

17

CreateItem e CreateProperty sono obsolete in MSBuild 3.5 (sebbene continueranno sempre a funzionare, ovviamente). Era abbastanza ovvio che avevamo bisogno della stessa sintassi familiare per ItemGroup e PropertyGroup per funzionare all'interno delle destinazioni.

Ma Gruppo Oggetti all'interno di un bersaglio ha alcuni poteri speciali extra. Può modificare gli elementi: ad esempio, questo aggiungerà true a tutti gli elementi nell'elenco Risorse che hanno un metadato denominato Primario con valore di true; solo se non è già Copia metadati:

<ItemGroup> 
    <Resources Condition=" '%(Primary)' == 'true' "> 
    <Copy Condition=" '%(Copy)' == '' ">true</Copy> 
    </Resources> 
</ItemGroup> 

Un altro potere magico: ora è possibile rimuovere gli elementi da un elenco.Questo esempio rimuoverà tutte le voci dalla lista delle risorse che hanno i metadati Tipo con il valore di bitmap:

<ItemGroup> 
    <Resources Condition=" '%(Type)'=='Bitmap' " Remove="@(Resources)"/> 
</ItemGroup> 

Questi poteri magici funzionano solo dentro al momento, non al di fuori.

Per i dettagli completi di questa roba, consiglio vivamente il libro di Sayed Hashimi su MSBuild. Si trova facilmente su Amazon.

Dan - team msbuild.

1

Come informazioni aggiuntive per gli altri che passano qui: Il Build-Engine che contiene un'API per costruire progetti MSBuild non supporta l'aggiunta di ItemGroup alla nuova modalità di destinazione. Qui dovrai usare la vecchia maniera.

Problemi correlati