Kuro5hin.org: technology and culture, from the trenches
create account | help/FAQ | contact | links | search | IRC | site news
[ Everything | Diaries | Technology | Science | Culture | Politics | Media | News | Internet | Op-Ed | Fiction | Meta | MLP ]
We need your support: buy an ad | premium membership

[P]
Comparing ant and make as Java build tools

By GusherJizmac in Technology
Mon Sep 24, 2001 at 08:44:18 PM EST
Tags: Software (all tags)
Software

Recently, the tool ant has come to the forefront as a build tool for Java. It uses XML build files and contains many built-in commands to make it easy to work with Java code and Java projects. There are extensions to it to simplify developing web-based Java applications with tools like BEA Weblogic. Upon hearing about ant, many developers might first ask "Why not just use make?". This author has extensive experience with make, and with Java development, and the following article attempts to answer this question by offering a comparison of ant and make as build tools, under the assumption that Java applications are being developed. The conlusion drawn is that while ant has some powerful advantages, it is not as easily extensible, nor as flexible as make for most development situations and there isn't a strong argument in favor of using it.


Introduction

When my company first began serious Java application development (in the form of web-based, J2EE applications), my instinct was to create a Makefile system to handle the compilation of Java code, as well as some basic development environment setup procedures. This was done and included in our standard development procedure. Then, a while ago, I began reading about ant, which purported to be a better tool for automating builds in a Java environment. After reading about it, I decided to implement a simple J2EE application (using Tomcat and Oracle) using ant, instead of my company's Makefile system. This article documents my experience and impressions about using ant as a Java development tool. First, however, I provide a simple overview of the two tools.

make

If you aren't familiar with make (wherby I mean specifically GNU Make), it is a UNIX-based tool that reads a Makefile, which is a set of targets (with dependants) that get "made" when a target is out of date. What happens when a target is "made" is entirely up to the Makefile author. Usually, this means compiling source code into object or executable code, but it could be anything, including checkout of resources from source control or creating distributable archives. What happens during a make is typically calls to various shell commands. Since make originally was a UNIX program, make was designed assuming the full range of UNIX commands.

Make is very flexible, in that you have a wide latitude to define variables, manipulate those variables and pass them to any command available on your system. A simple Makefile might look like this:

FILE_BASE = hello
$(FILE_BASE) : $(FILE_BASE).o
    gcc -o $(FILE_BASE) $(FILE_BASE).o

$(FILE_BASE).o : $(FILE_BASE).c
    gcc -c $(FILE_BASE).c

Here, hello is a target, with hello.o being a dependant. hello.o is also a target itself, with hello.c as it's dependant. In most cases, make assumes that targets and dependants are files. So, in this example, if hello has an earlier modification date than hello.o, it will run the associated command (namely gcc -o hello hello.o), which creates hello and brings it up to date. So, if you had a whole slew of source files, make allows you to only recompile those that changed, not the whole tree. For more about what you can do with make, see the links at the end of the article.

ant

ant is part of the Apache Jakarta project. Ant has a similar concept to make in terms of targets and dependants, but ant doesn't assume that targets and dependants are files by default. Ant also doesn't assume that the purpose of dependants are to bring targets up to date, it's merely a simple dependancy. Ant also makes use of built-in commands to implement targets, rather than assuming shell commands are available (although you can execute arbitrary shell commands). This makes ant run on any Java-supported platform. Many of the commands are specific to compiling or working with Java code. Since ant is written in Java, it has the added feature of running the Java compiler from within itself, which ends up making compilation quite fast. Ant relies on this fact, even, because the typical compilation target results in compiling every single java source it can find each time you run it. For users of make, this may sound horrendous, but the compilation step (for me) took the same amount of time to compile one class as it did for 50.

Ant also uses an XML-based syntax for creating the buildfiles (although it is not strict XML in the sense that a DTD for all of ant cannot easily be made, and the syntax allows for a lot more flexibility than you might expect in an XML file). Following is an example:

<project name="foobar" 
         default="compile" 
         basedir=".">
  <description>Foobar!
  </description>
  <!-- set global properties for this build -->
  <property name="src" value="."/>
  <property name="build" value="site/foobar/war_file/WEB-INF/classes"/>

  <target name="init">
    <!-- Create the time stamp -->
    <tstamp/>
    <!-- Create the build directory structure used by compile -->
    <mkdir dir="${build}"/>
  </target>

  <target name="compile" depends="init">
    <!-- Compile the java code from ${src} into ${build} -->
    <javac debug="on" srcdir="${src}" destdir="${build}">
        <classpath>
            <pathelement path="${classpath}"/>
            <fileset dir=".">
                <include name="compiled/**/*.jar"/>
            </fileset>
        </classpath>
    </javac>
  </target>
</project>

Here, compile is a target (and the default target), and it compiles the java source code. It is dependant on the init target, which ensures that the build directory exists, as well as creating a timestamp. Note that here, everytime that the compile target is executed, the init target will also be executed. These aren't files with timestamps that may become out of date; they are simply chained events that occur in a certian order. I should note that you can conditionally execute the commands of a target, based on execute-time criteria, much as you can in make. Additionally, you can write Java classes to create your own built-in commands, or you can use a special built-in command that lets you run an arbitrary command-line command.

Evaluation Method

I have many years of experience with GNU make, and worked on our company's Makefile system. I'm familiar with makes pros and cons, especially with respect to Java development, which I've been doing steadily for the past 3 years. This is obviously going to make me a little biased against ant, because I know much more about make. However, my first experience with make was to create platform independant (UNIX, Windows, OS/2) build-files for creating shared libraries, so I remember what it was like to have to learn a wierd tool and get it to work in a general sense. Also, creating shared libraries (at least at the time) was not the trivial task that compilation is, and so I needed to learn make quite well to get it working right. My hope was that this experience would allow me to be objective with respect to ant.

I downloaded and installed ant, and set it up as my compilation tool for my project. Our company's Makefile system does the following things for the average developer:

  • Maintain a list of 3rd party jars needed for the project.
  • Checkout those jars if they are not checked out
  • Compile any Java classes changed since the last compile
  • "clean" functionality, which deletes all generated or checked-out files so you can do a "clean" build
Deployment of jars and classes (to the developer's Tomcat instance, not to a production server) is done by manipulating the arguments of the compilation command, so that the classes end up where tomcat is expecting them. My goal with ant was to create a buildfile that gave me this functionality. Doing so was very straightforward, save for configuring it to check out my jars only if they didn't exist. This required some more hunting and experimenting. Specifics on this appear below.

Once I had my ant file, I was off and developing and didn't really notice much of a difference between using make. With both systems I simply type a 'make' or 'ant' and my code compiles. The first time I build, my jars get checked out.

Comparison of the two Tools

My comparison will take two parts: The first will focus on the differences with using each tool for my specific task, namely writing a Java-based web application. The second part will discuss my more general impressions of ant vs. make as build tools, apart from my specific project (but still within the realm of writing Java applications).

Using ant on my J2EE Web Application

Boy does ant compile fast! The biggest difference I noticed was the speed at which ant compiled. I was quite distressed while creating my buildfile that ant would be compiling all the code every time, but after the first compile, I had to change to by output directory to verify that the classes were actually there, because I couldn't believe it had compiled all those sources so quickly. From a pure user perspective, however, ant didn't integrate with vim out of the box. With make (more specifically javac), you can have vim run your build and then step you to each line with syntax errors, because vim can parse the output of javac. Since ant reformats javac's output, vim wasn't able to do this. I assume that some tweaking with vim could alleviate this, but I didn't look into it. The reformatting (which amounts to indenting javac's output and prepending each line with a flag indicating that the output came from javac) made it harder to read the output of javac (probably because I was used to reading it direct from javac). I'm not sure if there is an option to disable this, but I couldn't find it.

I did have a somewhat difficult time getting ant to checkout my jar files only if they didn't exist. It required using the "uptodate" builtin command and creating a timestamped file. Perhaps there is a better way to do it, but the documentation wasn't clear. Accomplishing this in make was quite simple. I could make a target named for each jar (make allows for creating make-time targets dynamically, wheras ant can only have static targets defined at buildfile-creation), and then the command for that target is to check it out of CVS. The effect is that the checkout only happens when the file doesn't exist.

Using ant to make a full-blown development system

My company's Makefile system supports (or will support) additional functionality, including tagging source files, committing class files for distribution, running checks on source files before tagging, and other things needed for a sophisticated development environment. Implementing these is fairly straightfoward, because make and shell programming is very similar to LISP programming, where code and data are interchangeable, and there is a high degree of dynamicism. This allows for a general-purpose Makefile that needs to know little or nothing about the files on which it operates. My checkout example above indicates what I mean. A better example is if I want to make a "tag" target, that tags all source files as "stage", so they can be pushed to a staging environment. Before tagging, I need to make sure that each file has been committed to CVS. I can't imagine how to do this with ant without writing a builtin command or shell script (or, worse yet, hard-coding the java source file names in the buildfile). I'm sure it can be done, but in make, it is very simple. Since you can construct targets and commands dynamically at make-time, I can write a generic make target that does this check and fails if any file isn't committed to CVS. Being able to do this easily is, in my opinion, is a pretty basic feature that a build system should have. Ant could support this with a more robust variable assignment mecahnism and with a way to create dynamic targets, or a way to treat property values as lists for iteration.

