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</artifactId> <version>${fastffi.revision}</version> <classifier>${os.detected.classifier}</classifier> </dependency> <dependency> <groupId>com.alibaba.fastffi</groupId> <artifactId>llvm4jni-runtime</artifactId> <version>${fastffi.revision}</version> </dependency> </dependencies> <plugins> <plugin> <groupId>kr.motd.maven</groupId> <artifactId>os-maven-plugin</artifactId> <version>1.7.0</version> <executions> <execution> <phase>initialize</phase> <goals> <goal>detect</goal> </goals> </execution> </executions> </plugin> </plugins>
-
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