summaryrefslogtreecommitdiff
path: root/HOWTO/INSTALL-ANDROID.md
blob: 7d5af0b0ec20833e7488efea443aee728611a9de (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
Cross Compiling Erlang/OTP - ANDROID
====================================

Introduction
------------

This document describes how to cross compile Erlang/OTP to Android/Rasberry Pi platforms.


### Download and Install Android NDK ###

https://developer.android.com/ndk


### Define System Variables ###

    $ export NDK_ROOT=/path/to/android-ndk
    $ export PATH=$NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH
    $ # export PATH=$NDK_ROOT/toolchains/lvvm/prebuilt/darwin-x86_64/bin:$PATH


### Configure Erlang/OTP ###

If you are building Erlang/OTP from git, you will need to run this
to generate the configure scripts.

    $ ./otp_build autoconf


Use the following commands when compiling a 64-bit version.

    $ export NDK_ABI_PLAT=android21      # When targeting Android 5.0 Lollipop


    $ # Either without OpenSSL support:
    $
    $ ./otp_build configure \
         --xcomp-conf=./xcomp/erl-xcomp-arm64-android.conf  \
         --without-ssl


    $ # Or with OpenSSL linked statically:
    $
    $ cd /path/to/OpenSSL/source/dir/built/for/android-arm64
    $ # First follow the NOTES.ANDROID build instructions from OpenSSL
    $
    $ # Then to avoid the full installation of this cross-compiled build,
    $ # manually create a 'lib' directory at the root of the OpenSSL directory
    $ # (at the same level as 'include') and link 'libcrypto.a' inside it.
    $
    $ mkdir lib
    $ ln -s ../libcrypto.a lib/libcrypto.a
    $ cd -   # Return to the Erlang/OTP directory
    $
    $ # This previous step is needed for the OpenSSL static linking to work as
    $ # the --with-ssl option expects a path with both the 'lib' and 'include'
    $ # directories. Otherwise the Erlang/OTP build will fallback to dynamic
    $ # linking if it doesn't find 'libcrypto.a' in its expected location.
    $ ./otp_build configure \
         --xcomp-conf=./xcomp/erl-xcomp-arm64-android.conf  \
         --with-ssl=/path/to/OpenSSL/source/dir/built/for/android-arm64 \
         --disable-dynamic-ssl-lib


Use the following commands instead when compiling a 32-bit version.

    $ export NDK_ABI_PLAT=androideabi16  # When targeting Android 4.1 Jelly Bean


    $ # Either without OpenSSL support:
    $
    $ ./otp_build configure \
         --xcomp-conf=./xcomp/erl-xcomp-arm-android.conf  \
         --without-ssl


    $ # Or with OpenSSL linked statically:
    $
    $ cd /path/to/OpenSSL/source/dir/built/for/android-arm
    $ # First follow the NOTES.ANDROID build instructions from OpenSSL
    $
    $ # Then to avoid the full installation of this cross-compiled build,
    $ # manually create a 'lib' directory at the root of the OpenSSL directory
    $ # (at the same level as 'include') and link 'libcrypto.a' inside it.
    $
    $ mkdir lib
    $ ln -s ../libcrypto.a lib/libcrypto.a
    $ cd -   # Return to the Erlang/OTP directory
    $
    $ # This previous step is needed for the OpenSSL static linking to work as
    $ # the --with-ssl option expects a path with both the 'lib' and 'include'
    $ # directories. Otherwise the Erlang/OTP build will fallback to dynamic
    $ # linking if it doesn't find 'libcrypto.a' in its expected location.
    $ ./otp_build configure \
         --xcomp-conf=./xcomp/erl-xcomp-arm-android.conf  \
         --with-ssl=/path/to/OpenSSL/source/dir/built/for/android-arm \
         --disable-dynamic-ssl-lib


### Compile Erlang/OTP ###

    $ make noboot [-j4]
      or
    $ make [-j4]


### Make Release ###

    $ make RELEASE_ROOT=/path/to/release/erlang_23.0_arm release


### Target Deployment for Rasberry Pi ###

Make a tarball out of /path/to/release/erlang_23.0_arm and copy it to target
device. Extract it and install.

    $ ./Install /usr/local/erlang_23.0_arm


### Target Deployment for Android testing ###

The adb tool from the Android SDK can be used to deploy Erlang/OTP to a target
Android device, for testing purpose mainly, as the /data/local/tmp path used
for installation below is executable only from the adb shell command, but not
from other local applications due to Android sandbox security model.

    $ cd /path/to/release/erlang_23.0_arm
    $ # For testing purpose, configure the Erlang/OTP scripts to use the target
    $ # installation path in /data/local/tmp which is executable from adb shell
    $ ./Install -cross -minimal /data/local/tmp/erlang_23.0

To properly integrate into an Android application, the installation would have
to target /data/data/[your/app/package/name]/files/[erlang/dir/once/unpacked]
as shown in https://github.com/JeromeDeBretagne/erlanglauncher as an example.

WARNING: adb has issues with symlinks (and java.util.zip too). There is only
one symlink for epmd in recent Erlang/OTP releases (20 to master-based 23) so
it has to be removed before using adb push, and then recreated manually on the
target device itself if needed (or epmd can simply be duplicated instead).

    $ # Make sure that the epmd symlink is not present before adb push
    $ rm bin/epmd
    $ cp erts-X.Y.Z/bin/epmd bin/epmd
    $ cd ..
    $ # The release can now be deployed in the pre-configured target directory
    $ adb push erlang_23.0_arm /data/local/tmp/erlang_23.0

Start an interactive shell onto the target Android device, and launch erl.

     $ adb shell
     :/ $ /data/local/tmp/erlang_23.0/bin/erl
     Eshel VX.Y.Z (abort with ^G)
     1> q().
     ok
     2> :/ $ # Erlang/OTP is running on Android, congratulations! :-)


### Known Issues ###

 * native inet:gethostbyname/1 return {error, nxdomain} on Raspberry PI.
   Use dns resolver to by-pass the issue (see
   http://www.erlang.org/doc/apps/erts/inet_cfg.html)


### References ###

  The port derives some solutions from https://code.google.com/p/erlang4android/