Incremental java compile AKA javac print compile dependencies

Jonathan Gibbons jonathan.gibbons at oracle.com
Wed May 26 08:10:01 PDT 2010


On 05/25/2010 06:38 PM, Joshua Maurice wrote:
> On Tue, May 25, 2010 at 6:01 PM, Jonathan Gibbons 
> <jonathan.gibbons at oracle.com <mailto:jonathan.gibbons at oracle.com>> wrote:
>
>     On 05/25/2010 05:11 PM, Joshua Maurice wrote:
>
>
>
>         What is relevant is that to get decent levels of incremental,
>         aka skipping unnecessary rebuilds, the build system needs to
>         know for each java X, the full list of class files and java
>         files which will be directly used by javac when compiling X.
>         Whenever any of those direct compile dependencies have an
>         "interface" / "signature" change, X needs to be recompiled.
>
>
>     Stop right there.   There's likely a wrong assumption here, hidden
>     in the word "directly".
>
>     If you start from scratch, with no classes precompiled, when you
>     compile X, javac will pull in from the sourcepath the transitive
>     closure of X and all its dependencies.  Thus if X refers to Y, and
>     if the implementation of Y refers to Z, then javac will compile X
>     and Y and Z, even though there no direct reference in any way from
>     X to Z.   This is why your proposed technique of tracking -verbose
>     output will not work.
>
>
> What? For starters, I'm planning on specifically not using the 
> -sourcepath option. Suppose a user touches X only, and nothing else 
> depends on X, like your example, and I want to only recompile X.java. 
> However, if I give the -sourcepath option, then as you note, javac 
> will recompile X, Y, and Z, but Y and Z are useless recompiles.



If you have mutually referential class files (X refers to Y, Y refers to 
X) then you either need -sourcepath or you need to compile X and Y 
together.   Most large code bases will have such mutually referential 
classes.  If you're talking about a general purpose build tool, you need 
to deal with this case. If you're only dealing with a specific code base 
that does not have mutually referential classes, that's a whole lot less 
of an interesting problem.

Mutually referential class files are what make it difficult to identify 
the set of dependencies for each individual class.  Unless you look at 
the class file or get into and look at the AST, you'll likely end up 
finding the set of dependencies for groups or cycles of classes, and 
those can sometimes be surprisingly large.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20100526/3c005e5f/attachment.html 


More information about the compiler-dev mailing list