/rust-ffi

A project to generate bindings to a rust foreign function interface for other languages.

Primary LanguageRustMozilla Public License 2.0MPL-2.0

rust-ffi

A project to generate bindings to a rust foreign function interface for other languages.

This is only a proof of concept and not designed to be easy to use.

Currently, only generating a C/C++ header for a rust foreign function interface is supported.

For more information see this introductory blog post.

Overview

This tool is split into several parts.

  1. metadata-ffi: A schema for describing a rust foreign function interface that can be communicated between tools
  2. emit-ffi: A rust compiler driver that will ouput a ffi.json for a crate
  3. c-ast: A C/C++ abstract syntax tree designed for code generation
  4. c-ffi: A library to convert a ffi.json into a C/C++ AST and output it as a header
  5. cargo-ffi: A cargo subcommand to use emit-ffi for a crate, then translate the ffi.json into a C/C++ header

Usage

cd ~/path/to/project/
cargo +nightly ffi

The header will be output in the current working directory, named after the crate.

No command line options or configuration files are currently supported.

Example

See example/ for a test crate with generated headers already made.

Building

The emit-ffi driver links to the rustc compiler internals and requires a nightly compiler.

The latest compiler confirmed to work is:

rustc 1.34.0-nightly (4b1e39b7b 2019-02-05)

You can install nightly rustc using rustup:

rustup toolchain add nightly

To build this workspace using rustup:

cargo +nightly build

Additionally, emit-ffi requires libraries from the sysroot to be in the parent directory:

cp -R ~/.rustup/toolchains/nightly-x86_64-apple-darwin/lib target/
set -gx DYLD_LIBRARY_PATH '~/.rustup/toolchains/nightly-x86_64-apple-darwin/lib'

Be sure to re-run that command after deleting the target directory, such as after cargo clean.

In order to use cargo ffi, cargo-ffi must be in the current $PATH:

export PATH='path/to/rust-ffi/target/debug/':$PATH

Example

cd ~/Projects/rust-ffi/
cargo +nightly build

cp -R ~/.rustup/toolchains/nightly-x86_64-apple-darwin/lib target/
export PATH='$PWD/target/debug/':$PATH

cd example/easy
cargo +nightly ffi

Warning

Do not use cargo-ffi in the rust-ffi directory or you will need to rebuild.

cargo-ffi will perform a clean before generating a header to ensure the shim driver will be used, this will remove the emit-ffi binary before it can be used.

Future work

This is currently just a proof of concept.

The significant work items remaining are:

  1. C/C++ output for enum's containing fields
  2. Generics
  3. Statics
  4. Zero sized types
  5. repr(transparent)
  6. Opaque type propagation
  7. fn ABI specifications
  8. Documentation comments
  9. Configuration/extensibility
  10. Tests