Laboratorium 2 - Apache Ant
Wstęp
- Narzędzie Ant, podobnie jak make
służy do zarządzania
kompilacją projektów składających się z wielu plików
źródłowych.
Głównym zastosowaniem Anta jest kompilacja projektów pisanych
w języku Java. Dzięki temu, że sam Ant jest napisany w Javie,
jest niezależny od systemu operacyjnego (działa tak samo pod Windows, jak i pod Liuxem)
i można go zastosować do innych celów (np. kompilacja dokumentów Latex).
- Aby używać Anta należy napisać skrypt o nazwie
build.xml, będący odpowiednikiem makefile.
Dzięki użyciu XML, skrypty Anta mogą być w łatwy sposób integrowane z
narzędziami dewloperskimi, takimi jak Eclipse. Plik build.xml
zawiera:
- cele (target) które są do zrealizowania i zależności między nimi
- sposób realizacji celów: zadania (task).
Przy pomocy polecenia ant kompilujemy
projekt. Jako argument możemy podać cel, na przykład ant clean.
Jeżeli nie podamy argumentów, wówczas będzie realizowany cel domyślny.
Budowa skryptu build.xml
-
Plik build.xml składa się z jednego projektu (project) i co najmniej
jednego (domyślnego) celu (target).
Cel zawiera elementy opisujące zadania (target). Przykładowy projekt
ma wygląd:
<project name="HelloProject" default="dist" basedir=".">
<description>
This is a description of a project.
</description>
Atrybut name określa nazwę projektu, default domyślny cel,
basedir katalog roboczy projektu, a description opcjonalny opis.
-
Cel może zależeć od innych celów, określonych przez atrybut depends.
<target name="A"/>
<target name="B" depends="A"/>
<target name="C" depends="B,A"/>
Jeżeli cel ma więcej zależności (oddzielonych przecinkami), wówczas w pierwszej kolejności
jest wykonywany cel pierwszy od lewej. Uwaga: w pierwszej kolejności muszą być spełnione
zależności tych celów. W powyższym przykładzie, jeżeli będziemy chcieli wykonać cel C, wówczas najpierw
zostanie wykonany cel A, następnie B, a na końcu C, ponieważ C zależy od B, a B zależy od A.
Każdy cel jest wykonywany tylko raz.
-
Zadanie (task) jest kodem, który można wykonać. Każdy task ma strukturę:
<nazwa atrybut1="wartość1" atrybut2="wartość2" ... />
Ant posiada bogaty zestaw wbudowanych zadań, służących do wykonywania takich czynności jak kompilacja,
operacje na plikach, tworzenie archiwów JAR, uruchamianie programów, korzystanie z CVS, a także do sterowania wykonaniem skryptów Anta (np. zadania warunkowe). Istnieją również zadania opcjonalne, a także można tworzyć własne definicje zadań (w języku Java).
-
Każdy element może mieć zdefiniowany identyfikator przez użycie atrybutu
id. Potem możemy odwołać się do tego elementu używając atrybutu
refid w elemencie tego samego typu.
Przykładowo, następujący projekt:
<project ... >
<target ... >
<rmic ...>
<classpath>
<pathelement location="lib/"/>
<pathelement path="${java.class.path}/"/>
<pathelement path="${additional.path}"/>
</classpath>
</rmic>
</target>
<target ... >
<javac ...>
<classpath>
<pathelement location="lib/"/>
<pathelement path="${java.class.path}/"/>
<pathelement path="${additional.path}"/>
</classpath>
</javac>
</target>
</project>
Może byc przepisany jako:
<project ... >
<path id="project.class.path">
<pathelement location="lib/"/>
<pathelement path="${java.class.path}/"/>
<pathelement path="${additional.path}"/>
</path>
<target ... >
<rmic ...>
<classpath refid="project.class.path"/>
</rmic>
</target>
<target ... >
<javac ...>
<classpath refid="project.class.path"/>
</javac>
</target>
</project>
Zmienne w skrypcie Anta
- W pliku build.xml można definiować zmienne, przy pomocy zadania property tak jak
w poniższym przykładzie:
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="dist" location="dist"/>
Ant posiada wbudowane zmienne, takie jak basedir, ant.version,
ant.file, ant.project.name, ant.java.version.
-
Do zmiennych odwołujemy się używając znaku dolara i nawiasów klamrowych, tak jak w poniższym
celu używamy zmiennej build:
<target name="init">
<!-- Utworzenie katalogu build w którym będą umieszczane skompilowane pliki. -->
<mkdir dir="${build}"/>
</target>
Najważniejsze zadania Anta
- Zadania operujące na systemie plików:
<mkdir dir="nowy_katalog"/>
<copy file="myfile.txt" tofile="mycopy.txt"/>
<copy file="myfile.txt" todir="../some/other/dir"/>
<delete dir="katalog"/>
- Kompilacja plików języka Java
<javac srcdir="${src}" destdir="${build}"/>
Zadanie javac wyszukuje i kompiluje wszystkie pliki *.java w podanym katalogu i podkatalogach.
Javac kompiluje tylko te pliki, które zostały zmodyfikowane po ich ostatniej kompilacji.
-
Tworzenie archiwum JAR
<jar jarfile="${dist}/lib/HelloProject.jar" basedir="${build}"/>
-
Tworzenie dokumentacji przy pomocy Javadoc
<javadoc
destdir="docs/api"
windowtitle="Test API">
<fileset dir="src" defaultexcludes="yes">
<include name="pl/edu/agh/**"/>
</fileset>
</javadoc>
Uwaga: Javadoc nie sprawdza, czy pliki źródłowe były zmodyfikowane, tylko generuje całą dokumentację od początku.
- Uruchomienie aplikacji Javy. Należy podać klasę zawierającą metodę Main().
<java classname="hello.client.Main">
<classpath>
<pathelement location="dist/lib/hello.jar"/>
<pathelement path="${java.class.path}"/>
</classpath>
</java>
Typy
Ant posiada bogaty zestaw wbudowanych typów, ułatwiających wykonywanie zadań na zbiorach plików,
dopasowanie wzorców, korzystanie z wyrażeń regularnych itp. Poniżej zamieszczone są przykłady najczęściej używanych:
-
Zbiory plików:
<fileset dir="${server.src}" casesensitive="yes">
<include name="**/*.java"/>
<exclude name="**/*Test*"/>
</fileset>
-
Zbiory wzorców są bardziej ogólne:
<patternset id="non.test.sources">
<include name="**/*.java"/>
<exclude name="**/*Test*"/>
</patternset>
można się do nich następnie odwoływać przez nazwę:
<fileset dir="${client.src}" >
<patternset refid="non.test.sources"/>
</fileset>
-
UWAGA: We wzorcach nazw plików można używać symbolu podwójnej gwiazdki
(**), co oznacza wszystkie katalogi i ich podkatalogi (rekursywnie
wgłąb) spełniające wzorzec. Na przykład: do wzorca: **/srv/** pasują
wszystkie pliki, w których ścieżce występuje element srv; do wzorca
hello/**/*.java pasują wszystkie pliki o rozszerzeniu .java w
katalogu hello i w całym poddrzewie jego podkatalogów.
- Większość zadań korzysta z domyślnych wzorców nazw plików, na których
operuje. Np. javac zamienia pliki .java na pliki
.class w podanym drzewie katalogów.
Ćwiczenie
-
Proszę pobrać przykładowy projekt hello.tar.gz, rozpakować go, a następnie
skompilować załączonym do niego skryptem build.xml.
- Uwaga:
-
Proszę rozbudować skrypt o następujące cele:
- javadoc - generujący dokumentację
- rebuild - kompilujący wszystkie pliki od nowa
- tworzenie osobnych plików JAR dla pakietów hello.srv i hello.client
- rebuild.dist - tworzenie całej dystrybucji od początku
- run - uruchomienie aplikacji hello
- opcjonalnie: pobranie źródeł z CVS.
Informacje dodatkowe
-
Szczegółowe informacje zawarte są na stronie projektu Ant:
ant.apache.org.
-
Jeżeli Ant nie jest zainstalowany, można go łatwo zainstalować samodzielnie.
Wystarczy pobrać binarną dystrybucję, rozpakować ją, a następnie
ustawić zmienną środowiskową ANT_HOME aby wskazywała ścieżkę do tej
dystrybucji, oraz do zmiennej PATH dołączyć ANT_HOME/bin. Mozna
to zrobic w katalogu /tmp, zeby uniknac rozpakowywania przez
sieciowy system plikow, np.:
mkdir /tmp/$USER
cd /tmp/$USER
wget http://apache.forall.pl/ant/binaries/apache-ant-1.7.0-bin.tar.gz
tar zxvf apache-ant-1.7.0-bin.tar.gz
export ANT_HOME=/tmp/$USER/apache-ant-1.7.0
export PATH=$ANT_HOME/bin:$PATH
Bartosz Baliś, balis at agh.edu.pl
Maciej Malawski, malawski at agh.edu.pl
|