Version: v0.0.0-alpha
(DO NOT USE
Table of Contents
Odin bindings to native Erlang libraries: erl_nif
, erl_driver
, erl_interface
.
⚠️ None of this has been tested (yet). I initially created this project as a way to learn Odin, and get a deeper understanding of Erlang NIFs.
- Make sure ASDF is installed
- Install the Odin ASDF plugin:
asdf plugin add odin
- Install the Erlang ASDF plugin:
asdf plugin add erlang
- Install ASDF tools:
asdf install
make run_tests
- The tests don't do much at the moment other than load and call a simple NIF written in Odin.
-
Create a simple NIF in Odin
// example_nif.odin package example_nif import "core:fmt" import "core:c" import "core:runtime" // Change to the path of wherever you've put the package import nif "../odin_erl_nif" import enif "../odin_erl_nif/erl_nif" // Name of the Erlang module the NIFs are being loaded into ERLANG_MODULE_NAME :: "example_nif" @export odin_add : enif.ErlangFFIPointer : proc "c" (env: ^enif.ErlNifEnv, argc: c.int, argv: [^]enif.ERL_NIF_TERM) -> enif.ERL_NIF_TERM { x: c.int if (enif.get_int(env, argv[0], &x) == 0) { return enif.make_badarg(env); } y: c.int if (enif.get_int(env, argv[1], &y) == 0) { return enif.make_badarg(env); } return enif.make_int(env, x + y) } // List of functions to export as NIFs // {<erlang function name>, <arity>, <function pointer>, <flags>} nif_funcs := [?]enif.ErlNifFunc { {"odin_add", 2, odin_add, 0}, } // Register the NIFs with Erlang @(init, private) _ :: proc() { nif.init(ERLANG_MODULE_NAME, nif_funcs[:]) }
-
Create an Erlang file to load the nif
% example_nif.erl -module(example_nif). -export([odin_add/2]). -nifs([odin_add/2]). -on_load(init/0). init() -> ok = erlang:load_nif("./example_nif", 0). odin_add(_X, _Y) -> exit(nif_library_not_loaded).
-
Compile Odin Library
Get your Erlang major and minor version with:
erlang:system_info(nif_version).
odin build "<project folder>" \ -define:ERL_NIF_MAJOR_VERSION=<nif_version major version> \ -define:ERL_NIF_MINOR_VERSION=<nif_version minor version> \ -build-mode:shared -no-entry-point \ -extra-linker-flags="-dynamiclib -undefined dynamic_lookup -fpic" \ -out="example_nif.so"
-
Start an erlang shell with
erl
1> c(example_nif). 2> example_nif:odin_add(2, 3). 5
scripts
- Helper scripts to build the project.
src
erl_nif
- Low level bindings for
erl_nif
, anderL_driver
. The functions and types in this packages should very closely follow the structure and format of the native libraries.
- Low level bindings for
odin_erl_nif
- High level helpers that make the low level
erl_nif
bindings nicer to work with.
- High level helpers that make the low level
tests
- Test directory
- 🚧 Create bindings for functions and types in
erl_nif
- 🚧 Functions
- 🚧 Types
- 🚧 Create bindings for functions and types in
erl_driver
- Functions
- 🚧 Types
- Create bindings for functions and types in
erl_interface
- Functions
- Types
- 🚧 Setup test framework
- Write tests for all
erl_nif
functions - Write tests for all
erl_driver
functions - Write tests for all
erl_interface
functions - Create Odin allocator that uses the Erlang allocator
- Add support for rebar3
- 🚧 Create helper library that wraps the low level functions with a higher-level interface.
✅ - Complete
🚧 - Being worked on
See the open issues for a full list of proposed features (and known issues).
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
Distributed under the MIT License. See LICENSE.txt
for more information.