ant - uptodate task : regenerate only outdated fil

2019-06-01 00:01发布

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?

2条回答
Viruses.
2楼-- · 2019-06-01 00:36

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

查看更多
我想做一个坏孩纸
3楼-- · 2019-06-01 00:52

The problem is that you are testing the property i18n.uptodate before you run the uptodate task. Your condition block must run before you enter the build-languageclasses target.

You should reorganize your code like that:

  • remove the unless="i18n.uptodate" on the main target
  • split the build-languageclasses into 2 target.
  • the first is dedicated to the initialization of your condition and contains the <condition> block only.
  • the second that contains the code to generate you files (<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

<property name="source" value="${basedir}/src"/>
<property name="dist" value="${basedir}/dist"/>

<target name="init">
    <condition property="that.uptodate">
        <uptodate>
            <srcfiles dir="${source}" includes="*.txt"/>
            <mapper type="glob" from="*.txt" to="${dist}/*.bat"/>
        </uptodate>
    </condition>
</target>

<target description="check that" name="dist" unless="that.uptodate" depends="init">
    <echo>we have something to do!</echo>
</target>

HIH M.

查看更多
登录 后发表回答