Integrating ant with other systems also seems to be quite cumbersome. You bascially have two choices to integrate ant with other systems (e.g. clear case if you don't use CVS): writing a java class, or using the <Exec...> builtin command. Writing a Java class seems quite cumbersome, and often Java is not suited to executing system-level tasks involved with running command-line tools typically provided by configuration management tool vendors. Using the builtin command is also somewhat cumbersome, as it is not as flexible as just running the command through a shell. You are bascially specifying all the parameters to pass to the java method that executes external commands, and as mentioned before, this is not always appropriate for executing command line tasks.

Even if this is done (as many have done with providing builtin commands for BEA Weblogic), your commands won't work if the interface changes. For example, BEA radically changed their EJB deployment procedure between version 4.5 and 5.1. An ant builtin task would have to be rewritten, recompiled and redistributed to accomodate this. Another example is the change between javadoc for java 1.1 and for java2. If such a change occurs again, ant will not easily be able to take advantage of the better featureset. This is because with ant, you would have to reimplement your builtin task. With make, you can easily change your Makefile.

Additionally, ant doesn't have nearly the documentation, developer knowledge, or proven value that make has. I know that whatever needs my organization will have (including developing non-Java applications), make will be able to support them. I cannot say the same for ant.

That said, ant has some good things going for it. For one, if you are a developer that knows neither make nor ant, you will be up and compiling javacode a lot faster with ant. ant essentially provides a builtin Makefile for compiling and running Java code, and that's pretty good. Make was designed with compiling C code in mind, and getting it to work with Java requires some non-obvious make coding that does require some prioir knowledge of make to do. Additionally, ant compiles incredibly fast. While I didn't try ant on a real sized project (e.g. 1000s of classes), for my one-person development effort, it was much faster than make (of course, you could have make call ant for compiling). Finally, ant is truely cross-platform. Ant will run on Max OS 9 and VMS. Make will not (without additional software installed). In make's favor, I should point out that Cygwin provides free versions of make and all other GNU tools for windows, including bash, and that the vast amount of Java coders in the world are using either UNIX or Windows. So, for most Java coders, make is platform independant (although it does require an extra package for Windows).

Summary

OK, I don't want to fill this article up with anecdotal evidence or, worse yet, ranting. So, I'll try to capture my thoughts in the following pros/cons table:

  • ant
    • Pros
      • Fast Compiles.
      • Easy to get up and running for compilation.
      • True platform independance.
      • Good error reporting of buildfile syntax errors.
    • Cons
      • Property value assignment very simple and inflexible.
      • Cannot create dynamic targets at build-time, making complex build tasks difficult to write.
      • Compiling every source file every time might be a problem for large systems.
      • Integration with other systems limited to Java classes or executing command line through Java.
      • Wrapping commands in "builtin tasks" exposes them to breakage when underlying tasks change.
      • Sparse documentation, not widely used
      • Use for non-Java projects not realistic without more builtin commands.
  • make
    • Pros
      • Incredibly flexible
      • Run-time dynamicism simplifies creating complex tasks
      • Powerful variable creation mechanism simplifies creating complex tasks
      • Integration with other build and deployment tools is very simple through shell commands
      • Assumes targets and dependants are files, which makes it easy to write targets that only do the work that is needed
      • Extensive documentation, developer knowledge and proven track record as industry standard build tool
      • Can be used for any type of project, even projects that mix languages and technologies.
    • Cons
      • Requires UNIX command set installed to be effective.
      • Requires some non-beginner level make coding to work effectively with Java compiler.
      • Complex Makefiles can be difficult to debug if not architected properly.
      • Typical UNIX user-unfriendly error messages increase learning curve.
      • Full system compiles are slower because of multiple javac invocations (although this could be remedied by calling ant for compiles only :)

I've also come up with the following, that I believe characterizes the situations in which ant or make are warranted:

  • Use ant if:
    • You are a single developer or one of a very small development group working a small Java-based application and you don't know make.
    • You are working on a project that will be developed or deployed on a platform other than UNIX or Windows
    • Your developers are all using their own build scripts and you need something fast and are not looking to build a large general-purpose build system
  • Use make if:
    • You know make
    • You are working on a medium to large sized project or on a project with more than a few developers.
    • You need to integrate with a variety of configuration management tools
    • You are building a medium to long-term solution for build and deployment that must handle a wide variety of tools and technologies

Conclusions

While ant is an interesting tool, I don't see it as a heavy-duty build tool for Java development. Furthermore, ant's overall design seems to be the opposite of make. ant tries to be all things to all people and reimplements functionality that's available and proven on UNIX. ant tries to have a command for everything. Looking at the list of builtin commands one can't help but get the feeling that ant was made by someone who did not understand make and didn't want to learn it, and slowly realized that there's a lot of functionality a build tool will need if it cannot rely on the UNIX command set. Comments on the ant homepage support this (e.g. "Makefiles are inherently evil") to an extent. make, on the other hand, is a framework for running arbitrary commands. True, make requires UNIX to be useful, but UNIX commands are available on almost all platforms where Java is being developed. Yes, make can be hard to learn, and it does have it's quirks, but it works and it works well for almost any situation. The make code to implement java compilation (ant's biggest draw, IMO) is quite simple (even if non-trival to derive). This is one time only operation. I think ant is great if you are a single developer who can't afford an IDE and don't want to mess with make. With ant, you'll be up and running quickly. For a Release Engineer or Lead Programmer on a project, though, make is a tried and tested tool that works just as well with Java as it does with C, and you know that it will do whatever you want it to do.

References

Before You Respond!!

I know that many of you who prefer ant will want to put me in my place and point out that because I don't know ant very well, I will be biased towards make. Aside from requestng that you post constructive comments on this issue instead of flames, I would ask that you keep the following in mind:

  • Make does have a large base of users, and many will be less objective than I am without arguments more convincing than "Makefiles are evil". The greatest tool in the world that no one uses is worthless.
  • Do you know a lot about make and build systems? I do, and I've built a lot of Makefiles and used make to do a lot of things that would be needed in any serious build system. If you have something to say about ant's ability to complete with make at this level, I hope you have done something more than just compile java code and create a .war file
  • Have you worked on a large Java project that lasted more than a few months and required more than a few developers? Have you worked on a project where non-programmers needed to create or modify files that were part of the overall build?
  • I know that make and ant are not the only build tools around. I know that other build tools cost money, and I'm operating under the assumption that someone using these tools cannot or will not buy a build tool. I also don't have much experience with them, but I tried to write the article so that that wouldn't matter
OK, I just want comments to be constructive and useful. I don't purport to know everything and have no problem being set straight, as long as convincing arguments are made.

Sponsors

Voxel dot net
o Managed Hosting
o VoxCAST Content Delivery
o Raw Infrastructure

Login

Poll
I prefer
o make 24%
o ant 27%
o some IDE 20%
o typing everything on the command line 10%
o entering Java bytecode directly 17%

Votes: 69
Results | Other Polls

Related Links
o ant
o BEA Weblogic
o make
o Cygwin
o Ant Homepage
o Ant Documentation
o Make Homepage
o Make Documentation
o Cygwin Homepage
o Java Homepage
o Tomcat Homepage
o Also by GusherJizmac


