sribe
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???
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #ai
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 9- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
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).
sribe
OK, I see now:
mod: ...in the application def inmix.exsapp: ...nameuse Application, nostart/2OvermindDL1
Well
use Application, as that is what defines the entrance, but thestartis generally just a nop.sribe
When I tried
startas a noop, it complained about the return value. (I did not try just returning{:ok, nil})When I remove both the
startfunction anduse Application, it still works. Apparently theuseis not needed, just a module whose name matches theapp:key in the project def is enough for it to base paths on that module.Also, instead of function
applicationreturning[], I just removed that function altogether frommix.exs, and it still works.OvermindDL1
Actually I ‘think’ you can just leave the
startfunction out entirely from the callback module, at least you could in erlang if I recall right. Otherwise an empty supervisor pid is fine.sribe
I didn’t realize that, and didn’t try it–just assumed something would complain about the bogus pid.
The key to leaving out
startin the module is leaving outmod: ...inmix.exs–that results in it not trying to callstart, and also seems to allow for droppinguse Applicationdimitarvp
Yep, you can even see part of that in
mix help new:grantwest
@sribe Is you work by chance open source? I am trying to do the same thing and I’d love something to reference.
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