Bluish Coder

Programming Languages, Martials Arts and Computers. The Weblog of Chris Double.


2015-06-21

Building Erlang for Android

Support for building Erlang on Android is provided in the standard Erlang source.

Build setup

I use the Erlang git version for building. Cloning can be done with:

git clone https://github.com/erlang/otp

In the xcomp directory of the cloned repository there is an erl-xcomp-arm-android.conf file that contains details for cross compiling to Android. This can be modified per the instructions in the Erlang cross compilation documentation but the defaults are probably fine.

Some environment variables need to be set to locate the Android NDK:

export NDK_ROOT=/path/to/ndk/root
export NDK_PLAT=android-21

The NDK_PLAT environment variable identifies the Android API version to use for building. In this case android-21 is for KitKat (See STABLE-APIS.html).

Add the path to the Android version of the gcc compiler:

export PATH=$PATH:$NDK_ROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin

When building from the git repository an initial step of generating configuration files needs to be done. This requires autoconf version 2.59. If autoconf2.59 is the command to run this version you may need to change some symlinks or defaults for your OS or you can edit the otp_build file to replace occurences of autoconf with autoconf2.59.

Building

Building from git requires generating build configuration files first:

./otp_build autoconf

Once generated, run the configure step. This will configure both a host version of Erlang for bootstrapping and the Android version:

./otp_build configure --xcomp-conf=xcomp/erl-xcomp-arm-android.conf

Build a bootstrap system of Erlang for the host machine, followed by one for the Android target:

./otp_build boot -a

Installing

Installing to an Android device involves running a build step to copy the files to a temporary directory, run a script to change paths to the directory where the installation will be on the Android device and pushing the final result to the device.

In the following series of commands I use /tmp/erlang as the temporary directory on the host system and /data/local/tmp/erlang as the install directory on the Android device. The directory /data/local/tmp is writable on non-rooted Android KitKat devices. It's useful for testing.

./otp_build release -a /tmp/erlang
cd /tmp/erlang
./Install -cross -minimal /data/local/tmp/erlang

One of the files bin/epmd is a symlink which adb push has problems with. For the copying of the files below I delete the file and manually recreate the symlink after the push:

adb shell mkdir /data/local/tmp/erlang
cd /tmp
rm erlang/bin/epmd
adb push erlang /data/local/tmp/erlang/
adb shell ln -s /data/local/tmp/erlang/erts-6.4.1/bin/epmd \
                /data/local/tmp/erlang/bin/epmd

The adb commands assume the device is already connected and can be accessed via adb.

Running

Once the final push completes Erlang can be run via adb shell or a terminal application on the device:

$ adb shell
$ cd /data/local/tmp/erlang
$ sh bin/erl    
Eshell V6.4.1  (abort with ^G)
1> 

You may get an error about sed not being found. This is due to a sed command run on the first argument of the erl shell script. A workaround for this is to build an Android version of sed and install it along with Erlang.

Networking

I've tested with some basic Erlang functionality and it works fine. Some tweaks need to be made for networking however. The method Erlang uses for DNS lookup doesn't work on Android. By default it's using native system calls. With a configuration file it can be changed to use its own internal DNS method. Create a file with the following contents:

{lookup, [file,dns]}.
{nameserver, {8,8,8,8}}.

In this case the nameserver for DNS lookups is hardcoded to Google's DNS. Ideally this would be looked up somehow using Android functionality for whatever is configured on the phone but this works for test cases. Push this file to the device and run erl with it passed as an argument like so (inetrc is the name I used for the file in this case):

$ adb push inetrc /data/local/tmp/erlang/
$ adb shell
$ cd/data/local/tmp/erlang
$ sh bin/erl -kernel inetrc '"./inetrc"'

Network examples should now work:

1> inets:start().
ok
2> inet_res:getbyname("www.example.com",a).
{ok,{hostent,"www.example.com",[],inet,4,[{93,184,216,34}]}}
3> httpc:request(get, {"http://bluishcoder.co.nz/index.html", []}, [], []).
{ok,...}

More information on the inetrc file format is available in the Erlang documentation.

Conclusion

This showed that a basic installation of Erlang works on Android. I've also tested on a Firefox OS phone with root access. An interesting project would be to install Erlang on either a Firefox OS or an Android AOSP build as a system service and write phone services in Erlang as a test for an Erlang based device.

Tags


This site is accessable over tor as hidden service mh7mkfvezts5j6yu.onion, or Freenet using key:
USK@1ORdIvjL2H1bZblJcP8hu2LjjKtVB-rVzp8mLty~5N4,8hL85otZBbq0geDsSKkBK4sKESL2SrNVecFZz9NxGVQ,AQACAAE/bluishcoder/-30/


Tags

Archives
Links