ラベル Ant の投稿を表示しています。 すべての投稿を表示
ラベル Ant の投稿を表示しています。 すべての投稿を表示

2013年2月10日日曜日

[Ant]Ant から Makefile を呼び出す

Ant から Makefile を呼び出すのはいささか本末転倒のような気がするが、既に Makefile がある環境などで CruiseControl を使いたい場合などに応用ができるかもしれない。
build.xml に を使用して make を呼び出すようにしておく。
<?xml version="1.0"?>
<project name="hello" basedir="." default="all">
  <target name="clean">
    <exec executable="make">
      <arg value="clean"/>
    </exec>
  </target>
  <target name="compile">
    <exec executable="make">
      <arg value=""/>
    </exec>
  </target>
  <target name="all" depends="clean,compile"/>
</project>

[Ant]CppUnit テスト

以下のような build.xml を準備する
<?xml version="1.0"?>
<project name="CppUnit" basedir="." default="all">
  <taskdef resource="cpptasks.tasks"/>
  <property name="build.dir" value="build"/>
  <property name="dist.dir" value="dist"/>
  <property name="src.dir" value="src"/>
  <target name="init">
    <mkdir dir="${build.dir}"/>
    <mkdir dir="${dist.dir}"/>
  </target>
  <target name="clean">
    <delete dir="${build.dir}"/>
    <mkdir dir="${build.dir}"/>
    <delete dir="${dist.dir}"/>
    <mkdir dir="${dist.dir}"/>
  </target>
  <target name="compile" depends="init">
    <cc outtype="executable"
        subsystem="console"
        outfile="${dist.dir}/test"
        objdir="${build.dir}"
        debug="true">
      <compiler name="g++">
        <fileset dir="${src.dir}" includes="*.cpp"/>
      </compiler>
      <linker name="gcc" libtool="true">
        <libset libs="cppunit,stdc++"/>
      </linker>
    </cc>
  </target>
  <target name="test" depends="compile">
    <exec executable="${dist.dir}/test.exe">
      <arg value=""/>
    </exec>
  </target>
  <target name="all" depends="init,clean,compile"/>
</project>
ant, ant test を実行すると CppUnit のテスト用に作成した test.exe が実行され結果が表示される。
>ant test
Buildfile: build.xml
init:
compile:
[cc] Starting dependency analysis for 3 files.
[cc] 3 files are up to date.
[cc] 0 files to be recompiled from dependency analysis.
[cc] 0 total files to be compiled.
[cc] Starting link
test:
[exec] This is Counter test
[exec] CounterTest::test_init : OK
[exec] CounterTest::test_incr : OK
[exec] CounterTest::test_clear : assertion
[exec] CounterTest.cpp:34:Assertion
[exec] Test name: CounterTest::test_clear
[exec] equality assertion failed
[exec] - Expected: 1
[exec] - Actual : 0
[exec]
[exec] Failures !!!
[exec] Run: 3 Failure total: 1 Failures: 1 Errors: 0
[exec] Result: 1
BUILD SUCCESSFUL
Total time: 0 seconds

