Artikel

März 2004 | Artikel

Arbeitsameise

(Link zum Artikel: http://www.it-republik.de/dotnet/artikel/0508)

Das Open Source Build-Tool NAnt

Text: von André Achtermeier und Dietmar Leibec
  • Teilen
  • kommentieren
  • empfehlen
  • Bookmark and Share
Wer mit dem VS.NET größere Projekte verwirklicht, gelangt schnell an die Grenzen des integrierten Build-Tools. Lange Build-Zeiten trüben den Entwicklungsspaß. So werden beispielsweise teilweise auch Projekte neu gebaut, an denen keine Änderungen vorgenommen wurden. Gerade in multilingualen Projekten ist dies ein schwerwiegendes Problem. Das Open Source Projekt NAnt schafft hier Abhilfe. Mit NAnt bestimmt wieder der Entwickler, wann, was und wie gebaut werden soll.

Ich baue mal eben die Solution neu. Solange es sich um eine überschaubare Solution mit wenigen Projekten in einer einzigen Sprache handelt, kann man sich schon mal eben zu dieser Aussage hinreißen lassen. Eine Solution wächst naturgemäß im Laufe des Projekts an. Gegebenenfalls kommen einige Projekte hinzu, die in einer anderen Sprache geschrieben sind. Wer sich dann immer noch auf das integrierte Build-Tool des Visual Studios verlässt, testet oftmals die Belastbarkeit seiner Nerven. Bei einer Windows-Solution mit 55 Projekten, wobei 25 Projekte in C# geschrieben sind und die restlichen Projekte in VB.NET, dauert der Build-Prozess schon mal über drei Minuten. Wer dann noch einen Rebuild ausführt, kann sich in der Zwischenzeit bei einer Tasse Kaffee entspannen. Build-Tools helfen an dieser und anderen Stellen, beispielsweise bei der so genannten Continuous Integration, den Build-Prozess zu optimieren, natürlich auch bei Projekten, die nicht mit VS.NET realisiert werden. Selbst Microsoft hat diese Schwachstelle erkannt und stellt mit BuildIt ein separates Tool zur Verfügung [1]. NAnt ist sicherlich das bekannteste Tool in diesem Sektor.

Open Source Projekt NAnt
Auf der NAnt-Seite (nant.sourceforge.net) kann die aktuelle Version des Tools heruntergeladen werden. Das Tool ist zwar ursprünglich eine Portierung des Java-Tools Ant, wurde aber komplett neu geschrieben und wächst im Leistungsumfang stetig an. Eine ausführliche Installationsanleitung liegt dem Tool bei. Wer bereits das .NET-Framework 1.1.x einsetzt, muss vor Benutzung die Datei Nant.exe.config im \bin-Verzeichnis anpassen, denn diese ist auf die Version 1.0 voreingestellt. Es empfiehlt sich, NAnt in den Systempfad aufzunehmen.
Steckbrief NAnt
NAnt ist ein Open Source-Projekt, welches von Jakarta Ant inspiriert wurde. Es handelt sich dabei um ein sehr leistungsfähiges Build-Tool mit vielen Zusatzoptionen. Seit Ende 2003 ist die Version 0.84 frei erhältlich. Da NAnt ständig weiterentwickelt wird, empfiehlt sich ein Eintrag in die Mailingliste(n). Diese bieten auch eine gute Plattform, um sich mit anderen NAnt-Usern auszutauschen.
Grundlagen
NAnt arbeitet mit Task-Klassen und wird über eine XML-Datei konfiguriert. Die Konfigurationsdateien besitzen immer die Endung .build. NAnt schaut standardmäßig nach so einer Datei im angegebenen Verzeichnis, wenn der Befehl nant eingegeben wird. Natürlich kann der Entwickler auch mehr als eine Konfigurationsdatei in dem Verzeichnis lagern, aber in diesem Fall muss NAnt die gewünschte Konfigurationsdatei mit der Zusatzoption -buildfile mitgeteilt werden. Der Aufbau einer Build-Datei gestaltet sich wie folgt:
  1. <project name=?framework?>
  2. <property name=?buildDir?/>
  3. <target name=?gacinstall?>
  4. ...
  5. </target>
  6. </project>
Die Targets können individuell angesprochen werden. So wird beispielsweise ein Target mit dem Namen Debug über das Kommando nant Debug angesprochen. Üblicherweise beinhaltet eine Build-Datei mehr als einen Task, sodass es sich empfiehlt, einen default-Task anzugeben:
  1. <project name=?framework? default=?Debug?>
Ein Target kann ein anderes Target mit dem call-Tag ansprechen. Diese Option ist nützlich, wenn das Build-Skript eine gewisse Komplexität erreicht hat und nur ein Befehl den kompletten Build-Prozess anstoßen soll.
NAnt Contribution Tasks
Eine nützliche Erweiterung der augelieferten NAnt-Versionen sind die so genannten NAnt Contribution Tasks, welche unter nantcontrib.sourceforge.net/ zu finden sind. Der Download bietet unter anderem auch den Buildfile-Generator SLingShot, welcher sich als Add-in in VS.NET integrieren lässt. Auch diese Tasks werden mit einer umfassenden Dokumentation ausgeliefert. Auf einige der Features wird im weiteren Verlauf genauer eingegangen.
Continuous Integration
Continuous Integration (CI) ist ein Teil des eXtreme Programming-Prozesses (XP) und rät den Entwicklungsteams, die Solution mehrmals am Tag zu bauen, um sicherzustellen, dass Fehler schnell entdeckt werden und jedes Teammitglied die aktuellste Version verwendet. Hierzu werden Source Control-Server eingesetzt (zum Beispiel CVS, VSS etc.). Martin Fowler beschreibt CI ausführlich unter [2]. Ein nützliches Tool in diesem Kontext ist CruiseControl.NET, welches frei erhältlich ist [3]. CruiseControl.NET automatisiert CI, indem es NAnt und NUnit nahtlos in den Source Control-Server integriert. So kann die Solution automatisch gebaut, getestet und im Source Control-Server zur Verfügung gestellt werden. Die Vorteile liegen auf der Hand. Es ist damit sichergestellt, dass den Entwicklern nur funktionsfähige Versionen der Solution zur Verfügung stehen.
Fallstudie
Ein Beispielprojekt soll den Umgang mit NAnt verdeutlichen und die Vorteile des Build-Tools herausstellen. Unsere Solution soll in der Lage sein, Lieferungen von Erdgas zu fakturieren. Wir nennen diese Solution trivial Abrechnung. Dazu benötigen wir drei Projekte, die, wie in Abpictureung 1 gezeigt, in Beziehung zueinander stehen.
Das Projekt Fakturierung ist für die eigentliche Abrechnung zuständig und in VB.NET geschrieben. Dieses Projekt nutzt die Daten der Energieauswertung und der Preispflege. Diese beiden Projekte sind in C# geschrieben. Es handelt sich demnach um eine multilinguale Solution, zu der im Folgenden das Build-Skript erstellt werden soll. Hier kommt der Buildfile-Generator des NAnt Contribution Tasks SLingShot ins Spiel. Mit Hilfe dieses Tools wird ein Grundgerüst für das Build-Skript erstellt. Allerdings ist SLingShot zunächst für die Verwendung in C#-Projekten ausgerichtet. Der Befehl, welcher zum Entwicklerglück führt, lautet:
  1. Slingshot.exe -nant -sln c:\projekte\Abrechnung\Abrechnung.sln
Der aufmerksame Leser wird sicherlich sofort erkannt haben, dass Slingshot eine VS.NET-Solution benötigt. Wer lieber mit dem Build-Tool make arbeitet ersetzt -nant einfach durch -make und schon produziert Slingshot das Build-Skript mit der make-Syntax.
Integration externer Komponenten
NAnt unterstützt den Zugriff auf Systemvariablen und ermöglicht es darüber hinaus, systemspezifische Eigenschaften im Build-Skript zu berücksichtigen. Dies erlaubt die Erstellung eines flexiblen Build-Skripts. Beispielhaft seien hier die unterschiedlichen Programmverzeichnisse von englisch- und deutschsprachigen Windows-Versionen aufgeführt. Dazu werden im Build-Skript zunächst die Standardeinstellungen mit geladen. Im Anschluss daran wird eine Property definiert, welche sich für das Windows-Programmverzeichnis wie folgt darstellt:
  1. <property name="program.dir" value="${sys.os.folder.programfiles}" />
Mit ${program.dir} wird nun der Pfad für die Programme, Komponenten etc. aus der Systemeinstellung geladen. Muss in einem Target eine solche externe Quelle referenziert werden, so wird das mit dem Tag
  1. <includes name="${program.dir}\AppliedTechnologies\bin\apptech.UIComponents.dll" />
realisiert. Dieses Prinzip besitzt für alle Property-Werte Gültigkeit.

Fassen wir an dieser Stelle kurz zusammen. Das Grundgerüst für ein NAnt-Build-Skript wurde erstellt. Die Entwickler können pfadunabhängig die Komponente apptech.UIComponents.dll nutzen. Im nächsten Schritt werden die Targets der Solution untersucht.
Targets
SLingShot baut das Skript so auf, dass es Targets für die Debug-Version und Targets für die Release-Version konfiguriert. In diesem Beispiel konzentrieren wir uns auf die Targets für die Debug-Version. Wenn wir den Befehl nant im Verzeichnis des Skripts ausführen wird das Default-Target angesprochen. In unserem Fall wäre das:
  1. <target name=?Debug? depends=?Fakturierung,Energieauswertung,Preispflege?/>
NAnt arbeitet die abhängigen Targets der Reihenfolge nach ab. Zuerst würde demnach der Aufruf des Targets mit dem Namen Fakturierung erfolgen:
  1. <target name=?Fakturierung?>
  2. <vbc target=?library? output=?${build.outputdir}? debug=?false?/>
  3. <sources>
  4. ...hier stehen die Klassen des Projekts
  5. </sources>
  6. <references>
  7. ...hier stehen die Referenzen des Projekts
  8. </references>
  9. </target>
Der Entwickler muss NAnt mitteilen, welchen Compiler er für welches Target benutzen soll. Das wäre beispielsweise für VB.NET <vbc... und für C# <csc.... Abpictureung 2 gibt einen kurzen Überblick über NAnt-Tags zu einer VS.NET-Solution.
NAnt und der Global Assembly Cache (GAC)
NAnt ermöglicht die automatisierte Installation von Komponenten in den GAC. Für diesen Zweck wird ein zusätzlicher Task des Contribution-Packages benötigt. Dieser Task trägt den Namen gac. Während des Build-Prozesses ruft dieser Task das .NET-Tool gacutil.exe auf. Ein Target für diese Aufgabe könnte so aussehen:
  1. <gac assembly="${build.dir}\Energieauswertung.dll" uninstall="true"/>
Die Eigenschaft uninstall sorgt dafür, dass bereits registrierte DLLs vorher aus dem GAC deinstalliert werden. Dies stellt sicher, dass immer nur die aktuellste Version der entsprechenden DLL im GAC eingetragen ist.
NAnt und automatische Unit-Tests
Unit-Tests die mit dem Unit-Framework NUnit geschrieben wurden, können ebenfalls automatisch unter Einsatz von NAnt durchlaufen werden. Für NUnit V2.x wird der Task benötigt. Ein Beispiel dazu findet sich ebenfalls in der mitgelieferten Referenz. Für nähere Informationen über Unit-Tests siehe [4], [5] und [6].
Fazit
Wer in seinen Projekten sicherstellen möchte, dass möglichst viele Prozesse rund um den Build-Vorgang automatisiert werden, der ist mit dem Einsatz von NAnt und Continuous Integration gut beraten. Automatische Build-Prozesse, automatisierte Tests und die ständige Gewissheit, Probleme im Build-Prozess frühzeitig aufzudecken, sollten Grund genug sein,um über den Einsatz von NAnt nachzudenken.

Links und Literatur


Anzeige

Kommentare

zurück zum Seitenanfang