Build-Automatisierung

Transcription

Build-Automatisierung
Software-Engineering 2: Automatische
Build-Werkzeuge
Prof. Dr. Axel Böttcher
22. Oktober 2012
Motivation 1
Entwicklungprozesse in der Praxis, Beispiel Facbook:
Our development cycle is extremely fast, and we’ve built
tools to keep it that way. It’s common to write code and
have it running on the live site a few days later. This
comes as a pleasant surprise to engineers who have
worked at other companies where code takes months or
years to see the light of day. If you work with us, you will
be able to make an immediate impact.
(siehe
https://www.facebook.com/careers/teams/engineering,
kopiert am 18.10.2012)
Motivation 2: Die IDE-Konfiguration ist
Entwickler-spezifisch
Zum Beispiel das Eclipse .classpath-file:
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry including="**/*.java" kind="src" output="target/test-classes" path="src/test/java"/>
<classpathentry including="**/*.java|*.properties|*.xml" kind="src" path="src/main/java"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="/Users/axel/Eclipse/ShareIt/lib/antlr-2.7.6.jar"/>
<classpathentry kind="lib" path="/Users/axel/Eclipse/ShareIt/lib/junit-3.8.jar"/>
<classpathentry kind="lib" path="/Users/axel/Eclipse/ShareIt/lib/architecture-rules-2.1.1.jar"/>
<classpathentry kind="lib" path="/Users/axel/Eclipse/ShareIt/lib/asm-1.5.3.jar"/>
</classpath>
Was passiert zum Beispiel, wenn ab sofort Junit Version 4.10
verwendet verden soll?
=⇒Abstraktion erforderlich
Motivation
Frage: welche Schritte sind notwendig, um Software auslieferfertig
zu bauen?
Maven Konzepte
I
Abstrakte Projektbeschreibung durch ein Project Object
Model (POM): pom.xml
I
Convention over Configuration: was nicht explizit vorgegeben
ist, wird nach einer Konvention behandelt.
I
Declarative Execution
I
Build anhand von Life Cycles“
”
Plugin-Mechanismus. Durch Herunterladen von Plugins nach
Bedarf sehr schlanke Basis.
I
I
Verwaltung von Abhängigkeiten (Dependencies) in
Repositories
Die Maven Koordinaten
groupId Bezeichnet die Organisationseinheit (Gruppe,
Abteilung, Firma ...), die für das Projekt
verantwortlich ist
atifactId Bezeichnet ein spezielles Projekt dieser Gruppe
version Die Version des Projekts
packaging Auslieferungsformat (jar, war, ...)
Archetypen
Ein maven-archetyp ist ein Projekt-Prototyp (Vorlage), z.B.
Web-Projekt, Web-Projekt auf Jetty-Basis, J2EE-Projekt ........
(über 600 vordefinierte Archetypen)
Mit mvn archetype:generate alleine zeigt Maven eine Liste aller
verfügbarer Projekt-Archetypen an und ermöglicht eine interaktive
Konfiguration.
Start: Erzeugen eines Projektes
mvn archetype:generate\
-DinteractiveMode=false\
-DgroupId=edu.hm.se2\
-DartifactId=demo\
-DpackageName=edu.hm.cs.se2.demo\
-Dpackage=edu.hm.cs.se2.demo
erzeugt ein simples Stub-Projekt mit folgendem pom:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>edu.hm.se2</groupId>
<artifactId>demo</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>demo</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Build Lifecycles
Maven kennt standardmäßig die drei Build Lifecycles default, clean
und site, bestehend aus jeweils mehreren abhängigen Phasen:
Build Lifecycles
Maven kennt standardmäßig die drei Build Lifecycles default, clean
und site, bestehend aus jeweils mehreren abhängigen Phasen:
validate
initialize
generate-sources
pre-clean
clean
post-clean
pre-site
site
post-site
compile
site-deploy
test
package
install
deploy
Build Lifecycles
Maven kennt standardmäßig die drei Build Lifecycles default, clean
und site, bestehend aus jeweils mehreren abhängigen Phasen:
validate
initialize
generate-sources
pre-clean
clean
post-clean
pre-site
site
post-site
compile
test
package
install
site-deploy
Der Aufruf
mvn <phase>
führt alle Phasen einschließlich der angegebenen aus. Beispiel:
mvn test
Auch kombinierbar:
mvn clean test
deploy
Plugins und Goals
Die Durchführung der Arbeit wird an Goals von Plugins delegiert.
Diese Goals sind auch direkt aufrufbar:
mvn plugin:goal
Beispiel ausführen dss Gompile-goal des Compiler-Plugins:
mvn compiler:compile
mvn help:describe -Dplugin=compiler -Dfull
Direktes Ausführen von Plugins prüft keine Vorbedingungen, wie
bei Verwendung der Phasen.
Deklaration von Abhängigkeiten (Dependencies)
<project>
<groupId>edu.hm.se2</groupId>
<artifactId>demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8</version>
<scope>test</scope>
</dependency>
</dependencies>
Dependencies werden rekursiv aufgelöst.
mvn dependency:resolve
zeigt alle Abhängigkeiten an.
Repositories
Remote: Maven central, oder konfigurierbar
Onsite: Nexus oder Artifactory-Server (für externe Dependencies
als Proxies)
In lokalem Verzeichnis ~/user/.m2/...
Deployment lokal oder onsite möglich.
Maven central
local
3rd-party
on-site
Das Programm make
I
I
Sehr mächtiges Build-Management-Werkzeug
Ursprünglich 1977 für UNIX entwickelt
I
I
Heute verschiedene Varianten, zum Beispiel:
I
I
I
Standard Build-Werkzeug für sehr viele Projekte, auch heute
noch!
nmake (Microsoft)
gmake (GNU make, beispielsweise in Linux)
Kommandozeilenbasiert
I
Typischer Aufruf:
make Programmname
I
Ohne Argument erzeugt make meist das gesamte
Programmpaket
Das Makefile
I
make sucht standardmäßig eine Datei namens Makefile oder
makefile
I
Bei OpenSource-Projekten wird das Makefile mit dem
Quellcode ausgeliefert
Das Makefile enthät die komplette Beschreibung, wie make
die einzelnen Dateien eines Projektes verarbeiten soll:
I
I
I
I
Welche Ergebnisdateien (targets) sollen erzeugt werden?
Beispiel: Eine .class-Datei
Von welchen Ausgansdateien (dependencies) hängen die
jeweiligen targets ab?
Beispiel: Eine oder mehrere .java-Quelldatei(en)
Wie sollen die jeweiligen Ergebnisdatein erzeugt werden
(commands)?
Beispiel: Compilieren der enstprechenden .class-Dateien mit
javac
Eine Regel im Makefile
I
Das Erstellen einer Datei wird durch eine Rule (Regel)
festgelegt:
target [target ...]: [dependency ...]
command
...
I
Beispiel für eine Rule:
editor.class: editor.java
javac -g editor.java
I
Die Regel besagt:
Wenn editor.class (das target) nicht vorhanden ist
oder editor.java (eine dependency) neuer ist als
editor.class,
dann führe den Befehl (command) javac -g editor.java
aus!
I
Achtung: Vor jedem command muss ein Tabulator -Zeichen
stehen!
Makefile für ein kleines Projekt
I
’#’ am Zeilenanfang: Kommentar
I
# Makefile fuer ein kleines Projekt
# JAR-Datei aus zwei Klassen erstellen
project.jar: editor.class utility.class
jar cf project.jar editor.class utility.class
# Java-Quellcode compilieren
editor.class: editor.java
javac -g editor.java
utility.class: utility.java
javac -g utility.java
Variablen im Makefile
I
Variablen werden mit Zuweisungsausdruck definiert und belegt
I
Verwendung einer Variablen mit $(VARIABLE): reine
Textersetzung
I
Beispiel:
# Makefile fuer ein kleines Projekt
JFLAGS = -g
JAVAC = /absoluter/pfad/zu/meiner/version/von/javac
...
editor.class: editor.java
$(JAVAC) $(JFLAGS) editor.java
I
Vorteile: Leichter lesbar und wartbar
Pattern Rules und automatische Variablen
Eine Pattern Rule enthält das %-Zeichen. Eine Regel
%.class : %.java
gibt an, wie ein beliebiges stem.class aus stem.java zu bauen
ist.
$@ Name von target
$< Name der ersten dependency
$? Name aller Dependencies, die aktueller sind als das
Target, mit Leerschritten getrennt
$∗ Der Stamm (engl.: stem) (bei %.ext der Dateiname
ohne Extension)
Beispiel:
%.class: %.java
javac -g $<
ant
I
In Java geschriebenes Werkzeug
I
Besonders für die Entwicklung im Java-Umfeld geeignet
I
XML-basiertes Build-File (build.xml)
I
Viele Built-in Tasks: jar, javac, javadoc, chmod, copy, cvs,
ant, ...
Grundsätzliche Struktur der Build-Files
<project name="myproject" default="dist" basedir=".">
<target name="init">
...
</target>
<target name="compile" depends="init">
...
</target>
<target name="dist" depends="compile,init">
...
</target>
</project>
Eigene ant-Tasks
I
Eigene Tasks erben von org.apache.tools.ant.Task.
I
Implementierung der Methode void execute()
I
Ggf. auch init() redefinieren
I
Übergabe der Build-Parameter über Getter und Setter, deren
Namen zu XML-Attributen passen müssen
<target name="mmix-test" depends="declare" description="bla
<echo message="MMIX assembly:"/>
<mmixal expand="yes" buffer="250" listfile="xxx.mml"/>
</target>
Erfordert setBuffer(...) und setListfile(...)
ant vs. make
ant:
I
Besser lesbar; intuitiver (aber mehr Schreibarbeit).
I
Java-zentriert. Alle Tasks sind in Java geschrieben
I
Abhängigkeiten werden beschrieben in Form von
Arbeitsschritten; z.B. entscheidet die Compile-Task, was zu
übersetzen ist. Bei make angegeben durch Zeitstempel von
Dateien. (Dadurch bei Ant manchmal mehr Doppelarbeit).
make:
I
Eingeschränkt portierbar
I
Beliebige Shell-Kommandos in Tasks integrierbar (Verhalten
ändert sich aber, wenn sich externe Programme ändern)
I
Sehr mächtig; Tendenz zur Unlesbarkeit.
I
Problem, wenn Abhängigkeiten zu beschreiben vergessen
werden.
Eclipse-Integration
I
ant wird von Eclipse direkt unterstützt (Editor, Ausführung
über Kontextmenü, Code-Assist)
I
Die Plugin-Sammlung zur Entwicklung in C/C++ (CDT)
bietet ähnliche Unterstützung für Makefiles

Documents pareils