xml-general mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stefano Mazzocchi <stef...@apache.org>
Subject Re: Makefile's
Date Thu, 25 Nov 1999 13:23:32 GMT
Dirk-Willem van Gulik wrote:
> 
> I am looking at various makefile options, gmake vs make vs Ant. 

I'm happy you brought this up. In my experience, I learned my little
make _after_ knowing my big java. So I must admit I'm totally
unaccustomed to the makefile "design patterns" or style guidelines.

I wrote the cocoon makefile and, gee, I can tell you it sucks pretty
bad. But it does the job for me and I'm a very lazy guy (reason why
Cocoon uses 8 external packages? I was to lazy to write them :)

So, I'm happy to find out if I'm missing something and what are the best
ways of building software.

Anyway, I'll discuss my opinions in building java file and all the
different methods I've found in my experience (mostly on highly modular
and dynamically loaded server side stuff, which is not the easiest part
of Java)

> Is there a good reason why a lot of OS java author's seem prefer
> 
>         1.      to simply compile everything in one javac statement
>                 which has been CD's to the right output
>                 directory. Regardless of wether all java files need
>                 to be recompiled.
> over
>         2.      compile everhting and use a -o/-d/-xxx output
>                 specifier
> over
>         3.      defined dependencies and do it file by file
>                 instead of all, and only when needed
> 
> Is there a good reason ? Are dependencies too hard ? Or do (some)
> compiler's work this out themselfes well enough ?

First: javac sucks. Even Sun knows that (in fact the have a new version
rewritten from scratch that does a better job).

Second: java dependencies are _impossible_ to determine when dynamic
loading is extensively used.

For example:

 javac -cp . Main.java

tells javac to compile Main.java and, given the classpath, it's able to
produce all the dependency classes in one shot. Also Jikes is able to do
that.

But suppose your main does something like this

 public class Main {
   public static void main(String[] a) {
     ((Module) Class.forName(a[0]).newInstance()).run();
   }
}

public interface Module {
  void run();
}

public class MyModule implements Module {
   public void run() {
     System.out.println("I'm your favorite module");
  }
}

javac will find a dependency for Module and will compile the two classes
Main.class and Module.class, but will find no evidence of MyModule.

Cocoon uses such a dynamically binding architecture based on OO
polymorphism in a very extensive way. You won't be able to compile
something like that using a simple "javac" call like the one above.
 
> And secondly, why is there such a strong desire to move the *.class
> file's far away from the source ?

This is due to the classpath problem.

I usually have one (or more) directories where I put all my java files
(c:\java\classes on win32, /usr/local/java/classes on unix) and I place
this in my classpath so that I don't have to modify it every time I
compile something.

Doing "javac -d /usr/local/java/classes ..." allows me to forget about
classpath problems (unless class conflicts occur but this is another
issue).

> (i.e. from make:)
> 
> ----
> something:
>         ( cd somewhre; $(JAVAC) $(JAVACFLAGS) $(SRCS))
> ---

This is because usually the classpath includes the "." directory.

> over
> 
> ----
> something:
>         $(JAVAC) $(JAVACFLAGS) $(DIRFLAG) somwhere $(SRCS)
> ----

This doesn't always work because stupid javac looks for the compiled
classes in the classpath. The above works because you happen to put the
compiled classes in the classpath and javac is able to find them. I
know, I know, it sucks.
 
> over
> 
> ----
> OBJS = ${SRCS:.java=.class}
> 
> .SUFFIXES : .java .class
> 
> something: $(OBJS)
> 
> .java.class
>         $(JAVAC) $(JAVACFLAGS) $(DIFGLAG) somwhere/$@ $<
>         # optional @mv something

This is normal make style, right?

I see these problems:

1) the classpath problem above (but it could be solved here with the
appropriate -cp $(DIRFLAG) or something like that)

2) the JVM startup overhead

Real numbers: compiling Apache FOP using this make style takes about 4
minutes on my Celeron 450Mhz under win98 on JDK 1.2.2 classicVM. Takes
about 20 seconds using single javac call on same system.

You say, sure but what if you go native? So I used jikes.

1 minute for make style, 5 second for single call.

Which one would you choose?

-- 
Stefano Mazzocchi      One must still have chaos in oneself to be
                          able to give birth to a dancing star.
<stefano@apache.org>                             Friedrich Nietzsche



Mime
View raw message