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.exsto build shared library intopriv, and the wrapper module with@on_loadof:erlang.load_nif('priv/foo.so', nil)
- 
That worked: I could iex -S mix run --no-haltthen exercise the NIF usingFoo.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.exandlib/foo_app/application.ex, and inmix.exsremoved themod:entry from the application.mix compileandmix testboth 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 inprivrelative 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 thatmix releasedoes not copy the NIF lib at all, not even if I addMix.Project.build_structureto the end of the compile mix task afterpriv/foo.sois 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 astart/2with 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???





















