Merge pull request #14 from lag-linaro/arm64-support-erlang

Build Erlang from source on AArch64 (ARMv8)
diff --git a/bin/apt-dependencies.sh b/bin/apt-dependencies.sh
index d771da8..8af5235 100755
--- a/bin/apt-dependencies.sh
+++ b/bin/apt-dependencies.sh
@@ -40,11 +40,11 @@
 apt-get update && apt-get install -y lsb-release
 
 SCRIPTPATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-VERSION=$(/usr/bin/lsb_release -cs)
-ARCH=$(arch)
+. ${SCRIPTPATH}/detect-arch.sh >/dev/null
+. ${SCRIPTPATH}/detect-os.sh >/dev/null
 debians='(wheezy|jessie|stretch|buster)'
 ubuntus='(precise|trusty|xenial|artful|bionic)'
-echo "Detected Ubuntu/Debian version: ${VERSION}   arch: ${ARCH}"
+echo "Detected Ubuntu/Debian version: ${VERSION_CODENAME}   arch: ${ARCH}"
 
 # bionic Docker image seems to be missing /etc/timezone...
 if [[ ! -f /etc/timezone ]]; then
@@ -87,7 +87,7 @@
 popd
 
 # fix for broken sphinx on ubuntu 12.04 only
-if [[ ${VERSION} == "precise" ]]; then
+if [[ ${VERSION_CODENAME} == "precise" ]]; then
   pip3 install docutils==0.13.1 sphinx==1.5.3
 fi
 
@@ -95,36 +95,40 @@
 pip3 install --upgrade sphinx_rtd_theme nose requests hypothesis==3.79.0
 
 # install dh-systemd if available
-if [[ ${VERSION} != "precise" ]]; then
+if [[ ${VERSION_CODENAME} != "precise" ]]; then
   apt-get install -y dh-systemd
 fi
 
 # relaxed lintian rules for CouchDB
 mkdir -p /usr/share/lintian/profiles/couchdb
 chmod 0755 /usr/share/lintian/profiles/couchdb
-if [[ ${VERSION} =~ ${debians} ]]; then
+if [[ ${VERSION_CODENAME} =~ ${debians} ]]; then
   cp ${SCRIPTPATH}/../files/debian.profile /usr/share/lintian/profiles/couchdb/main.profile
-  if [[ ${VERSION} == "jessie" ]]; then
+  if [[ ${VERSION_CODENAME} == "jessie" ]]; then
     # remove unknown lintian rule privacy-breach-uses-embedded-file
     sed -i -e 's/, privacy-breach-uses-embedded-file//' /usr/share/lintian/profiles/couchdb/main.profile
     # add rule to suppress python-script-but-no-python-dep
     sed -i -e 's/Disable-Tags: /Disable-Tags: python-script-but-no-python-dep, /' /usr/share/lintian/profiles/couchdb/main.profile
   fi
-elif [[ ${VERSION} =~ ${ubuntus} ]]; then
+elif [[ ${VERSION_CODENAME} =~ ${ubuntus} ]]; then
   cp ${SCRIPTPATH}/../files/ubuntu.profile /usr/share/lintian/profiles/couchdb/main.profile
-  if [[ ${VERSION} == "xenial" ]]; then
+  if [[ ${VERSION_CODENAME} == "xenial" ]]; then
     # add rule to suppress python-script-but-no-python-dep
     sed -i -e 's/Disable-Tags: /Disable-Tags: python-script-but-no-python-dep, /' /usr/share/lintian/profiles/couchdb/main.profile
   fi
 else
-  echo "Unrecognized Debian-like release: ${VERSION}! Skipping lintian work."
+  echo "Unrecognized Debian-like release: ${VERSION_CODENAME}! Skipping lintian work."
 fi
-chmod 0644 /usr/share/lintian/profiles/couchdb/main.profile
+
+MAINPROFILE=/usr/share/lintian/profiles/couchdb/main.profile
+if [[ -e ${MAINPROFILE} ]]; then
+    chmod 0644 ${MAINPROFILE}
+fi
 
 # js packages, as long as we're not told to skip them
 if [[ $1 != "nojs" ]]; then
   # config the CouchDB repo & install the JS packages