Display: Sort:
Comparing ant and make as Java build tools | 89 comments (82 topical, 7 editorial, 0 hidden)
this is nice (3.83 / 6) (#5)
by speek on Mon Sep 24, 2001 at 05:00:06 PM EST

But I just like Ant. I never went to school for computers, so I've never been seriously exposed to Unix. And no, running Linux at home isn't really teaching me all those built-in commands...

The documentation is straightforward and clear for Ant (I'm surprised that's one thing you picked on, actually). I'm not sure why I would want dynamic targets just yet - your example of checking out jar files only if they don't exist just shows your ignorance of the available tag in Ant - unless I've misunderstood your example.

I have nothing against Make - but I've only used it a few times for a few simple school projects. Ant made more sense when starting from scratch to learn a build tool. There is no question that Make provides more power and flexibility. I just haven't had a reason to care yet.

--
al queda is kicking themsleves for not knowing about the levees

Heh (3.50 / 2) (#8)
by regeya on Mon Sep 24, 2001 at 06:32:17 PM EST

I never went to school for computers, so I've never been seriously exposed to Unix. And no, running Linux at home isn't really teaching me all those built-in commands...

Back before I switched to journalism as a major, my profs were too busy teaching us how to rewrite Eliza in Scheme to teach us about Make. I learned about it at home, using GNU Make, on a Linux box. Everything I know (and the reason for my oddball Makefiles :-) is thanks to the O'Reilly book on Make. :-)

Eh, give it a shot. Once you learn a bit about Make, you'll probably learn to love it.

[ yokelpunk | kuro5hin diary ]
[ Parent ]

Parsing output - Read the Fine Manual (4.25 / 4) (#9)
by smileyy on Mon Sep 24, 2001 at 07:12:33 PM EST

Having your editor parse ant output (specifically, the fact that it will prepend [javac] to compiler output seems to be a question that comes up a lot. So much, that its a frequently asked question.

The long answer can be found here, while the shorter answer is...use the -emacs option

% ant -emacs <target>


--
...alone in suicide, which is deeper than death...
A couple of inaccuracies... (4.00 / 5) (#11)
by smileyy on Mon Sep 24, 2001 at 07:18:43 PM EST

You talk about ant compiling your code. This is misleading, since ant will just call javac or jikes (or your java compiler of choice) to perform the compilation.

Also, ant doesn't recompile every file every time. Ant will only recompile source files that are newer than their corresponding class files. That's probably why ant seemed so fast to you.


--
...alone in suicide, which is deeper than death...
I dont' think that's right, but I can't back it up (none / 0) (#12)
by GusherJizmac on Mon Sep 24, 2001 at 07:26:56 PM EST

My makefile only compiles java files that have changed and it is slower than ant. Ant compiled 50 java files (I did a clean first) in the same time it took to do 1 (both faster than calling javac from the command line). I believe that ant invokes the compiler from within the jvm that runs ant and this makes it faster. I remember seeing something on the site indicating this, but I can't find it.

Also, I remember seeing statements on the ant site to the effect of "it compiles all the sources every time, but it's so fast, you won't notice". Given how fast it is, this seems believable.
<sig> G u s h e r J i z m a c </sig>
[ Parent ]

Is make invoking a new process for each file? (none / 0) (#14)
by smileyy on Mon Sep 24, 2001 at 07:57:43 PM EST

You didn't post your makefile, but does it invoke a new javac process for each file that you're compiling? That'd be hideously slow, since you'd be creating a new JVM each time. Even if you do fork the JVM for running javac in ant, you're still only creating one new process.


--
...alone in suicide, which is deeper than death...
[ Parent ]
Yes (none / 0) (#15)
by GusherJizmac on Mon Sep 24, 2001 at 08:19:17 PM EST

Make runs javac for each file, via something like:

%.class : %.java
    javac $<

That's the most straightforward way to get it to compile only what had changed. As I mentioned in the article, one could use ant (or do whatever ant does) to do the compilation, or use a faster Java compiler.
<sig> G u s h e r J i z m a c </sig>
[ Parent ]
a better way to do it with make (none / 0) (#24)
by boxed on Tue Sep 25, 2001 at 03:57:21 AM EST

...would be to create a list of files that needs to be compiled with make then passing this list to a java program that compiles it. This would take make closer to ants speed. But just switching to jikes should take make way past ant with javac.

[ Parent ]
Which begs the question... (5.00 / 1) (#33)
by ttfkam on Tue Sep 25, 2001 at 11:10:45 AM EST

what about Ant with Jikes? In your comparison, where would make lie?

Also note that the new iterations of javac are not quite as dog slow as the original -- a complete rewrite and faster JVM speeds. The advantages of Jikes, while still impressive and worth checking out, are not as vast as they once were.

If I'm made in God's image then God needs to lay off the corn chips and onion dip. Get some exercise, God! - Tatarigami
[ Parent ]
JDK 1.4 javac (none / 0) (#50)
by egomaniac on Tue Sep 25, 2001 at 03:04:12 PM EST

Agreed. In fact, since switching to the JDK 1.4 beta I've been completely won over by the new javac. It's night-and-day better than previous releases.

ego

[ Parent ]
Jikes vs Java in Ant (none / 0) (#67)
by Dacta on Tue Sep 25, 2001 at 09:51:18 PM EST

We have a few moderatly complex projects which we use ant to build.

Using the javac (modern 1.3) compiler, it takes about 5 minutes for one project. Using Jikes it is under 1 minute.

We have done a fair amount of optimisation of our build files so we only compile things once - sometimes you'll find that ant will build things multiple times, once for each target, unless you define the dependancies properly.

We haven't tried a full build with the 1.4 compiler, yet.



[ Parent ]
It's javac (none / 0) (#28)
by mcherm on Tue Sep 25, 2001 at 09:41:20 AM EST

javac itself only compiles files that are newer. If your makefile invokes javac separately for each file that needs compiling, while and invokes a single javac process for the entire tree of files (but javac skips over the files that don't need recompiling), then that would explain why ant seems faster for you.

It's largely because make was really designed for c.

-- Michael Chermside
[ Parent ]

XML build files (3.00 / 1) (#13)
by wiredog on Mon Sep 24, 2001 at 07:44:05 PM EST

Borland Builder and, I think, Delphi/Kylix use XML build files.

If there's a choice between performance and ease of use, Linux will go for performance every time. -- Jerry Pournelle
Inner Classes ?? (4.00 / 6) (#16)
by Estragon on Mon Sep 24, 2001 at 09:27:06 PM EST

How does ant deal with inner classes? Make has a hard time with them. What you need is an implicit rule that knows the target foo$bar.class depends upon the target foo.java.

It would be nice to do something like:

%1.class %1$$%2.class : %1.java
        insert java compile rule here

Can ant solve this problem?

of course it does (none / 0) (#29)
by zzzeek on Tue Sep 25, 2001 at 10:04:21 AM EST

"bar" exists in the same source file as "foo"! Changes to "foo" or "bar" always result in a recompilation of both.

[ Parent ]
Inner Classes meet RMI Stubs (none / 0) (#45)
by Estragon on Tue Sep 25, 2001 at 12:51:23 PM EST

Ah! But it isn't that simple. Now that I am at work I can dig out a difficult example:

Target foo$bar.class depends upon foo.java, and the target is generated by running javac on the dependent. Ideally, we could write a rule like:

%1.class %1$$%2.class : %1.java
        javac ...

Target foo_Stub.class depends upon foo.class and the target is generated by running rmic on the dependent. Ideally:

%_Stub.class : %.class
        rmic ...

Now the problem: You need to build a jar file that contains an RMI stub for an inner class. You have the file "foo.java", and are building a target that depends upon "foo$bar_Stub.class".

You can't easily set up make to figure out that it must javac foo.java and then rmic foo$bar.class to build "foo$bar_Stub.class".

Can ant do this?

[ Parent ]

i think you are over complicating it (none / 0) (#54)
by zzzeek on Tue Sep 25, 2001 at 03:29:12 PM EST

to have ANT run rmic would be a separate target than the target that compiles the initial classes, and would be dependent on the entire set of foo.java etc. being up to date first, then the stubs are generated, then the stubs are compiled. If there is a slightly slicker way you are accustomed to with "make", the devlopers of ANT have made decisions not to overcomplicate the whole tool for the sake of tiny "make"-like gains which arent really needed anyway.

I used ANT on a large project with 6 developers over the course of 8 months, including targets to check code out of CVS, run weblogic's EJB code generator and secondary compilation steps, generating code into about 8 separate jar files, and the thing did everything just fine, simply, with no need for arcane "make" syntaxes or shell scripts. The author of the article has used "make" for 20 years and obviously has no hope of ever being open to something new.



[ Parent ]
The complications are real (none / 0) (#63)
by Estragon on Tue Sep 25, 2001 at 09:02:28 PM EST

The problem is complicated because the problem is complicated.

I didn't make this question up out of the blue. It is a real situation we had to solve. There is no way to make an implicit rule in make that infers that the target foo$bar.class depends upon foo.java. The work around I devised was ugly.

I'm still asking if there is an amazingly easy way for ant to solve this problem. A 10 minute look at the documentation web pages didn't give me an answer.

[ Parent ]

Depend task (none / 0) (#69)
by donaldp on Tue Sep 25, 2001 at 11:42:12 PM EST

Have a look at the depend task
Cheers, Pete
[ Parent ]
Shell-level scripts in Java (4.50 / 4) (#17)
by slaytanic killer on Mon Sep 24, 2001 at 09:53:06 PM EST

When I built the build with Ant, I found myself writing built-in tasks with Java. Used regexes a lot, to boot. It was terrible. I would write hundreds of brainless Java lines a day, just for trivial things to express in a better scripting language.

Try Jython. It's kind of Lisp-like because you're manipulating lots of lists, and you don't have to put extra slashes for regexps and it's more fun to write stuff with... I did not rewrite my build in Jython because I already had the system stable, but it is worth a look. It also has the interactive evaluator, like Scheme, so you can just sit there and test stuff on some directories.

BTW, Jikes rocks. I don't quite understand using Javac, though there are situations where people say they need to.

Portability (none / 0) (#38)
by ttfkam on Tue Sep 25, 2001 at 11:35:04 AM EST

Javac will just work from platform to platform. Also it is included in any JSDK. Jikes is written in C and is a separate package. It must therefore be downloaded first and then built (or install package or binary tarball). It's an extra couple of steps. Not major, but just as people use IE on Windows instead of Mozilla, using what's there is easier if it adequately handles the job for you.

Also with regards to speed, sometimes it just doesn't matter. For example, if you are running a JSP server, you want all the compilation speed that you can get. Compilation time equates directly to the amount of time it takes to get a web page returned. On the other hand, Cocoon2 with Ant/javac on my box at work takes about 40 seconds to compile from scratch.

That's just enough time to scan the new posts in the k5 discussions and find gems like this make vs. Ant comparison.

This isn't like the old days where a build would take hours (days!) on a large C or C++ project. A (very) large Java project may take a few minutes to build. The horror! Most Java projects are not that large. Cocoon2 is not one of the smaller projects out there.

It's much the same reason that people don't compare 2D line drawing performance in video cards anymore. Sure one card may be faster than another, but the speed of the slower one is still faster than what we need (or even see, in the case of video cards).

Anyone who works in Java knows the mantra: I don't care if it's as fast as X. Is it fast *enough* for the problem at hand? If yes, then it's not an issue. If not, then you look at alternatives. Simple.

40 seconds for a clean build is fast enough for me, because an incremental build -- what I usually do -- is close enough to instantaneous that my video card analogy comes to mind.
In this case, "I don't quite understand using" Jikes, though there are situations where people need to.


If I'm made in God's image then God needs to lay off the corn chips and onion dip. Get some exercise, God! - Tatarigami
[ Parent ]
Speed is by far not the only advantage of Jikes (none / 0) (#42)
by slaytanic killer on Tue Sep 25, 2001 at 12:15:27 PM EST

In this case, "I don't quite understand using" Jikes, though there are situations where people need to.
Well, what makes a better compiler?

  • Resulting bytecodes
    Apparently Jikes is the most JLS-compliant compiler out there, save for Sun JDK 1.4 betas. (I checked that out with a Google search.)

    As for optimization, I have no idea. My gut feeling is that the JDK is a reference implementation, which should not be expected to spit out great code, just reasonably correct code.

  • Errer/warnung messages
    JLS compliance makes me a happy camper. I like the error messages from Jikes. Javac's error messages are good as well, but I prefer Jikes. I expect it to be more nit-picky.

  • Versatility on secondary issues
    I will grant that "secondary issues" don't necessarily show up here. I have a vague sense that Jikes handles dependencies better than Javac, though I'm not sure if that shows up in Ant. However, you wrote:
    Jikes is written in C and is a separate package. It must therefore be downloaded first and then built (or install package or binary tarball). It's an extra couple of steps.
    And to that, I say that things like keeping Jikes up and hitting the spacebar to recompile at will keeps Jikes on my hard drive. After all, I must download the JDK. And my editor. And my regex package. High-performance XML libs.

    Plus, when I wrote the build, I made sure any developer could just double-click an install program to run full builds on their own machines. There is no "extra couple of steps" to install Jikes. Takes longer and more manual labor to close five windows, than to use Jikes.

  • Speed
    I don't just think Jikes is better, I think it beats the pants off Javac. Now, my builds have a lot of overhead, with file accesses and whatnot, so the benefits of speed are muted. Still, 40 second compiles are absurd! Jikes will do it in five. You can do Google searches to find time comparisons. 40 second compiles make quick read-eval combos impossible. It results in a concentration break, when you want to see the results of something minor.

    For quick read-eval development, 40 seconds is too much. I know you're talking about clean builds, but I'd rather wait 5 seconds than 40, no matter what.

    That's just enough time to scan the new posts in the k5 discussions and find gems like this make vs. Ant comparison.
    And these little forced breaks are what kill your concentration and productivity. Everytime you get a clean CVS, you have to go through one clean build.

    Now, we're making our way to JDK 1.4, so we'll see how the two stand then. But for the time being, my analysis stands.

    [ Parent ]

  • and re: portability (none / 0) (#43)
    by slaytanic killer on Tue Sep 25, 2001 at 12:24:42 PM EST

    Jikes is written in C and is a separate package.
    If Javac is written in Java, I'd be impressed.

    But if you can't use Jikes, then just use Javac. I would never write a convention saying that only Jikes has to be used. It's just a convenience that is useful for many.

    This is bordering on religious war, and I'll just accept the fact that one can conceivably find benchmarks where Javac is faster than Jikes, and that there are nice little things... but just use what you want.

    Good code is the holy grail, and compilers are nice but not worth arguing about instead of better code-writing.

    [ Parent ]

    javac (5.00 / 1) (#49)
    by egomaniac on Tue Sep 25, 2001 at 03:01:29 PM EST

    If Javac is written in Java, I'd be impressed.

    What's this supposed to mean? *All* major compilers are written in their own languages, javac included (feel free to check out the JDK source code if you don't believe me). What do you think gcc was written in?

    I'd have to agree with the pro-javac people out there too. I love Jikes, but javac has gotten fast enough that 99% of the time I just don't care.

    ego

    [ Parent ]
    I should have checked (nt) (none / 0) (#52)
    by slaytanic killer on Tue Sep 25, 2001 at 03:25:52 PM EST

    (no text)

    [ Parent ]
    correction (none / 0) (#48)
    by trane on Tue Sep 25, 2001 at 02:15:49 PM EST

    For example, if you are running a JSP server, you want all the compilation speed that you can get. Compilation time equates directly to the amount of time it takes to get a web page returned.

    Only the first time the page is requested after the JSP server has been started. After that the page is served without recompilation. Unless the page has changed, then it is recompiled.

    [ Parent ]

    correction? (none / 0) (#55)
    by ttfkam on Tue Sep 25, 2001 at 04:02:38 PM EST

    Yes after the page is first requested, but then the compiler choice makes no difference. When you have a non-trivial amount of JSP pages changing (eg. any JSP development server) the speed of recompile makes a huge difference in no time at all.

    Engines such as Cocoon2 are doubly true for this.

    My original statement stands.

    If I'm made in God's image then God needs to lay off the corn chips and onion dip. Get some exercise, God! - Tatarigami
    [ Parent ]
    To the author (3.00 / 4) (#18)
    by valency on Mon Sep 24, 2001 at 10:01:25 PM EST

    Can you give us an example of when it might be absolutely necessary to create dynamic targets at build-time? I don't deny that such situations exist, I just can't think of any.

    Also, isn't Make's integration with other systems "limited to executing command lines"? The Ant exec target gives you at least that much power.



    ---
    If you disagree, and somebody has already posted the exact rebuttal that you would use: moderate, don't post.
    Example of dynamic targets (w/ Makefile) (5.00 / 1) (#31)
    by tmoertel on Tue Sep 25, 2001 at 10:59:43 AM EST

    Dynamically determined targets are very useful when you have dependency relationships between various types of targets, and the targets themselves are created or managed by an external process. There are lots of real world scenarios when this situation exists: content management, remote build systems, batch validation, etc.

    For example, you have a source directory into which XML documents may be added, changed, and removed without your knowledge. When you type make you want to create HTML files in an output directory based upon whatever is found the source directory. Since you don't know what you'll find, you can't know what your targets are when you write your Makefile. You must determine your targets on the fly, dynamically:
        # Makefile

        SOURCES := $(wildcard source/*)
        TARGETS := $(foreach src,$(SOURCES),\
                       $(patsubst source/%.xml,output/%.html,$(src)))
        
        .PHONY : all
        all : $(TARGETS)
        
        output/%.html : source/%.xml
            cat $< > $@  # real build command goes here

    Here the targets are determined at make time based upon the contents of the source directory. An implicit pattern rule establishes the dependency between each HTML output document and its corresponding XML source document and also provides the command to build HTML documents.

    The magic works as expected:
     
    $ mkdir source output
    $ ls -CF
    Makefile output/ source/
    $ make
    make: Nothing to be done for `all'.
    $ : > source/input1.xml
    $ make
    cat source/input1.xml > output/input1.html # real build command goes here
    $ make
    make: Nothing to be done for `all'.
    $ : > source/input2.xml
    $ make
    cat source/input2.xml > output/input2.html # real build command goes here
    $ ls output
    input1.html input2.html

    --
    My blog | LectroTest

    [ Disagree? Reply. ]


    [ Parent ]
    Ant can do this even more easily than make (none / 0) (#47)
    by valency on Tue Sep 25, 2001 at 02:11:08 PM EST

    <apply executable="your-command-here" dir="output/>
      <fileset dir=".">
        <include name="source/**/*.xml"/>
      </fileset>
    </apply>


    ---
    If you disagree, and somebody has already posted the exact rebuttal that you would use: moderate, don't post.
    [ Parent ]
    Are you sure? (none / 0) (#53)
    by tmoertel on Tue Sep 25, 2001 at 03:27:31 PM EST

    Your Ant buildfile doesn't seem to accomplish half of what my Makefile does. You didn't even provide an Ant equivalent for the trivial cat placeholder, about the simplest build command you're ever likely to encounter in a real-world Makefile. If something that trivial is cumbersome to represent in Ant, what are we to think about Ant's ability to easily represent more-complicated build commands, which might require pipelines, conditional execution, and so on?

    Please finish off your example buildfile so that it actually does the same thing that my Makefile does (i.e., execute cat, save the output of each execution to the correct directory with the correct file extension, build only when necessary, etc.) Once you finish adding the mappers, command execution, and other devil-is-in-the-details work, we'll have an apples-to-apples comparison. Then we'll see if Ant really is easier.

    --
    My blog | LectroTest

    [ Disagree? Reply. ]


    [ Parent ]
    Please stop being petty (none / 0) (#56)
    by valency on Tue Sep 25, 2001 at 04:19:34 PM EST

    I wrote that last target off the top of my head. Here's a tested one. It processes only the files that have changed, uses the correct extension, and generates exactly, precisely the same output as your Makefile for any give set of source files. And it's shorter and easer to read, too.




    <apply executable="cp" dest="output/">
        <srcfile/>
        <targetfile/>
        <fileset dir="source/" includes="**/*.xml"/>
        <mapper type="glob" from="*.xml" to="*.html"/>
    </apply>


    ---
    If you disagree, and somebody has already posted the exact rebuttal that you would use: moderate, don't post.
    [ Parent ]
    Please stop being sophistic: Use cat (none / 0) (#59)
    by tmoertel on Tue Sep 25, 2001 at 05:00:49 PM EST

    There's nothing petty about asking for an honest comparison. But since you assumed the worst of me, I hope you won't mind if I ask you to stop being sophistic. ;-)

    To the point: Hand waving won't hide your substituting cp for cat. The two are not interchangeable; e.g., they handle permissions and pre-existing destination files differently; cat works fine but cp fails when there are multiple prerequisite input files per output file; etc. Moreover, I made it clear in the previous post and in the Makefile's comments that cat was a placeholder -- a stand-in for a real build command with common I/O redirection -- and your buildfile conveniently ignores the I/O redirection.

    If you are interested in an honest comparison, please provide a buildfile that uses cat, just like the Makefile did, and just like I asked you to in my previous post.

    --
    My blog | LectroTest

    [ Disagree? Reply. ]


    [ Parent ]
    You just don't get it (none / 0) (#61)
    by valency on Tue Sep 25, 2001 at 05:37:12 PM EST

    If you desperately need cat, write a one line shell script "cat <$1> $2" and substitute that for "cp" in my ant build file. 99% of the time, this won't be necessary. But if you're going to pick nits like this, that's the answer you're looking for.

    The reason you're so fixed on using cat is that you still can't break out of the Makefile mentality. You're still looking at ant as a glorified shell script interpreter. It's not. You only need to be doing piped redirection up, down, left and right when you're dealing with C/UNIX-era build tools and C/UNIX-era languages.

    This whole exchange reminds me of trying to explain the virtues of type checking to people who've been hacking assembly language for years. The assembly language guy will always be able to come up with some incredibly arcane thing that you can't do in C, and harp on it until you're sick of talking to him.



    ---
    If you disagree, and somebody has already posted the exact rebuttal that you would use: moderate, don't post.
    [ Parent ]
    I *do* get it. Do you? (none / 0) (#62)
    by tmoertel on Tue Sep 25, 2001 at 06:44:53 PM EST

    You're still looking at ant as a glorified shell script interpreter. It's not.
    No, I look at Ant buildfiles as having a substantially more verbose and less flexible configuration syntax than Makefiles, which are tailor made to describe dependency and build relationships and also provide the full power of a shell underneath to accomplish builds.

    The reason I asked you to provide a buildfile that used cat was to demonstrate that it is generally painful to represent build tasks in Ant buildfiles, unless Ant has a built-in core task that matches, or there happens to be a command-line tool that does exactly what you want (without I/O redirection). Otherwise, you're out of luck. You end up writing little scripts (as you suggested), creating classes, or using hacks like an Apply task that calls a shell to do its dirty work. Do you deny that this is the case?

    You only need to be doing piped redirection up, down, left and right when you're dealing with C/UNIX-era build tools and C/UNIX-era languages.
    Baloney. Almost all development related tools, regardless of platform -- including most Java tools, such as javac, jar, javadoc, javah, rmic -- are command-line oriented. The standard way of gluing them together is via I/O redirection, pipes, and conditional execution -- things that shells do exceptionally well. The only reason you don't have to go through hell in order to glue Java tools together under Ant is because they are provided as built-in core tasks. If they weren't, Java tasks would be as staggeringly difficult as the unassailable cat challenge. ;-)

    In fact, if you examine the core tasks, you'll notice that Ant is trying awfully hard to live up to the shell standard. Why, there are tasks for all the good old ``C/Unix-era'' favorites: chmod, copy, delete, echo, exec, gunzip, gzip, mail, mkdir, move, patch, sleep, tar, touch, and zip, among others. I guess since they're in Ant, these old timers must have graduated from the ``C/Unix era'' into the the Hype-Age-Java era? Or perhaps Ant isn't a futuristic as it's made out to be.

    For Java work, both Ant and Make get the job done, and neither seems markedly better than the other. For almost all other types of work, however, Makefiles have the advantage. They work out of the box, without requiring ancillary scripts, classes, or buildfile hacks. Ant doesn't have the same reach.

    --
    My blog | LectroTest

    [ Disagree? Reply. ]


    [ Parent ]
    A man with his mind made up (none / 0) (#70)
    by Will Sargent on Wed Sep 26, 2001 at 02:47:10 AM EST

    "No, I look at Ant buildfiles as having a substantially more verbose and less flexible configuration syntax than Makefiles, which are tailor made to describe dependency and build relationships and also provide the full power of a shell underneath to accomplish builds."

    If that's what you see, then I'm sure no power on earth could convince you otherwise.

    The question is, if you're so convinced why are you spending your time among heathens? I wouldn't touch Make unless I had to, and for reasons which have already been pointed out. You're welcome to disagree, but please don't waste people's time.

    ----
    I'm pickle. I'm stealing your pregnant.
    [ Parent ]
    I think he's being reasonable (I'm no expert) (5.00 / 1) (#71)
    by slaytanic killer on Wed Sep 26, 2001 at 07:09:42 AM EST

    I've done a fair bit with Ant, but I've only had other people work with make. So I'm not certain if make's advantages are that great. But he seemed to be making a fair appraisal of Ant's strengths/weaknesses. It's good for pure Java dev. For other stuff, time for me to learn make.

    I didn't really enjoy writing built-in tasks in Java... That's one reason I'd jump to .NET in a heartbeat, because it was cruel and very stupid for Sun to insist on a one-language platform.

    [ Parent ]
    BTW, what I think he misses... (5.00 / 1) (#72)
    by slaytanic killer on Wed Sep 26, 2001 at 07:12:40 AM EST

    I do think what he misses was Ant's chief strength, which is readability. And plus, it had far less time to gain maturity than make. I have absolutely no problem handing off Ant XML files to anyone else, even nonprogrammers. That's what verbosity gets you.

    [ Parent ]
    A man with his eyes wide open (5.00 / 1) (#78)
    by tmoertel on Wed Sep 26, 2001 at 02:02:34 PM EST

    I wrote
    "No, I look at Ant buildfiles as having a substantially more verbose and less flexible configuration syntax than Makefiles, which are tailor made to describe dependency and build relationships and also provide the full power of a shell underneath to accomplish builds."
    to which you responded
    If that's what you see, then I'm sure no power on earth could convince you otherwise.
    If you disagree with my points, why do you attack me, rather than refute my points? Please stay on topic.

    The reason that I say Ant build files are more verbose and less flexible than Makefiles is because an objective analysis shows that they are -- not because I'm a stubborn mule that refuses to listen to reason. It is precisely because I listen to reason that I still prefer Make.

    Perhaps a demonstration is in order. It is well established that Ant is at its best on Java projects, so I will use the build.xml file from Tomcat-3.2.2 for my example. The first few lines of the file:

    <project name="Tomcat" default="main" basedir=".">


      <!-- ==================== Initialization properties ===================== -->
      <property name="ant.home" value="../jakarta-ant"/>
      <property name="debug" value="on"/>
      <property name="j2ee.home" value="../../j2ee/build/unix"/>
      <property name="jaxp" value="../jaxp-1.0.1" />
      <property name="optimize" value="true" />
      <property name="servlet.jar" value="../jakarta-servletapi/lib/servlet.jar"/>
      <property name="tomcat.build" value="../build/tomcat"/>
      <property name="tomcat.dist" value="../dist/tomcat"/>


    Let's compare them with their Makefile equivalents. (I'm italicizing the Makefile to distinguish it from the Ant build file.)

    Tomcat : main


    # Initialization properties

    ant.home      = ../jakarta-ant
    debug         = on
    j2ee.home     = ../../j2ee/build/unix
    jaxp          = ../jaxp-1.0.1
    optimize      = true
    servlet.jar   = ../jakarta-servletapi/lib/servlet.jar
    tomcat.build  = ../build/tomcat
    tomcat.dist   = ../dist/tomcat


    You tell me, which is less verbose? easier to read?

    Continuing, with the next block of lines from the Ant build file:

      <!-- ======================== Copy static files ========================= -->
      <target name="prepare">

        <!-- Create destination directories -->
        <mkdir dir="${tomcat.build}"/>
        <mkdir dir="${tomcat.build}/bin"/>
        <mkdir dir="${tomcat.build}/classes"/>
        <mkdir dir="${tomcat.build}/conf"/>
        <mkdir dir="${tomcat.build}/doc"/>
        <mkdir dir="${tomcat.build}/lib"/>
        <mkdir dir="${tomcat.build}/lib/test"/>
        <mkdir dir="${tomcat.build}/lib/test/Golden"/>
        <mkdir dir="${tomcat.build}/logs"/>
        <mkdir dir="${tomcat.build}/src"/>
        <mkdir dir="${tomcat.build}/webapps"/>


    and the Makefile equivalent:

    # Copy static files

    prepare :

        # Create destination directories

        mkdir ${tomcat.build}{,/{bin,classes,conf,doc,lib,logs,src,webapps}} \
              ${tomcat.build}/lib/{test{,/Golden}}



    Are you beginning to see a pattern?

    Let's continue:

        <!-- Copy executables and scripts -->
        <copy todir="${tomcat.build}/bin">
          <fileset dir="${ant.home}/bin" includes="ant*"/>
          <fileset dir="src/shell"/>
        </copy>

        <!-- Copy configuation files -->
        <copy todir="${tomcat.build}/conf">
          <fileset dir="src/etc"/>
        </copy>
        <copy tofile="${tomcat.build}/conf/build.xml"
                file="build.xml"/>

        <!-- Copy documentation and other miscellaneous files -->
        <copy todir="${tomcat.build}/doc">
          <fileset dir="src/doc"/>
        </copy>
        <copy tofile="${tomcat.build}/LICENSE" file="LICENSE"/>

        <!-- Copy library JAR files -->
        <copy tofile="${tomcat.build}/lib/ant.jar"
                file="${ant.home}/lib/ant.jar"/>
        <copy tofile="${tomcat.build}/lib/servlet.jar"
                file="${servlet.jar}"/>
        <copy tofile="${tomcat.build}/lib/jaxp.jar"
                file="${jaxp}/jaxp.jar"/>
        <copy tofile="${tomcat.build}/lib/parser.jar"
                file="${jaxp}/parser.jar"/>

        <!-- Copy golden files for the tests webapp -->
        <copy todir="${tomcat.build}/lib/test/Golden">
          <fileset dir="src/tests/share/tests/jsp/Golden"/>
        </copy>


    And, again, from the Makefile:

        CP = cp -r

        # Copy executables and scripts
        $(CP) ${ant.home}/bin/ant* src/shell ${tomcat.build}/bin

        # Copy configuation files
        $(CP) src/etc build.xml       ${tomcat.build}/conf/build.xml


        # Copy documentation and other miscellaneous files
        $(CP) src/doc LICENSE         ${tomcat.build}

        # Copy library JAR files
        $(CP) ${servlet.jar}          ${tomcat.build}/lib/servlet.jar
        $(CP) ${ant.home}/lib/ant.jar \
              ${jaxp}/jaxp.jar        \
              ${jaxp}/parser.jar      ${tomcat.build}/lib

        # Copy golden files for the tests webapp
        $(CP) src/tests/share/tests/jsp/Golden ${tomcat.build}/lib/test/


    Notice any difference in the signal-to-noise ratio?

    Shall we continue?

        <!-- Fixups for line endings and executable permissions -->
        <fixcrlf srcdir="${tomcat.build}" includes="**/*.sh" cr="remove"/>
        <fixcrlf srcdir="${tomcat.build}" includes="**/*.bat" cr="add"/>
        <chmod perm="+x" file="${tomcat.build}/bin/ant"/>
        <chmod perm="+x" file="${tomcat.build}/bin/antRun"/>
        <chmod perm="+x" file="${tomcat.build}/bin/jspc.sh"/>
        <chmod perm="+x" file="${tomcat.build}/bin/startup.sh"/>
        <chmod perm="+x" file="${tomcat.build}/bin/shutdown.sh"/>
        <chmod perm="+x" file="${tomcat.build}/bin/tomcat.sh"/>
        <chmod perm="+x" file="${tomcat.build}/doc/appdev/sample/build.sh"/>


    And the Makefile version:

        # Fixups for line endings and executable permissions

        find ${tomcat.build} -name '*.sh' | while read F; do \
            tr -d \\015 < $$F > $$F.fixcr && mv $$F.fixcr $$F; done
        find ${tomcat.build} -name '*.bat' | while read F; do \
            sed 's/\n/\r\n/g' < $$F > $$F.fixcr && mv $$F.fixcr $$F; done

        chmod +x ${tomcat.build}/bin/{ant,antRun}
                 ${tomcat.build}/bin/{jspc.sh,startup.sh,shutdown.sh,tomcat.sh}
                 ${tomcat.build}/doc/appdev/sample/build.sh


    Here Ant shows its first small win with its fixcrlf built-in core task. It takes two lines of shell script to duplicate the behavior in the Makefile. Nevertheless, the Makefile version of this chunk is still the smaller of the two.

    By now I've converted the first quarter of the original Ant build file. The resulting Makefile is smaller, simpler, less verbose, and less noisy. If you look through the remainder of the build file, I think that you'll agree that it is mostly meat-and-potatoes stuff much like I converted earlier. Even in Java projects, most of the build work is still meat and potatoes, where Make shines. No doubt there are a few quintessentially Java-specific places where Ant shines, but if you were to finish the Tomcat exercise I have little doubt as to the overall result: By any reasonable, objective measure (e.g., S/N, verbosity, redundancy, overall size, etc.), the Makefile would be the winner.

    In the future, please don't dismiss my views so hastily. The reason I prefer Make to Ant isn't because I'm stuck in my ways. It's because I've done my homework (rather than taking somebody's word for it) and found Make to be no worse than Ant for Java-related stuff and markedly superior for just about everything else.

    But maybe I'm just living with blinders on. Perhaps you would be so good as to show me the light by converting a heavy-duty non-Java Makefile over to Ant? ;-)

    --
    My blog | LectroTest

    [ Disagree? Reply. ]


    [ Parent ]
    From the Ant side (5.00 / 2) (#80)
    by slaytanic killer on Thu Sep 27, 2001 at 04:24:04 PM EST

  • You wrote:
    Perhaps a demonstration is in order. It is well established that Ant is at its best on Java projects, so I will use the build.xml file from Tomcat-3.2.2 for my example. The first few lines of the file:
    Then you showed a tedious Ant property list. That looks like either a mistake or just formalism. You can simply just write an Ant .properties file that looks exactly like your Make example, sans the Tomcat : main line.

    Just use:
    <properties file="props.properties" />

  • Your next example was a long list of mkdir's. Well, that should go about as fast, because you'd use cut & paste. Once you have the first line, which itself is partly constructed from another line, you just make a few copies, fill in the data, and you're done.

    Also, you may be coming from the perspective of using a text editor. However, many use XML editors for Ant. Maybe there aren't that many great XML editors, but that could be a function of the decades lead Make and text files have had.

    When people decry XML as not made for being wonderfully human-readable, they really assume you'll be using something like vi to read it.

    Also, if you look at the two examples, Ant's syntax is much more regular, which probably is more important to readability than brevity. Not to mention that XML can be displayed in many flexible ways which are extraordinarily readable.

    Quick, if you had to write a GUI frontend to either Ant or Make, which would you choose?

    [ Parent ]

  • not handled by ant (none / 0) (#87)
    by Ranger Rick on Sat Sep 29, 2001 at 01:12:34 PM EST

    ...because it's the job of XSLT. One of the reasons they went with XML is because there are numerous tools that already exist for generating and manipulating XML files.

    :wq!


    [ Parent ]
    Not widely used? (2.33 / 3) (#19)
    by jdludlow on Mon Sep 24, 2001 at 11:29:45 PM EST

    You say that ant is not widely used. How do you arrive at this conclusion? I use ant all the time, but I don't remember ever telling anyone that I was doing so.

    dependency detecting (4.25 / 4) (#20)
    by sesquiped on Tue Sep 25, 2001 at 12:54:29 AM EST

    I've had some experience with make, so I'm going to use that to illustrate my point: a makefile line for Foo.class obviously depends on Foo.java, but it might also depend on other classes in the package, like Bar.java. It's generally not a good idea to write down all those dependencies manually, since they're bound to change and then the actual depencies won't match what make is working with. My question, then, is how do you create makefiles that contain the true dependencies amoung files in your project? With C, you can use commands like gcc -MM, which lets the compiler figure them out for you. But in Java, it's much harder to figure out dependencies because you don't have to explicitly import anything. It's more of a job for the compiler, and indeed, many Java compilers will figure them out for you and only recompile what has changed if you run them as 'javac *.java'. But if the compiler does this already, then where does a build tool fit in?

    Sorry that was so rambling...

    javac *.java doesn't scale (4.00 / 1) (#23)
    by Carnage4Life on Tue Sep 25, 2001 at 03:55:57 AM EST

    It's more of a job for the compiler, and indeed, many Java compilers will figure them out for you and only recompile what has changed if you run them as 'javac *.java'.

    This works if you are writing a small application where all the source files are in a single directory. On the other hand, what happens if you have a complex app with several packages in several different directories? How would you manage compiling a single package or would you simply compile you entire application that may contain hundreds of files to compile a package that may contain only 5 files that may depend on 10 more in another package?

    [ Parent ]
    Why use javac... (5.00 / 1) (#26)
    by rossyb on Tue Sep 25, 2001 at 04:27:17 AM EST

    JavaC is slow - it's a sample compilier and nothing more IMHO. Jikes however, is excellent. Fast, reliable, in fast active development (find a bug in Javac and you'll have to wait for the next Java release) and handles "jikes `find . -name *.java`" very well thankyou very much. Excellent dependancy tracking. Also, when used outside of a Make/Ant environment put it in "incremental" mode and jikes won't quit after compiling. Then, hit space again and it will recompile the files which changes since the last compile (following dependancies of course)

    Very nice.



    [ Parent ]
    Only a piece of the puzzle (5.00 / 1) (#40)
    by ttfkam on Tue Sep 25, 2001 at 11:49:51 AM EST

    What about creating *.jar files? *.war files? *.ear files? Are you going to do it over and over by hand? You will if you only use Jikes. What about copying the *.class files to a different directory? You don't want to put the *.java files in the *.jar file do you?

    The compiler is the most important component of the build process to be sure, but it not the only important build component.

    If I'm made in God's image then God needs to lay off the corn chips and onion dip. Get some exercise, God! - Tatarigami
    [ Parent ]
    but how? (5.00 / 1) (#66)
    by sesquiped on Tue Sep 25, 2001 at 09:49:56 PM EST

    My original comment wasn't very well-worded, so let me clarify. I only mentioned the stuff I knew because I knew it. I would like to learn more, though, so I have about two questions:

    How does ant handle java dependencies?

    What can you do with and around make to allow it to handle java dependencies?

    [ Parent ]
    Java dependency checking is probably impossible.. (none / 0) (#30)
    by pijokela on Tue Sep 25, 2001 at 10:07:14 AM EST

    I have never seen a build system for Java that handles dependency checking correctly. Jikes might do it - I haven't tried that.

    Ant(javac really) or javac or Codewarrior 6 or Visual Cafe 4 all fail miserably.

    I have simply learned to first try compiling the changed files (for example: javac *.java) and when that fails I just recompile everything.

    I think it may well be impossible to do 100% dependency checking in java. Or at least the dependency checking will be as hard as just compiling everything. I would really like to get something like .h files to Java to help with this issue. Of course heavy use of interfaces does help.

    With few or no interfaces it is easy to realise that most files in a project depend on each other.

    [ Parent ]
    Not supposed to (4.50 / 2) (#39)
    by ttfkam on Tue Sep 25, 2001 at 11:45:30 AM EST

    A class which only talks to an interface isn't technically dependent upon a class that implements that interface. It is only conceptually dependent and therefore outside the scope of dependecy algorithms. That's the point of an interface. It's also the reason for a build system. You can tell the build system to compile all of the files in a particular directory; for example, all of the implementation classes for a particular interface.

    Or there's
    % jikes `find . -name *.java`
    - or -
    % javac `find . -name *.java`

    But that's UNIX-specific...

    If I'm made in God's image then God needs to lay off the corn chips and onion dip. Get some exercise, God! - Tatarigami
    [ Parent ]
    right... (5.00 / 1) (#64)
    by sesquiped on Tue Sep 25, 2001 at 09:37:17 PM EST

    Right. If the interface of a class (I'm using "interface" here in the general sense of everything that's not implementation) doesn't change, then other classes that use it don't have to be recompiled. This is similar to how C programs that use a shared library don't have to be recompiled when the library changes.

    But if some type in the "interface" changes, or the number of parameters to some function, then every classes that uses it will have to be recompiled. So, how does ant deal with dependency analysis? Also, are there any good techniques to get make to handle it too?

    [ Parent ]
    Depend task (none / 0) (#68)
    by donaldp on Tue Sep 25, 2001 at 11:34:37 PM EST

    Ant has the depend task that will create correct dependency setup by deleting all classes that implement the updated interface. The only time it doesn't work is when you use a static final primitive value from another class and that other class has the value updated. The reason being that Javas .class file format inlines such values which makes it impossible for Depend task to "know" about the source for constant.
    Cheers, Pete
    [ Parent ]
    Dependency checking is impossible. (none / 0) (#88)
    by jgraf on Wed Oct 03, 2001 at 03:41:49 AM EST

    class Example {

    public static void main(String[] args) throws Throwable {
    Class klass = Class.forName(args[0]);
    Object obj = klass.newInstance();
    System.out.println(obj.toString());
    }

    }


    [ Parent ]
    antfarm (4.33 / 6) (#21)
    by macpeep on Tue Sep 25, 2001 at 01:35:12 AM EST

    At work, we need to compile our app (non-Java) on several platforms. We solved this problem by coding our own version of ant that is remotely controllable, and that sends its logs remotely, over RMI, to a central server. On the central server is a web based tool that allows one to control the remote ant's, as well as view the build log history. With this system, engineers can build to any target platform from their own desk, and view the logs. At the same time, the system acts as a continuous build system.

    Doing things like this is *SO* much easier with ant and Java than with make.

    not so hard (4.00 / 1) (#27)
    by brlewis on Tue Sep 25, 2001 at 09:08:45 AM EST

    ssh otherhost '(cd $builddir; make all |& tee all.log)'

    [ Parent ]
    Re: not so hard (none / 0) (#32)
    by macpeep on Tue Sep 25, 2001 at 11:10:05 AM EST

    What part of "multiple platforms" did you not understand? :)

    [ Parent ]
    Re: not so hard (none / 0) (#36)
    by LukeyBoy on Tue Sep 25, 2001 at 11:15:04 AM EST

    LOL works on my Win2K machine with no problem actually (thank you Cygwin!).

    [ Parent ]
    xp (none / 0) (#41)
    by macpeep on Tue Sep 25, 2001 at 11:58:07 AM EST

    It's not issuing the command remotely that is the problem. Every platform, more or less, have ports of SSH to it. The problem is the platforms that the building takes place on (pretty complex and varying toolchains). On one, we build for EPOC, on another for Windows CE, on a third for a bunch of mobile Linuxes and so on. If a developer wants to build on EPOC but there's already a build in progress, we also have to wait until the build is finished. The logs and output of a developers build have to be available to all other developers - same for the automated builds. Setting up the buildfiles also has to be easy so that adding a file to the build isn't a pain in the ass (so you won't have to do it for each and every single platform). ant goes a long way to solve this since it makes it easy to code extensions. I'm not saying it's impossible with make - I'm saying it's way easier with ant.

    [ Parent ]
    I smell a religious war coming on... (3.37 / 8) (#22)
    by Will Sargent on Tue Sep 25, 2001 at 03:45:51 AM EST

    Ant is not Make. Make is not Ant.

    In some respects, this argument mirrors the "Java vs C++" wars that make their way around Slashdot every so often. Java is slower, simpler and more restrictive than C++. However, what it loses in flexibility it makes up for in pluggability. It's very easy to write new TaskDefs if you need to do something in Ant, and you can use the pre-built stuff or exec for everything else.

    I've used Ant in situations involving over 20 developers and N designers and multiple J2EE projects. If I tried to use Ant on Mozilla, I'd be screwed, but I think this is missing the point: Java has less moving parts than C++, so I don't NEED the flexibility of make. That's why it works so well.
    ----
    I'm pickle. I'm stealing your pregnant.
    What's wrong with religious wars? (none / 0) (#58)
    by jacob on Tue Sep 25, 2001 at 04:40:41 PM EST

    Well, when they're the virtual kind that has to do with programming anyway. Java vs. C++ is the best thing that ever happens on Slashdot, or here either for that matter ... well, just see the link in my .sig.



    --
    "it's not rocket science" right right insofar as rocket science is boring

    --Iced_Up

    [ Parent ]
    Dynamic targets (4.25 / 4) (#25)
    by 3john on Tue Sep 25, 2001 at 04:00:53 AM EST

    If dynamic targets and such appeal to you, have a look at the <SCRIPT> task .
    You can use python and jaavscript in your tasks. Make sure you actually *work* through the example, too. It is more than it seems at first glance.

    Example of a dymanic target? (none / 0) (#34)
    by kostya on Tue Sep 25, 2001 at 11:11:10 AM EST

    I'm not sure I understand exactly what the author means by dynamic target, but maybe this is an example.

    Our build process is pretty rapid, so it's very important that we know the exact build of a jar file, especially when we publish them to other groups. Our dev process commits version changes only when they make it to a production situation. So SIT foo113.jar from yesterday could be three builds away from foo113.jar of today.

    The solution is to automatically (or at least easily) increment build numbers and then to keep a record of how the jar was created in the jar (basically a log of the build is included). This requires writing state out to a file, and then reading that state from a file. I don't use ant, so I'm not sure how easy that is with ant. It isn't all that hard in make, but it is hard with make on NT because NT's cmd shell bites. My solution was to use perl for number handling (ever try to work with numbers in NT batch?) and then write the state file as a makefile. Each project then includes its statefile if it exists and then uses the version numbers and history to determine the jarfile name and version.

    In our case, we needed simple make files that developers could just add or subtract lines to but would have the entire automated build and history logging built in. Actual changes required by a developer of a new project are about 10 lines maybe. We just used a lot of includes. I can rebuild 6 projects from scratch in about 2 minutes (jikes rocks)--and that includes probably 6 EJB compiles.

    Someone who knows ant should feel free to enlighten me ...



    ----
    Veritas otium parit. --Terence
    Full of incorrect information (4.50 / 8) (#35)
    by mulvaney on Tue Sep 25, 2001 at 11:15:03 AM EST

    1. Ant does not recompile everything each time you run it. It only recompiles .java files that are newer (timestamp) than the .class file. The only way to get it to recompile everything is to have some kind of clean rule, which would delete all the .class files. Are you calling a clean rule before your compile rule every time?
    2. Ant has a very large number of users. Virtually every java project available on the web uses ant. Check all the different Apache projects, including such important projects as Tomcat and the Xerces.
    3. It is easier to integrate with CVS than you imply. You could do your tag rule with the command:

      <cvs command="tag mytag" />

    4. Ant has great documentation at http://jakarta.apache.org/ant. By looking at it for 15 seconds I found the <availble> command, which can be used to determine if a file exists (which would solve the other problem you had with ant.)
    I work on a large java project that switched from Imake/make to ant a few months ago. It has been a very successful switch.

    I have a couple of questions about how you used make.

    1. Did you edit the Makefiles directly? You don't mention using Imake or anything else to generate them. It would seem that editing all those Makefiles directly would be a nightmare...
    2. What kind of rules did you use to compile the java classes? Did you invoke a javac for each different .java file, with a rule like:
    foo.java : foo.class
    javac -d /bar foo.java
    Or something like that? (My syntax may be off a little bit, its been a while since I used make :) If that is what you used, then that is why ant is so much faster. Invoking a new javac for each class is prohibitably expensive.

    Assuming that you did it that way, how do you account for circular dependencies in java files? Did you make rules to compile several files at once?

    This is one of the problems we had with Imake. Our rules required us to edit the Imakefile with each source file we added, and make sure that we compiled things in the correct order. I think this is the most compelling reason to use ant over make: make just doesn't work for java dependency relationships.

    With ant, you don't have to worry about stuff like that, and you can think like a java developer and not a C programmer.

    -Mike

    Re: Virtually every java project available on ... (5.00 / 1) (#65)
    by jonabbey on Tue Sep 25, 2001 at 09:49:11 PM EST

    Aw, Mike, I'm hurt. You know Ganymede isn't using Ant.. ;-)

    It is awfully tempting to move to Ant, though. I worked with a consultant who moved the ARL timesheet JSP/JDBC app to Ant, and it looked pretty darn sweet, albeit a cognitive shift from Makefiles (what, no tab-delimited syntax?!).

    Ganymede is using custom Perl scripts and Make right now, and there's inertia there not to break things, especially when it would lead to a new dependency that people would need to have in order to build things, but sooner or later I'll probably tackle it in order to support building Ganymede on Win32, etc.


    Ganymede, a GPL'ed metadirectory for UNIX and friends.
    [ Parent ]
    make? (none / 0) (#83)
    by mulvaney on Fri Sep 28, 2001 at 05:08:49 PM EST

    Heh, the first thing I did when I left ARL was to write myself a copy of the build.perl scripts. I used them at my current job for months, until we switched to ant. Actually, in my version, it would check the Imakefile to make sure that file was listed in there before it added it to the build.

    I am so glad we are not using make any more. ant has solved every problem for us in the java world. We still use make to do our builds actually, because we have a lot of perl/tcl/C stuff, but when it gets to a java based directory the make rule is basically 'ant'.

    I can't think of an easier way to build java projects than ant.

    Anyway, I don't see any Makefiles in the Ganymede CVS, so I don't know how you are building stuff now. It would be non-trivial to switch to ant though, because ant requires your source to be laid out in the same hierarchy as the class files. so you would have to put all the code in the arlut.csd.ganymede package in the arlut/csd/ganymede directory. Obviously, you don't have things laid out like that now, so it would require some serious CVS mucking. :)

    -Mike

    [ Parent ]
    javac, blach (4.00 / 2) (#37)
    by hardburn on Tue Sep 25, 2001 at 11:34:05 AM EST

    While javac is nice in that everyone with a JDK already has it, I prefer jikes. It is much, much faster then javac, and has some of the best debugging output I've ever seen in a compiler (not that I would know much about that; my code compiles perfectly the first time . . . )


    ----
    while($story = K5::Story->new()) { $story->vote(-1) if($story->section() == $POLITICS); }


    works with ant... (none / 0) (#86)
    by Ranger Rick on Sat Sep 29, 2001 at 01:06:26 PM EST

    ...with a single option:

    ant -Dbuild.compiler=jikes [project]

    :wq!


    [ Parent ]
    But you clearly *don't* know Ant (4.54 / 11) (#44)
    by lordpixel on Tue Sep 25, 2001 at 12:42:11 PM EST

    I read your "please read before responding" but I'm going to say it anyway:

    Clearly you know make a _lot_ better than you know Ant. So you commit the classic fallacy of trying to do what you do in make the same way in ant. Sometimes that fits, sometimes ant just does it differently.

    You should have spent more time on the ant-user mailing list - you'd understand how to do many of the things you ask about.

    You're also not doing your argument any favours by failing to understand the basic dependancy rules for compiling Java. It makes you come accross as a C programmer who's trying their hand at Java - fine, but I'm not going to be immediately impressed by the "depth" of your analysis in this case either.

    As for the "more users" argument - ant's userbase is only small by the standards of a tool which has been around for decades like make. Its userbase is *huge* by most project's standards, and its focussed almost entirely on Java, whereas Make can barely handle basic Java dependancies, let alone give me the power to intergate something like JUnit or Weblogic. Sure I can always call it on the command line, but...

    You're right. BEA have changed their EJB tool definition with every major release. And ant has followed every change, because it hasa highly active community. With make, *you* would have had to update your makfile because the syntax of the command line tools changed. With ant, its done for you, and if you need it sooner, guess what, you can use command line tools from inside ant (or code it yourself in Java and contribute it back to the project if that's sensible for you).

    Yes, there is sure to be some class of problems where make is better - I used it myself to build Java projects before ant came along, its certainly capable - but most people will waste time in make if Java is what they're doing.



    I am the cat who walks through walls, all places and all times are alike to me.
    Autoconf/automake? (none / 0) (#46)
    by tjansen on Tue Sep 25, 2001 at 01:58:10 PM EST

    I wonder why nobody mentioned autoconf/automake. There is a number of Java-macros and they make configuring the make environment and installation quite easy. IMHO they are a good choice for Java development as well, especially for open-source software (because with a wide distribution of the source it gets harder to make assumptions about the make environment, so you need that autoconfiguration and installation stuff).

    Ant scales well (4.80 / 5) (#51)
    by yigal on Tue Sep 25, 2001 at 03:08:20 PM EST

    At my company we switched to Ant more than one year ago (back in the times of Ant 1.1). Now, after more than a year, it still works and it is still editable. In my opinion, this is largely due to the fact that Ant is much more verbose than Make.

    When auto-building a release, Ant will help us to compile hundreds of classes, put it in a fair number of jarfiles and copy files around, in the meanwhile creating zipfiles, tarballs, tagging and committing stuff, and using XSLT stylesheets to convert our docbooks documents into HTML. And when all is finished, it uploads the code to the Spot You Want. All this takes less than half an hour. And then we have a fully functional release, one for Windows, one for Linux, and one for the CD.

    And the neat integration with JUnit allows for a very fast edit-compile-failure-debug cycle. Completely compatible with Emacs.

    Just my happy experiences.

    YDD
    .sigmentationfault

    10 months with ant... (4.50 / 10) (#57)
    by technik on Tue Sep 25, 2001 at 04:22:45 PM EST

    10 months with ant and it is currently building 33 (today's count) products in three project areas across seven different teams in two companies and targeting both NT and Unix running Java1 and Java2 under ServletExec, JRun, Tomcat, WebSphere, and WebLogic (So many standards, so little time...). I first mentioned it in a diary entry on Advogato. Thanks to JPython I was able to quickly hack together support for PVCS (that VM is a wretched mess) which at the time was not supported. Some of these products were begun in 1997 and, mostly because no one knew better, have convoluted build requirements.

    The build system is maintained by the individual developers who, following the existing work, need about fifteen minutes of explanation before they're able to put together new product builds. Ever explain make in fifteen minutes? Me neither. That's a success right there.

    The SCM people love it because they can perform the builds from scratch themselves with simple commands (ant <project>, ant <product>, ant <product> -Dversion=1foo2bar3.0, etc.). They are generally former mainframe QA or developers and distributed systems look like an awful mess to them. I packaged up all the necessary tools and libraries including stable JDKs so they can start with a bare OS and have a working build in a few minutes. Sure, I could have done that with a native tool chain but having everything under the JVM makes for easier acceptance (even if it's not necessarily the best idea, for lots of reasons).

    I'd love to see what commercial build tools can do, but since I'm a fixed cost it's better for them in the short-term to let me do it myself than to shell out and hope that it works.

    - technik

    Jam. (none / 0) (#60)
    by i on Tue Sep 25, 2001 at 05:27:58 PM EST

    I wonder where Jam and FT Jam stand in the grand scheme of things.

    and we have a contradicton according to our assumptions and the factor theorem

    jam (none / 0) (#85)
    by Ranger Rick on Sat Sep 29, 2001 at 01:03:50 PM EST

    introduction to ant.

    :wq!


    [ Parent ]
    make bias (4.50 / 2) (#73)
    by jilles on Wed Sep 26, 2001 at 07:22:03 AM EST

    I have worked with ant recently and I think you have overlooked a few things and dismiss ant to easily:

    - Ant is XML based. This means that tool support is very easy. A good example is netbeans that allows you to create ant files in a point and click fashion (you can also edit the xml by hand or even do both). I would defininately call this an advantage. As ant becomes more popular, I expect that most java IDEs will integrate it with their project management.
    - Compilation of java source code pretty much scales linearly. This is because you don't have a linking phase until run-time. In other words most dependencies are resolved at run-time rather than compile time. Therefore compiling all sourcefiles shouldn't be a problem, especially if the compiler skips files that don't need recompilation.
    - Tool creators can actually include ant tasks. A good example is AspectJ that bundles ant tasks with their tools. This combined with tool integration should make it easy to integrate new tools into your build file.
    - With make you also break compatibility if the tools you call are updated (and for example have a changed command line interface). The problem with make however is that you will have to debug the script whereas with ant you can fix the task definition (e.g. to be backwards compatible) without ever touching the uses of the tasks.

    I agree that ant right now is most suitable for usage in combination with Java. However, it is all XML and it shouldn't be hard to create a C version of it. Make is a relic of the past. Using it costs you in terms of maintenance (of the build files). The syntax is awkward at best and very error prone (I recall having spent an entire afternoon once figuring out that I should have used a tab instead of four spaces). The worst thing about make is that it mixes configuration and tools. Ant separates the two since ant files only define properties and parameters. The actual tools are singled out in task definitions which are designed to be reusable rather than the ad hoc sripting often found in make files.
    Regards, Jilles
    Interesting points.... (none / 0) (#76)
    by GusherJizmac on Wed Sep 26, 2001 at 01:31:33 PM EST

    While I agree it's possible to write Makefiles as you describe, there's no reason you have to, and a well-written makefile can take advantages of everything you describe.

    Maybe you are used to a different way of working, but at most jobs I've had, the developers do not edit or create makefiles. At most, the lead engineer of the project will provide config options to a generic makefile at the start of the project, and that makefile handles compilation, etc. That file is maintained by a Release Engineer/Buildmaster, who's main job it is to see that compiling and deployment happen smoothly w/out the developers worrying about. Customizing a Makefile is incredibly simple. Using ant is more complex, especially if you end up having to write Java code to do it.

    Building and deploying code is a procedural, system level task. That is not something Java is good for (nor was it intended to be).

    In terms of XML, again, I don't see that as an advantage, because the average developer shouldn't be editing the buildfiles, and ant's loose syntax prevents a DTD from being created, so you don't get much benefit from the XML.
    <sig> G u s h e r J i z m a c </sig>
    [ Parent ]

    RTFM (4.00 / 6) (#74)
    by nichughes on Wed Sep 26, 2001 at 07:56:51 AM EST

    I got as far as
    You bascially have two choices to integrate ant with other systems (e.g. clear case if you don't use CVS): writing a java class, or using the Exec... builtin command.
    before I gave up on the article. If you are not familiar with the tasks available in Ant then you are preaching from a position of ignorance. Clearly you are trying to emulate Make using Ant, a classic mistake akin to writing procedural code in an OO language made worse by your own failure to read the user docs.

    Please refer to the user documentation. You will find that there is CVS support in one of the core tasks and Clearcase support in an optional task. I can vouch for the fact that the CVS support is more than adequate for any need we have come across in the past year.

    --
    Nic

    I wasn't talking about the existing tasks.... (4.00 / 2) (#75)
    by GusherJizmac on Wed Sep 26, 2001 at 01:22:58 PM EST

    Part of something someone might be interested in with regard to a build tool (or any tool) is how easy it is to integrate it with other tools that are not directly supported by default. I didn't know Clearcase had support, but replace that in my example with some other source control tool.

    The point was that if you want to integrate with something that ant doesn't currently support directly through builtin tasks, you either have to write your own builtin task or use the <Exec...> builtin task.

    With regard to my comments that calling command line tasks from Java is not that great, I've done a fair amount of system programming in C and PERL, and when I tried to create similar systems using Java, it just wasn't flexible enough at all. Java isn't made for systems programming, and a real build system for a serious project is a system thing and can require a lot of system level tasks to be performed; it's not just about compiling code.

    Additionally, the other point of that portion of it was that ant tries to think of everything you could want and have a builtin task for it. Make doesn't give you anything you want, rather it lets you do whatever you want. They are two different philosophies on how a tool should work. Do you make it less flexible, but easier to use for most common tasks? Or, do you make it incredibly flexible, but difficult to get going with?

    The point is that once you learn the more difficult, but more flexible system, that's what you should use, and for serious projects, you need flexibility.
    <sig> G u s h e r J i z m a c </sig>
    [ Parent ]

    Ant is extensible (none / 0) (#82)
    by nichughes on Fri Sep 28, 2001 at 04:11:00 AM EST

    Ant can be extended in a controlled and reusable manner, the way this is apprached is more a product of the Java philosophy than anything the Ant team have come up with. If you have a team of Java developers you should have no trouble at all extending Ant, if you do not what on Earth are you doing using Ant anyway?

    --
    Nic

    [ Parent ]

    Innovator's Dilemma (4.33 / 3) (#77)
    by ajm on Wed Sep 26, 2001 at 01:36:13 PM EST

    I think Ant is a pretty good example of the Innovator's Dilemma in action. Make is fantastic, it does, or can be made to do, just about anything that you need done in a build system. The average user makes use of a small fraction of the capabilities. Ant does less than make. However, ant completely satisfies some fraction of make users because it satisfies their requirements, and offers, for java developers, an orthogonal advantage, java integration, that make cannot. p.s. When I first looked at Ant I was also put off by the dismisal of make as evil. Stupid. Ant could certainly benefit from dependency analysis and other of make's features. Though it's great it is to some extent a reinvention of the make wheel in a less round form.

    Why not Imake? (3.00 / 1) (#79)
    by jcrosbie on Thu Sep 27, 2001 at 03:41:53 PM EST

    Why did the author write a Make build system to build for multiple platforms when Imake exists to do just that? Check out the X project for more info.

    Ant (5.00 / 6) (#81)
    by donaldp on Thu Sep 27, 2001 at 09:59:07 PM EST

    Hi,

    Theres some serious faults and innaccuracies in the above article regarding ant but that is excusable given that the author admits he is not that familiar with ant. Many of the more obvious faults have been corrected.

    However there is one pervading theme through the whole article. Namely he doesn't list simplicity as a pro for ant but does list complexity as a pro for make ;) I suspect he may be a build engineer or at least worn that hat at one time. IMO one of the biggest advantages of Ant is it's simplicity. Most users of ant pick up the basics of ant in 10 minutes and many are non-technical / non-programmers. The same can not be said about make. Any decent sized make setup virtually mandates a make guru on hand and can make it difficult for people other than make gurus to work with.

    I have used (GNU) make for far longer than ant has existed, but I am a committer for ant so I think I can say that I am reasonably familiar with both systems. Both have their strengths and both have their weaknesses. Personally I still use make for all my native compiling but use ant for all my xml, java and content related builds. Sometimes I throw a custom tcl system in there for good measure ;)

    There was a lot of issues brought up in response to this article. In many cases they are invalid or they tried to compare the worst of ant with the best of make (file copying and mkdir example). However there are two good examples of faults with the ant system. Namely

    1. ant doesn't deal well with complexity
    2. ant interacts with the system using java specific methods in most cases and thus is limited by java

    (1) is a recognized fault and will be addressed (hopefully) when Ant2 comes out. Time will tell if we succede in removing that failing.

    (2) is also gradually being fixed when the need becomes apparent.

    Anyways this kinda reminds me of the cgi vs servlet argument. Servlets are vastly simplified and can not be scripted without using other infrastructure. So instead of cut/copy/munging scripts you are actually forced to reuse at the component level. Servlets are much faster than cgi, require more knowledge to write but are far simpler to use. I suspect the same is true of tasks. Faster, harder to write and easier to reuse.

    However given that current ant solves 90% of the problems of most people who write java products need to be solved but is far more accessible than make I can't see it's popularity diminishing, nor it's rate of growth.

    I am sure some peeps will say that because it doesn't do X it is useless - much like they used to say that because C didn't do Y (while assembly can), thus C must be useless. ;)
    Cheers, Pete
    ant and large build systems (4.00 / 2) (#84)
    by Ranger Rick on Sat Sep 29, 2001 at 12:57:34 PM EST

    One of the reasons we went with ant instead of make is make's unsuitability to working with Java code. Yes, it can be coaxed into working with the way java builds, but it's a terrible pain in the ass.

    Our office is filled with Java coders, not build engineers. If I, with my defacto job of build engineer, were to use make, it would be just another thing that only I understand enough to tinker with. When you're job is supporting your programmers, being the only one who is able to modify the build system is not conducive to getting things done.

    Our entire codebase is based on Java and XML; ant is immediately understandable to anyone who works with our build, and, if we need to make additional tasks or classes, we have plenty of coders who are able to whip something together very quickly.


    :wq!


    Maintenance (4.00 / 1) (#89)
    by damphlett on Wed Oct 03, 2001 at 04:37:16 AM EST

    The people I work with place high value on being able to move jobs between staff, and even bring new staff in on a job. - .

    ANT files are just really self explanitory - you actually have to try to make them unreadable.

    Make files can range from reasonable to plain bizarre. Most people understand their own, but there are many different styles

    Comparing ant and make as Java build tools | 89 comments (82 topical, 7 editorial, 0 hidden)
    Display: Sort:

    kuro5hin.org

    [XML]
    All trademarks and copyrights on this page are owned by their respective companies. The Rest 2000 - Present Kuro5hin.org Inc.
    See our legalese page for copyright policies. Please also read our Privacy Policy.
    Kuro5hin.org is powered by Free Software, including Apache, Perl, and Linux, The Scoop Engine that runs this site is freely available, under the terms of the GPL.
    Need some help? Email help@kuro5hin.org.
    My heart's the long stairs.

    Powered by Scoop create account | help/FAQ | mission | links | search | IRC | YOU choose the stories!