guides/advanced/compiling-non-beam-code.md
It's almost guaranteed that you'll have some code in your project that won't be written in Elixir, Erlang, or another BEAM language. Nerves provides multiple ways of integrating this code and the one you choose depends on many things.
Here are rules of thumb:
elixir_makezigler for
specific languagespriv directory. Static linking is recommended.In a perfect world, it would be easy to use whatever language you wanted and
adding a program would be as simple as adding a reference to it to your mix deps. Sadly, that's not the case for embedded systems and sometimes an inferior
library may be preferable just because it carries fewer dependencies or is
easier to build.
Be aware of the following caveats with Nerves:
systemd or
BusyBox init. Initialization is done in either an
Application.start callback
or in a GenServer so that it can be supervised.Tip {: .tip}
If you require a long running process from a provided exectuable and need similar startup and supervision management of
systemd, you can also use:muontrapto start it in your application supervision. See this talk for more information
Before you even start, experience has shown that searching the Erlang/OTP docs three times and skimming the Erlang source lead to all kinds of amazing discoveries that may not require you to port any code at all. If you do need to port code, keep in mind that while Nerves uses the Linux kernel, it highly favors Erlang/OTP ways of building systems and not embedded Linux ways. If you find yourself continually fighting Nerves and missing embedded Linux, your use case may be better met by installing Elixir on embedded Linux rather than trying to make Nerves look more like embedded Linux. Many embedded Elixir libraries work fine on both Nerves and embedded Linux.
Refer to Environment Variables for sources available during compilation if needed.
In general, most Elixir and Erlang libraries that include NIFs and ports can be made to work with Nerves. Nerves is, however, less forgiving than normal compilation.
Three recommendations cannot be stressed enough:
Always compile under _build
ERROR: Unexpected executable format
error when this happens, but it causes a lot of confusion.Do not have a priv directory in your source tree
priv
directory to the build output priv directory, experience has been that
this feature causes confusion when building native code. If you do have
static assets that you want in the output priv directory, add a line to
your Makefile or mix.exs to copy them.Prefer ports over NIFs to interface with external code with Erlang VM (if the choice is available)
The Internet has many examples of how to write
NIFs. For an example Makefile that
works well with Nerves and embedded Linux, see the circuits_i2c
Makefile
or watch this clip about
cross-compilation and Makefiles with Nerves.
Tip {: .tip}
Consider zigler for a safer alternative to C and C++ that works with Nerves.