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 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
|
<!--
%%
%% %CopyrightBegin%
%%
%% SPDX-License-Identifier: Apache-2.0
%%
%% Copyright Ericsson AB 2025. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
%% %CopyrightEnd%
-->
Cross Compiling Erlang/OTP - ANDROID
====================================
Introduction
------------
This document describes how to cross compile Erlang/OTP to Android/Raspberry Pi platforms.
### Download and Install the 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 ###
Use the following commands when compiling an ARM 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.
$ ./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 when compiling an ARM 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.
$ ./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
Use the following commands when compiling an x86 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-x86_64-android.conf \
--without-ssl
$ # Or with OpenSSL linked statically:
$
$ cd /path/to/OpenSSL/source/dir/built/for/android-x86_64
$ # First follow the NOTES.UNIX build instructions from OpenSSL
$
$ # Then to avoid the full installation of this locally-compiled build,
$ # manually create a 'lib64' directory at the root of the OpenSSL source
$ # (at the same level as 'include') and link 'libcrypto.a' inside it.
$
$ mkdir lib64
$ ln -s ../libcrypto.a lib64/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 'lib64' and
$ # 'include' directories.
$ ./otp_build configure \
--xcomp-conf=./xcomp/erl-xcomp-x86_64-android.conf \
--with-ssl=/path/to/OpenSSL/source/dir/built/for/android-x86_64 \
--disable-dynamic-ssl-lib
### Compile Erlang/OTP ###
$ make noboot [-j4]
or
$ make [-j4]
### Make Release ###
$ make RELEASE_ROOT=/path/to/release/erlang release
### Target Deployment for Raspberry Pi ###
Make a tarball out of /path/to/release/erlang and copy it to target
device. Extract it and install.
$ ./Install /usr/local/erlang
### 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
$ # 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
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 24) 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 /data/local/tmp/erlang
Start an interactive shell onto the target Android device, and launch erl.
$ adb shell
:/ $ /data/local/tmp/erlang/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/
|