Powered by SmartDoc

Ant - an excellent java building tool

Sun Nov 30 23:34:10 JST 2003
Toru TAKAHASHI
torutk@alles.or.jp
http://www.alles.or.jp/~torutk/
Antは、元はApacheのJakartaプロジェクトにおいてJavaプログラム構築用に開発されたビルドツールです。現在は、Apache Antプロジェクトと、Jakartaを卒業(?)しております。Antの目的は、UNIXでおなじみのmakeツールの目的に似ていますが、Java向けおよびマルチプラットフォーム対応の点で大きく進歩しています。Antでビルドするための設定ファイルは、XMLで記述するようになっています。

目次

導入編

インストール

入手

Antは、Apacheのサイトから入手できます。バイナリ版とソース版とがリリースされています。ここではまず動かすことを目標にしていますので、バイナリ版を入手することにします。バイナリ版は、Apache AntプロジェクトのWebサイトからダウンロードします。

このページからたどって、jakarta-ant-1.5-4-bin.tar.bz2(または拡張子がzip)というファイルをダウンロードします。また、ここでは説明しませんが、LinuxのRPMパッケージ形式も入手可能です。

展開

入手したファイルをtarまたはzipツールでインストールしたいディレクトリへ展開します。ここでは、/java(d:\java)ディレクトリ下にインストールします。

antの展開(Cygwin)
torutk$ cd /java
java$ tar xjf /tmp/apache-ant-1.5-4-bin.tar.bz2
java$ cd apache-ant-1.5.4
apache-ant-1.5.4$ ls
KEYS     LICENSE.dom  LICENSE.xerces  WHATSNEW  docs/  lib/
LICENSE LICENSE.sax README bin/ etc/ welcome.html
jakarta-ant-1.5.4$

環境設定

antは実行時に次の2つの環境変数を参照します。

Antに必要な環境変数
環境変数名 設定値(Cygwin) 内容
ANT_HOME d:/java/apache-ant-1.5.4 Antをインストールしたディレクトリ
JAVA_HOME d:/java/j2dk1.4.2 JDKをインストールしたディレクトリ

JDKをインストールしたディレクトリを参照するのは、Antが内部でjavacを実行するためです。したがって、javaコンパイラが必要となるので、JDKの場所を設定します。

実行

Antをインストールしたディレクトリの下に、Windows用のant.batコマンドとUNIX用のantシェルスクリプトが提供されています。UNIX用のantシェルスクリプトはCygwinに対応しています。実行する際にフルパスでant(ant.bat)を指定するのは面倒なので、環境変数PATHにant(ant.bat)のあるディレクトリを追加するか、aliasでantにant(ant.bat)をフルパスで指定します。

antをaliasで設定する(例えば.bashrc中)
alias ant='d:/java/jakarta-ant-1.5.4/bin/ant'

では、何も指定しないでantを実行してみましょう。build.xmlファイルが見つからないとエラーメッセージが表示されます。次に、-versionオプションを指定して実行してみます。Antのバージョン番号とバイナリの作成年月日がメッセージ出力されます。

antの実行(Cygwin)
work$ ant
Buildfile: build.xml does not exist!
Build failed
work$ ant -version
Ant version 1.5.4 compiled on August 12 2003
work$

どんなコマンドラインオプションがあるかは、-helpオプションを指定してantを実行します。

antのコマンドオプション一覧
work$ ant -help
ant [options] [target [target2 [target3] ...]]
Options:
  -help                  print this message
  -projecthelp           print project help information
  -version               print the version information and exit
-diagnostics print information that might be helpful to
                         diagnose or report problems.
  -quiet, -q             be extra quiet
  -verbose, -v           be extra verbose
  -debug                 print debugging information
-emacs produce logging information without adornments
  -logfile <file>        use given file for log
    -l     <file>                ''
  -logger <classname>    the class which is to perform logging
-listener <classname> add an instance of class as a project \
    listener
  -buildfile <file>      use given buildfile
    -file    <file>              ''
    -f       <file>              ''
  -D<property>=<value>   use value for given property
  -propertyfile <name>   load all properties from file with -D
                         properties taking precedence
