cpptaskでlibのビルド

cygwinbashmingw*1+ant+antcontrib+cpptasks により、static library を作成し、それをリンクしたコンソールアプリをビルドします。

build.xmlの宣言部分

「xmlns:」で使用するant library を取り込み、参照用の名前を付けます。

<?xml version="1.0" encoding="UTF-8"?>
<project name="cppstub" default="build"  basedir="."
    xmlns:cpptasks="antlib:net.sf.antcontrib.cpptasks"
    xmlns:antx="antlib:net.sf.antcontrib">

  <!-- ********************************* -->
  <!-- *            定数               * -->
  <!-- ********************************* -->
  <property name="obj" location="obj"/>
  <property name="dist" location="dist"/>
  <property name="include" location="include"/>
            ........ 以下略

static libraryの作成

「outtype」は、executable、static、shared が指定できます。static library の場合は、当然staticを指定します。「core」を指定すると、「libcore.a」という名前で生成されます・

<cpptasks:cc outtype="static" subsystem="console" 
             outfile="${dist}/core" objdir="${obj}">
  <fileset dir="src" includes="*.cpp,**/*.cpp"/>
</cpptasks:cc>


プロジェクトのビルド

mingwを使っているので、「--enable-auto-import」が必要です。「libset」の順序は重要です。逆にするとシンボル不明というエラーになります。

<cpptasks:cc outtype="executable" subsystem="console" 
             outfile="${dist}/main" objdir="${obj}">
  <includepath> 
    <dirset dir="${include}">
      <include name="**"/>
    </dirset>
  </includepath>
  <fileset dir="src" includes="*.cpp,**/*.cpp"/>
  <linkerarg value="--enable-auto-import"/>
  <libset dir="${basedir}/lib" libs="core"/>
  <libset libs="stdc++, regex"/>
</cpptasks:cc>

プロジェクトのフォルダ構成

ビルドすると次のようなフォルダ構成とファイル配置になります。include/フォルダには、lib/src/ へのシンボリックリンクで *.h を配置し、libcore.a は lib/直下にコピーします*2

project/
 ├ dist/
 │ └ main.exe
 ├ include/
 │ └ core.h    (lib/src へのシンボリックリンク)
 ├ lib/
 │ ├ dist/
 │ │ └ libcore.a
 │ ├ obj/
 │ │ └ core.o
 │ ├ src/
 │ │ ├ core.h
 │ │ └ core.cpp
 │ ├ build.xml
 │ └ libcore.a (dist/ からコピー)
 ├ obj/
 │ └ main.o
 ├ src/
 │ └ main.cpp
 └ build.xml

シンボリックリンク

include/core.h は、lib/src/core.h のシンボリックリンクです。次のように、lib/srcフォルダ内の「*.h」のリンクをincludeフォルダに作成します。antcontribの「for」、「PropertyRegex」を使用して、各ファイルのbasenameを取り出してシンボリックリンクを作成しています。

<antx:for param="file">
  <path>
    <fileset dir="lib/src" includes="*.h"/>
  </path>
  <sequential>
    <antx:propertyregex override="yes"
                        property="fname"  input="@{file}"
			regexp=".*\\(.*\.h)" replace="\1"/>
    <exec executable="ln.exe">
      <arg value="-s"/> 
      <arg value="lib/src/${fname}"/>
      <arg value="include/${fname}"/>
    </exec>
  </sequential>
</antx:for>


補足

antのlocatin、path、dirsetの使い分けやワイルドカードのふさわしさがまだまだ理解不足で詰めが大甘なので、より複雑な利用で干渉することも考えられますが、現状ではとりあえずビルドできているようです。

*1:Qtに含まれるmingwを流用しています

*2:ライブラリの生成時に直接、lib/直下に生成してもかまわないとも思うのですが、現状ではdist/へ生成し、その後コピーという手順にしています。antの処理でoutfileに指定したフォルダにhistory.xmlが生成されます。それをlib/直下に放り出したくないという瑣末な拘りです