You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@ant.apache.org by Marina <pp...@yahoo.com> on 2010/09/26 15:23:39 UTC

conditional global variables?

Hello!
In essence, I would like to know how to define a global property conditionally, 
and then have it available to all build files via <import>.

Now the details:
I have a build.common.xml file with all global properties and paths defined. I 
import it into my main build and component build files via <import>, and this 
makes everything that is defined in the common file available to all other build 
files.
build.common.xml:
            <property name="build.classes" value="${build}/classes"/> 
            ...
      <path id="compile.classpath">
            <pathelement location="${build}/classes"/>
            <path refid="jdk.classpath"/>
            <fileset dir="${lib}">
                  <include name="**/*.jar"/>
            </fileset>
...


Then, I have a main build.xml that calls a few component build.xml via <ant 
file=...> call.
If I <import> the build.common.xml into all my build files - I have all 
properties and paths available to all builds.

It all works great, but now I want to have the build.classes property set 
conditionally, based on the build mode (dev vs. release). Ideally, I would like 
something similar to the C #ifdef macros:

build.common.xml:
if 
    mode='dev'
then 
            <property name="build.classes" value="${build}/dev/classes"/> 
else
            <property name="build.classes" value="${build}/release/classes"/> 

I can do the <if> logic if I define this property in the main build, for 
example, as part of some <init> task. But, it means that the property is not 
global anymore, and, which is more important, I cannot define my paths in the 
build.common.xml based on the value of this property. At least I could not 
figure out yet a way to do it...

So, I was pondering over a few options:
1. define all properties like that and paths in the main build.xml and pass them 
as parameters to all component builds - very involved and inflexible...
2. define a target <init> in the build.common.xml that defines all those 
properties and paths - and make all builds call it (or depend on it) - again, 
very involved in terms of refactoring my existing builds, and inflexible.
3. any other way???

If only I could just define that one global property conditionally! I feel like 
I'm missing some basic core concept here.... 

Any pointers?

Thanks!
Marina

Re: conditional global variables?

Posted by Matt Benson <gu...@gmail.com>.
On Sep 26, 2010, at 8:23 AM, Marina wrote:

> Hello!
> In essence, I would like to know how to define a global property conditionally, 
> and then have it available to all build files via <import>.
> 

Um, use the <condition> task?

-Matt

> Now the details:
> I have a build.common.xml file with all global properties and paths defined. I 
> import it into my main build and component build files via <import>, and this 
> makes everything that is defined in the common file available to all other build 
> files.
> build.common.xml:
>            <property name="build.classes" value="${build}/classes"/> 
>            ...
>      <path id="compile.classpath">
>            <pathelement location="${build}/classes"/>
>            <path refid="jdk.classpath"/>
>            <fileset dir="${lib}">
>                  <include name="**/*.jar"/>
>            </fileset>
> ...
> 
> 
> Then, I have a main build.xml that calls a few component build.xml via <ant 
> file=...> call.
> If I <import> the build.common.xml into all my build files - I have all 
> properties and paths available to all builds.
> 
> It all works great, but now I want to have the build.classes property set 
> conditionally, based on the build mode (dev vs. release). Ideally, I would like 
> something similar to the C #ifdef macros:
> 
> build.common.xml:
> if 
>    mode='dev'
> then 
>            <property name="build.classes" value="${build}/dev/classes"/> 
> else
>            <property name="build.classes" value="${build}/release/classes"/> 
> 
> I can do the <if> logic if I define this property in the main build, for 
> example, as part of some <init> task. But, it means that the property is not 
> global anymore, and, which is more important, I cannot define my paths in the 
> build.common.xml based on the value of this property. At least I could not 
> figure out yet a way to do it...
> 
> So, I was pondering over a few options:
> 1. define all properties like that and paths in the main build.xml and pass them 
> as parameters to all component builds - very involved and inflexible...
> 2. define a target <init> in the build.common.xml that defines all those 
> properties and paths - and make all builds call it (or depend on it) - again, 
> very involved in terms of refactoring my existing builds, and inflexible.
> 3. any other way???
> 
> If only I could just define that one global property conditionally! I feel like 
> I'm missing some basic core concept here.... 
> 
> Any pointers?
> 
> Thanks!
> Marina


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
For additional commands, e-mail: user-help@ant.apache.org


Re: conditional global variables?

Posted by Marina <pp...@yahoo.com>.
Thanks, David and Matt,

Matt, yes, <condition> was what I was looking for - for some reason I thought 
you coudl not use them outside of <target>s, and, thus, could not use to define 
global variables. But since it is working great - that's all I needed.

David, thanks for extensive suggested options - they all look good. I did want 
to get away from splitting all my targets into dev/release versions though, just 

to be able to use different property values. So, the <condition> approach worked 

great for me.

Thanks!
Marina

Re: conditional global variables?

Posted by David Weintraub <qa...@gmail.com>.
There are several ways this can be done:

One is to use multiple tasks:

<target name="compile">
    <antcall target="compile.dev"/>
    <antcall target="compile.release"/>
</target>

<target name=compile.dev"
    if="mode.dev">
    <property name="build.classes" value="${build}/dev/classes"/>
</target>

<target name="compile.release"
    unless="mode.dev">
    <property name="build.classes" value="${build}/release/classes"/>
</target>

In the example you gave, you could simply set the property "type" to
either "dev" or "release":

    <property name="build.classes" value="${build}/${type}/classes"/>

You can also use separate XML property files:

    <xmlproperty file="build.${type}.xml" keeproot="false"/>

Or, you can use the antcontrib library which includes a conditional
"if" statement. If you do this, I would put the ant-contrib.jar file
in a directory called "antlib" in the root of your project and use the
following <typedef>:

<taskdef resource="net/sf/antcontrib/antlib.xml">
    <classpath>
        <pathelement location="${basedir}/antlib/ant-contrib.jar"/>
    </classpath>

This way, ant will work without having to specifically install the
ant-contrib.jar file.

You can find Ant-Contrib at: http://ant-contrib.sourceforge.net

The <if> task looks like this:

<if>
    <isset property="type">
    <then>
        <property name="build.classes" value="${build}/dev/classes"/>
    </then>
    <else>
        <property name="build.classes" value="${build}/release/classes"/>
    </else>
</if>

-- 
David Weintraub
qazwart@gmail.com

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
For additional commands, e-mail: user-help@ant.apache.org