-inputhandler <class> the class which will handle input requests
-find <file> search for buildfile towards the root of the
                         filesystem and use it
work$

超簡単なantによるビルド

実際に、antを用いてJavaプログラムを構築します。antが実行する構築ファイルを記述します。

ビルドするディレクトリ構造
somewhere build.xml
bin
classes
src HelloAnt.java

実際に構築するファイル内容は下記を参照。

build.xml
<?xml version='1.0' encoding='Shift_JIS' ?>
<!--
 Ant - 主にjava向けビルドツール。
 簡単な構築ファイル例
 2003.3.8 by Toru TAKAHASHI

 Ant構築ファイルはprojectを記述します。projectは省略できない3つの
 プロパティ(name, default, basedir)を持ちます。
  name   : プロジェクト名
  default: ant実行時にターゲット名が指定されていない場合に、ここで
          指定したターゲットを実行します。
  basedir: 各設定で指定するパスの起点となるディレクトリ。"."はこの
          設定ファイルがあるディレクトリになります。
	  (antを実行したディレクトリではない点に注意)
 また、projectは複数のtargetから構成されます。
-->

<!--
 project定義。名前は"foo", デフォルト実行ターゲットは"dist",起点は
 この設定ファイルがあるディレクトリ。antがターゲット名を指定されず 
 に起動されたら、target="dist"を実行します。これは次のような構造を
 となるディレクトリ構造を持ちます。
    somewhere
        +------- build.xml
        |
        +------- classes/
        |
        +------- bin/
        |
        +------- src/
-->
<project name="foo" default="dist" basedir=".">
<!--
 このプロジェクト内全体で有効となるプロパティ(変数)を定義。
 プロパティsrcは値srcを持つ。プロパティbuildは値classesを持つ。
 プロパティdistは値binを持つ。
 プロパティは、${プロパティ名}で参照可能。
 -->
  <property name="src" value="src" />
  <property name="build" value="classes" />
  <property name="dist" value="bin" />

<!-- prepareという名前のターゲットを定義。-->
  <target name="prepare">
    <!-- 名前がプロパティbuildの値であるディレクトリを作成する -->
    <mkdir dir="${build}" />
  </target>

<!--
 compileという名前のターゲットを定義。このターゲットは、prepare
 ターゲットに依存している。
-->
  <target name="compile" depends="prepare">
    <!--
      javaコンパイラを実行。プロパティsrcの値にある名前のディレクトリの
      中とそのサブディレクトリを再帰的に探して存在するJavaソースファイル
      をコンパイルする。コンパイルされたバイトコードは、destdirプロパティ
      で指定されたディレクトリ以下に生成される。
      つまりjavacが-dオプション付きで実行される。
    -->
    <javac srcdir="${src}" destdir="${build}" />
  </target>

<!--
  distという名前のターゲットを定義。このターゲットは、compileターゲット
  に依存している。
-->
  <target name="dist" depends="compile">
    <mkdir dir="${dist}/lib" />
    <!--
      jarコマンドを実行する。
        jarfile:生成するjarファイルパス
	basedir:jarfileとjar化するファイルのディレクトリパス
    -->
    <jar jarfile="${dist}/lib/foo.jar"
     basedir="${build}" />
  </target>

<!--
  cleanという名前のターゲットを定義。
-->
  <target name="clean">
    <!--
      deltreeは、属性dirで指定されたディレクトリとその下のファイルと
      ディレクトリを削除する。
    -->
    <delete dir="${build}" />
    <delete dir="${dist}" />
  </target>
</project>

では、この構築ファイルを実行してみましょう。最初は、ソースディレクトリと構築ファイルがあります。antを実行すると、カレントディレクトリにあるbuild.xmlというファイル名のファイルを探し、見つかればこれを読み込んで実行します。build.xmlではデフォルトのターゲットにdistを指定しています。ターゲットdistはターゲットcompileに依存しており、ターゲットcompileはターゲットprepareに依存しています。そこで、prepare→compile→distの順に実行していきます。ターゲットが実行されると、ターゲット中に記述されたタスクが実行されていきます。下記実行例では、ターゲットprepareの中で、[mkdir]タスクが実行され、ターゲットcompileの中で[javac]タスクが実行され、ターゲットdistの中で[mkdir]タスクと[jar]タスクが実行されています。

