MSBuild Items – Die Planeten im Universum

Im vierten Teil der MSBuild Serie möchte die MSBuild Items vorstellen, die einen weiteren zentralen Bestandteil jedes Buildscriptes darstellen. Vorab nochmals kurz die Liste der bereits veröffentlichten MSBuild Artikel

  1. MSBuild – Ein Überblick
  2. MSBuild – Leichte Kost
  3. MSBuild – Jenseits von HelloBuildWorld (MSBuild Properties)

 

Was sind denn überhaupt MSBuild Items

Als Items werden im MSBuild Jargon sämtliche Elemente bezeichnet die zur Ausführung des Buildvorgangs von Nöten sind. Im Normalfall also Dateien. Hierbei gibt es keinerlei Beschränkung auf Dateitypen, Dateigrößen oder sonstige Metadaten. Der Entwickler eines Build-Files kann selbst definieren was als Item für den Build angegeben oder verwendet werden soll.

 

ItemGroup – Der Container

Analog zu Properties werden auch Items in MSBuild in Gruppen zusammengefasst. Items werden daher logischerweise in ItemGroup-Elementen angeordnet. Es können beliebig viele ItemGroup-Nodes direkt unter dem “Project”-Node, dem Rootelement einer MSBuild-Konfiguration definiert werden.

Eine Projektdatei mit einer einfachen ItemGroup sieht demnach so aus

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <!-- some items will be defined here-->
  </ItemGroup>
</Project>

 

Genau wie PropertyGroup Elemente können auch auf ItemGroup Nodes Bedingungen deklariert werden, der Syntax hierfür ist der gleiche wie auf allen anderen Elementen. Als Beispiel an dieser Stelle einfach kurz eine ItemGroup die nur verwendet wird wenn die Property “Condition” auf “RELEASE” eingestellt ist.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Condition="'$(Configuration)' == 'RELEASE'">
    <!-- some items will be defined here-->
  </ItemGroup>
</Project>
 

 

MSBuild Items erstellen

Bei der Definition von MSBuild Items kann man analog zu den MSBuild Properties den Key der Items selbst definieren, allerdings gibt es gerade für Items viele vordefinierte Keys wie zum Beispiel Resource, Reference usw. (intern entspricht ein ItemTyp immer einem anderen Objekttypen). Unabhängig vom ItemTyp verfügt ein Item-Node (auch wenn es nicht so heißt :)) über drei Attribute

  • Include
    • Gibt zugehörige(s) Element(e) an
  • Exclude
    • Gibt ausgeschlossene(s) Element(e) an
  • Condition
    • Auszuwertende Bedingung

Wie so oft gibt es auch bei der Angabe von Items mehrere Wege die ins berühmte Rom führen. Man kann Items entweder als “Liste” auf einem Item-Node angeben oder man erstellt für jedes Item einen eigenen Knoten in einer ItemGroup.

 

Items in einer Liste erstellen

Um mehrere Items direkt in einer Liste zu deklarieren, müssen diese lediglich durch ein Semikolon (;) getrennt werden.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Condition="'$(Configuration)' == 'DEBUG'">
    <Files Include="Program.cs; ICustomerService.cs; CustomerService.cs"/>
  </ItemGroup>
</Project>
 

Die Dateien (An dieser Stelle bewusst nicht Klassen oder Codefiles genannt) Program.cs, ICustomerService.cs und CustomerService.cs werden automatisch in ein ITaskItem-Array gepackt, welches den Namen “Files” trägt.

 

Single Item per Node

Die zweite Variante habe ich einfach mal “Single Item per Node” getauft, weil es dem entspricht was man macht… Leider gibt es meines Wissens keinen Ausdruck für diese Art der Deklaration. Um die gleichen Files wie in der Listendeklaration anzugeben muss das Projektfile wie folgt aussehen

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Condition="'$(Configuration)' == 'DEBUG'">
    <Files Include="*Program.cs"/>
    <Files Include="ICustomerService.cs"/>
    <Files Include="CustomerService.cs"/>
  </ItemGroup>
</Project>

 

Es ist hierbei dem Entwickler freigelassen welchen Weg er zum erstellen eines MSBuild Items verwendet.

 

Wildcards zur Lokalisierung von Elementen in Include bzw Exclude

Ein weiteres wichtiges und zeitsparendes Feature bei der Definition von Items, sind die unterstützten Wildcards, mit denen MSBuild umgehen kann.

