JDK-4175374 : RFE: javamake tool (was Javac should generate make(1) dependencies)
  • Type: Enhancement
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 1.1.5,1.2.0,5.0
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic,solaris_2.6
  • CPU: generic,sparc
  • Submitted: 1998-09-22
  • Updated: 2002-04-21
  • Resolved: 2002-04-21
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Description

Name: clC74495			Date: 09/22/98


Like all good C/C++ compilers, javac should offer
a command line option for generating makefile
dependencies. This should be very easy to do for
the compiler and would be a very cool feature for
all of us guys managing big projects with the help
of make(1).


Thanks, tom.
(Review ID: 37053)
======================================================================

Comments
EVALUATION Hi Tom, It is not straightforward to write make rules for general java programs. I wanted to add a feature like this but ran into troubles... In C or C++, your interfaces are put into separate header files. In make you add dependencies on the header files to represent a dependency on an external api. In java, you have no separate header files. If class Foo and Bar depend on each others external api's, then you have two .java files which depend on each other. This is not something that happens with .c files. Also, compile-time constants are mandated by the JLS to be inlined. Class Foo may inline a compile time constant from Bar and class Bar may also inline a compile time constant from Foo. (In the C/C++ world, this is akin to having two header files both depend on each other's #defines -- doesn't work.) If both Foo.java and Bar.java have been modified, then you may need to compile both simultaneously (same command line) in order to get the correct results. I don't know of a straightforward rule system for make which can build up these cliques of sources which must be compiled simultaneously and issue them in the same command. I realize this is a short explanation. I think that a make-like tool for java would be very valuable for java programmers. I believe that it will probably have to be integrated into the compiler to get it to be robustly correct. todd.turnidge@Eng 1998-09-28 We are investigating a redesign of the compiler's command-line level semantics to provide a robust make-like recompilation facility integrated within the compiler. I believe, however, that it would be possible to emit make(1) rules if desired -- it would simply be necessary to collect cliques of mutually-dependent source files into single rules, and the rules would potentially have to be re-generated after every compilation, due to newly-discovered dependencies. Seems doable, though. See 4303048. william.maddox@Eng 2000-01-27 This will probably be added to tiger as a separate tool. ###@###.### 2001-11-12 The following is copied from the evaluation of 4607526: Sure, use -verbose. I suspect that's not what you want, though. javac does not "use dependency information" when it compiles sources. The only dependency it uses is to check before it loads a specfic class file if the corresponding source file is newer. javac simply uses symbol tables in memory, and if it has none in memory then it loads a class file, or a source file is the source file is newer than the class file. But wait, you say, certainly javac knows when it is loading classes, and it would only load a class if that class were needed. That is only true if you are compiling a single source file and all other source files are up-to-date. If the compiler needs to process more than one source file, then the compiler uses the class structure it has built in memory instead of going back to the classes to load them. In that case, the compiler does not have any mechanism to determine which sources depend on a class and which do not. In fact, the compiler does not process one source file before another. Rather, it interleaves processing of all source files as information is needed. Specifying only a single source file on the command line won't necessarily get the desired effect, because the compiler may have to load another source file. But what about the -Xdepend option? Surely that generates dependencies, at least internally? No, for at least two reasons. First, there is no such option; that option disappeared with the rewrite of javac in 1.3. But even in previous releases, that option did not work correctly, and for some very good reasons. The compiler's only mechanism for examining a class file is to load it into its symbol table. Once it has done that, it is too late to decide that the class file is out of date (perhaps because one of the classes upon which it depends has changed). -Xdepend never handled this situation correctly The problem is a bit worse even that this. I imagine that what you really want is a way to build make dependencies so you can build a makefile for an arbitrary Java program. The bad news is that this isn't possible because java programs contain circular dependencies. Make can't handle circular dependencies, which in this case takes the form of a set of targets that must be built simultaneously using a synthesized, combined compile command. Finally, I'd like to point out that you probably wouldn't like the result if you could get what you're asking for. Let's take a simple example, java.lang.Object. What does it depend on? Well, Object uses classes String, Integer, InterruptedException, and Throwable. Throwable uses a bunch of stuff from java.io, including PrintStream, PrintWriter, and ObjectOutputStream. ObjectOutputStream uses sun.misc.SoftCache, java.util.Arrays, java.security.AccessController, and java.security.PrivilegedAction. java.security.AccessController uses sun.security.util.Debug and java.security.AccessControlContext. I could go on and on, but the basic point is that indirectly, java.lang.Object depends on a huge portion of J2SE. Another way of thinking about this is that you can compile most applications that don't use dynamic loading simply by pointing the compiler at the main source file and giving the source path to the rest of the application. In effect, most of J2SE depends on most of J2SE, and the dependency list of even the simplest class would be huge. Don't imagine that J2SE is special in this regard; the same would be true of most any user application. My question is this: what is the underlying need that this request is trying to satisfy. I believe it is a desire to have a mechanism that minimizes what gets recompiled when some sources change. For that purpose, I suggest you consider javamake. A prototype of that tool was recently completed in Sun Microsystems Research Labs, and offered to us in Java land to include as a feature in an upcoming release. See http://www.experimentalstuff.com/Technologies/JavaMake/index.html I suspect that is a more realistic alternative to what would likely be specified by the author of this RFE. ###@###.### 2001-12-13 ---------------------------------------------------------------------- For Tiger planning purposes this RFE has been split into two: 4633403 include the javamake tool 4639384 javac should provide dependency information and I'm closing this RFE as a duplicate of 4633403 ###@###.### 2002-04-21
21-04-2002