Daniel Hoag
Daniel Hoag

Reputation: 99

Using Ant to build dependencies of the current build target

Say I have a library and a binary target, let's call them MyLib and MyBin, MyBin depends on MyLib.

I'm trying to create an Ant buildfile for MyBin that first builds MyLib and then includes it in the classpath when building MyBin.

I've tried using Ant tasks as in Building other, dependent projects with Ant .

However, it's not working, and from ant -v I think the MyBin build-deps target is not even building MyLib. Seems like it's confusing MyBin and MyLib properties? I'm not sure how to prevent this though.

I'm dumping only MyBin/build.xml below, but the MyLib is almost identical, except it does not have the build-deps target.

<project name="MyBin" default="main" basedir=".">
    <property name="projectName" value="MyBin" />
    <property name="src.dir" location="src" />
    <property name="build.dir" location="bin" />
    <property name="dist.dir" location="dist" />
    <property name="dist.lib.dir" location="dist/lib" />
    <property name="lib.dir" value="lib" />


<target name="build-deps" depends="init">
<!-- MyLib main target does clean -> build -> jar to dist folder -->
<!-- Its build.xml uses many of the same property values as above -->
        <ant antfile="../MyLib/build.xml" target="main"/>
</target>

<path id="classpath">
    <fileset dir="${basedir}/">
        <include name="../MyLib/dist/**/*.jar" />
    </fileset>
</path>

<!-- Need classpath to run this -->
<target name="compile" depends="build-deps" description="compile the source ">
    <javac includeantruntime="false" srcdir="${src.dir}"
                   destdir="${build.dir}" classpathref="classpath" />
</target>

<!-- Group all dependencies into a big dependency-all.jar -->
<target name="copy-dependencies">

    <mkdir dir="${dist.lib.dir}" />

    <jar jarfile="${dist.lib.dir}/dependencies-all.jar">
        <zipgroupfileset dir="${lib.dir}">
            <include name="**/*.jar" />
        </zipgroupfileset>
    </jar>

</target>

<!-- jar it, extract above dependency-all.jar and zip it with project files -->
<target name="jar" depends="compile, copy-dependencies"
            description="package, output to JAR">

    <mkdir dir="${dist.dir}" />
    <mkdir dir="${dist.lib.dir}" />

    <jar jarfile="${dist.dir}/${projectName}.jar" basedir="${build.dir}">
        <manifest>
            <attribute name="Main-Class" value="${main-class}" />
        </manifest>
        <zipfileset src="${dist.lib.dir}/dependencies-all.jar"
                            excludes="META-INF/*.SF" />
    </jar>

</target>

<target name="clean" description="clean up">
    <delete dir="${build.dir}" />
    <delete dir="${dist.dir}" />
</target>

<!-- Default, run this -->
<target name="main" depends="clean, compile, jar" />
</project>

What I see with ant -v in MyBin is something along the lines of:

build-deps:
Project base dir set to: /MyBin
      [ant] calling target(s) [main] in build file /MyLib/build.xml
parsing buildfile /MyLib/build.xml with URI = file:/MyLib/build.xml
Project base dir set to: /MyBin
Override ignored for property "projectName"
Override ignored for property "build.dir"
Override ignored for property "dist.dir"
Override ignored for property "dist.lib.dir"
Override ignored for property "lib.dir"
[pathconvert] Set property classpath.name = 
      [ant] Entering /MyLib/build.xml...
Build sequence for target(s) `main' is [clean, init, copy-dependencies, jar, main]
Complete build sequence is [clean, init, copy-dependencies, jar, main, ]

clean:
   [delete] Deleting directory /MyBin/bin
   [delete] Deleting directory /MyBin/bin

init:
    [mkdir] Created dir: /MyBin/bin

copy-dependencies:
      [ant] Exiting /MyLib/build.xml.

Upvotes: 3

Views: 2237

Answers (1)

martin clayton
martin clayton

Reputation: 78105

On your specific question:

seems like it's confusing MyBin and MyLib properties? I'm not sure how to prevent this though.

You are using this to invoke the MyLib build:

<ant antfile="../MyLib/build.xml" target="main" />

A build invoked via the <ant> task this way by default inherits all properties from the caller, including basedir, hence the build is run in the wrong place.

Instead you could use, for example:

<ant dir="../MyLib" />

That will run build.xml in the specified directory, set the basedir property, and call the default target, which should be main if you are using a very similar buildfile for the library as you say. If you don't want to inherit properties from MyBin when executing the MyLib task, specify inheritAll=false in the task.

From the <ant> task docs for the dir attribute:

the directory to use as a basedir for the new Ant project (unless useNativeBasedir is set to true). Defaults to the current project's basedir, unless inheritall has been set to false, in which case it doesn't have a default value. This will override the basedir setting of the called project. Also serves as the directory to resolve the antfile and output attribute's values (if any).

Upvotes: 1

Related Questions