-  echo "deb https://apache.bintray.com/couchdb-deb ${VERSION} main" | \
+  echo "deb https://apache.bintray.com/couchdb-deb ${VERSION_CODENAME} main" | \
       sudo tee /etc/apt/sources.list.d/couchdb.list
   for server in $(shuf -e pgpkeys.mit.edu \
                           ha.pool.sks-keyservers.net \
diff --git a/bin/apt-erlang.sh b/bin/apt-erlang.sh
index aa1599a..941b8dc 100755
--- a/bin/apt-erlang.sh
+++ b/bin/apt-erlang.sh
@@ -36,13 +36,19 @@
   exit 1
 fi
 
+SCRIPTPATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
 # you DID run apt-dependencies.sh first, didn't you?
 VERSION=$(/usr/bin/lsb_release -cs)
 
 apt-get update || true
 
+arms='(aarch64)'
+
 if [[ ${ERLANGVERSION} == "default" ]]; then
   apt-get update && apt-get install -y erlang-nox erlang-dev erlang erlang-eunit erlang-dialyzer
+elif [[ $ARCH =~ $arms ]]; then
+    ${SCRIPTPATH}/source-erlang.sh
 else
   wget https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb
   dpkg -i erlang-solutions_1.0_all.deb
@@ -59,7 +65,9 @@
 # dangling symlinks cause make release to fail.
 # so, we remove the manpage symlink
 # see endless complaints about this on GH issues, SO, etc.
-rm /usr/lib/erlang/man
+if [[ -h /usr/lib/erlang/man ]]; then
+    rm /usr/lib/erlang/man
+fi
 
 # clean up
 apt-get clean
diff --git a/bin/detect-arch.sh b/bin/detect-arch.sh
new file mode 100755
index 0000000..60cb779
--- /dev/null
+++ b/bin/detect-arch.sh
@@ -0,0 +1,73 @@
+#!/usr/bin/env bash
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+
+# This shell script detects which architecture we're currently
+# operating on, and sets an environment variable the calling
+# script can use.
+
+# stop on error
+set -e
+
+case "${OSTYPE}" in
+  linux*)
+      if [ -x /usr/bin/arch -o -x /bin/arch ]; then
+	  export ARCH=`arch`
+      fi
+
+      if [ -x /usr/bin/uname -o -x /bin/uname ]; then
+	  export ARCH=`uname -m`
+      fi
+
+      if [ "$ARCH" == "" ]; then
+	  echo "$0 uses 'arch' or 'uname' which appear to be missing"
+	  exit 1
+      fi
+      ;;
+  *bsd*)
+    # TODO
+    echo "Currently unable to detect Arch on BSD"
+    exit 1
+    ;;
+  darwin*)
+    # TODO
+    echo "Currently unable to detect Arch on macOS (OSX)"
+    exit 1
+    ;;
+  solaris*)
+    # TODO
+    echo "Currently unable to detect Arch on Solaris-like OS"
+    exit 1
+    ;;
+  msys*)
+    # TODO
+    echo "Currently unable to detect Arch on Windows (msys)"
+    exit 1
+    ;;
+  cygwin*)
+    # TODO
+    echo "Currently unable to detect Arch on Windows (cygwin)"
+    exit 1
+    ;;
+  *)
+    echo "Unknown OS detected: ${OSTYPE}"
+    exit 1
+    ;;
+esac
+
+echo "Detected architecture: $ARCH"
diff --git a/bin/install-dependencies.sh b/bin/install-dependencies.sh
index a8c5d22..0b50b7e 100755
--- a/bin/install-dependencies.sh
+++ b/bin/install-dependencies.sh
@@ -38,7 +38,7 @@
 
 # This works if we're not called through a symlink
 # otherwise, see https://stackoverflow.com/questions/59895/
-SCRIPTPATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+export SCRIPTPATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
 
 # The directory when developers could put their own scripts which would be run
 EXTRA_SCRIPTS_DIR=${SCRIPTPATH}/extra
@@ -78,12 +78,16 @@
 
 # TODO: help info on -h
 
+. ${SCRIPTPATH}/detect-arch.sh
 . ${SCRIPTPATH}/detect-os.sh
 
+arms='(aarch64)'
+
 case "${OSTYPE}" in
   linux*)
     redhats='(rhel|centos|fedora)'
     debians='(debian|ubuntu)'
+    latest='(stretch|buster|bionic)'
 
     if [[ ${ID} =~ ${redhats} ]]; then
       NODEVERSION=${NODEVERSION} \
@@ -94,6 +98,19 @@
       fi
       run_scripts ${EXTRA_SCRIPTS_DIR} 'yum-'
     elif [[ ${ID} =~ ${debians} ]]; then
+
+      # Catching this early, so as to avoid user frustration
+      if [[ ${ERLANGVERSION%%.*} -le 19 ]] && [[ ${VERSION_CODENAME} =~ ${latest} ]]; then
+        if [[ $ARCH =~ $arms ]] && [[ ! ${SKIPERLANG} ]]; then
+          echo ""
+          echo "Recent versions of Linux (Stretch, Bionic, etc) provide a version of libssl"
+          echo "which is too new to complile earlier (<=19) versions of Erlang.  Please"
+          echo "either choose an earlier distro release or a more rencent version of Erlang."
+          echo ""
+          exit 1
+        fi
+      fi
+
       NODEVERSION=${NODEVERSION} ERLANGVERSION=${ERLANGVERSION} \
           ${SCRIPTPATH}/apt-dependencies.sh ${JSINSTALL}
       if [[ ! ${SKIPERLANG} ]]; then
