infer icon indicating copy to clipboard operation
infer copied to clipboard

any plans for bazel support ?

Open darkcrawler01 opened this issue 7 years ago • 22 comments

https://github.com/bazelbuild/bazel

darkcrawler01 avatar Sep 07 '16 02:09 darkcrawler01

No current plans. If you have experience building Bazel plugins and are interested in contributing one for Infer, that would be awesome!

sblackshear avatar Sep 07 '16 02:09 sblackshear

Infer has support for Buck which is similar to Bazel. It works by redirecting to Infer the compiler invocations. Using the same approach may work for Bazel too. The code is here: https://github.com/facebook/infer/blob/master/infer/lib/python/inferlib/bucklib.py

jeremydubreil avatar Sep 07 '16 18:09 jeremydubreil

@jeremydubreil @sblackshear - With the last release I noticed that Infer has support for clang compilation databases. Assuming we can get Bazel to output this would that be the preferred method for integration?

[Clang] Improved support for cmake and Xcode compilation databases. Use with infer --compilation-database compile_commands.json (for cmake and Buck), or with infer --compilation-database-escaped compile_commands.json (for xcbuild and xcpretty).

https://github.com/facebook/infer/releases/tag/v0.10.0

rahul-malik avatar Mar 10 '17 19:03 rahul-malik

@rahul-malik I would recommend using compilation dbs to integrate with Bazel. I don't think infer can reasonably support a large range of build systems "natively". Going through an intermediate compilation DB is a more scalable solution.

Note however that infer doesn't support running its Java frontend using compilation DBs yet. Let us know if that'd be helpful to add for you (are there tools out there that output Java compilation databases?).

jvillard avatar Mar 13 '17 11:03 jvillard

@jvillard - Thanks! The compilation db should work well since we're only interested in analyzing our targets which are compiled with llvm/clang which already supports outputting a compilation database (I'm unaware of any Java compilation db as well).

rahul-malik avatar Mar 13 '17 18:03 rahul-malik

@shs96c Is there any issue with getting the clang database out then passing that to infer capture --compilation-database compile_commands.json?

jvillard avatar Sep 13 '17 11:09 jvillard

I'd like to also check java code :)

shs96c avatar Sep 13 '17 11:09 shs96c

If we're adding support for multiple languages and couldn't use a clang db, the extra actions API could be used to capture the compiler invocations:

https://docs.bazel.build/versions/master/be/extra-actions.html

rahul-malik avatar Sep 13 '17 14:09 rahul-malik

@shs96c: For the Java side, could we reuse for Bazel the same strategy as used with Buck, which is to specify the path to an external javac compiler pointing to Infer? Buck basically calls Infer this way:

  buck build --config tools.javac=/path/to/infer <rest of the buck command>

This option to specify an external Java compiler was originally added to Buck specifically for the integration with Infer so I don't know if there is something equivalent for Bazel.

jeremydubreil avatar Sep 14 '17 07:09 jeremydubreil

I remember it being added very well :) There's a java_toolchain option in Bazel that might work:

https://docs.bazel.build/versions/master/be/java.html#java_toolchain

I'm not sure what a JavaBuilder is in this context, but the docs suggest it expects the javac to be a jar, not an executable.

On Thu, Sep 14, 2017 at 8:25 AM, Jeremy Dubreil [email protected] wrote:

@shs96c https://github.com/shs96c: For the Java side, could we reuse for Bazel the same strategy as used with Buck, which is to specify the path to an external javac compiler pointing to Infer? Buck basically calls Infer this way:

buck build --config tools.javac=/path/to/infer

This option to specify an external Java compiler was originally added to Buck specifically for the integration with Infer so I don't know if there is something equivalent for Bazel.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/facebook/infer/issues/457#issuecomment-329397095, or mute the thread https://github.com/notifications/unsubscribe-auth/AABuRW5F8kBJYBVBzbSs7Npgke60h_Gnks5siNTpgaJpZM4J2eRG .

shs96c avatar Sep 14 '17 07:09 shs96c

@shs96c JavaBuilder is Bazel wrapper around Javac invocation, that does some magic:

  • Error Prone integration
  • strict dependency checking
  • reduce classpath magic

However, in very recent Bazel version there is an easy way to use so called VanillaJavaBuilder to skip all the magic I mentioned above.

Gerrit Code Review uses this invocation to support most recent Java versions, that are not supported yet by Bazel natively. With this CL: [1] pending for review you could say something like this in gerrit tree:

  $ bazel build --host_javabase=:absolute_javabase \
    --define=ABSOLUTE_JAVABASE=/usr/lib64/jvm/java-11 \
    --define=USE_ABSOLUTE_JAVABASE=true \
    --host_java_toolchain=//:toolchain_vanilla \
    --java_toolchain=//:toolchain_vanilla \
    :release

Instead of passing /usr/lib64/jvm/java-11 I could pass the path to infer and that would probably solve infer integration for Bazel?

[1] https://gerrit-review.googlesource.com/c/gerrit/+/194040

davido avatar Oct 31 '18 09:10 davido

If I try to pass: bazel build --define=ABSOLUTE_JAVABASE=/usr/local/bin/infer, then it doesn't work, as Bazel tries to add bin/java to this Java home directory:

java.io.IOException: Cannot run program "/usr/local/bin/infer/bin/java" (in directory "/home/jenkins/.cache/bazel/_bazel_jenkins/bb2dc09ec74ab7b7157cd89c2ef96641/execroot/gerrit"): error=20, Not a directory

