sribe

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.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???

Showing Posts 1 to 9

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:

sribe

sribe OP

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
OvermindDL1

OvermindDL1

Well use Application, as that is what defines the entrance, but the start is generally just a nop.

sribe

sribe OP

When I tried start as a noop, it complained about the return value. (I did not try just returning {:ok, nil})

When I remove both the start function and use Application, it still works. Apparently the use is not needed, just a module whose name matches the app: key in the project def is enough for it to base paths on that module.

Also, instead of function application returning [], I just removed that function altogether from mix.exs, and it still works.

OvermindDL1

OvermindDL1

Actually I ‘think’ you can just leave the start function out entirely from the callback module, at least you could in erlang if I recall right. Otherwise an empty supervisor pid is fine.

sribe

sribe OP

I didn’t realize that, and didn’t try it–just assumed something would complain about the bogus pid.

The key to leaving out start in the module is leaving out mod: ... in mix.exs–that results in it not trying to call start, and also seems to allow for dropping use Application

dimitarvp

dimitarvp

Yep, you can even see part of that in mix help new:

A --sup option can be given to generate an OTP application skeleton including a
supervision tree. Normally an app is generated without a supervisor and without
the app callback.

grantwest

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

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

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews