Unable to compile ratatouille for nerves

Hi all
I’m still in the beginning of my nerves development, but I’m fascinated by the possibilities it offers.
Currently I’m trying to get a simple ratatouille app to get working on nerves. It occurs to me to be a really cool solution to bring a CLI app to a raspi 400 with a small monitor.

My problem is that the ratatouille package won’t compile for aarch64 architecture (actually one of its dependencies). Since it contains C code I guess it tries to cross-compile the given code.
I read the documentation about Compiling Non-BEAM Code but I must admit I’m not really into the cross compiling matters yet.
Under the hood the dependency ex_termbox is required and causing the problem.

I get the following error message trying to mix deps.compile :

Nerves environment
  MIX_TARGET:   rpi4
  MIX_ENV:      dev

==> ex_termbox
/Users/daniel/.nerves/artifacts/nerves_toolchain_aarch64_nerves_linux_gnu-darwin_x86_64-1.5.0/bin/aarch64-nerves-linux-gnu-gcc -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64  -pipe -O2 -I/Users/daniel/.nerves/artifacts/nerves_system_rpi4-portable-1.18.1/staging/usr/include -I/Users/daniel/.asdf/installs/erlang/24.1/erts-12.1/include -Ic_src/termbox/src -fPIC --sysroot=/Users/daniel/.nerves/artifacts/nerves_system_rpi4-portable-1.18.1/staging -shared -dynamiclib -undefined dynamic_lookup -o priv/termbox_bindings.so c_src/termbox_bindings.c c_src/termbox/build/src/libtermbox.a
aarch64-nerves-linux-gnu-gcc: error: dynamic_lookup: No such file or directory
make: *** [priv/termbox_bindings.so] Error 1
could not compile dependency :ex_termbox, "mix compile" failed. Errors may have been logged above. You can recompile this dependency with "mix deps.compile ex_termbox", update it with "mix deps.update ex_termbox" or clean it with "mix deps.clean ex_termbox"
==> rata_nerv
** (Mix) Could not compile with "make" (exit status: 2).
You need to have gcc and make installed. Try running the
commands "gcc --version" and / or "make --version". If these programs
are not installed, you will be prompted to install them.

To replay my scenario just create a nerves app and add the depenency {:ratatouille, "~> 0.5"} to your mix.exs.

Any help or hints are appreciated.
Thanks
Daniel

1 Like

Hi @daniel_frey,

I took a quick look at the ex_termbox Makefile in the hopes that this would be easy. I made a pass at https://github.com/ndreynolds/ex_termbox/pull/8.

I feel like there’s more work since ex_termbox works outside of Erlang’s normal I/O. However, it might work for you on a Raspberry Pi 400. I only tested building ex_termbox and seeing that its native code loaded. Trying the sample code didn’t show what I expected on an RPi 3A, but I think that may have been me trying to do too much at the iex prompt and not being sure what to expect. Perhaps you can make it farther.

1 Like

Hi @fhunleth
Thank you so much for your help! Looking at the pull request wouldn’t ever be able to make these changes and learned a lot.
You’re right though, I’m a step further but I have not yet reached the goal :wink:
I guess I’d need a terminal to communicate with and not iex, which behaves differently I assume.
I first need to understand the boot process of nerves and what it starts and if I can influence this. I don’t think it needs a bash, but a kind of terminal ex_termbox can communicate with.
I’ll keep this thread up to date with my findings if they are successful.
Thanks a lot again!

Erlang/OTP handles terminal input in a similar, but different way that Linux does. It defines an I/O protocol that’s used to print the IEx prompt and take input. If you look up the term group leader, that’s the Erlang process that figures out what to do with console input/output. Each Erlang process has a group leader that routes text to the appropriate place - be it over ssh or a local display.

Linux uses terminals and pseudo-terminals to accomplish the same thing. These are at the OS process level.

ex_termbox goes right to the Linux terminal associated with the Erlang runtime. On Nerves that’s selected by erlinit's ctty option. On the Raspberry Pi 4, that’s an HDMI output (/dev/tty1). See the default configuration. That should be what you want. If not, there’s a way to configure it via the config.exs.

I think that it would be better if ex_termbox could work within Erlang’s I/O system, but that’s probably some work. I think that you might get lucky in that this isn’t needed for your use case.