sribe

sribe

How do you package a lib with a NIF?

I’m creating a NIF, and having some issues around packaging.

  • I started with an empty Elixir app, added the NIF source in its own directory, the appropriate task to mix.exs to build shared library into priv, and the wrapper module with @on_load of :erlang.load_nif('priv/foo.so', nil)

  • That worked: I could iex -S mix run --no-halt then exercise the NIF using Foo.func(...); also foo’s tests worked.

  • I want to package this as a library that can just be pulled in as a normal dependency. It’s just simple functions, no need for its own application or any processes. So I deleted lib/foo_app.ex and lib/foo_app/application.ex, and in mix.exs removed the mod: entry from the application. mix compile and mix test both work.

  • Now for the problems: using it. I create a new empty application, add the dependency {:foo, path: "../foo", app: false}. Compile works, but when I try to run (or test), the load of the NIF fails, because it’s not in priv relative to the executing project location, but rather in _build/dev/lib/local_dependency

  • It seems that maybe to load the NIF I should use Application.app_dir(:foo, "priv") but that gives an error about unknown application, while :code.priv_dir(:foo) gives :bad_name. Also, I note that mix release does not copy the NIF lib at all, not even if I add Mix.Project.build_structure to the end of the compile mix task after priv/foo.so is created.

  • So maybe I have to have an empty dummy application in the lib project, just to make all the build parts happy? And indeed, adding back a dummy app, setting the mod: to point to it, etc, makes things work. But of course the dummy app needs a start/2 with a return of the right form, so:

defmodule Foo.App do
  use Application
  def start(_, _) do
    Supervisor.start_link([], [strategy: :one_for_one])
  end
end

It seems silly to have to implement a do-nothing supervisor in order for the NIF lib to be copied and able to be located. Isn’t there a better way to structure and pull in this lib???

Most Liked

OvermindDL1

OvermindDL1

Not a supervisor, but a no-op Application is all you need, it doesn’t need to start anything at all. Priv directories are in relation to an Application root (as are config files and more too). :slight_smile:

acalejos

acalejos

Shameless plug, but you can check out a library i wrote that does this. It uses Application only to handle config options. Otherwise its just a wrapper for a C library. Everything in the mix.exs referring to “precompilation” might be useful too if you want to precompile your NIF shared libraries for a more seamless experience if publishing to Hex.

https://github.com/acalejos/exgboost

sribe

sribe

OK, I see now:

  • Leave out mod: ... in the application def in mix.exs
  • But do have a module which matches the app: ... name
  • But leave the module totally empty, no use Application, no start/2

Where Next?

Popular in Questions Top

Kurisu
For example for a current url like http://localhost:4000/cosmetic/products?_utf8=✓&query=perfume&page=2, I would like to get: ...
New
shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

Other popular topics Top

lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 39297 209
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
klo
Got a question about when to concat vs. prepending items to list then reversing to achieve appending. So i know lists boil down to [1 | ...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New

We're in Beta

About us Mission Statement