Search code examples
javaantbuild-process

Multiple source folders: Avoid implicit compilation with Ant


Consider the following project layout (assuming A and B depend on each other):

.
|-- bin1
|-- bin2
|-- src1
|   `-- A.java
`-- src2
    `-- B.java

After compilation, I want the classes to reside in their respective folders liike this:

.
|-- bin1
|   `-- A.class
|-- bin2
|   `-- B.class
|-- src1
|   `-- A.java
`-- src2
    `-- B.java

This is quite simple from the command line:

 $ javac -implicit:none -sourcepath src1:src2 -d bin1 src1/*
 $ javac -implicit:none -sourcepath src1:src2 -d bin2 src2/*

Eclipse also does it that way if so configured. But I cannot figure out how to do it with Ant.

Appendix: My current javac tasks:

    <javac destdir="${classes.1.dir}">
        <src path="${src.1.dir}" />
        <src path="${src.2.dir}" />
    </javac>
    <javac destdir="${classes.2.dir}">
        <classpath path="${classes.1.dir}" />
        <src path="${src.2.dir}" />
    </javac>

Note the circular dependency. The second task works well, it only compiles what’s in src2 as it has a classpath dependency on the other build. The first task, however, cannot take a classpath, since nothing is yet compiled, and with src it of course compiles too much.


Solution

  • This is extremely ugly and needs some cleaning, but it should do what your looking for

    <target name="compile" depends="clean,init" description="Compiles all source files.">
        <mkdir dir="temp"/>
        <javac srcdir="src1" sourcepath="src2" destdir="temp">
            <classpath>
                <fileset dir="lib">
                    <include name="**/*.jar"/>
                </fileset>
            </classpath>
        </javac>
        <javac srcdir="src2" sourcepath="src1" destdir="temp">
            <classpath>
                <fileset dir="lib">
                    <include name="**/*.jar"/>
                </fileset>
            </classpath>
        </javac>
        <javac srcdir="src1" destdir="bin1">
            <classpath>
                <fileset dir="lib">
                    <include name="**/*.jar"/>
                </fileset>
                <pathelement location="temp"/>
            </classpath>
        </javac>
        <javac srcdir="src2" destdir="bin2">
            <classpath>
                <fileset dir="lib">
                    <include name="**/*.jar"/>
                </fileset>
                <pathelement location="temp"/>
            </classpath>
        </javac>
        <delete dir="temp"/>
    </target>