tags:

views:

912

answers:

2

Say I have my sources in my src/ tree (and possibly in my test/ tree). Say I would like to compile only part of that tree. The reasons why I might want to do that are various. Just as an example, I might want to create the smallest possible jar (without including certain classes), or I might want the fastest compile time for what I am compiling. I absolutely want to compile all the dependencies, though!

This can be easily achieved from the command line with:

javac -d build/ -cp whatever -sourcepath src src/path/to/MyClass.java

Now, how can you do that with ant? The javac ant task compiles everything:

The source and destination directory will be recursively scanned for Java source files to compile.

One can use the excludes and includes parameters, but they are problematic for this purpose. In fact, it seems that one has to explicitly setup all the includes (not automatic dependency lookup), and even worst that excludes has priority on includes:

When both inclusion and exclusion are used, only files/directories that match at least one of the include patterns and don't match any of the exclude patterns are used.

Thus, you cannot use

<javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="classpath"
            excludes="**/*.java" includes="src/path/to/MyClass.java" />

Because it will not compile anything :-(

Is there any way of achieving that simple command line javac with ant?


EDITED: Thank you for your answer, Sadie, I'm accepting it, because it does work in the way I was wondering in this question. But I have a couple of comments (too long to be in the comment field of your answer):

1) I did read the documentation (see links above), but it's unclear that with just includes you are actually also excluding everything else

2) When you just includes ant logs something like

[javac] Compiling 1 source file to /my/path/to/build

even if the dependencies make it compiling (much) more than just one source file.

A: 

Actually, ant only checks everything, if you run a compile twice in a row you will notice the second is much quicker. Actually, it can be easily persuaded to miss things.

If you don't even want it to consider everything, you're going to have to break it down into smaller modules/projects/source trees so that you're explicitly telling ant what to compile.

Draemon
+5  A: 

Why are you excluding as well as including? If you have at least one include, then files are only compiled if they're explicitly included. So this should work:

<javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="classpath"
        includes="src/path/to/MyClass.java" />

Or more flexibly:

<javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="classpath">
    <include name="src/path/to/MyClass.java"/>
    <include name="src/path/to/AnotherClass.java"/>
</javac>

To include only certain packages or classes in a jar, use a fileset attribute

<jar jarfile="${outlib}/something.jar">
    <fileset dir="${build.dir}">
        <include name='src/path/to/classes' />
    </fileset>
</jar>

Again, you can use multiple includes to combine separate packages. Experiment with includes and read the documentation and you're sure to find the answer you need.

Marcus Downing
please see my full comment in the question above
Davide