File 0584-Fix-Android-compilation-to-support-newer-Android-NDK.patch of Package erlang
From b3f5bbb6a472069781b3ab934b15b9cd80198565 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=B4me=20de=20Bretagne?=
<jerome.debretagne@gmail.com>
Date: Wed, 30 Oct 2019 00:20:46 +0100
Subject: [PATCH] Fix Android compilation to support newer Android NDK versions
Switch to use the Unified Headers introduced in Android NDK r14
optionnally and made mandatory since Android NDK r16 with the
remove of the older headers.
Switch to Clang for Android compilation, with GCC being deprecated
in Android NDK r16 and then fully removed in Android NDK r18b.
Add the default -g -O2 options to CFLAGS for Android as a -O option
is required since commit cc21219185d7ff90b5d3d09cae896082d7627ea9.
Fix ERL-1081: Move to dynamic linking, to avoid missing symbol
errors due to an incompatibility between Autoconf (AC_CHECK_FUNCS)
and the Android NDK.
Add a new Android cross-compile configuration for 64-bit ARMv8-A.
Update the documentation about how to cross compile for Android.
---
HOWTO/INSTALL-ANDROID.md | 115 ++++++++++++---
xcomp/erl-xcomp-arm-android.conf | 52 +++++--
xcomp/erl-xcomp-arm64-android.conf | 283 +++++++++++++++++++++++++++++++++++++
3 files changed, 417 insertions(+), 33 deletions(-)
create mode 100644 xcomp/erl-xcomp-arm64-android.conf
diff --git a/HOWTO/INSTALL-ANDROID.md b/HOWTO/INSTALL-ANDROID.md
index 31698d4ce3..34937b921e 100644
--- a/HOWTO/INSTALL-ANDROID.md
+++ b/HOWTO/INSTALL-ANDROID.md
@@ -4,48 +4,121 @@ Cross Compiling Erlang/OTP - ANDROID
Introduction
------------
-This document describes how to cross compile Erlang OTP to Android/Rasberry Pi platforms.
+This document describes how to cross compile Erlang/OTP to Android/Rasberry Pi platforms.
+
### Download and Install Android NDK ###
-https://developer.android.com/tools/sdk/ndk/index.html
+https://developer.android.com/ndk
+
### Define System Variables ###
-export NDK_ROOT=/usr/local/android
-export NDK_PLAT=android-9
-export PATH=$NDK_ROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/bin:$PATH
+ $ 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 when compiling a 64-bit version.
+
+ $ export NDK_ABI_PLAT=android24 # When targeting Android 7.0 Nougat
+ $ ./otp_build configure \
+ --xcomp-conf=./xcomp/erl-xcomp-arm64-android.conf \
+ --without-ssl
+
+
+Use the following instead when compiling a 32-bit version.
+
+ $ export NDK_ABI_PLAT=androideabi24 # When targeting Android 7.0 Nougat
+ $ ./otp_build configure \
+ --xcomp-conf=./xcomp/erl-xcomp-arm-android.conf \
+ --without-ssl
-### Configure OTP ###
-./otp_build configure \
- --xcomp-conf=./xcomp/erl-xcomp-arm-android.conf \
- --without-ssl
+### Compile Erlang/OTP ###
-### Compile OTP ###
+ $ # make noboot [-j4] # noboot doesn't work, is it a recent regression?
+ $ make [-j4]
-make noboot [-j4]
### Make Release ###
-./otp_build release -a /usr/local/otp_R16B03_arm
+ $ make RELEASE_ROOT=/path/to/release/erlang_23.0_arm release
-### Target Deployment ###
-Make a tarball out of /usr/local/otp_R16B03_arm and copy it to target device
-(e.g. Raspberry Pi). Extract it and install
+### Target Deployment for Rasberry Pi ###
-./Install /usr/local/otp_R16B03_arm
+Make a tarball out of /path/to/release/erlang_23.0_arm and copy it to target
+device. Extract it and install.
-Android SDK (adb tool) is used to deploy OTP/Erlang to target device for
-evaluation purpose only.
+ $ ./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.
+
+TODO: Propose a permanent fix for the following issue.
+Adapt the installation specifically for Android, by replacing manually /bin/sh
+into /system/bin/sh in the various Erlang/OTP release scripts, such as:
+ - bin/erl
+ - bin/start
+ - bin/start_erl
+ - erts-X.Y.Z/bin/erl
+ - erts-X.Y.Z/bin/erl.src
+ - erts-X.Y.Z/bin/start
+ - erts-X.Y.Z/bin/start_erl.src
+ - erts-X.Y.Z/bin/start.src
+ - etc.
+
+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! :-)
-adb push /usr/local/otp_R16B03_arm /mnt/sdcard/otp_R16B03_arm
-adb shell
### 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)
+ * 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 ###
diff --git a/xcomp/erl-xcomp-arm-android.conf b/xcomp/erl-xcomp-arm-android.conf
index 44ff7537d3..64f976fce8 100644
--- a/xcomp/erl-xcomp-arm-android.conf
+++ b/xcomp/erl-xcomp-arm-android.conf
@@ -2,7 +2,7 @@
##
## %CopyrightBegin%
##
-## Copyright Ericsson AB 2009-2010. All Rights Reserved.
+## Copyright Ericsson AB 2009-2019. 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.
@@ -18,8 +18,8 @@
##
## %CopyrightEnd%
##
-## File: erl-xcomp.conf.template
-## Author:
+## File: erl-xcomp-arm-android.conf
+## Author: Dmitry Kolesnikov
##
## -----------------------------------------------------------------------------
## When cross compiling Erlang/OTP using `otp_build', copy this file and set
@@ -60,14 +60,21 @@ erl_xcomp_host=arm-linux-androideabi
# * `erl_xcomp_configure_flags' - Extra configure flags to pass to the
# `configure' script.
-erl_xcomp_configure_flags="--disable-hipe --without-termcap"
+# Set --enable-builtin-zlib to avoid a inflateGetDictionary missing symbol
+erl_xcomp_configure_flags="--disable-hipe --without-termcap --without-wx \
+ --enable-builtin-zlib"
## -- Cross Compiler and Other Tools -------------------------------------------
##
##
-NDK_SYSROOT=$NDK_ROOT/platforms/$NDK_PLAT/arch-arm
+# Previously with older Android NDK versions before NDK r14, each Android
+# API level had a different set of headers, each in its own directory.
+#NDK_SYSROOT=$NDK_ROOT/platforms/$NDK_PLAT/arch-arm
+# Starting with Android NDK r14, a single set of headers (called Unified Headers)
+# is provided in one location for every Android API level.
+NDK_SYSROOT=$NDK_ROOT/sysroot
## If the cross compilation tools are prefixed by `<HOST>-' you probably do
## not need to set these variables (where `<HOST>' is what has been passed as
@@ -76,10 +83,15 @@ NDK_SYSROOT=$NDK_ROOT/platforms/$NDK_PLAT/arch-arm
## All variables in this section can also be used when native compiling.
# * `CC' - C compiler.
-CC="arm-linux-androideabi-gcc --sysroot=$NDK_SYSROOT"
+#
+# For older Android NDK versions still supporting GCC.
+#CC="arm-linux-androideabi-gcc --sysroot=$NDK_SYSROOT"
+# For more recent Android NDK versions only supporting Clang/LLVM.
+#NDK_ABI_PLAT=androideabi24 # when targeting Android 7.0 Nougat
+CC="armv7a-linux-$NDK_ABI_PLAT-clang"
# * `CFLAGS' - C compiler flags.
-CFLAGS="-static -march=armv7-a -msoft-float -mthumb"
+CFLAGS="-g -O2 -march=armv7-a -mfloat-abi=softfp -mthumb"
# * `STATIC_CFLAGS' - Static C compiler flags.
#STATIC_CFLAGS=
@@ -90,22 +102,38 @@ CFLAGS="-static -march=armv7-a -msoft-float -mthumb"
#CFLAG_RUNTIME_LIBRARY_PATH=
# * `CPP' - C pre-processor.
-CPP="arm-linux-androideabi-cpp --sysroot=$NDK_SYSROOT"
+#
+# For older Android NDK versions still supporting GCC.
+#CPP="arm-linux-androideabi-cpp --sysroot=$NDK_SYSROOT"
+# Not needed when using Clang/LLVM.
+#CPP=
# * `CPPFLAGS' - C pre-processor flags.
-CPPFLAGS="-static -march=armv7-a -msoft-float -mthumb"
+#
+# For older Android NDK versions still supporting GCC.
+#CPPFLAGS="-static -march=armv7-a -msoft-float -mthumb"
+# Not needed when using Clang/LLVM.
+#CPPFLAGS=
# * `CXX' - C++ compiler.
-CXX="arm-linux-androideabi-c++ --sysroot=$NDK_SYSROOT"
+#
+# For older Android NDK versions still supporting GCC.
+#CXX="arm-linux-androideabi-c++ --sysroot=$NDK_SYSROOT
+# For more recent Android NDK versions only supporting Clang/LLVM.
+CXX="armv7a-linux-$NDK_ABI_PLAT-clang++"
# * `CXXFLAGS' - C++ compiler flags.
-CXXFLAGS="-static -march=armv7-a -msoft-float -mthumb"
+CXXFLAGS="-march=armv7-a -mfloat-abi=softfp -mthumb"
# * `LD' - Linker.
+#
+# Not needed when using GCC.
#LD=
+# For more recent Android NDK versions only supporting Clang/LLVM.
+LD="arm-linux-androideabi-ld"
# * `LDFLAGS' - Linker flags.
-LDFLAGS="-static -march=armv7-a -msoft-float -mthumb"
+LDFLAGS="-march=armv7-a -mfloat-abi=softfp -mthumb"
# * `LIBS' - Libraries.
#LIBS=
diff --git a/xcomp/erl-xcomp-arm64-android.conf b/xcomp/erl-xcomp-arm64-android.conf
new file mode 100644
index 0000000000..bedee510e1
--- /dev/null
+++ b/xcomp/erl-xcomp-arm64-android.conf
@@ -0,0 +1,283 @@
+## -*-shell-script-*-
+##
+## %CopyrightBegin%
+##
+## Copyright Ericsson AB 2019. 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%
+##
+## File: erl-xcomp-arm64-android.conf
+## Author: Jérôme de Bretagne
+##
+## -----------------------------------------------------------------------------
+## When cross compiling Erlang/OTP using `otp_build', copy this file and set
+## the variables needed below. Then pass the path to the copy of this file as
+## an argument to `otp_build' in the configure stage:
+## `otp_build configure --xcomp-conf=<FILE>'
+## -----------------------------------------------------------------------------
+
+## Note that you cannot define arbitrary variables in a cross compilation
+## configuration file. Only the ones listed below will be guaranteed to be
+## visible throughout the whole execution of all `configure' scripts. Other
+## variables needs to be defined as arguments to `configure' or exported in
+## the environment.
+
+## -- Variables for `otp_build' Only -------------------------------------------
+
+## Variables in this section are only used, when configuring Erlang/OTP for
+## cross compilation using `$ERL_TOP/otp_build configure'.
+
+## *NOTE*! These variables currently have *no* effect if you configure using
+## the `configure' script directly.
+
+# * `erl_xcomp_build' - The build system used. This value will be passed as
+# `--build=$erl_xcomp_build' argument to the `configure' script. It does
+# not have to be a full `CPU-VENDOR-OS' triplet, but can be. The full
+# `CPU-VENDOR-OS' triplet will be created by
+# `$ERL_TOP/erts/autoconf/config.sub $erl_xcomp_build'. If set to `guess',
+# the build system will be guessed using
+# `$ERL_TOP/erts/autoconf/config.guess'.
+erl_xcomp_build=guess
+
+# * `erl_xcomp_host' - Cross host/target system to build for. This value will
+# be passed as `--host=$erl_xcomp_host' argument to the `configure' script.
+# It does not have to be a full `CPU-VENDOR-OS' triplet, but can be. The
+# full `CPU-VENDOR-OS' triplet will be created by
+# `$ERL_TOP/erts/autoconf/config.sub $erl_xcomp_host'.
+erl_xcomp_host=aarch64-linux-android
+
+# * `erl_xcomp_configure_flags' - Extra configure flags to pass to the
+# `configure' script.
+# Set --enable-builtin-zlib to avoid a inflateGetDictionary missing symbol
+erl_xcomp_configure_flags="--disable-hipe --without-termcap --without-wx \
+ --enable-builtin-zlib"
+
+
+## -- Cross Compiler and Other Tools -------------------------------------------
+
+##
+##
+# Previously with older Android NDK versions before NDK r14, each Android
+# API level had a different set of headers, each in its own directory.
+#NDK_SYSROOT=$NDK_ROOT/platforms/$NDK_PLAT/arch-arm
+# Starting with Android NDK r14, a single set of headers (called Unified Headers)
+# is provided in one location for every Android API level.
+NDK_SYSROOT=$NDK_ROOT/sysroot
+
+## If the cross compilation tools are prefixed by `<HOST>-' you probably do
+## not need to set these variables (where `<HOST>' is what has been passed as
+## `--host=<HOST>' argument to `configure').
+
+## All variables in this section can also be used when native compiling.
+
+# * `CC' - C compiler.
+#
+# For recent Android NDK versions only supporting Clang/LLVM.
+#NDK_ABI_PLAT=android24 # when targeting Android 7.0 Nougat
+CC="aarch64-linux-$NDK_ABI_PLAT-clang"
+
+# * `CFLAGS' - C compiler flags.
+CFLAGS="-g -O2"
+
+# * `STATIC_CFLAGS' - Static C compiler flags.
+#STATIC_CFLAGS=
+
+# * `CFLAG_RUNTIME_LIBRARY_PATH' - This flag should set runtime library
+# search path for the shared libraries. Note that this actually is a
+# linker flag, but it needs to be passed via the compiler.
+#CFLAG_RUNTIME_LIBRARY_PATH=
+
+# * `CPP' - C pre-processor.
+#
+# Not needed when using Clang/LLVM.
+#CPP=
+
+# * `CPPFLAGS' - C pre-processor flags.
+#
+# Not needed when using Clang/LLVM.
+#CPPFLAGS=
+
+# * `CXX' - C++ compiler.
+#
+# For recent Android NDK versions only supporting Clang/LLVM.
+CXX="aarch64-linux-$NDK_ABI_PLAT-clang++"
+
+# * `CXXFLAGS' - C++ compiler flags.
+#CXXFLAGS=
+
+# * `LD' - Linker.
+#
+# For recent Android NDK versions only supporting Clang/LLVM.
+LD="aarch64-linux-android-ld"
+
+# * `LDFLAGS' - Linker flags.
+#LDFLAGS=
+
+# * `LIBS' - Libraries.
+#LIBS=
+
+## -- *D*ynamic *E*rlang *D*river Linking --
+
+## *NOTE*! Either set all or none of the `DED_LD*' variables.
+
+# * `DED_LD' - Linker for Dynamically loaded Erlang Drivers.
+#DED_LD=
+
+# * `DED_LDFLAGS' - Linker flags to use with `DED_LD'.
+#DED_LDFLAGS=
+
+# * `DED_LD_FLAG_RUNTIME_LIBRARY_PATH' - This flag should set runtime library
+# search path for shared libraries when linking with `DED_LD'.
+#DED_LD_FLAG_RUNTIME_LIBRARY_PATH=
+
+## -- Large File Support --
+
+## *NOTE*! Either set all or none of the `LFS_*' variables.
+
+# * `LFS_CFLAGS' - Large file support C compiler flags.
+#LFS_CFLAGS=
+
+# * `LFS_LDFLAGS' - Large file support linker flags.
+#LFS_LDFLAGS=
+
+# * `LFS_LIBS' - Large file support libraries.
+#LFS_LIBS=
+
+## -- Other Tools --
+
+# * `RANLIB' - `ranlib' archive index tool.
+#RANLIB=
+
+# * `AR' - `ar' archiving tool.
+#AR=
+
+# * `GETCONF' - `getconf' system configuration inspection tool. `getconf' is
+# currently used for finding out large file support flags to use, and
+# on Linux systems for finding out if we have an NPTL thread library or
+# not.
+#GETCONF=
+
+## -- Cross System Root Locations ----------------------------------------------
+
+# * `erl_xcomp_sysroot' - The absolute path to the system root of the cross
+# compilation environment. Currently, the `crypto', `odbc', `ssh' and
+# `ssl' applications need the system root. These applications will be
+# skipped if the system root has not been set. The system root might be
+# needed for other things too. If this is the case and the system root
+# has not been set, `configure' will fail and request you to set it.
+erl_xcomp_sysroot="$NDK_SYSROOT"
+
+
+# * `erl_xcomp_isysroot' - The absolute path to the system root for includes
+# of the cross compilation environment. If not set, this value defaults
+# to `$erl_xcomp_sysroot', i.e., only set this value if the include system
+# root path is not the same as the system root path.
+#erl_xcomp_isysroot=
+
+## -- Optional Feature, and Bug Tests ------------------------------------------
+
+## These tests cannot (always) be done automatically when cross compiling. You
+## usually do not need to set these variables. Only set these if you really
+## know what you are doing.
+
+## Note that some of these values will override results of tests performed
+## by `configure', and some will not be used until `configure' is sure that
+## it cannot figure the result out.
+
+## The `configure' script will issue a warning when a default value is used.
+## When a variable has been set, no warning will be issued.
+
+# * `erl_xcomp_after_morecore_hook' - `yes|no'. Defaults to `no'. If `yes',
+# the target system must have a working `__after_morecore_hook' that can be
+# used for tracking used `malloc()' implementations core memory usage.
+# This is currently only used by unsupported features.
+#erl_xcomp_after_morecore_hook=
+
+# * `erl_xcomp_bigendian' - `yes|no'. No default. If `yes', the target system
+# must be big endian. If `no', little endian. This can often be
+# automatically detected, but not always. If not automatically detected,
+# `configure' will fail unless this variable is set. Since no default
+# value is used, `configure' will try to figure this out automatically.
+#erl_xcomp_bigendian=
+
+# * `erl_xcomp_clock_gettime_cpu_time' - `yes|no'. Defaults to `no'. If `yes',
+# the target system must have a working `clock_gettime()' implementation
+# that can be used for retrieving process CPU time.
+#erl_xcomp_clock_gettime_cpu_time=
+
+# * `erl_xcomp_getaddrinfo' - `yes|no'. Defaults to `no'. If `yes', the target
+# system must have a working `getaddrinfo()' implementation that can
+# handle both IPv4 and IPv6.
+#erl_xcomp_getaddrinfo=
+
+# * `erl_xcomp_gethrvtime_procfs_ioctl' - `yes|no'. Defaults to `no'. If `yes',
+# the target system must have a working `gethrvtime()' implementation and
+# is used with procfs `ioctl()'.
+#erl_xcomp_gethrvtime_procfs_ioctl=
+
+# * `erl_xcomp_dlsym_brk_wrappers' - `yes|no'. Defaults to `no'. If `yes', the
+# target system must have a working `dlsym(RTLD_NEXT, <S>)' implementation
+# that can be used on `brk' and `sbrk' symbols used by the `malloc()'
+# implementation in use, and by this track the `malloc()' implementations
+# core memory usage. This is currently only used by unsupported features.
+#erl_xcomp_dlsym_brk_wrappers=
+
+# * `erl_xcomp_kqueue' - `yes|no'. Defaults to `no'. If `yes', the target
+# system must have a working `kqueue()' implementation that returns a file
+# descriptor which can be used by `poll()' and/or `select()'. If `no' and
+# the target system has not got `epoll()' or `/dev/poll', the kernel-poll
+# feature will be disabled.
+#erl_xcomp_kqueue=
+
+# * `erl_xcomp_linux_clock_gettime_correction' - `yes|no'. Defaults to `yes' on
+# Linux; otherwise, `no'. If `yes', `clock_gettime(CLOCK_MONOTONIC, _)' on
+# the target system must work. This variable is recommended to be set to
+# `no' on Linux systems with kernel versions less than 2.6.
+#erl_xcomp_linux_clock_gettime_correction=
+
+# * `erl_xcomp_linux_nptl' - `yes|no'. Defaults to `yes' on Linux; otherwise,
+# `no'. If `yes', the target system must have NPTL (Native POSIX Thread
+# Library). Older Linux systems have LinuxThreads instead of NPTL (Linux
+# kernel versions typically less than 2.6).
+#erl_xcomp_linux_nptl=
+
+# * `erl_xcomp_linux_usable_sigaltstack' - `yes|no'. Defaults to `yes' on Linux;
+# otherwise, `no'. If `yes', `sigaltstack()' must be usable on the target
+# system. `sigaltstack()' on Linux kernel versions less than 2.4 are
+# broken.
+#erl_xcomp_linux_usable_sigaltstack=
+
+# * `erl_xcomp_linux_usable_sigusrx' - `yes|no'. Defaults to `yes'. If `yes',
+# the `SIGUSR1' and `SIGUSR2' signals must be usable by the ERTS. Old
+# LinuxThreads thread libraries (Linux kernel versions typically less than
+# 2.2) used these signals and made them unusable by the ERTS.
+#erl_xcomp_linux_usable_sigusrx=
+
+# * `erl_xcomp_poll' - `yes|no'. Defaults to `no' on Darwin/MacOSX; otherwise,
+# `yes'. If `yes', the target system must have a working `poll()'
+# implementation that also can handle devices. If `no', `select()' will be
+# used instead of `poll()'.
+#erl_xcomp_poll=
+
+# * `erl_xcomp_putenv_copy' - `yes|no'. Defaults to `no'. If `yes', the target
+# system must have a `putenv()' implementation that stores a copy of the
+# key/value pair.
+#erl_xcomp_putenv_copy=
+
+# * `erl_xcomp_reliable_fpe' - `yes|no'. Defaults to `no'. If `yes', the target
+# system must have reliable floating point exceptions.
+#erl_xcomp_reliable_fpe=
+
+## -----------------------------------------------------------------------------
--
2.16.4