Basically, fastFFI has three components:
- FFI: DSL and API used to develop FFI applications.
- Annotation Processor: the code generator for FFI.
- LLVM4JNI: LLVM4JNI has two submodules:
- LLVM4JNI: a tool that translates LLVM bitcode into Java bytecode.
- LLVM4JNI Runtime: the runtime component used by generated bytecode.
An FFI application must include ffi
and llvm4jni-runtime
in its class path as runtime dependency.
- Checkout source code
git clone <path-to-fastffi> fastffi
- Prepare building environment
export LLVM11_HOME=<path-to-llvm-11>
LLVM11_HOME
should point to the home of LLVM 11. In Ubuntu, it is at /usr/lib/llvm-11
.
Basically, the build procedure the following binary:
$LLVM11_HOME/bin/clang++
$LLVM11_HOME/bin/ld.lld
$LLVM11_HOME/lib/cmake/llvm
- Use fastFFI with Maven.
<properties>
<fastffi.revision>0.1.2</fastffi.revision>
</properties>
<dependencies>
<!-- The FFI annotation -->
<dependency>
<groupId>com.alibaba.fastffi</groupId>
<artifactId>ffi</artifactId>
<version>${fastffi.revision}</version>
</dependency>
<!-- The FFI annotation processor for code generation -->
<dependency>
<groupId>com.alibaba.fastffi</groupId>
<artifactId>annotation-processor</artifactId>
<version>${fastffi.revision}</version>
</dependency>
<!-- The runtime component of LLVM4JNI -->
<dependency>
<groupId>com.alibaba.fastffi</groupId>
<artifactId>llvm4jni-runtime</artifactId>
<version>${fastffi.revision}</version>
<classifier>${os.detected.classifier}</classifier>
</dependency>
</dependencies>
- Use maven to build your applications. The generated code, including Java and C++ code, is available in
<project.dir>/target/generated-source/annotations
A Java programming language compiler must support standard options in the format -Akey[=value]
. fastFFI provides the following options:
fastffi.handleException
: whether generating code to handle C++ exceptions- default value:
false
- default value:
fastffi.manualBoxing
: usingnew Integer()
ornew Long()
to box a primitive integer.- default value:
true
- Auto boxing uses
Integer.valueOf
orLong.valueOf
, which cannot be properly handled by the escape analysis of C2 compiler.
- default value:
fastffi.strictTypeCheck
- default value:
false
- default value:
fastffi.nullReturnValueCheck
- default value:
true
- insert additional null check for native pointers
- default value:
fastffi.cxxOutputLocation
- default value:
CLASS_OUTPUT
- accept values:
CLASS_OUTPUT
,SOURCE_OUTPUT
,NATIVE_HEADER_OUTPUT
.
- default value:
fastffi.traceJNICalls
- default value:
false
- generate stuffs to trace the invocations of JNI wrappers
- default value:
fastffi.compactFFINames
- default value:
true
- generate compact FFI wrapper type names, non-compact names will benefit debugging, but increase the binary size
- default value:
Usage:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<compilerVersion>${javac.target}</compilerVersion>
<source>${javac.target}</source>
<target>${javac.target}</target>
<compilerArgs>
<arg>-Afastffi.strictTypeCheck=true</arg>
</compilerArgs>
</configuration>
</plugin>
-
Install a JDK (JDK 8 and 11)
-
Install LLVM 11, Maven and CMake
brew install llvm@11 cmake maven
- Set ENV
export LLVM11_HOME=/usr/local/opt/llvm@11
TBA