Running the BEAM as C

Here is an open issue. They still have an year or more to migrate to the new system since google play let’s you upload now starting from API-28.

In general there are few improvements that need to be done on Android. For example one of the problems is the compiled OTP size, currently it has about 30 MB, this is not ideal if you want to embed the runtime into every application, this is without any files with compiled code or additional libraries.

Maybe waiting for Lumen to mature would be most sane choice here.

What I would like to have is one app that integrated with the OPT elixir, the whole tool chain and, so it can download, build and run elixir+scenic based mini apps from

You opened a can of worms here, scenic currently uses glfw under the hood, which was not designed for touch screens and does not work as expected on android. Of course there are a few alternatives, however now the main goal is to create a .so library that will contain compiled OTP. Integrating elixir should be easy, since all you need elixir for is to compile source files.

@D4no0 I think @derek-zhou is bringing Scenic up as I mentioned it here. I don’t know what would be the best solution for a display. I just mentioned Scenic because it seemed like the best fit. If you know better, could you please contribute to that post? Also, if you’ve done some work in this beyond the GitHub repo please let us know. I’m really interested in what you’ve managed to get working so far.

Scenic is the way to go. The alternative would be to use the java android render pipeline, the problem with that is the fact that you lose the fault tolerance, if that pipeline crashes the application will crash. The argument that scenic is for fixed size screen makes no sense as android devices also have fixed size screen, so in this situation a relative layout library should be written on top of scenic that will handle the resizing at runtime based on screen size.

Agreed. For touch events for Android I was planning on just writing a wrapper to forward all of the touch events to Elixir that are fed into the C/C++. Then we can just handled them in Elixir. Of course these are just ideas right now unless someone knows if someone has made some progress already in this area.

As for iOS I haven’t made it that far but people have already made full apps in only C/C++ so I imagine there is a way.

All you need is to write new scenic drivers for something like glfm, of course if there are limitations in scenic currently they can be discussed with creator and add new features to scenic. However, as I said, this will become feasible only when OTP runtime will work stable on android-11.

Correct me if I am wrong, but why do we need the OTP in a .so file? The OTP would be part of the apk, and the github issue you cited says:

While exec() no longer works on files within the application home directory, it continues to be supported for files within the read-only /data/app directory.

If all the NIF required library such as Scenic etc, are pre-packaged into the apk, and the user installable parts are only in pure elixir/erlang, we could just mix run them, right?

Yes, since what you execute is the virtual machine (in our case located in .so package) that is pointing to the compiled source files.

Yes, of course. The BEAM runs in a number of its own threads so if you start up more threads in the OS process then that will work, this can be done from the BEAM using NFI code. You have to be very careful not to start sharing data with the BEAM threads; you’re on your own if you do that.

From other threads it is possible to send messages to processes you just have to careful that you only send Erlang data structures. There is a large library to help you do this. This is quite common in the BEAM itself, for example for doing file i/o.

I still don’t get the reason that demand .so. The apk file can contain multiple binaries, so long as they are not user installable and changeable, and one can exec() one of your own binaries from the main binary in your app. I see this as the perfect way to launch the BEAM to run user installed bytecode.

This might be true for now, however in next versions of android this might not be the case, the official and supported way to go is to create a .so library for every architecture.

You can have a binary for each supported architecture. What you say is google is going to disallow multiple processes in an app, which sounds completely backwards and does not add any security value. I don’t think Google will ever support elixir/erlang app development, so whatever we do will be venturing out from the safety zone. In this case, it is both important to read between the lines and not to read too much between the lines. Their motivation is security and their model is apple. Does iOS support multiple processes in an app?

I downloaded and ran the code. It compiled and ran but stopped running. It’s using a precompiled bin for Erlang though. This isn’t going to work for iOS as Apple won’t allow a bin bundled in an app. I’ll be looking into alternatives for the time being.

I achieved similar results to the previous experience by compiling the BEAM code in Android Studio and modifying the cmake file of this sample code and dropping the otp source code into the cpp folder. I can confirm that it builds but crashes on start so there is more work to be done.

If you read the build guide, you can notice there is also the install step, the binaries in example repos are preconfigured to work only with that application namespace, if you change it, it will no longer work. This involves running a bash script specifying the path to beam, this is the source of the issues previously discussed. Also IOS allows precompiled binaries, otherwise things like xamarin, cocos wouldn’t work on IOS to begin with, I guess what you wanted to say is that it doesn’t allow standalone executables bundled.

Do you have a link for Xamarin showing they are including a bin in their iOS releases?

Flutter seems to be using C++ for their interop.

1 Like