MSBuild bietet drei Wildcards an:

  1. *
    • Stellt “n” beliebige Zeichen dar
  2. ?
    • Stellt ein beliebiges Zeichen dar
  3. **
    • aktiviert die rekursive Suche
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Condition="'$(Configuration)' == 'DEBUG'">
    <Files Include="*.cs" Exclude="**\*.vb;DoNotCompile.cs;old s*it\DoNotCompile.cs"/>
  </ItemGroup>
</Project>

In diesem Beispiel werden zunächst alle C#-Code Files hinzugefügt, alle VB-Files werden ordnungsgemäß auf die Excludeliste geschoben wo auch die Datei DoNotCompile.cs und alle DoNotCompile.cs files aus den Ordnern “old sait”, “old sbit”… oder “old ***” landen.

 

Vordefinierte Items

Neben der Möglichkeit eigene “generische” Items, wie hier “Files”, zu generieren, lohnt sich auch ab und an mal ein Blick in das MSBuild Schema. Für viele Item-Typen hat das MSBuild Team bereits konkrete Typen definiert.

So werden zum Beispiel sämtliche Assembyverweise ebenfalls als Item in einer ItemGroup abgelegt, verwenden jedoch alle das XML-Node “Reference” dazu.

Wenn man eine solche Konkretisierung eines Items verwendet, hat dies zu Folge, dass die entsprechenden Tasks schneller etwas mit dem Item tun können, da dieses Item “nicht mehr so weakly typed” ist, wie es noch als Instanz eines simplen Item’s war.

Referenzen auf externe Assemblies dienen auch direkt bei jedem Visual Studio Projekt, dass Ihr erstellt, als super Anschauungsmaterial. Die Projektdatei einer einfache Console Anwendung besteht zum Teil aus folgenden Items

  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Core">
      <RequiredTargetFramework>3.5</RequiredTargetFramework>
    </Reference>
    <Reference Include="System.Xml.Linq">
      <RequiredTargetFramework>3.5</RequiredTargetFramework>
    </Reference>
    <Reference Include="System.Data.DataSetExtensions">
      <RequiredTargetFramework>3.5</RequiredTargetFramework>
    </Reference>
    <Reference Include="System.Data" />
    <Reference Include="System.Xml" />
  </ItemGroup>

 

Die Assemblies System.Core, System.Xml.Linq und System.Data.DataSetExtensions verfügen in der Projektdatei über die MetaInformation “RequiredTargetFramework”. Genau hier entscheidet VisualStudio 2008 ob die Assembly im aktuellen Projekt verwendet werden kann. Hier wird nämlich die Zielplattform-Einstellung in Visual Studio 2008 evaluiert.

 

Erweiterte Metadaten für Items

Jedes Item kann durch beliebig viele, individuelle Metadaten dekoriert werden. Auch bei Metadaten kann der Entwickler wieder selbst den XML-Node-Namen und Bedingungen vergeben werden.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Condition="'$(Configuration)' == 'DEBUG'">
    <Files Include="Program.cs">
      <EntryPoint>TRUE</EntryPoint>
      <CenterOfGravity>TRUE</CenterOfGravity>
    </Files> 
    <Files Include="ICustomerService.cs"/>
    <Files Include="CustomerService.cs"/>
  </ItemGroup>
</Project>

MSBuild gibt allerdings auch eine Reihe von Metadaten vor, die direkt auf einem Item abgefragt werden können. Unter anderem gehören dazu

  • FullPath
  • Filename
  • Extension
  • CreatedTime

 

 

MSBuild Items verwenden

Die bereits definierten Items sollten, sofern die Bedingungen zutreffen, auch irgendwo im Buildscript Verwendung finden. Normalerweise werden Build Items in Build Tasks verwendet. Die Files aus diesem Beispiel wären wie gemacht für den C#-Compiler Task (CSC).

Damit der Compiler diese Items auch finden kann, muss man also, genau wie bei den Properties, einen Verweis zum Item einfügen. Im Gegensatz zu MSBuild Properties geschieht dies nicht über $(…) sondern über

@(ItemTypeName) hier wäre es also @(Files)

 

Item-Metadaten verwenden

Alles was man definiert, möchte man verwenden, sonst würde man es ja nicht definieren, oder? Bei den eben angelegten Metadaten gehen wir mal davon aus.

Der Zugriff auf Metadaten bedarf ebenfalls einer besonderen Schreibweise