[Ant]C コンパイル

  • Windows の cygwin で gcc を使用する場合はパスの問題で cygwin の bash 上ではうまく動作しない。Windows 標準のコマンドプロンプトで gcc を実行する場合は cygwin/bin に gcc-3.exe というファイルがあるので gcc.exe という名前でコピーして gcc を実行できるようにしておく。
  • ANT Build Guide を参考に C++ のコンパイルができるよう Ant-Contrib を入手する。
  • Java SDK がない場合は Java SE Downloads から JDK をダウンロードする。
  • ant を使用するときに \Program Files\ 以下に tools.jar がないと言われる場合は、JDK をインストールしたディレクトリの lib 以下に tools.jar があるのでそれを指定のディレクトリにコピーしておく。
  • ダウンロードした ant-contrib の cpptasks で ant を実行し cpptasks.jar を作成する。cpptasks.jar は cpptasks-x.xx\target\lib に作成される。
  • cpptasks.jar を Ant の lib ディレクトリにコピーする。
  • cpptasks-x.xx\src\samples\hello で ant を実行しコンパイルできることを確認する。
  • ソースを作成するディレクトリ以下に src ディレクトリを作る。今回は ant_test というディレクトリで作成する。
    ant_test
        +--- src/
        |     +-- hello.c
              +--- build.xml
    
    Example: hello.c
    #include <stdio.h>
    int main(void)
    {
      printf("Hello, world\n");
      return 0;
    }
    
    Example: build.xml
    <?xml version="1.0"?>
    <project name="HelloWorld" basedir="." default="all">
      <taskdef resource="cpptasks.tasks"/>
      <property name="build.dir" value="build"/>
      <property name="dist.dir" value="dist"/>
      <property name="src.dir" value="src"/>
      <target name="init">
        <mkdir dir="${build.dir}"/>
        <mkdir dir="${dist.dir}"/>
      </target>
      <target name="clean">
        <delete dir="${build.dir}"/>
        <mkdir dir="${build.dir}"/>
        <delete dir="${dist.dir}"/>
        <mkdir dir="${dist.dir}"/>
      </target>
      <target name="compile" depends="init">
        <cc outtype="executable" subsystem="console" outfile="${dist.dir}/hello" objdir="${build.dir}">
          <fileset dir="${src.dir}" includes="*.c"/>
        </cc>
      </target>
      <target name="all" depends="init,clean,compile"/>
    </project>
    
  • コンパイラに cc を指定できるように次のように記述しておくことを忘れないようにする。
    <taskdef resource="cpptasks.tasks"/>
    
  • コンパイルは ant を実行すれば default で指定されている all が実行され、init, clean, compile が実行される。
  • dist, build などのディレクトリを作成しない場合は以下のように build.xml を記述できる。
    <?xml version="1.0"?>
    <project name="authAdminServiceStart" basedir="." default="all">
      <taskdef resource="cpptasks.tasks"/>
      <property name="obj.dir" value="."/>
      <property name="src.dir" value="."/>
      <target name="init">
      </target>
      <target name="clean">
        <delete>
          <fileset dir="." includes="*.o,*.exe"/>
        </delete>
      </target>
      <target name="compile" depends="init">
        <cc outtype="executable" subsystem="console" outfile="test" objdir="${obj.dir}">
          <fileset dir="${src.dir}" includes="*.cpp"/>
        </cc>
      </target>
      <target name="all" depends="init,compile"/>
    </project>
    

[Ant]Property

一度設定した property は上書きすることはできない
-v を付けて実行すると
Override ignored for property "HOGEHOGE"
と表示される

[Ant]SFTP

SFTP を使えるようにする
  1. JCraft から jsch-0.1.46.jar をダウンロードする
  2. ダウンロードしたファイルを ant インストールディレクトリにある lib に置く
  3. build.xml に以下を記載
    <target name="sftp-put">
      <scp todir="${FTPUSERID}:${FTPPASSWORD}@${FTPSERVER}:${FTPREMOTEDIRROOT}"
           file="test.txt"
           trust="true">
      </scp>
    </target>
    
  4. file 指定の代わりに fileset を使うことも可能
    <target name="sftp-put">
      <scp todir="${FTPUSERID}:${FTPPASSWORD}@${FTPSERVER}:${FTPREMOTEDIRROOT}"
           trust="true">
        <fileset dir=".">
          <include name="*.txt"/>
        </fileset>
      </scp>
    </target>
    

[Ant]build.xml 内で & 記号が使いたい

build.xml に上記の FTP 設定を書いている時にパスワードに & が使われていた
& は XML 記述内では予約語となっているので、そのまま書いたのでは build.xml を読み込ませたときにエラーが発生する
BUILD FAILED
home\build.xml:101: The entity name must immediately follow the '&' in the entity reference.
これは & を & と記述することで回避できる。
  • エラー
    password="pass&word"
    
  • OK
    password="pass&word"
    

[Ant]FTP

Fedora でのインストール方法
# yum install ant-commons-net
Windowsでのインストール方法
  1. FTP を使えるようにするため Apache Commons から Comons Net をインストールする
  2. 展開したファイルにある commons-net-3.1.jar を apache-ant をインストールしたディレクトリの lib に置く
  3. Windows Firewall が有効になっているので以下のように IO error が出る
    ftp-put:
    [ftp] sending files
    [ftp] try #1: IO error (index.html), number of maximum retries reached (0), giving up
    
