There is a pretty easy way around your problem if you are willing to create
more targets in your build, use a custom task, and use the "if" attribute
of the target.

Try something like the following:

<target name="compile_src"
depends="check_idl2java,do_idl2java,do_java_compile">
� <!-- dummy target used to control the order of execution -->
</target>

<target name="check_idl2java">
� <available file="some_well_known_file" property="found.generated"/>
� <ifnotdef property="found.generated" set="couldnt.find.generated"/>
</target>

<target name="do_idl2java" if="couldnt.find.generated"
depends="check_idl2java">
� <!-- do your idl to java compilation --->
</target>

<target name="do_java_compile" depends="do_idl2java">
� <!-- yadda yadda yadda -->
</target>

The ifnotdef task simply checks at execute and init time if the property
specified by the "property" attribute exists. �If it does, it sets the
property specified by the "set" attribute to "true", or to a specified
value if there is an = in the text. �There is also an "unset" attribute you
can use to remove a property. �I have a corresponding ifdef task that does
the logical opposite.

Here's the code for the ifnotdef task. �I've moved it from our
com.ibm.id.tools.ant.taskdefs package to the
org.apache.tools.ant.taskdefs.optional to make incorporating it a little
easier for you. �Sorry for the poor indenting, but VisualAge for Java
doesn't do the best job of exporting code from its repository to a file.
:-(

--- START FILE ---
package org.apache.tools.ant.taskdefs.optional;

import org.apache.tools.ant.*;
import org.apache.tools.ant.taskdefs.*;

/**
�* The IfNotDef taks is used to set and unset/remove properties at runtime.
�*
�* Creation date: (3/14/00 10:42:24 PM)
�* @author: Glenn McAllister
�*/
public class IfNotDef extends Task {
� � � � private java.lang.String set = null;
� � � � private java.lang.String prop = null;
� � � � private java.lang.String unSet = null;
/**
�* The execute method is used rather than init to ensure that the setting
and
�* unsetting of properties happens at runtime, rather than at "compile"
time.
�*
�* Creation date: (3/14/00 10:48:30 PM)
�* @exception org.apache.tools.ant.BuildException The standard build
exception wrapper.
�*/
public void execute() throws org.apache.tools.ant.BuildException {
� � � � if (prop == null) {
� � � � � � � � throw new BuildException("The property to test must have a
value!");
� � � � }

� � � � if(project.getProperty(prop) == null) {
� � � � � � � � if (set != null) {
� � � � � � � � � � � � setProperty();
� � � � � � � � }

� � � � � � � � if (unSet != null) {
� � � � � � � � � � � � project.log("Removing property " +
unSet,"IfNotDef",project.MSG_VERBOSE);
� � � � � � � � � � � � project.getProperties().remove(unSet);
� � � � � � � � }
� � � � } // if
}
/**
�* Set the name of the project property to test the existance of.
�*
�* Creation date: (3/14/00 10:46:09 PM)
�* @param newProp java.lang.String
�*/
public void setProp(java.lang.String newProp) {
� � � � prop = newProp;
}
/**
�* If the property exists, set the value to true, or to a specific value if
the
�* "set" attribute has an equals sign in it.
�* <p>
�* For example,<br>
�* <code>
�* <IfNotDef prop="some.property"
set="i.want.to.set.this.to=some_nifty_value" />
�* </code><br>
�* will set the property i.want.to.set.this.to to the string
some_nifty_value.
�* </p>
�*
�* Creation date: (3/15/00 7:52:17 PM)
�* @param set java.lang.String
�*/
protected void setProperty() {
� � � � // check to see if the property is to be set to a specific value.
� � � � int pos;
� � � � String prop_to_set = null;
� � � � String value = null;

� � � � if ((pos = set.indexOf("=")) > 0) {
� � � � � � � � prop_to_set = set.substring(0,pos-1);
� � � � � � � � value = set.substring(pos+1);
� � � � } else {
� � � � � � � � prop_to_set = set;
� � � � � � � � value = "true";
� � � � }
� � � � project.setProperty(prop_to_set, value);
}
/**
�* The name of the property to set to "true", or to a specific value.
�* <p>
�* For example,<br>
�* <code>
�* <IfNotDef prop="some.property"
set="i.want.to.set.this.to=some_nifty_value" />
�* </code><br>
�* will set the property i.want.to.set.this.to to the string
some_nifty_value.
�* </p>
�*
�* Creation date: (3/14/00 10:43:35 PM)
�* @param newSet java.lang.String
�*/
public void setSet(java.lang.String newSet) {
� � � � set = newSet;
}
/**
�* The name of the property to remove from the project property set.
�*
�* Creation date: (3/14/00 10:46:38 PM)
�* @param newUnSet java.lang.String
�*/
public void setUnset(java.lang.String newUnSet) {
� � � � unSet = newUnSet;
}
}
--- END FILE ---

Glenn McAllister
TID - Software Developer - VisualAge for Java
IBM Toronto Lab, (416) 448-3805
"An approximate answer to the right question is better than the
right answer to the wrong question." - John W. Tukey

Conor MacNeill wrote:

>
> Conditional execution of tasks is a topic of considerable debate on the
ant
> list. Many people have a strong desire to avoid creating within ant a new
> programming language.
>
> Conor

I agree 100%. And, I'm new to this arena, so
I'm not up to speed on what's been proposed, debated,
etc.

I'm trying to move from an Imakefile / Makefile
universe, and that stuff is a MESS. Full of fragments of
shell script, etc, etc. I have been able to do 95% of what
those Imakefiles did without anything special, and the build
xml file is more more readable.

But, there's the remaining 5%. And that 5% are the tasks
that have some conditional processing. If the build
universe were perfect, we could live without it. But,
I've never encountered a perfect world yet.

When I read about the "available" task,
it made sense that I could set a property to check
to see if something is available. But, if there isn't any
facility to use those properties to conditionally
perform some other task, then what's the point?

For example, we use CORBA. Before the java sources can
be compiled, we need to run a program that does idl to java
processing, creating additional java sources to be compiled.

If I make the compile target depend on the idl2java target,
then every time I compile, the idl2java processing occurs
and the generated java files' time stamps change, so now
ant thinks there are a bunch of files that need to be
recompiled. But the content of those generated files
really didn't change, so there is no reason to
re-compile. If I could set and TEST a property to see if one
of the generated files was present, I could suppress
the idl2java processing, and solve this problem. Next
time I do a "clean", the generated java files would
disappear, the corresponding 'available' property would be false,
and so I'd do the idl2java processing, then the compile.

I can't be the only one with this kind of situation in
a build. But right now, since I can't conditionally
run a java program based on the value of a property,
I have to live with having the idl to java processing happen
every build, causing extra compilation.

Or am I being dumb in this area, and not catching on to
some capability that would do what I want???

Thanks!

-ken



Reply via email to