How granular is Bazel's incremental Java build?

156 views
Skip to first unread message

Dan Fabulich

unread,
Jan 5, 2016, 8:49:26 PM1/5/16
to bazel-discuss
Suppose I have two libraries, "lib1" and "lib2"; "lib2" depends on "lib1".

lib2 --> lib1

I know that if I modify a file in "lib1," "lib2" will be recompiled. But will all of "lib2" be recompiled, or just the files in "lib2" that depend on the modified files?

For example, suppose "lib1" contains two files, "Lib1a.java" and "Lib1b.java" and "lib2" contains two files, "Lib2a.java" and "Lib2b.java". Lib2a.java depends on Lib1a.java; Lib2b depends on Lib1b.java.

A: Lib2a.java --> Lib1a.java
B: Lib2b.java --> Lib2b.java

Now suppose I modify Lib1a.java (A). Will Lib2b.java (B) be recompiled, even though it doesn't depend on Lib1a.java (A)?

I tried to verify this myself by setting up a toy example, below, where I modified the string that Lib1a.java returns, but I couldn't figure out what was being recompiled, because Bazel cleverly didn't bother modifying the timestamps for Lib2a.class or Lib2b.class.

So, tell me plainly: does Lib2b.java get recompiled or not? And, how can I verify this for myself?

Lib1a.java

    package com.example.lib1;

    public class Lib1a {
        public String lib1a() {
            return "lib1a";
        }
    }

Lib1b.java

    package com.example.lib1;

    public class Lib1b {
        public String lib1b() {
            return "lib1b";
        }
    }

Lib2a.java

    package com.example.lib2;

    import com.example.lib1.Lib1a;

    public class Lib2a {
        public String lib2a() {
            return (new Lib1a()).lib1a() + "lib2a";
        }
    }

Lib2b.java

    package com.example.lib2;

    import com.example.lib1.Lib1b;

    public class Lib2b {
        public String lib2b() {
            return (new Lib1b()).lib1b() + "lib2b";
        }
    }

Thomas Broyer

unread,
Jan 6, 2016, 3:40:06 AM1/6/16
to bazel-discuss
IIUC, if you don't change the API in lib1, then lib2 *won't* be recompiled *at all*.
And iff it's recompiled, then all files are compiled (no incremental compilation). If you need incremental compilation then you need to split your rules to use smaller file sets as input.

Dan Fabulich

unread,
Jan 6, 2016, 1:46:56 PM1/6/16
to bazel-discuss
Is there a way to automate splitting the rules? Seems like it should be possible to parse the Java to find all of its dependencies and cache the result. Indeed, I thought that was exactly what Bazel was for...?

Eddie Aftandilian

unread,
Jan 6, 2016, 2:11:12 PM1/6/16
to Dan Fabulich, bazel-discuss
Splitting the rules is a hard problem -- NP-hard, in fact.  We had an intern a few years ago who wrote a paper about it:

Also note that Bazel is a build system and is not supposed to be language-specific, but you need language-specific knowledge to split build targets.

On Wed, Jan 6, 2016 at 10:46 AM, Dan Fabulich <danfa...@gmail.com> wrote:
Is there a way to automate splitting the rules? Seems like it should be possible to parse the Java to find all of its dependencies and cache the result. Indeed, I thought that was exactly what Bazel was for...?

--
You received this message because you are subscribed to the Google Groups "bazel-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/f8ff1640-01b1-4599-b99f-f92621be3403%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages