I'm new to ant and rather used to Makefiles. In a project, the i18n language modules named Message_zh.class etc are built unconditionally from zh.po etc with every compile, although they already exist, which wastes much time. I figured these are the relevant parts of build.xml:
<target id="msgfmt" name="msgfmt">
<mkdir dir="po/classes" />
<propertyregex property="filename"
input="${file}"
regexp="[.]*/po/([^\.]*)\.po"
select="\1"
casesensitive="false" />
<exec dir="." executable="msgfmt">
<arg line="--java2 -d po/classes -r app.i18n.Messages -l ${filename} po/${filename}.po"/>
</exec>
</target>
<target id="build-languageclasses" name="build-languageclasses" >
<echo message="Compiling po files." />
<foreach target="msgfmt" param="file">
<path>
<fileset dir="po" casesensitive="yes">
<include name="**/*.po"/>
</fileset>
</path>
</foreach>
</target>
The target build-languageclasses is depended on in the compile target and so, every compile, the whole bunch is msgfmted again. How should this be written to invoke msgfmt only if 1. the po file was changed, or 2. the class file doesn't exist? I would be glad if this would be possible without further software. Can you help or point me to an example?
A first attempt at solution makes no difference in ant's behaviour:
<target id="build-languageclasses" description="compile if Messages??.class files not uptodate" name="build-languageclasses" unless="i18n.uptodate">
<condition property="i18n.uptodate">
<uptodate>
<srcfiles dir="${po}" includes="**/*.po"/>
<mapper type="glob" from="${po}/*.po" to="${po}/classes/app/i18n/Messages*.class"/>
</uptodate>
</condition>
<echo message="Compiling po files." />
<foreach target="msgfmt" param="file">
<path>
<fileset dir="po" casesensitive="yes">
<include name="**/*.po"/>
</fileset>
</path>
</foreach>
</target>
What's wrong here?
Try to use ant-contrib - OutOfDate - if you want the structure like in second source in first mail http://ant-contrib.sourceforge.net/tasks/tasks/outofdate.html
The problem is that you are testing the property
i18n.uptodate
before you run theuptodate
task. Your condition block must run before you enter thebuild-languageclasses
target.You should reorganize your code like that:
unless="i18n.uptodate"
on the main targetbuild-languageclasses
into 2 target.<condition>
block only.<foreach>
)The second target is configured to run conditionally depending on the property
i18n.uptodate
set by the first target.EDIT - Here is a working example of the uptodate task
HIH M.