llvm-j is a Java library for parsing and modifying LLVM IR.
The goals of llvm-j are:
- Provide an easy to use LLVM IR parser that feels like a native Java library (compared to a collection of JNI bindings).
- Make it easy to upgrade to higher versions of LLVM without API changes. This is important since LLVM updates may change the LLVM core API - we want our users to be able to use llvm-j independent of such changes, and allow them to use new LLVM versions without a need to update their code.
To achieve these goals, llvm-j uses Java bindings for the original LLVM C parsing library with java native access (JNA), but provides proxy classes for the most common parsing tasks. This way, the user never has to call the C bindings directly, but can work with our own, Java-like API (e.g., we aim to throw Exceptions for illegal states instead of returning values with a special error meaning).
The Java bindings for the LLVM C parsing library are automatically generated with JNAerator. Through this, it is easy to update the bindings to new versions of LLVM, and the user doesn't have to change any code since the llvm-j API stays the same.
Currently, we use LLVM 9.0.1-16.
If you didn't put the LLVM 9 shared library in one of your system directories for library lookup, you can tell llvm-j in which directory the library is in in two ways:
1. Provide system property `jna.library.path` to Java, for example `java -Djna.library.path=additional/lookup/path -jar appParsingLlvm.jar` or 2. Add the directory in the code with static method [`Module#addLibraryLookupPaths(List<Path>)`](ADDLINK), *before* calling `Module#parseIR(String)`.
To parse LLVM IR, call static method
the file to parse as argument.
Currently, llvm-j only understands LLVM IR in bitcode format
(usually file suffix *.bc).
Module#parseIR(String) will return a
To build this project yourself, you should first clone or download
The project consists of three components:
- The automatically generated Java bindings of the LLVM library
- The Java API
- The shared library of LLVM
ant to manage our build process.
If it is not yet installed on your system, you will have to do so.
Generated bindings are already provided and part of the project. Thus, generating them manually is usually not necessary.
If you still want to re-generate the bindings,
you require an installation of LLVM that includes the LLVM C headers.
/path/to/llvm includes the LLVM C-headers directory
ant bindings -Dllvm.home=/path/to/llvm/include/llvm-c
Notice that new bindings may require modifications to the proxy classes, since the LLVM C API may change over time.
Build Java API
To compile the Java API, run
ant in the project's root directory.
To create a jar file for distribution, run
The output of the command will tell you the name of the created jar file.
The jar file does not include the shared libraries of LLVM.
Get Shared Library of LLVM
llvm-j dynamically loads the shared libraries of LLVM, so they must be available for your machine in the right version. For convenience, we provide a mechanism to automatically download and extract the shared libraries from an Ubuntu package (for 64 bit systems). These libraries should work on most Linux distributions.
We assume that you have common command-line tools installed.
In addition, tool
chrpath is required.
On Ubuntu, it can be installed by running
sudo apt install chrpath.
Download: To automatically download the library and its dependencies, execute on the command-line, from the project's root directory:
The libraries will be automatically downloaded and put into directory
You can then either move them to a system path for libraries (e.g.,
/usr/local/lib) or put them in your project.
Others ways to get the library
If you use Windows, macOS, or the provided libraries do not work on your system, you can
- use an LLVM package that includes the shared libraries for your system or
- compile the shared libraries yourself.
For both options, make sure that you use the correct version of LLVM.
To create the JavaDoc, run
ant javadoc in the project's root directory.
Tools for Code Quality
We provide some checks that may help you in writing good and correct code. You can run:
- Eclipse Compiler
with Eclipse-specific warnings
- Google Code Formatter
You can run
ant all-checks to run CheckStyle, the Eclipse compiler, the JavaDoc
task (which performs linting for JavaDoc) and SpotBugs.
These tools are, of course, not enough to ensure good code quality, but only some helpers.
Currently, the proxy classes aim at parsing LLVM IR bitcode, not modifying it. If you miss any functionality, please create a new issue or message us to help us improve llvm-j!