The Artima Developer Community
Sponsored Link

Agile Buzz Forum
TouchFile

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Martin Fowler

Posts: 1573
Nickname: mfowler
Registered: Nov, 2002

Martin Fowler is an author and loud mouth on software development
TouchFile Posted: Apr 26, 2007 2:45 PM
Reply to this message Reply

This post originated from an RSS feed registered with Agile Buzz by Martin Fowler.
Original Post: TouchFile
Feed Title: Martin Fowler's Bliki
Feed URL: http://martinfowler.com/feed.atom
Feed Description: A cross between a blog and wiki of my partly-formed ideas on software development
Latest Agile Buzz Posts
Latest Agile Buzz Posts by Martin Fowler
Latest Posts From Martin Fowler's Bliki

Advertisement
TouchFile design 26 April 2007

When doing builds using make, you determine whether you need to do work by comparing the modificiaton dates of the output file and the input files. For things like compiling (a.out depends of foo.c) this works well, but sometimes the output is harder to see.

One example is running of tests - what's the output there? One output is a test report. The target for the test report can then compare the dates of the report file with the dates for the executable and any test data files. That way we ensure we only run tests when something has changed.

Most of the time the output files contain useful information. But for the purpose of determining whether a target needs to be run, you actually don't care about the contents of the output file, only its date. As a result a common idiom in make scripts is an empty file that's only used as a time marker. I call this a "touch file" because it's usually only manipulated by the unix touch command, which just updates the modification time of a file.

Touch files are often useful when you are trying to compare dates over a range of files. If your output is a whole tree of files, it can quicker to update a touch file than it is to navigate through the whole tree looking at update times.

Touch files are a common and natural idiom for make, however they are less common for ant. They are, however, still often useful. This struck me particularly in the last few days as I was examining how hibernate's HQL DomainSpecificLanguage is implemented. At the heart of HQL is a trio of Antlr parsers, whose grammar is defined by three grammar files. If any of these grammar files changes, the parser source code needs to be regnerated.

Here's the ant source for this:

<target name="init.antlr" depends="init" description="Check ANTLR dependencies.">
  <uptodate property="antlr.isUpToDate" targetfile="${dir.out.antlr-package}/.antlr_run">
    <srcfiles dir="${dir.grammar}" includes="*.g"/>
  </uptodate>
</target>

<target name="antlr" depends="init.antlr" unless="antlr.isUpToDate" description="Generate ANTLR parsers.">
  <taskdef name="antlrtask" classname="org.apache.tools.ant.taskdefs.optional.ANTLR">
    <classpath>
      <fileset dir="${dir.lib}">
        <include name="ant-antlr-*.jar"/>
        <include name="antlr-*.jar"/>
      </fileset>
    </classpath>
  </taskdef>
  <mkdir dir="${dir.out.antlr-package}" />
  <antlrtask target="${dir.grammar}/hql.g" outputdirectory="${dir.out.antlr-package}" />
  <antlrtask target="${dir.grammar}/hql-sql.g" outputdirectory="${dir.out.antlr-package}" />
  <antlrtask target="${dir.grammar}/sql-gen.g" outputdirectory="${dir.out.antlr-package}" />
  <touch file="${dir.out.antlr-package}/.antlr_run"/>
</target>

Note that the init.antlr task sets the antlr.isUpToDate property based on a specific .antlr_run file. The main antlr task doesn't run if this property is true. At the end of the antlr task, it touches the .antlr.run file, which is empty.

Within the main build for hibernate, this is the task that's used. As a result the parser source files are only generated if needed. If you really want to force a regeneration of the files, there's a separate target:

<target name="antlr.regen" depends="init,cleanantlr,antlr" description="Regenerate all ANTLR generated code." />

<target name="cleanantlr" depends="init" description="Clean up the generated ANTLR parsers.">
  <delete dir="${dir.out.antlr-package}"/>
</target>

Note that this target achieves its aim by stating a dependency on the cleanAntlr task. It doesn't indicate a dependency on init.antlr as that dependency is already in the antlr task.


Read: TouchFile

Topic: Smalltalk Daily 4/24/07: Moving to a New Release Previous Topic   Next Topic Topic: Windows Home Server CTP

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use