動作確認
  1. build.xml に以下を記述して動作確認
    <target name="ftp">
      <ftp server="server 名"
           userid="ユーザ名"
           password="パスワード"
           action="list"
           listing="./ftplist.txt"
           remotedir="/">
        <fileset>
          <include name="*" />
        </fileset>
      </ftp>
    </target>
    
  2. build.xml を実行したディレクトリに ftplist.txt が作成される。中には以下のようなファイルリストが入っている
    -rw-r--r-- 1 11111 11111 4877 Aug 06 08:29 index.html
    
  3. サーバにファイルをアップロードする場合 (put)
    <target name="ftp-put">
      <ftp server="${FTPSERVER}"
           userid="${FTPUSERID}"
           password="${FTPPASSWORD}"
           action="put"
           remotedir="/">
        <fileset dir=".">
          <include name="*.html" />
        </fileset>
      </ftp>
    </target>
    

[Ant]Copy

ファイルを指定のディレクトリにコピーする
<copy file="test.txt" todir="${BUILD}"/>
実行結果
[copy] Copying 1 file to /home/username/build

[Ant]Ant が実行しているコマンドを確認する

ant を実行する時に -verbose オプションを付加することで実行しているコマンドを確認することができる。
>ant -verbose
Apache Ant version 1.7.1 compiled on June 27 2008
Buildfile: build.xml
Detected Java version: 1.6 in: C:\Program Files\Java\jdk1.6.0_13\jre
Detected OS: Windows XP
parsing buildfile C:\home\Ant_CppUnit\build.xml with URI = file:/C:/home/Ant_CppUnit/build.xml
Project base dir set to: C:\home\Ant_CppUnit
[antlib:org.apache.tools.ant] Could not load definitions from resource org/apache/tools/ant/antlib.xml. It could not be found.
Build sequence for target(s) `all' is [init, clean, compile, all]
Complete build sequence is [init, clean, compile, all, compileonly, linkonly, test, ]
init:
[mkdir] Skipping C:\home\Ant_CppUnit\build because it already exists.
[mkdir] Skipping C:\home\Ant_CppUnit\dist because it already exists.
clean:
[delete] Deleting directory C:\home\Ant_CppUnit\build
[delete] Deleting C:\home\Ant_CppUnit\build\Counter.o
[delete] Deleting C:\home\Ant_CppUnit\build\CounterTest.o
[Delete] Deleting C:\home\Ant_CppUnit\build\history.xml
[delete] Deleting C:\home\Ant_CppUnit\build\test.o
[delete] Deleting directory C:\home\Ant_CppUnit\build
[mkdir] Created dir: C:\home\Ant_CppUnit\build
[delete] Deleting directory C:\home\Ant_CppUnit\dist
[delete] Deleting C:\home\Ant_CppUnit\dist\history.xml
[delete] Deleting directory C:\home\Ant_CppUnit\dist
[mkdir] Created dir: C:\home\Ant_CppUnit\dist
compile:
[cc] 3 total files to be compiled.
[cc] g++ -c -g C:\home\Ant_CppUnit\src\test.cpp C:\home\Ant_CppUnit\src\CounterTest.cpp C:\home\Ant_CppUnit\src\Counter.cpp
[cc] Starting link
[cc] gcc -g -o test ..\build\test.o ..\build\CounterTest.o ..\build\Counter.o
C++ のソースを Ant でコンパイルを行おうとしていてもリンクエラーが発生することがある。その場合に -verbose オプションを付けて実行すると最後の行で gcc によりリンクを行おうとしていることが確認できる。
これにより手元の cygwin 環境には libstdc++ がインストールされていないことが判明したので、libstdc++ をインストール。
build.xml の該当箇所を以下のように修正し再度実行したところ無事にコンパイル・リンクを行うことができた。
<target name="compile" depends="init">
  <cc outtype="executable"
      subsystem="console"
      outfile="${dist.dir}/test"
      objdir="${build.dir}"
      debug="true">
    <compiler name="g++">
      <fileset dir="${src.dir}" includes="*.cpp"/>
    </compiler>
    <linker name="gcc" libtool="true">
      <libset libs="cppunit,stdc++"/>
    </linker>
  </cc>
</target>

[Ant]Link 時に auto-import のエラーが出る

Ant に限った話ではないが Cygwin の gcc でコンパイル・リンクする時に以下のような auto-import に関する Warning が表示される時がある。
 [cc] Starting link
 [cc] /usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/ld:
 warning: auto-importing has been activated without --enable-auto-import specifi
ed on the command line.
 [cc] This should work unless it involves constant data structures referen
cing symbols from auto-imported DLLs.Info: resolving vtable for CppUnit::TestSui
teBuilderContextBaseby linking to __imp___ZTVN7CppUnit27TestSuiteBuilderContextB
aseE (auto-import)
この場合は Linker オプションに --enable-auto-import を渡してやればよい。Ant を使用している場合に Linker にオプション (引数) を付ける方法は以下の通り。
<target name="build" depends="init">
  <cc outtype="executable"
      subsystem="console"
      outfile="${dist.dir}/test"
      objdir="${build.dir}"
      debug="true">
    <compiler name="g++">
      <fileset dir="${src.dir}"
               includes="main.cpp,Counter.cpp,CounterTest.cpp"/>
    </compiler>
    <linker name="gcc" libtool="true">
    <libset libs="cppunit,stdc++"/>
      <linkerarg value="--enable-auto-import"/>
    </linker>
  </cc>
</target>
ant に -verbose オプションを付けて Linker に渡された引数を確認してみると --enable-auto-import が付いていることがわかる。
[cc] Starting link
[cc] gcc -Wl,--enable-auto-import -g -o test ..\build\main.o ..\build\CounterTest.o ..\build\Counter.o -lcppunit -lstdc++

[Ant]サブディレクトリを指定する

以下のように build.xml を配置してあるサブディレクトリを指定する
inheritAll に false を設定しておかないとベースの build.xml で定義した property や basedir がそのまま引き継がれてしまう
<project name="hoge" default="all">
  <target name="build">
(略)
    <ant dir="sub" inheritAll="false"/>
  </target>
  <target name="clean">
    <delete dir="${BUILD}"/>
    <ant dir="sub" inheritAll="false" target="clean"/>
  </target>
</project>

[Ant]XSLT

Example: build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="test01" default="xslt" basedir=".">
  <description>Simple example build file</description>
  <property name="BUILD" location="build"/>
  <property name="SRC" location="src"/>
  <property name="DOCBOOK_PUBLIC_ID" value="-//OASIS//DTD DocBook XML V4.5//EN"/>
  <property name="DOCBOOK_DTD" value="/usr/share/sgml/docbook/xml-dtd-4.5/docbookx.dtd"/>
  <target name="init" description="initialize">
    <tstamp/>
    <mkdir dir="${BUILD}"/>
  </target>
  <target name="xslt" depends="init">
    <xslt basedir="${SRC}" destdir="${BUILD}" extension=".html" style="${SRC}/test.xsl">
      <xmlcatalog>
        <dtd publicId="${DOCBOOK_PUBLIC_ID}" location="${DOCBOOK_DTD}"/>
      </xmlcatalog>
    </xslt>
  </target>
  <target name="clean" description="clean up">
    <delete dir="${BUILD}"/>
  </target>
</project>
これを実行すると ClassNotFoundException でエラーとなる
$ ant
Buildfile: build.xml
init:
xslt:
[xslt] java.lang.ClassNotFoundException: org.apache.tools.ant.taskdefs.optional.TraXLiaison

追加インストール
# yum install ant-trax
これで実行可能となる
$ ant
Buildfile: build.xml
init:
xslt:
[xslt] Transforming into /home/username/test01/build
[xslt] Processing /home/username/test01/src/test.xml to /home/username/test01/build/test.html
[xslt] Loading stylesheet /home/username/test01/src/test.xsl
BUILD SUCCESSFUL
Total time: 0 seconds
SAXON を使った build.xml の作成手順は SAXSON を参照

[Ant]動作確認

Example: build.xml
<project name="test00" default="dist" basedir=".">
  <description>Simple example build file</description>
  <property name="build" location="build"/>
  <target name="init" description="initialize">
    <tstamp/>
    <mkdir dir="${build}"/>
  </target>
  <target name="dist" depends="init">
  </target>
  <target name="clean" description="clean up">
    <delete dir="${build}"/>
  </target>
</project>
この build.xml を実行すると build ディレクトリが作成される

実行結果
$ ant
Buildfile: build.xml
init:
[mkdir] Created dir: /home/username/test00/build
dist:
BUILD SUCCESSFUL
Total time: 0 seconds
$ ls
build build.xml

[Ant]インストール

Linux
yum install ant
Windows
  1. The Apache Ant Project から apache-ant-1.8.2-bin.zip をダウンロードする
  2. Java SE から jdk-7u3-windows-i586.exe をダウンロードする
  3. Unable to locate tools.jar が出るので下記を環境変数に追加
    set JAVA_HOME=C:\Program Files\Java\jdk1.7.0_03
    
  4. Apache FOP のダウンロード
    Apache FOP からfop-1.0-bin.zip をダウンロードする