簡単antによるビルドの実行経過(Cygwin)
ex1$ ls -R .
.:
build.xml  src/

src:
HelloAnt.java
ex1$ ant
Buildfile: build.xml

prepare:
    [mkdir] Created dir: E:\ant\ex1\classes

compile:
    [javac] Compiling 1 source file to E:\ant\ex1\classes

dist:
    [mkdir] Created dir: E:\ant\ex1\bin\lib
      [jar] Building jar: E:\ant\ex1\bin\lib\foo.jar

BUILD SUCCESSFUL

Total time: 4 seconds
ex1$ ls -R .
.:
bin/  build.xml  classes/  src/

bin:
lib/

bin/lib:
foo.jar

classes:
HelloAnt.class

src:
HelloAnt.java

さて、上記のとおり無事成功した後に、同じantを再度実行してみます。

簡単antによるビルドの再実行経過(Cygwin)
ex1$ ant
Buildfile: build.xml

prepare:

compile:

dist:

BUILD SUCCESSFUL

Total time: 0 seconds
ex1$

今度は、それぞれのターゲットが起動されてもタスクが全然実行されていません。これはmakeと同様タスクの生成物が既にあるのでタスクの実行が不要であると判断されたためです。なかなか賢いですね。

さて、慣習ではmakefileに大抵cleanというターゲットを記述して、makeで生成されるファイルやディレクトリを削除するようになっています。antでもcleanというターゲットを記述しているので、実行してみます。

簡単antによるcleanの実行経過(Cygwin)
ex1$ ant clean
Buildfile: build.xml

clean:
   [delete] Deleting directory E:\ant\ex1\classes
   [delete] Deleting directory E:\ant\ex1\bin

BUILD SUCCESSFUL

Total time: 0 seconds
ex1$ 

実践編

コンパイル

javacによるコンパイル

javacを使ったコンパイルには、javacタスクが用意されています。javacのコンパイルオプションとjavacタスクの要素指定の対比を以下の表に示します。

javacコンパイルオプションとjavacタスクの対比
javacオプション javacタスク
-g debuglevel属性
-nowarn nowarn属性
-verbose verbose属性
-deprecation deprecation属性
-classpath classpath属性またはclasspathref属性またはclasspath要素
-sourcepath srcdir属性またはsrc要素
-bootclasspath bootclasspathref属性またはbootclasspath要素
-extdirs extdirs属性またはextdirs要素
-d destdir属性
-encoding encoding属性
-source source属性
-target

実行

javaの実行

antからjavaのクラスを起動することができます。javaの実行にはjavaタスクが用意されています。javaのコマンドオプションとjavaタスクの要素指定の対比を以下の表に示します。

javaコマンドオプションとjavaタスクの対比
javaオプション javaタスク
クラス名(FQCN) classname属性
-jar jarファイル名 jar属性
-cp classpath属性またはclasspathref属性またはclasspath要素
-classpath
-client jvmarg要素
-server
-hotspot
-Dname=value
-verbose[:class|gc|jni]
-version
-showversion
-?
-help
-X
-Xmx maxmemory属性
-ea[:packagename ...|:classname] jvmarg要素
-enableassertions[:packagename ...|:classname]
-da[:packagename ...|:classname]
-disableassesrtions[:packagename ...|:classname]
-esa
-enablesystemassertions
-dsa
-disablesystemassertions

外部コマンドの実行

クラスパス指定

javaタスクやjavacタスクにおいて、クラスパスを指定する方法がいくつかあります。

  1. 属性に指定する
  2. 子要素に指定する

属性に指定する

要素javaや要素javacの属性classpathに指定します。

子要素に指定する

javacタスクでclasspathを子要素に指定
  <javac srcdir="${src}" destdir="${build}">
    <classpath>
      <pathelement path="lib/alpha.jar;lib/beta.jar"/>
      <pathelement location="classes"/>
    </classpath>
  </javac>

Tips編

構築ファイル記述に関するTips