Next attempt is to try to pass: --define=ABSOLUTE_JAVABASE=/opt/infer and link /opt/infer/bin/java to infer itself:

  $ /opt/infer/bin/java --version
Infer version v0.15.0
Copyright 2009 - present Facebook. All Rights Reserved.

Then calling bazel build still failing with /opt/infer-linux64-v0.15.0/lib/infer/infer/bin/infer: unknown option '-jar'.:

$ bazel build --define=ABSOLUTE_JAVABASE=/opt/infer \
  --host_javabase=@bazel_tools//tools/jdk:absolute_javabase \
  --host_java_toolchain=@bazel_tools//tools/jdk:toolchain_vanilla \
  --java_toolchain=@bazel_tools//tools/jdk:toolchain_vanilla :headless
[...]
INFO: Analysed target //:headless (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
ERROR: /home/jenkins/gerrit/java/com/google/gerrit/server/BUILD:9:1: Building java/com/google/gerrit/server/libconstants.jar (1 source file) failed: Worker process did not return a WorkResponse:

---8<---8<--- Start of log, file at /home/jenkins/.cache/bazel/_bazel_jenkins/bb2dc09ec74ab7b7157cd89c2ef96641/bazel-workers/worker-9-Javac.log ---8<---8<---
/opt/infer-linux64-v0.15.0/lib/infer/infer/bin/infer: unknown option '-jar'.
Infer version v0.15.0
Copyright 2009 - present Facebook. All Rights Reserved.
Usage: infer command [options]
See `infer --help` for more information.
---8<---8<--- End of log ---8<---8<---

I think it might be easier to migrate build tool chain from Bazel to Buck to make infer work.

davido avatar Nov 06 '18 20:11 davido

@cushon Any idea, how we could hijack javac to call infer in Bazel driven build?

The problem is, that before switch from Buck to Bazel JGit/Gerrit community was able to run all the code base through infer. After migration to Bazel we lost that ability ;-(

davido avatar Nov 07 '18 09:11 davido

is there any update or plan for this topic? bazel become more and more popular, it would be cool to support it.

libratiger avatar Jul 29 '19 07:07 libratiger

Also interested! @martinoluca don't think you can escape from my feature requests just because I'm on the other side of the world.

giphy

uri-canva avatar Aug 15 '19 07:08 uri-canva

An aspect to provide alternative targets would probably work too.

shs96c avatar Aug 16 '19 09:08 shs96c

Gentle nudge :)

shs96c avatar Jan 16 '20 11:01 shs96c

@shs96c At @muse-dev we decompose many build systems into a machine readable description of the build steps (think javac ... ; javac ... ; ... or gcc ...) then feed those steps to several analyzers, infer among them. It shouldn't be hard to support bazel if we could just gain some insight into how to extract the invocations. Since you seem interested in this topic perhaps you are well-versed enough in Bazel and invested enough to teach me?

TomMD avatar Jan 22 '20 04:01 TomMD

@TomMD extracting build steps in that fashion sounds interesting but I presume you would be using internal APIs which historically have been changing a lot.

krlvi avatar Jan 22 '20 06:01 krlvi

As pointed out in my previous comment, the inspiration could be the current implementation of VanillaJavaBuilder.java#run:[1] method that is calling vanilla javac:

CompilationTask task =
            javaCompiler.getTask(
                new PrintWriter(output, true),
                fileManager,
                diagnosticCollector,
                JavacOptions.removeBazelSpecificFlags(optionsParser.getJavacOpts()),
                ImmutableList.<String>of() /*classes*/,
                sources);
        setProcessors(optionsParser, fileManager, task);
        ok = task.call();

The idea would be to have InferJavaBuilder.java and shell out to infer instead of vanilla javac.

Another question is how to teach infer to run preprocessors for code generation? One approach would be to let javac run the preprocessors, and then run infer with only (second) compile task.

Moreover, new toolchain should be added to bazel that understands new InferJavabuilder, and invoked like this:

  $ bazel build \
    --define=PATH_TO_INFER=/opt/infer \
    --host_java_toolchain=@bazel_tools//tools/jdk:toolchain_infer \
    --java_toolchain=@bazel_tools//tools/jdk:toolchain_infer \
  //...

To make it even more generic, it could be called GenericJavaBuilder.java so that it would work with any static analyser and not just with infer.

[1] https://github.com/bazelbuild/bazel/blob/7f0ba75ae6da3ceca8e5e865a1ce9b8c71a5249e/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/VanillaJavaBuilder.java#L145-L223

davido avatar May 18 '20 12:05 davido

It's pretty straightforward to create an extra action that runs Infer. Here's a Gist link: https://gist.github.com/ulfjack/c66180584f9efb9e9768bf8999ffcd8a

Use like this:

bazel build //src/main/java/... --experimental_action_listener=//src/infer/java/com/engflow/infer --spawn_strategy=local

ulfjack avatar Oct 31 '20 23:10 ulfjack

If anyone is still interested this for (Objective-)C(++) and wants to use compile_commands.json, we built https://github.com/hedronvision/bazel-compile-commands-extractor which should make getting a compile_commands.json from Bazel easy and fast.

(extra_actions have been deprecated, unfortunately, though that otherwise seems like a great solution for running it alongside a build.)

Does anyone have experience running infer via compile_commands.json and caching/getting fast incremental rebuilds?

cpsauer avatar Jul 01 '22 01:07 cpsauer