Mix Compiler Basics
The mix compiler takes care of compiling your NIFs along with your project, in addition to providing boilerplate generators.
Setting up a new Rust NIF in your project is fairly easy:
- Add the
:rustlerdependency to your applicationsmix.exs. - Run
mix deps.getto fetch the dependency. - Run
mix rustler.newand follow the instructions to generate the boilerplate for your NIF. - Enable the
:rustlermix compiler by addingcompilers: [:rustler] ++ Mix.compilers(),to theprojectsection of yourmix.exs. - Add a configuration entry to the
rustler_cratessection of yourmix.exs. See below. - Load the NIF in your program. See below.
Crate configuration
The rustler_crates configuration is a keyword list mapping the NIF id (an atom) to the NIF configuration (another keyword list). The nif configuration may contain the following entries:
path- The path to the crate directory relative to the project root.cargo(:system default) - The rust/cargo version to build the NIF with. May be one of the following::system- Use the version installed on the system.{:rustup, "rust-version"}- Userustupto compile the NIF with a spesific version.{:bin, "path"}- Usepathas the cargo command. This is not portable, and you should not normally use this.
default_features(true default) - Boolean indicating if you want the NIF built with or without default cargo features.features([] default) - List of binaries indicating what cargo features you want enabled when building.mode(:release default) - Indicates what cargo build flavor you want.:release- Optimized build, normally a LOT faster than debug.:debug- Unoptimized debug build with debug assertions and more.
When you are done, the project section might look something like this:
def project do
[app: :my_app,
version: "0.1.0",
compilers: [:rustler] ++ Mix.compilers,
rustler_crates: rustler_crates(),
deps: deps()]
end
defp rustler_crates do
[io: [
path: "native/io",
mode: (if Mix.env == :prod, do: :release, else: :debug),
]]
end
Loading the NIF
Loading a Rustler NIF is done in almost the same way as normal NIFs.
The actual loading is done by calling use Rustler, otp_app: :my_app in the module you want to load the NIF in.
This sets up the @on_load module hook to load the NIF when the module is first
loaded.
defmodule MyProject.MyModule do
use Rustler, otp_app: :my_project, crate: :my_crate
# When loading a NIF module, dummy clauses for all NIF function are required.
# NIF dummies usually just error out when called when the NIF is not loaded, as that should never normally happen.
def my_native_function(_arg1, _arg2), do: :erlang.nif_error(:nif_not_loaded)
end
Note that :crate is the name in the [lib] section of your Cargo.toml. The
:crate option is optional if your crate and otp_app use the same name.