@(ItemTypeName->’%(MetaDataName)’) also hier @(Files->’%(CenterOfGravity)’)

 

Alles bis dato gelernte angewendet könnte die MSBuildUniversum.proj so aussehen

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition="'$(Configuration)' ==''">DEBUG</Configuration>
  
  </PropertyGroup>
  <ItemGroup Condition="'$(Configuration)' == 'DEBUG'">
    
    <Files Include="*.cs" Exclude="**\*.vb;DoNotCompile.cs;old s*it\DoNotCompile.cs">
      <Website>http://www.dotnet-rocks.de</Website>
    </Files>
    <Reference Include="System.Xml"/>
  </ItemGroup>
  <Target Name="ShowMSBuildSkills">
    <Message Text="@(Files->'%(Filename)')"/>
    <Message Text="@(Files->'%(Extension)')"/>
    <Message Text="@(Files->'%(Website)')"/>
  </Target>
</Project>

 

Wenn das Script mit MSBuild.exe ausgeführt wird, erhaltet Ihr die folgende Bildschirmausgabe, die alle gewünschten Metadaten beinhaltet.

HelloMSBuildWorldReloaded5

 

Fazit

Mit MSBuild Items habe ich euch hoffentlich wieder einen Großteil des MSBuild Universums verständlich rüber gebracht. Wichtig ist meiner Meinung nach bei der Arbeit mit Build-Items immer genau zu prüfen ob es eventuell einen konkreten, vordefinierten Item-Typ innerhalb der ItemGroup bereits gibt. Gerade im Hinblick auf eigens entwickelte Tasks, gilt es sich dies anzueignen, weil hier dann viele Umwandlungen und Konvertierungen hin zu einem konkreten Typen wegfallen.

Im nächsten Teil der Artikelserie wird es um die geläufigsten Standard-Tasks von MSBuild gehen. Danach kommt noch ein kurzer Abstecher bei erweiterten Bedingungen bevor es über die Entwicklung eigener Tasks hin zu TeamBuild und all den anderen schönen Enterprise Sachen geht.

 

DotNetKicks-DE Image
Published Mittwoch, 10. Februar 2010 08:46 von ThorstenHans
Abgelegt unter: ,

Kommentare

# MSBuild Conditions - Die Wurmlöcher des Universums

Freitag, 12. Februar 2010 23:12 von .NET rocks

Im sechsten Teil der MSBuild Serie geht es um MSBuild Conditions, es sind die Wurmlöcher des MSBuild

# MSBuild Tasks – Die Umlaufbahnen im Universum

Freitag, 12. Februar 2010 23:13 von .NET rocks

Im fünften Teil der MSBuild Serie möchte die MSBuild Tasks vorstellen, Tasks verwenden hauptsächlich

# Das MSBuild Universum

Montag, 15. Februar 2010 08:22 von .NET rocks

Eine kurze Übersicht aller Artikel der MSBuild Serie &quot;Das MSBuild Universum&quot; MSBuild – Ein

# MSBuild Targets - Die Asteroiden im MSBuild Universum nutzen

Mittwoch, 17. Februar 2010 12:24 von .NET rocks

Im achten Teil der MSBuild Serie “Das MSBuild Universum” möchte ich nochmal etwas detaillierter auf MSBuild

# MSBuild Logger - Reisen im Universum sollte man protokollieren

Donnerstag, 18. Februar 2010 16:00 von .NET rocks

Im neunten Teil der Serie “Das MSBuild Universum” möchte ich MSBuild Logger vorstellen und zeigen was

# MSBuild Batching und MSBuild Choose – Die Flugbahnen von Körpern im Universum beeinflussen

Montag, 22. Februar 2010 21:51 von .NET rocks

Im zehnten Teil der Serie “Das MSBuild Universum” werde ich sowohl die Möglichkeiten des Batchings, als

# MSBuild Hook Ups - Die Tore zum Ur-Universum

Dienstag, 23. Februar 2010 08:19 von .NET rocks

Im elften – und vorletzten – Teil der Artikelserie “Das MSBuild Universum” möchte ich die Möglichkeiten

# IronMSBuild – Direkte Verbindung zu allen Planeten des Universums

Mittwoch, 24. Februar 2010 22:51 von .NET rocks

Im zwölften – und letzten – Teil der Artikelserie “Das MSBuild Universum” möchte ich IronMSBuild vorstellen

Kommentar abgeben

(verpflichtend) 
(verpflichtend) 
(optional)
(verpflichtend)