diff --git a/bin/source-erlang.sh b/bin/source-erlang.sh
new file mode 100755
index 0000000..07291d7
--- /dev/null
+++ b/bin/source-erlang.sh
@@ -0,0 +1,93 @@
+#!/usr/bin/env bash
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+
+# Build Erlang from source on systems where desired package
+# versions are not available
+#
+# While these scripts are primarily written to support building CI
+# Docker images, they can be used on any workstation to install a
+# suitable build environment.
+
+# stop on error
+set -e
+
+# Check if running as root
+if [[ ${EUID} -ne 0 ]]; then
+  echo "Sorry, this script must be run as root."
+  echo "Try: sudo $0 $*"
+  exit 1
+fi
+
+SCRIPTPATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+. ${SCRIPTPATH}/detect-os.sh
+
+redhats='(rhel|centos|fedora)'
+debians='(debian|ubuntu)'
+latest='(stretch|buster|bionic)'
+
+# Install per-distro dependencies according to:
+#  http://docs.basho.com/riak/1.3.0/tutorials/installation/Installing-Erlang/
+# NB: Dropping suggested superfluous packages; fop and unixodbc-dev
+if [[ ${ID} =~ ${redhats} ]]; then
+    yum install git gcc glibc-devel make ncurses-devel openssl-devel autoconf
+elif [[ ${ID} =~ ${debians} ]]; then
+    if [[ ${ERLANGVERSION%%.*} -le 19 ]] && [[ ${VERSION_CODENAME} =~ ${latest} ]]; then
+	echo "Recent versions of Linux (Stretch, Bionic, etc) provide a version of libssl"
+	echo "which is too new to complile earlier (<=19) versions of Erlang.  Please"
+	echo "either choose an earlier distro release or a more rencent version of Erlang."
+	exit 1
+    fi
+
+    apt-get update
+    apt-get install -y git build-essential autoconf libncurses5-dev openssl libssl-dev xsltproc
+else
+  echo "Sorry, we don't support this Linux (${ID}) yet."
+  exit 1
+fi
+
+# Pull down and checkout the requested Erlang version
+git clone https://github.com/erlang/otp.git
+cd otp
+git checkout OTP-${ERLANGVERSION} -b local-OTP-${ERLANGVERSION}
+
+# Configure Erlang - skip building things we don't want or need
+./otp_build autoconf
+
+./otp_build configure --without-javac --without-wx --without-odbc \
+  --without-debugger --without-observer --without-et  --without-cosEvent\
+  --without-cosEventDomain --without-cosFileTransfer \
+  --without-cosNotification --without-cosProperty --without-cosTime \
+  --without-cosTransactions --without-orber
+
+# Build Erlang
+make -j $(nproc)
+
+# Install Erlang
+make install
+
+# Clean-up
+cd -
+rm -rf otp
+
+if [[ ${ID} =~ ${redhats} ]]; then
+    yum clean all
+elif [[ ${ID} =~ ${debians} ]]; then
+    apt-get clean
+fi
diff --git a/bin/yum-dependencies.sh b/bin/yum-dependencies.sh
index e763abf..6de2d63 100755
--- a/bin/yum-dependencies.sh
+++ b/bin/yum-dependencies.sh
@@ -37,7 +37,7 @@
 SCRIPTPATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
 
 . ${SCRIPTPATH}/detect-os.sh >/dev/null
-ARCH=$(arch)
+. ${SCRIPTPATH}/detect-arch.sh >/dev/null
 echo "Detected RedHat/Centos/Fedora version: ${VERSION_ID}   arch: ${ARCH}"
 
 # TODO: Do the Right Things(tm) for Fedora
diff --git a/bin/yum-erlang.sh b/bin/yum-erlang.sh
index 1f4ae76..9674d46 100755
--- a/bin/yum-erlang.sh
+++ b/bin/yum-erlang.sh
@@ -34,9 +34,13 @@
   exit 1
 fi
 
+arms='(aarch64)'
+
 # TODO: Do the Right Things(tm) for Fedora
 if [[ ${ERLANGVERSION} == "default" ]]; then
   yum install -y erlang
+elif [[ $ARCH =~ $arms ]]; then
+  ${SCRIPTPATH}/source-erlang.sh
 else
   wget https://packages.erlang-solutions.com/erlang-solutions-1.0-1.noarch.rpm
   rpm -Uvh erlang-solutions-1.0-1.noarch.rpm