2100 lines
60 KiB
Bash
Executable File
2100 lines
60 KiB
Bash
Executable File
#! /bin/sh
|
|
|
|
# Copyright (c) 2016 Mark Allen
|
|
# Copyright (c) 2011, 2012 Spawngrid, Inc
|
|
# Copyright (c) 2011 Evax Software <contact(at)evax(dot)org>
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
# of this software and associated documentation files (the "Software"), to deal
|
|
# in the Software without restriction, including without limitation the rights
|
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
# copies of the Software, and to permit persons to whom the Software is
|
|
# furnished to do so, subject to the following conditions:
|
|
#
|
|
# The above copyright notice and this permission notice shall be included in
|
|
# all copies or substantial portions of the Software.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
# THE SOFTWARE.
|
|
|
|
unset ERL_TOP
|
|
|
|
KERL_VERSION="1.8.1"
|
|
|
|
#Grep fix for mac pcre errors
|
|
GREP_OPTIONS=''
|
|
|
|
DOCSH_GITHUB_URL="https://github.com/erszcz/docsh.git"
|
|
ERLANG_DOWNLOAD_URL="http://www.erlang.org/download"
|
|
KERL_CONFIG_STORAGE_FILENAME=".kerl_config"
|
|
|
|
if [ -z "$HOME" ]; then
|
|
echo "Error: \$HOME is empty or not set." 1>&2
|
|
exit 1
|
|
fi
|
|
|
|
# Default values
|
|
: ${OTP_GITHUB_URL:="https://github.com/erlang/otp"}
|
|
: ${KERL_BASE_DIR:="$HOME"/.kerl}
|
|
: ${KERL_CONFIG:="$HOME"/.kerlrc}
|
|
: ${KERL_DOWNLOAD_DIR:="${KERL_BASE_DIR:?}"/archives}
|
|
: ${KERL_BUILD_DIR:="${KERL_BASE_DIR:?}"/builds}
|
|
: ${KERL_GIT_DIR:="${KERL_BASE_DIR:?}"/gits}
|
|
|
|
if [ -n "$OTP_GITHUB_URL" ]; then
|
|
_OGU="$OTP_GITHUB_URL"
|
|
fi
|
|
if [ -n "$KERL_CONFIGURE_OPTIONS" ]; then
|
|
_KCO="$KERL_CONFIGURE_OPTIONS"
|
|
fi
|
|
if [ -n "$KERL_CONFIGURE_APPLICATIONS" ]; then
|
|
_KCA="$KERL_CONFIGURE_APPLICATIONS"
|
|
fi
|
|
if [ -n "$KERL_CONFIGURE_DISABLE_APPLICATIONS" ]; then
|
|
_KCDA="$KERL_CONFIGURE_DISABLE_APPLICATIONS"
|
|
fi
|
|
if [ -n "$KERL_SASL_STARTUP" ]; then
|
|
_KSS="$KERL_SASL_STARTUP"
|
|
fi
|
|
if [ -n "$KERL_DEPLOY_SSH_OPTIONS" ]; then
|
|
_KDSSH="$KERL_DEPLOY_SSH_OPTIONS"
|
|
fi
|
|
if [ -n "$KERL_DEPLOY_RSYNC_OPTIONS" ]; then
|
|
_KDRSYNC="$KERL_DEPLOY_RSYNC_OPTIONS"
|
|
fi
|
|
if [ -n "$KERL_INSTALL_MANPAGES" ]; then
|
|
_KIM="$KERL_INSTALL_MANPAGES"
|
|
fi
|
|
if [ -n "$KERL_INSTALL_HTMLDOCS" ]; then
|
|
_KIHD="$KERL_INSTALL_HTMLDOCS"
|
|
fi
|
|
if [ -n "$KERL_BUILD_PLT" ]; then
|
|
_KBPLT="$KERL_BUILD_PLT"
|
|
fi
|
|
if [ -n "$KERL_BUILD_DOCS" ]; then
|
|
_KBD="$KERL_BUILD_DOCS"
|
|
fi
|
|
if [ -n "$KERL_BUILD_BACKEND" ]; then
|
|
_KBB="$KERL_BUILD_BACKEND"
|
|
fi
|
|
OTP_GITHUB_URL=
|
|
KERL_CONFIGURE_OPTIONS=
|
|
KERL_CONFIGURE_APPLICATIONS=
|
|
KERL_CONFIGURE_DISABLE_APPLICATIONS=
|
|
KERL_SASL_STARTUP=
|
|
KERL_DEPLOY_SSH_OPTIONS=
|
|
KERL_DEPLOY_RSYNC_OPTIONS=
|
|
KERL_INSTALL_MANPAGES=
|
|
KERL_INSTALL_HTMLDOCS=
|
|
KERL_BUILD_PLT=
|
|
KERL_BUILD_DOCS=
|
|
KERL_BUILD_BACKEND=
|
|
|
|
# ensure the base dir exists
|
|
mkdir -p "$KERL_BASE_DIR" || exit 1
|
|
|
|
# source the config file if available
|
|
if [ -f "$KERL_CONFIG" ]; then . "$KERL_CONFIG"; fi
|
|
|
|
if [ -n "$_OGU" ]; then
|
|
OTP_GITHUB_URL="$_OGU"
|
|
fi
|
|
if [ -n "$_KCO" ]; then
|
|
KERL_CONFIGURE_OPTIONS="$_KCO"
|
|
fi
|
|
if [ -n "$_KCA" ]; then
|
|
KERL_CONFIGURE_APPLICATIONS="$_KCA"
|
|
fi
|
|
if [ -n "$_KCDA" ]; then
|
|
KERL_CONFIGURE_DISABLE_APPLICATIONS="$_KCDA"
|
|
fi
|
|
if [ -n "$_KSS" ]; then
|
|
KERL_SASL_STARTUP="$_KSS"
|
|
fi
|
|
if [ -n "$_KDSSH" ]; then
|
|
KERL_DEPLOY_SSH_OPTIONS="$_KDSSH"
|
|
fi
|
|
if [ -n "$_KDRSYNC" ]; then
|
|
KERL_DEPLOY_RSYNC_OPTIONS="$_KDRSYNC"
|
|
fi
|
|
if [ -n "$_KIM" ]; then
|
|
KERL_INSTALL_MANPAGES="$_KIM"
|
|
fi
|
|
if [ -n "$_KIHD" ]; then
|
|
KERL_INSTALL_HTMLDOCS="$_KIHD"
|
|
fi
|
|
if [ -n "$_KBPLT" ]; then
|
|
KERL_BUILD_PLT="$_KBPLT"
|
|
fi
|
|
if [ -n "$_KBD" ]; then
|
|
KERL_BUILD_DOCS="$_KBD"
|
|
fi
|
|
if [ -n "$_KBB" ]; then
|
|
KERL_BUILD_BACKEND="$_KBB"
|
|
fi
|
|
|
|
if [ -z "$KERL_SASL_STARTUP" ]; then
|
|
INSTALL_OPT=-minimal
|
|
else
|
|
INSTALL_OPT=-sasl
|
|
fi
|
|
|
|
if [ -z "$KERL_BUILD_BACKEND" ]; then
|
|
KERL_BUILD_BACKEND="tarball"
|
|
else
|
|
KERL_BUILD_BACKEND="git"
|
|
KERL_USE_AUTOCONF=1
|
|
fi
|
|
|
|
KERL_SYSTEM=$(uname -s)
|
|
case "$KERL_SYSTEM" in
|
|
Darwin|FreeBSD|OpenBSD)
|
|
MD5SUM="openssl md5"
|
|
MD5SUM_FIELD=2
|
|
SED_OPT=-E
|
|
CP_OPT=-a
|
|
;;
|
|
*)
|
|
MD5SUM=md5sum
|
|
MD5SUM_FIELD=1
|
|
SED_OPT=-r
|
|
CP_OPT=-pr
|
|
;;
|
|
esac
|
|
|
|
|
|
usage()
|
|
{
|
|
echo "kerl: build and install Erlang/OTP"
|
|
echo "usage: $0 <command> [options ...]"
|
|
printf "\n <command> Command to be executed\n\n"
|
|
echo "Valid commands are:"
|
|
echo " build Build specified release or git repository"
|
|
echo " install Install the specified release at the given location"
|
|
echo " deploy Deploy the specified installation to the given host and location"
|
|
echo " update Update the list of available releases from your source provider"
|
|
echo " list List releases, builds and installations"
|
|
echo " delete Delete builds and installations"
|
|
echo " install-docsh Install erl shell documentation access extension - docsh"
|
|
echo " path Print the path of a given installation"
|
|
echo " active Print the path of the active installation"
|
|
echo " plt Print Dialyzer PLT path for the active installation"
|
|
echo " status Print available builds and installations"
|
|
echo " prompt Print a string suitable for insertion in prompt"
|
|
echo " cleanup Remove compilation artifacts (use after installation)"
|
|
echo " version Print current version (current: $KERL_VERSION)"
|
|
exit 1
|
|
}
|
|
|
|
if [ $# -eq 0 ]; then usage; fi
|
|
|
|
get_releases()
|
|
{
|
|
if [ "$KERL_BUILD_BACKEND" = "git" ]
|
|
then
|
|
get_git_releases
|
|
else
|
|
get_tarball_releases
|
|
fi
|
|
}
|
|
|
|
get_git_releases()
|
|
{
|
|
git ls-remote --tags "$OTP_GITHUB_URL" \
|
|
| egrep -o 'OTP[_-][^^{}]+' \
|
|
| sed $SED_OPT 's/OTP[_-]//' \
|
|
| sort -n \
|
|
| uniq
|
|
}
|
|
|
|
get_tarball_releases()
|
|
{
|
|
curl -f -q -L -s $ERLANG_DOWNLOAD_URL/ | \
|
|
sed $SED_OPT -e 's/^.*<[aA] [hH][rR][eE][fF]=\"\otp_src_([-0-9A-Za-z_.]+)\.tar\.gz\">.*$/\1/' \
|
|
-e '/^R1|^[0-9]/!d' | \
|
|
sed -e "s/^R\(.*\)/\1:R\1/" | sed -e "s/^\([^\:]*\)$/\1-z:\1/" | sort | cut -d':' -f2
|
|
}
|
|
|
|
update_checksum_file()
|
|
{
|
|
if [ "$KERL_BUILD_BACKEND" = "git" ];
|
|
then
|
|
return 0
|
|
else
|
|
echo "Getting checksum file from erlang.org..."
|
|
curl -f -L -o "$KERL_DOWNLOAD_DIR/MD5" "$ERLANG_DOWNLOAD_URL/MD5" || exit 1
|
|
fi
|
|
}
|
|
|
|
ensure_checksum_file()
|
|
{
|
|
if [ ! -s "$KERL_DOWNLOAD_DIR"/MD5 ]; then
|
|
update_checksum_file
|
|
fi
|
|
}
|
|
|
|
check_releases()
|
|
{
|
|
if [ ! -f "$KERL_BASE_DIR"/otp_releases ]; then
|
|
get_releases > "$KERL_BASE_DIR"/otp_releases
|
|
fi
|
|
}
|
|
|
|
is_valid_release()
|
|
{
|
|
check_releases
|
|
while read -r rel; do
|
|
if [ "$1" = "$rel" ]; then
|
|
return 0
|
|
fi
|
|
done < "$KERL_BASE_DIR"/otp_releases
|
|
return 1
|
|
}
|
|
|
|
assert_valid_release()
|
|
{
|
|
if ! is_valid_release "$1"; then
|
|
echo "$1 is not a valid Erlang/OTP release"
|
|
exit 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
get_release_from_name()
|
|
{
|
|
if [ -f "$KERL_BASE_DIR"/otp_builds ]; then
|
|
while read -r l; do
|
|
rel=$(echo "$l" | cut -d "," -f 1)
|
|
name=$(echo "$l" | cut -d "," -f 2)
|
|
if [ "$name" = "$1" ]; then
|
|
echo "$rel"
|
|
return 0
|
|
fi
|
|
done < "$KERL_BASE_DIR"/otp_builds
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
get_newest_valid_release()
|
|
{
|
|
check_releases
|
|
|
|
rel=$(tail -1 "$KERL_BASE_DIR"/otp_releases)
|
|
|
|
if [ ! -z "$rel" ]; then
|
|
echo "$rel"
|
|
return 0
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
is_valid_installation()
|
|
{
|
|
if [ -f "$KERL_BASE_DIR"/otp_installations ]; then
|
|
while read -r l; do
|
|
name=$(echo "$l" | cut -d " " -f 1)
|
|
path=$(echo "$l" | cut -d " " -f 2)
|
|
if [ "$name" = "$1" -o "$path" = "$1" ]; then
|
|
if [ -f "$path"/activate ]; then
|
|
return 0
|
|
fi
|
|
fi
|
|
done < "$KERL_BASE_DIR"/otp_installations
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
assert_valid_installation()
|
|
{
|
|
if ! is_valid_installation "$1"; then
|
|
echo "$1 is not a kerl-managed Erlang/OTP installation"
|
|
exit 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
assert_build_name_unused()
|
|
{
|
|
if [ -f "$KERL_BASE_DIR"/otp_builds ]; then
|
|
while read -r l; do
|
|
name=$(echo "$l" | cut -d "," -f 2)
|
|
if [ "$name" = "$1" ]; then
|
|
echo "There's already a build named $1"
|
|
exit 1
|
|
fi
|
|
done < "$KERL_BASE_DIR"/otp_builds
|
|
fi
|
|
}
|
|
|
|
_check_required_pkgs()
|
|
{
|
|
has_dpkg=$(which dpkg)
|
|
has_rpm=$(which rpm)
|
|
if [ -n "$has_dpkg" -o -n "$has_rpm" ]; then
|
|
# found either dpkg or rpm (or maybe even both!)
|
|
if [ -n "$has_dpkg" -a -n "$has_rpm" ]; then
|
|
echo "WARNING: You appear to have BOTH rpm and dpkg. This is very strange. No package checks done."
|
|
elif [ -n "$has_dpkg" ]; then
|
|
_check_dpkg
|
|
elif [ -n "$has_rpm" ]; then
|
|
_check_rpm
|
|
fi
|
|
fi
|
|
}
|
|
|
|
_dpkg_is_installed()
|
|
{
|
|
# gratefully stolen from
|
|
# https://superuser.com/questions/427318/test-if-a-package-is-installed-in-apt
|
|
# returns 0 (true) if found, 1 otherwise
|
|
dpkg-query -Wf'${db:Status-abbrev}' "$1" 2>/dev/null | grep -q '^i'
|
|
}
|
|
|
|
_check_dpkg()
|
|
{
|
|
required="
|
|
libssl-dev
|
|
make
|
|
automake
|
|
autoconf
|
|
libncurses5-dev
|
|
gcc
|
|
"
|
|
|
|
for pkg in $required; do
|
|
if ! _dpkg_is_installed "$pkg"; then
|
|
echo "WARNING: It appears that a required development package '$pkg' is not installed."
|
|
fi
|
|
done
|
|
}
|
|
|
|
_rpm_is_installed()
|
|
{
|
|
rpm --quiet -q "$1" 1>/dev/null 2>&1
|
|
}
|
|
|
|
_check_rpm()
|
|
{
|
|
required="
|
|
openssl-devel
|
|
make
|
|
automake
|
|
autoconf
|
|
ncurses-devel
|
|
gcc
|
|
"
|
|
|
|
for pkg in $required; do
|
|
if ! _rpm_is_installed "$pkg"; then
|
|
echo "WARNING: It appears a required development package '$pkg' is not installed."
|
|
fi
|
|
done
|
|
}
|
|
|
|
do_git_build()
|
|
{
|
|
assert_build_name_unused "$3"
|
|
|
|
GIT=$(echo -n "$1" | $MD5SUM | cut -d ' ' -f $MD5SUM_FIELD)
|
|
mkdir -p "$KERL_GIT_DIR" || exit 1
|
|
cd "$KERL_GIT_DIR" || exit 1
|
|
echo "Checking out Erlang/OTP git repository from $1..."
|
|
if [ ! -d "$GIT" ]; then
|
|
git clone -q --mirror "$1" "$GIT" > /dev/null 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error mirroring remote git repository"
|
|
exit 1
|
|
fi
|
|
fi
|
|
cd "$GIT" || exit 1
|
|
git remote update --prune > /dev/null 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error updating remote git repository"
|
|
exit 1
|
|
fi
|
|
|
|
rm -Rf "${KERL_BUILD_DIR:?}/$3"
|
|
mkdir -p "$KERL_BUILD_DIR/$3" || exit 1
|
|
cd "$KERL_BUILD_DIR/$3" || exit 1
|
|
git clone -l "$KERL_GIT_DIR/$GIT" otp_src_git > /dev/null 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error cloning local git repository"
|
|
exit 1
|
|
fi
|
|
cd otp_src_git || exit 1
|
|
git checkout "$2" > /dev/null 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
git checkout -b "$2" "$2" > /dev/null 2>&1
|
|
fi
|
|
if [ $? -ne 0 ]; then
|
|
echo "Couldn't checkout specified version"
|
|
rm -Rf "${KERL_BUILD_DIR:?}/$3"
|
|
exit 1
|
|
fi
|
|
if [ ! -x otp_build ]; then
|
|
echo "Not a valid Erlang/OTP repository"
|
|
rm -Rf "${KERL_BUILD_DIR:?}/$3"
|
|
exit 1
|
|
fi
|
|
echo "Building Erlang/OTP $3 from git, please wait..."
|
|
if [ -z "$KERL_BUILD_AUTOCONF" ]; then
|
|
KERL_USE_AUTOCONF=1
|
|
fi
|
|
_do_build "git" "$3"
|
|
echo "Erlang/OTP $3 from git has been successfully built"
|
|
list_add builds "git,$3"
|
|
}
|
|
|
|
get_otp_version()
|
|
{
|
|
echo $1 | sed $SED_OPT -e 's/R?([0-9]{1,2}).+/\1/'
|
|
}
|
|
|
|
get_perl_version()
|
|
{
|
|
if assert_perl; then
|
|
# This is really evil but it's portable and it works. Don't @ me bro
|
|
perl -e 'print int(($] - 5)*1000)'
|
|
else
|
|
echo "FATAL: I couldn't find perl which is required to compile Erlang."
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
assert_perl()
|
|
{
|
|
perl_loc=$(which perl)
|
|
if [ -z "$perl_loc" ]; then
|
|
return 1
|
|
else
|
|
# 0 to bash is "true" because of Unix exit code conventions
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
get_javac_version()
|
|
{
|
|
java_loc=$(which javac)
|
|
if [ -z "$java_loc" ]; then
|
|
# Java's not installed, so just return 0
|
|
0
|
|
else
|
|
javaout=$(javac -version 2>&1)
|
|
echo "$javaout" | cut -d' ' -f2 | cut -d'.' -f2
|
|
fi
|
|
}
|
|
|
|
show_configuration_warnings()
|
|
{
|
|
# $1 is logfile
|
|
# $2 is section header (E.g. "APPLICATIONS DISABLED")
|
|
# Find the row number for the section we are looking for
|
|
INDEX=$(grep -n -m1 "$2" $1 | cut -d: -f1)
|
|
|
|
# If there are no warnings, the section won't appear in the log
|
|
if [ -n "$INDEX" ]; then
|
|
# Skip the section header, find the end line and skip it
|
|
# then print the results indented
|
|
tail -n +$(($INDEX+3)) $1 | \
|
|
sed -n '1,/\*/p' | \
|
|
awk -F: -v logfile="$1" -v section="$2" \
|
|
'BEGIN { printf "%s (See: %s)\n", section, logfile }
|
|
/^[^\*]/ { print " *", $0 }
|
|
END { print "" } '
|
|
fi
|
|
}
|
|
|
|
show_logfile()
|
|
{
|
|
echo "$1"
|
|
tail "$2"
|
|
echo
|
|
echo "Please see $2 for full details."
|
|
}
|
|
|
|
maybe_patch()
|
|
{
|
|
# $1 = OS platform e.g., Darwin, etc
|
|
# $2 = OTP release
|
|
|
|
release=$(get_otp_version "$2")
|
|
case "$1" in
|
|
Darwin)
|
|
maybe_patch_darwin "$release"
|
|
;;
|
|
SunOS)
|
|
maybe_patch_sunos "$release"
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
|
|
maybe_patch_all "$release"
|
|
}
|
|
|
|
maybe_patch_all()
|
|
{
|
|
perlver=$(get_perl_version)
|
|
if [ "$perlver" -ge 22 ]; then
|
|
case "$1" in
|
|
14)
|
|
apply_r14_beam_makeops_patch >> "$LOGFILE"
|
|
;;
|
|
15)
|
|
apply_r15_beam_makeops_patch >> "$LOGFILE"
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
# Are we building docs?
|
|
if [ -n "$KERL_BUILD_DOCS" ]; then
|
|
if [ "$1" -le 16 ]; then
|
|
javaver=$(get_javac_version)
|
|
if [ "$javaver" -ge 8 ]; then
|
|
apply_javadoc_linting_patch >> "$LOGFILE"
|
|
fi
|
|
fi
|
|
fi
|
|
}
|
|
|
|
maybe_patch_darwin()
|
|
{
|
|
# Reminder: $1 = OTP release version
|
|
if [ "$1" -le 14 ]; then
|
|
CFLAGS="-DERTS_DO_INCL_GLB_INLINE_FUNC_DEF"
|
|
apply_darwin_compiler_patch >> "$LOGFILE"
|
|
elif [ "$1" -eq 16 ]; then
|
|
# TODO: Maybe check if clang version == 9
|
|
apply_r16_wx_ptr_patch >> "$LOGFILE"
|
|
elif [ "$1" -ge 17 -a "$1" -le 19 ]; then
|
|
apply_wx_ptr_patch >> "$LOGFILE"
|
|
fi
|
|
}
|
|
|
|
maybe_patch_sunos()
|
|
{
|
|
if [ "$1" -le 14 ]; then
|
|
apply_solaris_networking_patch >> "$LOGFILE"
|
|
fi
|
|
}
|
|
|
|
do_normal_build()
|
|
{
|
|
assert_valid_release "$1"
|
|
assert_build_name_unused "$2"
|
|
FILENAME=""
|
|
download $1
|
|
mkdir -p "$KERL_BUILD_DIR/$2" || exit 1
|
|
if [ ! -d "$KERL_BUILD_DIR/$2/$FILENAME" ]; then
|
|
echo "Extracting source code"
|
|
UNTARDIRNAME="$KERL_BUILD_DIR/$2/$FILENAME-kerluntar-$$"
|
|
rm -rf "$UNTARDIRNAME"
|
|
mkdir -p "$UNTARDIRNAME" || exit 1
|
|
# github tarballs have a directory in the form of "otp[_-]TAGNAME"
|
|
# Ericsson tarballs have the classic otp_src_RELEASE pattern
|
|
# Standardize on Ericsson format because that's what the rest of the script expects
|
|
(cd "$UNTARDIRNAME" && tar xzf "$KERL_DOWNLOAD_DIR/$FILENAME.tar.gz" && mv -f ./* "$KERL_BUILD_DIR/$2/otp_src_$1")
|
|
rm -rf "$UNTARDIRNAME"
|
|
fi
|
|
|
|
echo "Building Erlang/OTP $1 ($2), please wait..."
|
|
_do_build "$1" "$2"
|
|
echo "Erlang/OTP $1 ($2) has been successfully built"
|
|
list_add builds "$1,$2"
|
|
}
|
|
|
|
_flags()
|
|
{
|
|
|
|
# We need to munge the LD and DED flags for clang 9 shipped with
|
|
# High Sierra (macOS 10.13)
|
|
case "$KERL_SYSTEM" in
|
|
Darwin)
|
|
osver=$(uname -r)
|
|
case "$osver" in
|
|
17*)
|
|
# Make sure we don't overwrite values that someone who
|
|
# knows better than us set.
|
|
if [ -z "$DED_LD" ]; then
|
|
DED_LD="clang"
|
|
fi
|
|
if [ -z "$CC" ]; then
|
|
CC="clang"
|
|
fi
|
|
if [ -z "$DED_LDFLAGS" ]; then
|
|
host=$(./erts/autoconf/config.guess)
|
|
DED_LDFLAGS="-m64 -bundle -bundle_loader ${ERL_TOP}/bin/$host/beam.smp"
|
|
fi
|
|
CFLAGS="$CFLAGS" DED_LD="$DED_LD" CC="$CC" DED_LDFLAGS="$DED_LDFLAGS" $@
|
|
;;
|
|
*)
|
|
CFLAGS="$CFLAGS" $@
|
|
;;
|
|
esac
|
|
;;
|
|
*)
|
|
CFLAGS="$CFLAGS" $@
|
|
;;
|
|
esac
|
|
|
|
}
|
|
|
|
_do_build()
|
|
{
|
|
case "$KERL_SYSTEM" in
|
|
Darwin)
|
|
OSVERSION=`uname -r`
|
|
RELVERSION=`get_otp_version "$1"`
|
|
|
|
# Ensure that the --enable-darwin-64bit flag is set on all macOS
|
|
# That way even on older Erlangs we get 64 bit Erlang builds
|
|
# macOS has been mandatory 64 bit for a while
|
|
echo -n $KERL_CONFIGURE_OPTIONS | grep "darwin-64bit" 1>/dev/null 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
KERL_CONFIGURE_OPTIONS="$KERL_CONFIGURE_OPTIONS --enable-darwin-64bit"
|
|
fi
|
|
|
|
case "$OSVERSION" in
|
|
17*|16*|15*)
|
|
echo -n $KERL_CONFIGURE_OPTIONS | grep "ssl" 1>/dev/null 2>&1
|
|
# Reminder to self: 0 from grep means the string was detected
|
|
if [ $? -ne 0 ]; then
|
|
whichbrew=$(which brew)
|
|
if [ -n "$whichbrew" -a -x "$whichbrew" ]; then
|
|
brew_prefix=$(brew --prefix openssl)
|
|
if [ -n "$brew_prefix" -a -d "$brew_prefix" ]; then
|
|
KERL_CONFIGURE_OPTIONS="$KERL_CONFIGURE_OPTIONS --with-ssl=$brew_prefix"
|
|
fi
|
|
elif [ ! -d /usr/include/openssl -o ! -d /usr/local/include/openssl ]; then
|
|
# Apple removed OpenSSL from El Capitan, but its still in this
|
|
# funky location, so set ssl headers to look here
|
|
xc_ssl='/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift-migrator/sdk/MacOSX.sdk/usr'
|
|
if [ -d "$xc_ssl/include/openssl" ]; then
|
|
KERL_CONFIGURE_OPTIONS="$KERL_CONFIGURE_OPTIONS --with-ssl=$xc_ssl"
|
|
fi
|
|
unset xc_ssl
|
|
fi
|
|
fi
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
;;
|
|
Linux)
|
|
# we are going to check here to see if the Linux uses dpkg or rpms
|
|
#
|
|
# this is a "best effort" attempt to discover if a Linux has the
|
|
# packages needed to build Erlang. We will always assume the user
|
|
# knows better than us and are going to go ahead and try to build
|
|
# Erlang anyway. But at least it will be a clear warning to the
|
|
# user if a build fails.
|
|
_check_required_pkgs
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
|
|
if [ -n "$KERL_BUILD_DOCS" ]; then
|
|
KERL_CONFIGURE_OPTIONS="$KERL_CONFIGURE_OPTIONS --prefix=$KERL_BUILD_DIR/$2/release_$1"
|
|
fi
|
|
|
|
ERL_TOP="$KERL_BUILD_DIR/$2/otp_src_$1"
|
|
cd "$ERL_TOP" || exit 1
|
|
LOGFILE="$KERL_BUILD_DIR/$2/otp_build_$1.log"
|
|
|
|
# Check to see if configuration options need to be stored or have changed
|
|
TMPOPT="/tmp/kerloptions.$$"
|
|
echo "$CFLAGS" > "$TMPOPT"
|
|
echo "$KERL_CONFIGURE_OPTIONS" >> "$TMPOPT"
|
|
SUM=$($MD5SUM "$TMPOPT" | cut -d ' ' -f $MD5SUM_FIELD)
|
|
# Check for a .kerl_config.md5 file
|
|
if [ -e "./$KERL_CONFIG_STORAGE_FILENAME.md5" ]; then
|
|
# Compare our current options to the saved ones
|
|
read -r OLD_SUM < "./$KERL_CONFIG_STORAGE_FILENAME.md5"
|
|
if [ "$SUM" != "$OLD_SUM" ]; then
|
|
echo "Configure options have changed. Reconfiguring..."
|
|
rm -f configure
|
|
mv "$TMPOPT" "./$KERL_CONFIG_STORAGE_FILENAME"
|
|
echo "$SUM" > "./$KERL_CONFIG_STORAGE_FILENAME.md5"
|
|
else
|
|
# configure options are the same
|
|
rm -f "$TMPOPT"
|
|
fi
|
|
else
|
|
# no file exists, so write one
|
|
mv "$TMPOPT" ./.kerl_config
|
|
echo "$SUM" > ./.kerl_config.md5
|
|
fi
|
|
|
|
# Don't apply patches to "custom" git builds. We have no idea if they will apply
|
|
# cleanly or not.
|
|
if [ "$1" != "git" ]; then
|
|
maybe_patch "$KERL_SYSTEM" "$1"
|
|
fi
|
|
if [ -n "$KERL_USE_AUTOCONF" ]; then
|
|
./otp_build autoconf $KERL_CONFIGURE_OPTIONS >> "$LOGFILE" 2>&1 && \
|
|
_flags ./otp_build configure $KERL_CONFIGURE_OPTIONS >> "$LOGFILE" 2>&1
|
|
else
|
|
_flags ./otp_build configure $KERL_CONFIGURE_OPTIONS >> "$LOGFILE" 2>&1
|
|
|
|
fi
|
|
echo -n $KERL_CONFIGURE_OPTIONS | grep "--enable-native-libs" 1>/dev/null 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
make clean >> "$LOGFILE" 2>&1
|
|
_flags ./otp_build configure $KERL_CONFIGURE_OPTIONS >> "$LOGFILE" 2>&1
|
|
fi
|
|
if [ $? -ne 0 ]; then
|
|
show_logfile "Configure failed." "$LOGFILE"
|
|
list_remove builds "$1 $2"
|
|
exit 1
|
|
fi
|
|
|
|
for SECTION in "APPLICATIONS DISABLED" \
|
|
"APPLICATIONS INFORMATION" \
|
|
"DOCUMENTATION INFORMATION"; do
|
|
show_configuration_warnings "$LOGFILE" "$SECTION"
|
|
done
|
|
|
|
if [ -n "$KERL_CONFIGURE_APPLICATIONS" ]; then
|
|
find ./lib -maxdepth 1 -type d -exec touch -f {}/SKIP \;
|
|
for i in $KERL_CONFIGURE_APPLICATIONS; do
|
|
rm ./lib/"$i"/SKIP
|
|
if [ $? -ne 0 ]; then
|
|
echo "Couldn't prepare '$i' application for building"
|
|
list_remove builds "$1 $2"
|
|
exit 1
|
|
fi
|
|
done
|
|
fi
|
|
if [ -n "$KERL_CONFIGURE_DISABLE_APPLICATIONS" ]; then
|
|
for i in $KERL_CONFIGURE_DISABLE_APPLICATIONS; do
|
|
touch -f ./lib/"$i"/SKIP
|
|
if [ $? -ne 0 ]; then
|
|
echo "Couldn't disable '$i' application for building"
|
|
exit 1
|
|
fi
|
|
done
|
|
fi
|
|
|
|
_flags ./otp_build boot -a $KERL_CONFIGURE_OPTIONS >> "$LOGFILE" 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
show_logfile "Build failed." "$LOGFILE"
|
|
list_remove builds "$1 $2"
|
|
exit 1
|
|
fi
|
|
if [ -n "$KERL_BUILD_DOCS" ]; then
|
|
echo "Building docs..."
|
|
make docs >> "$LOGFILE" 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
show_logfile "Building docs failed." "$LOGFILE"
|
|
list_remove builds "$1 $2"
|
|
exit 1
|
|
fi
|
|
make install-docs >> "$LOGFILE" 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
show_logfile "Installing docs failed." "$LOGFILE"
|
|
list_remove builds "$1 $2"
|
|
exit 1
|
|
fi
|
|
fi
|
|
rm -f "$LOGFILE"
|
|
ERL_TOP="$ERL_TOP" ./otp_build release -a "$KERL_BUILD_DIR/$2/release_$1" > /dev/null 2>&1
|
|
cd "$KERL_BUILD_DIR/$2/release_$1" || exit 1
|
|
./Install $INSTALL_OPT "$KERL_BUILD_DIR/$2/release_$1" > /dev/null 2>&1
|
|
}
|
|
|
|
do_install()
|
|
{
|
|
rel=$(get_release_from_name "$1")
|
|
if [ $? -ne 0 ]; then
|
|
echo "No build named $1"
|
|
exit 1
|
|
fi
|
|
if ! is_valid_install_path "$2"; then
|
|
exit 1
|
|
fi
|
|
mkdir -p "$2" || exit 1
|
|
absdir=$(cd "$2" && pwd)
|
|
echo "Installing Erlang/OTP $rel ($1) in $absdir..."
|
|
ERL_TOP="$KERL_BUILD_DIR/$1/otp_src_$rel"
|
|
cd "$ERL_TOP" || exit 1
|
|
ERL_TOP="$ERL_TOP" ./otp_build release -a "$absdir" > /dev/null 2>&1 &&
|
|
cd "$absdir" && ./Install $INSTALL_OPT "$absdir" > /dev/null 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
echo "Couldn't install Erlang/OTP $rel ($1) in $absdir"
|
|
exit 1
|
|
fi
|
|
list_add installations "$1 $absdir";
|
|
cat <<ACTIVATE > "$absdir"/activate
|
|
# credits to virtualenv
|
|
kerl_deactivate()
|
|
{
|
|
if [ -n "\$_KERL_SAVED_ERL_AFLAGS" ]; then
|
|
ERL_AFLAGS="\$_KERL_SAVED_ERL_AFLAGS"
|
|
export ERL_AFLAGS
|
|
unset _KERL_SAVED_ERL_AFLAGS
|
|
fi
|
|
if [ -n "\$_KERL_PATH_REMOVABLE" ]; then
|
|
PATH=\`echo \${PATH} | sed -e "s#\${_KERL_PATH_REMOVABLE}:##"\`
|
|
export PATH
|
|
unset _KERL_PATH_REMOVABLE
|
|
fi
|
|
if [ -n "\$_KERL_MANPATH_REMOVABLE" ]; then
|
|
MANPATH=\`echo \${MANPATH} | sed -e "s#\${_KERL_MANPATH_REMOVABLE}:##"\`
|
|
export MANPATH
|
|
unset _KERL_MANPATH_REMOVABLE
|
|
fi
|
|
if [ -n "\$_KERL_SAVED_REBAR_PLT_DIR" ]; then
|
|
REBAR_PLT_DIR="\$_KERL_SAVED_REBAR_PLT_DIR"
|
|
export REBAR_PLT_DIR
|
|
unset _KERL_SAVED_REBAR_PLT_DIR
|
|
fi
|
|
if [ -n "\$_KERL_ACTIVE_DIR" ]; then
|
|
unset _KERL_ACTIVE_DIR
|
|
fi
|
|
if [ -n "\$_KERL_SAVED_PS1" ]; then
|
|
PS1="\$_KERL_SAVED_PS1"
|
|
export PS1
|
|
unset _KERL_SAVED_PS1
|
|
fi
|
|
if [ -n "\$_KERL_DOCSH_DOT_ERLANG" ]; then
|
|
rm "\$HOME/.erlang"
|
|
unset _KERL_DOCSH_DOT_ERLANG
|
|
fi
|
|
if [ -n "\$_KERL_DOCSH_USER_DEFAULT" ]; then
|
|
unset DOCSH_USER_DEFAULT
|
|
unset _KERL_DOCSH_USER_DEFAULT
|
|
fi
|
|
if [ -n "\$BASH" -o -n "\$ZSH_VERSION" ]; then
|
|
hash -r
|
|
fi
|
|
if [ ! "\$1" = "nondestructive" ]; then
|
|
unset -f kerl_deactivate
|
|
fi
|
|
unset KERL_ENABLE_PROMPT
|
|
unset KERL_PROMPT_FORMAT
|
|
}
|
|
kerl_deactivate nondestructive
|
|
|
|
_KERL_SAVED_REBAR_PLT_DIR="\$REBAR_PLT_DIR"
|
|
export _KERL_SAVED_REBAR_PLT_DIR
|
|
_KERL_PATH_REMOVABLE="$absdir/bin"
|
|
PATH="\${_KERL_PATH_REMOVABLE}:\$PATH"
|
|
export PATH _KERL_PATH_REMOVABLE
|
|
_KERL_MANPATH_REMOVABLE="$absdir/lib/erlang/man:$absdir/man"
|
|
MANPATH="\${_KERL_MANPATH_REMOVABLE}:\$MANPATH"
|
|
export MANPATH _KERL_MANPATH_REMOVABLE
|
|
REBAR_PLT_DIR="$absdir"
|
|
export REBAR_PLT_DIR
|
|
_KERL_ACTIVE_DIR="$absdir"
|
|
export _KERL_ACTIVE_DIR
|
|
# https://twitter.com/mononcqc/status/877544929496629248
|
|
export _KERL_SAVED_ERL_AFLAGS=" \$ERL_AFLAGS"
|
|
kernel_history=\$(echo "\$ERL_AFLAGS" | grep 'kernel shell_history' || true)
|
|
if [ -z "\$kernel_history" ]; then
|
|
export ERL_AFLAGS="-kernel shell_history enabled \$ERL_AFLAGS"
|
|
fi
|
|
if [ -f "$KERL_CONFIG" ]; then . "$KERL_CONFIG"; fi
|
|
if [ -n "\$KERL_ENABLE_PROMPT" ]; then
|
|
_KERL_SAVED_PS1="\$PS1"
|
|
export _KERL_SAVED_PS1
|
|
if [ -n "\$KERL_PROMPT_FORMAT" ]; then
|
|
FRMT="\$KERL_PROMPT_FORMAT"
|
|
else
|
|
FRMT="(%BUILDNAME%)"
|
|
fi
|
|
PRMPT=\$(echo "\$FRMT" | sed 's^%RELEASE%^$rel^;s^%BUILDNAME%^$1^')
|
|
PS1="\$PRMPT\$PS1"
|
|
export PS1
|
|
fi
|
|
if [ -d "$absdir/lib/docsh" ]; then
|
|
export DOCSH_USER_DEFAULT="$absdir/lib/docsh/user_default"
|
|
export _KERL_DOCSH_USER_DEFAULT=yes
|
|
if [ -f "\$HOME/.erlang" ]; then
|
|
if [ ! x"\$KERL_DOCSH_DOT_ERLANG" = x"exists" ]; then
|
|
echo "Couldn't symlink correct \$HOME/.erlang - file exists - docsh might not work."
|
|
echo "Please make sure \$HOME/.erlang contains code"
|
|
echo "from $absdir/lib/docsh/dot.erlang"
|
|
echo "and export KERL_DOCSH_DOT_ERLANG=exists to suppress this warning."
|
|
fi
|
|
else
|
|
ln -s "$absdir/lib/docsh/dot.erlang" "\$HOME/.erlang"
|
|
export _KERL_DOCSH_DOT_ERLANG=yes
|
|
fi
|
|
fi
|
|
if [ -n "\$BASH" -o -n "\$ZSH_VERSION" ]; then
|
|
hash -r
|
|
fi
|
|
ACTIVATE
|
|
|
|
cat <<ACTIVATE_FISH > "$absdir/activate.fish"
|
|
# credits to virtualenv
|
|
function _kerl_remove_el --description 'remove element from array'
|
|
set -l new_array
|
|
for el in \$\$argv[1]
|
|
if test \$el != \$argv[2]
|
|
set new_array \$new_array \$el
|
|
end
|
|
end
|
|
set -x \$argv[1] \$new_array
|
|
end
|
|
|
|
function kerl_deactivate --description "deactivate erlang environment"
|
|
if set --query _KERL_PATH_REMOVABLE
|
|
_kerl_remove_el PATH "\$_KERL_PATH_REMOVABLE"
|
|
set --erase _KERL_PATH_REMOVABLE
|
|
end
|
|
if set --query _KERL_MANPATH_REMOVABLE
|
|
_kerl_remove_el MANPATH "\$_KERL_MANPATH_REMOVABLE"
|
|
set --erase _KERL_MANPATH_REMOVABLE
|
|
end
|
|
if set --query _KERL_SAVED_REBAR_PLT_DIR
|
|
set -x REBAR_PLT_DIR "\$_KERL_SAVED_REBAR_PLT_DIR"
|
|
set --erase _KERL_SAVED_REBAR_PLT_DIR
|
|
end
|
|
if set --query _KERL_ACTIVE_DIR
|
|
set --erase _KERL_ACTIVE_DIR
|
|
end
|
|
if functions --query _kerl_saved_prompt
|
|
functions --erase fish_prompt
|
|
# functions --copy complains about about fish_prompt already being defined
|
|
# so we take a page from virtualenv's book
|
|
. ( begin
|
|
printf "function fish_prompt\n\t#"
|
|
functions _kerl_saved_prompt
|
|
end | psub )
|
|
functions --erase _kerl_saved_prompt
|
|
end
|
|
if set --query _KERL_DOCSH_DOT_ERLANG
|
|
rm "\$HOME/.erlang"
|
|
set --erase _KERL_DOCSH_DOT_ERLANG
|
|
end
|
|
if set --query _KERL_DOCSH_USER_DEFAULT
|
|
set --erase DOCSH_USER_DEFAULT
|
|
set --erase _KERL_DOCSH_USER_DEFAULT
|
|
end
|
|
if test "\$argv[1]" != "nondestructive"
|
|
functions --erase kerl_deactivate
|
|
functions --erase _kerl_remove_el
|
|
end
|
|
end
|
|
kerl_deactivate nondestructive
|
|
|
|
set -x _KERL_SAVED_REBAR_PLT_DIR "\$REBAR_PLT_DIR"
|
|
set -x _KERL_PATH_REMOVABLE "$absdir/bin"
|
|
set -x PATH "\$_KERL_PATH_REMOVABLE" \$PATH
|
|
set -x _KERL_MANPATH_REMOVABLE "$absdir/lib/erlang/man" "$absdir/man"
|
|
set -x MANPATH \$MANPATH "\$_KERL_MANPATH_REMOVABLE"
|
|
set -x REBAR_PLT_DIR "$absdir"
|
|
set -x _KERL_ACTIVE_DIR "$absdir"
|
|
if test -f "$KERL_CONFIG.fish"
|
|
source "$KERL_CONFIG.fish"
|
|
end
|
|
if set --query KERL_ENABLE_PROMPT
|
|
functions --copy fish_prompt _kerl_saved_prompt
|
|
function fish_prompt
|
|
echo -n "($1)"
|
|
_kerl_saved_prompt
|
|
end
|
|
end
|
|
if test -d "$absdir/lib/docsh"
|
|
set -x DOCSH_USER_DEFAULT "$absdir/lib/docsh/user_default"
|
|
set -x _KERL_DOCSH_USER_DEFAULT yes
|
|
if test -f "\$HOME/.erlang"
|
|
if test ! x"\$KERL_DOCSH_DOT_ERLANG" = x"exists"
|
|
echo "Couldn't symlink correct \$HOME/.erlang - file exists - docsh might not work."
|
|
echo "Please make sure \$HOME/.erlang contains code"
|
|
echo "from $absdir/lib/docsh/dot.erlang"
|
|
echo "and export KERL_DOCSH_DOT_ERLANG=exists to suppress this warning."
|
|
end
|
|
else
|
|
ln -s "$absdir/lib/docsh/dot.erlang" "\$HOME/.erlang"
|
|
set -x _KERL_DOCSH_DOT_ERLANG yes
|
|
end
|
|
end
|
|
ACTIVATE_FISH
|
|
|
|
cat <<ACTIVATE_CSH > "$absdir/activate.csh"
|
|
# This file must be used with "source bin/activate.csh" *from csh*.
|
|
# You cannot run it directly.
|
|
|
|
alias kerl_deactivate 'test \$?_KERL_SAVED_PATH != 0 && setenv PATH "\$_KERL_SAVED_PATH" && unset _KERL_SAVED_PATH; rehash; test \$?_KERL_SAVED_MANPATH != 0 && setenv MANPATH "\$_KERL_SAVED_MANPATH" && unset _KERL_SAVED_MANPATH; test \$?_KERL_SAVED_REBAR_PLT_DIR != 0 && setenv REBAR_PLT_DIR "\$_KERL_SAVED_REBAR_PLT_DIR" && unset _KERL_SAVED_REBAR_PLT_DIR; test \$?_KERL_ACTIVE_DIR != 0 && unset _KERL_ACTIVE_DIR; test \$?_KERL_DOCSH_USER_DEFAULT != 0 && unsetenv DOCSH_USER_DEFAULT && unset _KERL_DOCSH_USER_DEFAULT; test \$?_KERL_DOCSH_DOT_ERLANG != 0 && rm "\$HOME/.erlang" && unset _KERL_DOCSH_DOT_ERLANG; test \$?_KERL_SAVED_PROMPT != 0 && set prompt="\$_KERL_SAVED_PROMPT" && unset _KERL_SAVED_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate'
|
|
|
|
# Unset irrelevant variables.
|
|
kerl_deactivate nondestructive
|
|
|
|
if ( \$?REBAR_PLT_DIR ) then
|
|
set _KERL_SAVED_REBAR_PLT_DIR = "\$REBAR_PLT_DIR"
|
|
else
|
|
set _KERL_SAVED_REBAR_PLT_DIR=""
|
|
endif
|
|
|
|
set _KERL_PATH_REMOVABLE = "$absdir/bin"
|
|
set _KERL_SAVED_PATH = "\$PATH"
|
|
setenv PATH "\${_KERL_PATH_REMOVABLE}:\$PATH"
|
|
|
|
if ( ! \$?MANPATH ) then
|
|
set MANPATH = ""
|
|
endif
|
|
set _KERL_MANPATH_REMOVABLE = "$absdir/lib/erlang/man:$absdir/man"
|
|
set _KERL_SAVED_MANPATH = "\$MANPATH"
|
|
setenv MANPATH "\${_KERL_MANPATH_REMOVABLE}:\$MANPATH"
|
|
|
|
setenv REBAR_PLT_DIR "$absdir"
|
|
|
|
set _KERL_ACTIVE_DIR = "$absdir"
|
|
|
|
if ( -f "$KERL_CONFIG.csh" ) then
|
|
source "$KERL_CONFIG.csh"
|
|
endif
|
|
|
|
if ( \$?KERL_ENABLE_PROMPT ) then
|
|
set _KERL_SAVED_PROMPT = "\$prompt"
|
|
|
|
if ( \$?KERL_PROMPT_FORMAT ) then
|
|
set FRMT = "\$KERL_PROMPT_FORMAT"
|
|
else
|
|
set FRMT = "(%BUILDNAME%)"
|
|
endif
|
|
|
|
set PROMPT = \`echo "\$FRMT" | sed 's^%RELEASE%^$rel^;s^%BUILDNAME%^$1^'\`
|
|
set prompt = "\$PROMPT\$prompt"
|
|
endif
|
|
|
|
if ( -d "$absdir/lib/docsh" ) then
|
|
setenv DOCSH_USER_DEFAULT "$absdir/lib/docsh/user_default"
|
|
set _KERL_DOCSH_USER_DEFAULT = "yes"
|
|
if ( -f "\$HOME/.erlang" ) then
|
|
if ( \$?KERL_DOCSH_DOT_ERLANG == 0 ) then
|
|
echo "Couldn't symlink correct \$HOME/.erlang - file exists - docsh might not work."
|
|
echo "Please make sure \$HOME/.erlang contains code"
|
|
echo "from $absdir/lib/docsh/dot.erlang"
|
|
echo "and export KERL_DOCSH_DOT_ERLANG=exists to suppress this warning."
|
|
endif
|
|
else
|
|
ln -s "$absdir/lib/docsh/dot.erlang" "\$HOME/.erlang"
|
|
set _KERL_DOCSH_DOT_ERLANG = "yes"
|
|
endif
|
|
endif
|
|
|
|
rehash
|
|
ACTIVATE_CSH
|
|
|
|
if [ -n "$KERL_BUILD_DOCS" ]; then
|
|
DOC_DIR="$KERL_BUILD_DIR/$1/release_$rel/lib/erlang"
|
|
if [ -d "$DOC_DIR" ]; then
|
|
echo "Installing docs..."
|
|
cp $CP_OPT "$DOC_DIR/" "$absdir/lib"
|
|
if [ -d "$absdir/lib/erlang/man" ]; then
|
|
ln -s "$absdir/lib/erlang/man" "$absdir/man"
|
|
ln -s "$absdir/lib/erlang/doc" "$absdir/html"
|
|
elif [ -d "$absdir/lib/man" ]; then
|
|
ln -s "$absdir/lib/man" "$absdir/man"
|
|
ln -s "$absdir/lib/doc" "$absdir/html"
|
|
fi
|
|
fi
|
|
else
|
|
if [ "$KERL_BUILD_BACKEND" = "tarball" ]; then
|
|
if [ "$rel" != "git" ]; then
|
|
if [ -n "$KERL_INSTALL_MANPAGES" ]; then
|
|
echo "Fetching and installing manpages..."
|
|
download_manpages "$rel"
|
|
fi
|
|
|
|
if [ -n "$KERL_INSTALL_HTMLDOCS" ]; then
|
|
echo "Fetching and installing HTML docs..."
|
|
download_htmldocs "$rel"
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
KERL_CONFIG_STORAGE_PATH="$KERL_BUILD_DIR/$1/otp_src_$rel/$KERL_CONFIG_STORAGE_FILENAME"
|
|
[ -e "$KERL_CONFIG_STORAGE_PATH" ] && cp "$KERL_CONFIG_STORAGE_PATH" "$absdir/$KERL_CONFIG_STORAGE_FILENAME"
|
|
|
|
if [ -n "$KERL_BUILD_PLT" ]; then
|
|
echo "Building Dialyzer PLT..."
|
|
build_plt "$absdir"
|
|
fi
|
|
|
|
PID=$$
|
|
PARENT_PID=$(ps -p $PID -o ppid | grep -E "[0-9]+" -o)
|
|
PARENT_CMD=$(ps -p $PARENT_PID -o ucomm | tail -n 1)
|
|
case "$PARENT_CMD" in
|
|
fish)
|
|
SHELL_SUFFIX=".fish"
|
|
;;
|
|
csh)
|
|
SHELL_SUFFIX=".csh"
|
|
;;
|
|
*)
|
|
SHELL_SUFFIX=""
|
|
;;
|
|
esac
|
|
|
|
echo "You can activate this installation running the following command:"
|
|
echo ". ${absdir}/activate${SHELL_SUFFIX}"
|
|
echo "Later on, you can leave the installation typing:"
|
|
echo "kerl_deactivate"
|
|
}
|
|
|
|
install_docsh() {
|
|
REPO_URL=$DOCSH_GITHUB_URL
|
|
GIT=$(echo -n $REPO_URL | $MD5SUM | cut -d ' ' -f $MD5SUM_FIELD)
|
|
BUILDNAME=$1
|
|
DOCSH_DIR="$KERL_BUILD_DIR/$BUILDNAME/docsh"
|
|
DOCSH_REF="0.4.0"
|
|
ACTIVE_PATH=$2
|
|
|
|
OTP_VERSION=$(get_otp_version $1)
|
|
# This has to be updated with docsh updates
|
|
DOCSH_SUPPORTED="^1[89]$"
|
|
echo $OTP_VERSION | grep "$DOCSH_SUPPORTED" > /dev/null 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
echo "Erlang/OTP version $OTP_VERSION not supported by docsh (does not match regex $DOCSH_SUPPORTED)"
|
|
exit 1
|
|
fi
|
|
|
|
mkdir -p "$KERL_GIT_DIR" || exit 1
|
|
cd "$KERL_GIT_DIR" || exit 1
|
|
echo "Checking out docsh git repository from ${REPO_URL}..."
|
|
if [ ! -d "$GIT" ]; then
|
|
git clone -q --mirror "$REPO_URL" "$GIT" > /dev/null 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error mirroring remote git repository"
|
|
exit 1
|
|
fi
|
|
fi
|
|
cd "$GIT" || exit 1
|
|
git remote update --prune > /dev/null 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error updating remote git repository"
|
|
exit 1
|
|
fi
|
|
|
|
rm -Rf "$DOCSH_DIR"
|
|
mkdir -p "$DOCSH_DIR" || exit 1
|
|
cd "$DOCSH_DIR" || exit 1
|
|
git clone -l "$KERL_GIT_DIR/$GIT" $DOCSH_DIR > /dev/null 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error cloning local git repository"
|
|
exit 1
|
|
fi
|
|
cd $DOCSH_DIR || exit 1
|
|
git checkout "$DOCSH_REF" > /dev/null 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
git checkout -b "$DOCSH_REF" "$DOCSH_REF" > /dev/null 2>&1
|
|
fi
|
|
if [ $? -ne 0 ]; then
|
|
echo "Couldn't checkout specified version"
|
|
rm -Rf "$DOCSH_DIR"
|
|
exit 1
|
|
fi
|
|
|
|
./rebar3 compile
|
|
if [ $? -ne 0 ]; then
|
|
echo "Couldn't compile docsh"
|
|
rm -Rf "$DOCSH_DIR"
|
|
exit 1
|
|
fi
|
|
|
|
## Install docsh
|
|
if [ -f $ACTIVE_PATH/lib/docsh ]; then
|
|
echo "Couldn't install $ACTIVE_PATH/lib/docsh - the directory already exists"
|
|
rm -Rf "$DOCSH_DIR"
|
|
exit 1
|
|
else
|
|
cp -R $DOCSH_DIR/_build/default/lib/docsh $ACTIVE_PATH/lib/
|
|
fi
|
|
## Prepare dot.erlang for linking as $HOME/.erlang
|
|
if [ -f $ACTIVE_PATH/lib/docsh/dot.erlang ]; then
|
|
echo "Couldn't install $ACTIVE_PATH/lib/docsh/dot.erlang - the file already exists"
|
|
rm -Rf "$DOCSH_DIR"
|
|
exit 1
|
|
else
|
|
cat $DOCSH_DIR/templates/dot.erlang > $ACTIVE_PATH/lib/docsh/dot.erlang
|
|
fi
|
|
## Warn if $HOME/.erlang exists
|
|
if [ -f $HOME/.erlang ]; then
|
|
echo "$HOME/.erlang exists - kerl won't be able to symlink a docsh-compatible version."
|
|
echo "Please make sure your $HOME/.erlang contains code"
|
|
echo "from $ACTIVE_PATH/lib/docsh/dot.erlang"
|
|
echo "and export KERL_DOCSH_DOT_ERLANG=exists to suppress further warnings"
|
|
fi
|
|
## Install docsh user_default
|
|
if [ -f $ACTIVE_PATH/lib/docsh/user_default.beam ]; then
|
|
echo "Couldn't install $ACTIVE_PATH/lib/docsh/user_default.beam - the file already exists"
|
|
rm -Rf "$DOCSH_DIR"
|
|
exit 1
|
|
else
|
|
erlc -I $DOCSH_DIR/include -o $ACTIVE_PATH/lib/docsh/ $DOCSH_DIR/templates/user_default.erl
|
|
fi
|
|
}
|
|
|
|
download_manpages()
|
|
{
|
|
FILENAME=otp_doc_man_$1.tar.gz
|
|
tarball_download "$FILENAME"
|
|
echo "Extracting manpages"
|
|
cd "$absdir" && tar xzf "$KERL_DOWNLOAD_DIR/$FILENAME"
|
|
}
|
|
|
|
download_htmldocs()
|
|
{
|
|
FILENAME="otp_doc_html_$1.tar.gz"
|
|
tarball_download "$FILENAME"
|
|
echo "Extracting HTML docs"
|
|
(cd "$absdir" && mkdir -p html && \
|
|
tar -C "$absdir/html" -xzf "$KERL_DOWNLOAD_DIR/$FILENAME")
|
|
}
|
|
|
|
build_plt()
|
|
{
|
|
dialyzerd=$1/dialyzer
|
|
mkdir -p $dialyzerd || exit 1
|
|
plt=$dialyzerd/plt
|
|
build_log=$dialyzerd/build.log
|
|
dialyzer=$1/bin/dialyzer
|
|
dirs=`find $1/lib -maxdepth 2 -name ebin -type d -exec dirname {} \;`
|
|
apps=`for app in $dirs; do basename $app | cut -d- -f1 ; done | grep -Ev 'erl_interface|jinterface' | xargs echo`
|
|
$dialyzer --output_plt $plt --build_plt --apps $apps >> $build_log 2>&1
|
|
status=$?
|
|
if [ $status -eq 0 -o $status -eq 2 ]; then
|
|
echo "Done building $plt"
|
|
return 0
|
|
else
|
|
echo "Error building PLT, see $build_log for details"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
do_plt()
|
|
{
|
|
ACTIVE_PATH="$1"
|
|
if [ -n "$ACTIVE_PATH" ]; then
|
|
plt=$ACTIVE_PATH/dialyzer/plt
|
|
if [ -f "$plt" ]; then
|
|
echo "Dialyzer PLT for the active installation is:"
|
|
echo $plt
|
|
return 0
|
|
else
|
|
echo "There's no Dialyzer PLT for the active installation"
|
|
return 1
|
|
fi
|
|
else
|
|
echo "No Erlang/OTP installation is currently active"
|
|
return 2
|
|
fi
|
|
}
|
|
|
|
print_buildopts()
|
|
{
|
|
buildopts="$1/$KERL_CONFIG_STORAGE_FILENAME"
|
|
if [ -f "$buildopts" ]; then
|
|
echo "The build options for the active installation are:"
|
|
cat "$buildopts"
|
|
return 0
|
|
else
|
|
echo "The build options for the active installation are not available."
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
do_deploy()
|
|
{
|
|
if [ -z "$1" ]; then
|
|
echo "No host given"
|
|
exit 1
|
|
fi
|
|
host="$1"
|
|
|
|
assert_valid_installation "$2"
|
|
rel="$(get_name_from_install_path "$2")"
|
|
path="$2"
|
|
remotepath="$path"
|
|
|
|
if [ ! -z "$3" ]; then
|
|
remotepath="$3"
|
|
fi
|
|
|
|
ssh $KERL_DEPLOY_SSH_OPTIONS "$host" true > /dev/null 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
echo "Couldn't ssh to $host"
|
|
exit 1
|
|
fi
|
|
|
|
echo "Cloning Erlang/OTP $rel ($path) to $host ($remotepath) ..."
|
|
|
|
rsync -aqz -e "ssh $KERL_DEPLOY_SSH_OPTIONS" $KERL_DEPLOY_RSYNC_OPTIONS "$path/" "$host:$remotepath/"
|
|
if [ $? -ne 0 ]; then
|
|
echo "Couldn't rsync Erlang/OTP $rel ($path) to $host ($remotepath)"
|
|
exit 1
|
|
fi
|
|
|
|
ssh $KERL_DEPLOY_SSH_OPTIONS "$host" "cd \"$remotepath\" && env ERL_TOP=\"\`pwd\`\" ./Install $INSTALL_OPT \"\`pwd\`\" > /dev/null 2>&1"
|
|
if [ $? -ne 0 ]; then
|
|
echo "Couldn't install Erlang/OTP $rel to $host ($remotepath)"
|
|
exit 1
|
|
fi
|
|
|
|
ssh $KERL_DEPLOY_SSH_OPTIONS "$host" "cd \"$remotepath\" && sed -i -e \"s#$path#\"\`pwd\`\"#g\" activate"
|
|
if [ $? -ne 0 ]; then
|
|
echo "Couldn't completely install Erlang/OTP $rel to $host ($remotepath)"
|
|
exit 1
|
|
fi
|
|
|
|
echo "On $host, you can activate this installation running the following command:"
|
|
echo ". $remotepath/activate"
|
|
echo "Later on, you can leave the installation typing:"
|
|
echo "kerl_deactivate"
|
|
}
|
|
|
|
|
|
# Quoted from https://github.com/mkropat/sh-realpath
|
|
# LICENSE: MIT
|
|
|
|
realpath() {
|
|
canonicalize_path "$(resolve_symlinks "$1")"
|
|
}
|
|
|
|
resolve_symlinks() {
|
|
_resolve_symlinks "$1"
|
|
}
|
|
|
|
_resolve_symlinks() {
|
|
_assert_no_path_cycles "$@" || return
|
|
|
|
local dir_context path
|
|
path=$(readlink -- "$1")
|
|
if [ $? -eq 0 ]; then
|
|
dir_context=$(dirname -- "$1")
|
|
_resolve_symlinks "$(_prepend_dir_context_if_necessary "$dir_context" "$path")" "$@"
|
|
else
|
|
printf '%s\n' "$1"
|
|
fi
|
|
}
|
|
|
|
_prepend_dir_context_if_necessary() {
|
|
if [ "$1" = . ]; then
|
|
printf '%s\n' "$2"
|
|
else
|
|
_prepend_path_if_relative "$1" "$2"
|
|
fi
|
|
}
|
|
|
|
_prepend_path_if_relative() {
|
|
case "$2" in
|
|
/* ) printf '%s\n' "$2" ;;
|
|
* ) printf '%s\n' "$1/$2" ;;
|
|
esac
|
|
}
|
|
|
|
_assert_no_path_cycles() {
|
|
local target path
|
|
|
|
target=$1
|
|
shift
|
|
|
|
for path in "$@"; do
|
|
if [ "$path" = "$target" ]; then
|
|
return 1
|
|
fi
|
|
done
|
|
}
|
|
|
|
canonicalize_path() {
|
|
if [ -d "$1" ]; then
|
|
_canonicalize_dir_path "$1"
|
|
else
|
|
_canonicalize_file_path "$1"
|
|
fi
|
|
}
|
|
|
|
_canonicalize_dir_path() {
|
|
(cd "$1" 2>/dev/null && pwd -P)
|
|
}
|
|
|
|
_canonicalize_file_path() {
|
|
local dir file
|
|
dir=$(dirname -- "$1")
|
|
file=$(basename -- "$1")
|
|
(cd "$dir" 2>/dev/null && printf '%s/%s\n' "$(pwd -P)" "$file")
|
|
}
|
|
|
|
# END QUOTE
|
|
|
|
is_valid_install_path()
|
|
{
|
|
|
|
# don't allow installs into .erlang because
|
|
# it's a special configuration file location
|
|
# for OTP
|
|
if [ $(basename -- "$1") = ".erlang" ]; then
|
|
echo "ERROR: You cannot install a build into '.erlang'. (It's a special configuration file location for OTP.)"
|
|
return 1
|
|
fi
|
|
|
|
candidate=$(realpath "$1")
|
|
canonical_home=$(realpath "$HOME")
|
|
canonical_base_dir=$(realpath "$KERL_BASE_DIR")
|
|
|
|
# don't allow installs into home directory
|
|
if [ "$candidate" = "$canonical_home" ]; then
|
|
echo "ERROR: You cannot install a build into $HOME. It's a really bad idea."
|
|
return 1
|
|
fi
|
|
|
|
# don't install into our base directory either.
|
|
if [ "$candidate" = "$canonical_base_dir" ]; then
|
|
echo "ERROR: You cannot install a build into $KERL_BASE_DIR."
|
|
return 1
|
|
fi
|
|
|
|
INSTALLED_NAME=$(get_name_from_install_path $candidate)
|
|
if [ -n "$INSTALLED_NAME" ]; then
|
|
echo "ERROR: Installation ($INSTALLED_NAME) already registered for this location ($1)"
|
|
return 1
|
|
fi
|
|
|
|
# if the install directory exists,
|
|
# do not allow installs into a directory
|
|
# that is not empty
|
|
if [ -e "$1" ]; then
|
|
if [ -d "$1" ]; then
|
|
count=$(ls -la "$1" | wc -l)
|
|
if [ $count -ne 3 ]; then
|
|
echo "ERROR: $1 does not appear to be an empty directory."
|
|
return 1
|
|
fi
|
|
else
|
|
echo "ERROR: $1 is not a directory."
|
|
return 1
|
|
fi
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
maybe_remove()
|
|
{
|
|
candidate=$(realpath "$1")
|
|
canonical_home=$(realpath "$HOME")
|
|
|
|
if [ "$candidate" = "$canonical_home" ]; then
|
|
echo "WARNING: You cannot remove an install from $HOME; it's your home directory."
|
|
return 0
|
|
fi
|
|
|
|
ACTIVE_PATH="$(get_active_path)"
|
|
if [ "$candidate" = "$ACTIVE_PATH" ]; then
|
|
echo "ERROR: You cannot delete the active installation. Deactivate it first."
|
|
exit 1
|
|
fi
|
|
|
|
rm -Rf "$1"
|
|
}
|
|
|
|
list_print()
|
|
{
|
|
if [ -f "$KERL_BASE_DIR/otp_$1" ]; then
|
|
if [ "$(wc -l "$KERL_BASE_DIR/otp_$1")" != "0" ]; then
|
|
if [ -z "$2" ]; then
|
|
cat "$KERL_BASE_DIR/otp_$1"
|
|
else
|
|
echo `cat "$KERL_BASE_DIR/otp_$1"`
|
|
fi
|
|
return 0
|
|
fi
|
|
fi
|
|
echo "There are no $1 available"
|
|
}
|
|
|
|
list_add()
|
|
{
|
|
if [ -f "$KERL_BASE_DIR/otp_$1" ]; then
|
|
while read -r l; do
|
|
if [ "$l" = "$2" ]; then
|
|
return 1
|
|
fi
|
|
done < "$KERL_BASE_DIR/otp_$1"
|
|
echo "$2" >> "$KERL_BASE_DIR/otp_$1" || exit 1
|
|
else
|
|
echo "$2" > "$KERL_BASE_DIR/otp_$1" || exit 1
|
|
fi
|
|
}
|
|
|
|
list_remove()
|
|
{
|
|
if [ -f "$KERL_BASE_DIR/otp_$1" ]; then
|
|
sed $SED_OPT -i -e "/^.*$2$/d" "$KERL_BASE_DIR/otp_$1" || exit 1
|
|
fi
|
|
}
|
|
|
|
list_has()
|
|
{
|
|
if [ -f "$KERL_BASE_DIR/otp_$1" ]; then
|
|
grep "$2" "$KERL_BASE_DIR/otp_$1" > /dev/null 2>&1 && return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
path_usage()
|
|
{
|
|
echo "usage: $0 path [<install_name>]"
|
|
}
|
|
|
|
list_usage()
|
|
{
|
|
echo "usage: $0 list <releases|builds|installations>"
|
|
}
|
|
|
|
delete_usage()
|
|
{
|
|
echo "usage: $0 delete <build|installation> <build_name or path>"
|
|
}
|
|
|
|
cleanup_usage()
|
|
{
|
|
echo "usage: $0 cleanup <build_name|all>"
|
|
}
|
|
|
|
update_usage()
|
|
{
|
|
echo "usage: $0 update releases"
|
|
}
|
|
|
|
get_active_path()
|
|
{
|
|
if [ -n "$_KERL_ACTIVE_DIR" ]; then
|
|
echo "$_KERL_ACTIVE_DIR"
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
get_name_from_install_path()
|
|
{
|
|
if [ -f "$KERL_BASE_DIR"/otp_installations ]; then
|
|
grep -m1 -E "$1$" "$KERL_BASE_DIR"/otp_installations | cut -d' ' -f1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
get_install_path_from_name()
|
|
{
|
|
if [ -f "$KERL_BASE_DIR"/otp_installations ]; then
|
|
grep -m1 -E "$1$" "$KERL_BASE_DIR"/otp_installations | cut -d' ' -f2
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
do_active()
|
|
{
|
|
ACTIVE_PATH="$(get_active_path)"
|
|
if [ -n "$ACTIVE_PATH" ]; then
|
|
echo "The current active installation is:"
|
|
echo "$ACTIVE_PATH"
|
|
return 0
|
|
else
|
|
echo "No Erlang/OTP installation is currently active"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
make_filename()
|
|
{
|
|
release=$(get_otp_version "$1")
|
|
if [ $release -ge 17 ]; then
|
|
echo "OTP-$1"
|
|
else
|
|
echo "OTP_$1"
|
|
fi
|
|
}
|
|
|
|
download()
|
|
{
|
|
mkdir -p "$KERL_DOWNLOAD_DIR" || exit 1
|
|
if [ "$KERL_BUILD_BACKEND" = "git" ]; then
|
|
FILENAME=$(make_filename "$1")
|
|
github_download "$FILENAME.tar.gz"
|
|
else
|
|
FILENAME="otp_src_$1"
|
|
tarball_download "$FILENAME.tar.gz"
|
|
fi
|
|
}
|
|
|
|
github_download()
|
|
{
|
|
# if the file doesn't exist or the file has no size
|
|
if [ ! -s "$KERL_DOWNLOAD_DIR/$1" ]; then
|
|
echo "Downloading $1 to $KERL_DOWNLOAD_DIR"
|
|
curl -f -L -o "$KERL_DOWNLOAD_DIR/$1" "$OTP_GITHUB_URL/archive/$1" || exit 1
|
|
fi
|
|
}
|
|
|
|
tarball_download()
|
|
{
|
|
if [ ! -s "$KERL_DOWNLOAD_DIR/$1" ]; then
|
|
echo "Downloading $1 to $KERL_DOWNLOAD_DIR"
|
|
curl -f -L -o "$KERL_DOWNLOAD_DIR/$1" "$ERLANG_DOWNLOAD_URL/$1" || exit 1
|
|
update_checksum_file
|
|
fi
|
|
ensure_checksum_file
|
|
echo "Verifying archive checksum..."
|
|
SUM="$($MD5SUM "$KERL_DOWNLOAD_DIR/$1" | cut -d ' ' -f $MD5SUM_FIELD)"
|
|
ORIG_SUM="$(grep -F "$1" "$KERL_DOWNLOAD_DIR"/MD5 | cut -d ' ' -f 2)"
|
|
if [ "$SUM" != "$ORIG_SUM" ]; then
|
|
echo "Checksum error, check the files in $KERL_DOWNLOAD_DIR"
|
|
exit 1
|
|
fi
|
|
echo "Checksum verified ($SUM)"
|
|
}
|
|
|
|
apply_solaris_networking_patch()
|
|
{
|
|
patch -p1 <<_END_PATCH
|
|
--- otp-a/erts/emulator/drivers/common/inet_drv.c
|
|
+++ otp-b/erts/emulator/drivers/common/inet_drv.c
|
|
@@ -4166,16 +4166,7 @@
|
|
break;
|
|
|
|
case INET_IFOPT_HWADDR: {
|
|
-#ifdef SIOCGIFHWADDR
|
|
- if (ioctl(desc->s, SIOCGIFHWADDR, (char *)&ifreq) < 0)
|
|
- break;
|
|
- buf_check(sptr, s_end, 1+2+IFHWADDRLEN);
|
|
- *sptr++ = INET_IFOPT_HWADDR;
|
|
- put_int16(IFHWADDRLEN, sptr); sptr += 2;
|
|
- /* raw memcpy (fix include autoconf later) */
|
|
- sys_memcpy(sptr, (char*)(&ifreq.ifr_hwaddr.sa_data), IFHWADDRLEN);
|
|
- sptr += IFHWADDRLEN;
|
|
-#elif defined(SIOCGENADDR)
|
|
+#if defined(SIOCGENADDR)
|
|
if (ioctl(desc->s, SIOCGENADDR, (char *)&ifreq) < 0)
|
|
break;
|
|
buf_check(sptr, s_end, 1+2+sizeof(ifreq.ifr_enaddr));
|
|
_END_PATCH
|
|
}
|
|
|
|
apply_darwin_compiler_patch()
|
|
{
|
|
patch -p0 <<_END_PATCH
|
|
--- erts/emulator/beam/beam_bp.c.orig 2011-10-03 13:12:07.000000000 -0500
|
|
+++ erts/emulator/beam/beam_bp.c 2013-10-04 13:42:03.000000000 -0500
|
|
@@ -496,7 +496,8 @@
|
|
}
|
|
|
|
/* bp_hash */
|
|
-ERTS_INLINE Uint bp_sched2ix() {
|
|
+#ifndef ERTS_DO_INCL_GLB_INLINE_FUNC_DEF
|
|
+ERTS_GLB_INLINE Uint bp_sched2ix() {
|
|
#ifdef ERTS_SMP
|
|
ErtsSchedulerData *esdp;
|
|
esdp = erts_get_scheduler_data();
|
|
@@ -505,6 +506,7 @@
|
|
return 0;
|
|
#endif
|
|
}
|
|
+#endif
|
|
static void bp_hash_init(bp_time_hash_t *hash, Uint n) {
|
|
Uint size = sizeof(bp_data_time_item_t)*n;
|
|
Uint i;
|
|
--- erts/emulator/beam/beam_bp.h.orig 2011-10-03 13:12:07.000000000 -0500
|
|
+++ erts/emulator/beam/beam_bp.h 2013-10-04 13:42:08.000000000 -0500
|
|
@@ -144,7 +144,19 @@
|
|
#define ErtsSmpBPUnlock(BDC)
|
|
#endif
|
|
|
|
-ERTS_INLINE Uint bp_sched2ix(void);
|
|
+ERTS_GLB_INLINE Uint bp_sched2ix(void);
|
|
+
|
|
+#ifdef ERTS_DO_INCL_GLB_INLINE_FUNC_DEF
|
|
+ERTS_GLB_INLINE Uint bp_sched2ix() {
|
|
+#ifdef ERTS_SMP
|
|
+ ErtsSchedulerData *esdp;
|
|
+ esdp = erts_get_scheduler_data();
|
|
+ return esdp->no - 1;
|
|
+#else
|
|
+ return 0;
|
|
+#endif
|
|
+}
|
|
+#endif
|
|
|
|
#ifdef ERTS_SMP
|
|
#define bp_sched2ix_proc(p) ((p)->scheduler_data->no - 1)
|
|
_END_PATCH
|
|
}
|
|
|
|
# javadoc 8 includes always-enabled document linting which causes
|
|
# documentation builds to fail on older OTP releases.
|
|
apply_javadoc_linting_patch()
|
|
{
|
|
# The _END_PATCH token is quoted below to disable parameter substitution
|
|
patch -p0 <<'_END_PATCH'
|
|
--- lib/jinterface/doc/src/Makefile.orig 2016-05-23 14:34:48.000000000 -0500
|
|
+++ lib/jinterface/doc/src/Makefile 2016-05-23 14:35:48.000000000 -0500
|
|
@@ -142,7 +142,7 @@
|
|
rm -f errs core *~
|
|
|
|
jdoc:$(JAVA_SRC_FILES)
|
|
- (cd ../../java_src;$(JAVADOC) -sourcepath . -d $(JAVADOC_DEST) \
|
|
+ (cd ../../java_src;$(JAVADOC) -Xdoclint:none -sourcepath . -d $(JAVADOC_DEST) \
|
|
-windowtitle $(JAVADOC_TITLE) $(JAVADOC_PKGS))
|
|
|
|
man:
|
|
_END_PATCH
|
|
}
|
|
|
|
# perl 5.24 fatalizes the warning this causes
|
|
apply_r14_beam_makeops_patch()
|
|
{
|
|
patch -p0 <<'_END_PATCH'
|
|
--- erts/emulator/utils/beam_makeops.orig 2016-05-23 21:40:42.000000000 -0500
|
|
+++ erts/emulator/utils/beam_makeops 2016-05-23 21:41:08.000000000 -0500
|
|
@@ -1576,7 +1576,7 @@
|
|
if $min_window{$key} > $min_window;
|
|
|
|
pop(@{$gen_transform{$key}})
|
|
- if defined @{$gen_transform{$key}}; # Fail
|
|
+ if defined $gen_transform{$key}; # Fail
|
|
my(@prefix) = (&make_op($comment), &make_op('', 'try_me_else', &tr_code_len(@code)));
|
|
unshift(@code, @prefix);
|
|
push(@{$gen_transform{$key}}, @code, &make_op('', 'fail'));
|
|
_END_PATCH
|
|
}
|
|
|
|
# https://github.com/erlang/otp/commit/21ca6d3a137034f19862db769a5b7f1c5528dbc4.diff
|
|
apply_r15_beam_makeops_patch()
|
|
{
|
|
patch -p1 <<'_END_PATCH'
|
|
--- a/erts/emulator/utils/beam_makeops
|
|
+++ b/erts/emulator/utils/beam_makeops
|
|
@@ -1711,7 +1711,7 @@ sub tr_gen_to {
|
|
my $prev_last;
|
|
$prev_last = pop(@{$gen_transform{$key}})
|
|
- if defined @{$gen_transform{$key}}; # Fail
|
|
+ if defined $gen_transform{$key}; # Fail
|
|
|
|
if ($prev_last && !is_instr($prev_last, 'fail')) {
|
|
error("Line $line: A previous transformation shadows '$orig_transform'");
|
|
_END_PATCH
|
|
}
|
|
|
|
#https://github.com/erlang/otp/commit/a64c4d806fa54848c35632114585ad82b98712e8.diff
|
|
apply_wx_ptr_patch()
|
|
{
|
|
patch -p1 <<'_END_PATCH'
|
|
diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp
|
|
index 0d2da5d4a79..8118136d30e 100644
|
|
--- a/lib/wx/c_src/wxe_impl.cpp
|
|
+++ b/lib/wx/c_src/wxe_impl.cpp
|
|
@@ -666,7 +666,7 @@ void * WxeApp::getPtr(char * bp, wxeMemEnv *memenv) {
|
|
throw wxe_badarg(index);
|
|
}
|
|
void * temp = memenv->ref2ptr[index];
|
|
- if((index < memenv->next) && ((index == 0) || (temp > NULL)))
|
|
+ if((index < memenv->next) && ((index == 0) || (temp != (void *)NULL)))
|
|
return temp;
|
|
else {
|
|
throw wxe_badarg(index);
|
|
@@ -678,7 +678,7 @@ void WxeApp::registerPid(char * bp, ErlDrvTermData pid, wxeMemEnv * memenv) {
|
|
if(!memenv)
|
|
throw wxe_badarg(index);
|
|
void * temp = memenv->ref2ptr[index];
|
|
- if((index < memenv->next) && ((index == 0) || (temp > NULL))) {
|
|
+ if((index < memenv->next) && ((index == 0) || (temp != (void *) NULL))) {
|
|
ptrMap::iterator it;
|
|
it = ptr2ref.find(temp);
|
|
if(it != ptr2ref.end()) {
|
|
_END_PATCH
|
|
}
|
|
|
|
apply_r16_wx_ptr_patch()
|
|
{
|
|
patch -p1 <<'_END_PATCH'
|
|
diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp
|
|
index cc9bcc995..1b1912630 100644
|
|
--- a/lib/wx/c_src/wxe_impl.cpp
|
|
+++ b/lib/wx/c_src/wxe_impl.cpp
|
|
@@ -757,7 +757,7 @@ void * WxeApp::getPtr(char * bp, wxeMemEnv *memenv) {
|
|
throw wxe_badarg(index);
|
|
}
|
|
void * temp = memenv->ref2ptr[index];
|
|
- if((index < memenv->next) && ((index == 0) || (temp > NULL)))
|
|
+ if((index < memenv->next) && ((index == 0) || (temp != (void *)NULL)))
|
|
return temp;
|
|
else {
|
|
throw wxe_badarg(index);
|
|
@@ -769,7 +769,7 @@ void WxeApp::registerPid(char * bp, ErlDrvTermData pid, wxeMemEnv * memenv) {
|
|
if(!memenv)
|
|
throw wxe_badarg(index);
|
|
void * temp = memenv->ref2ptr[index];
|
|
- if((index < memenv->next) && ((index == 0) || (temp > NULL))) {
|
|
+ if((index < memenv->next) && ((index == 0) || (temp != (void *)NULL))) {
|
|
ptrMap::iterator it;
|
|
it = ptr2ref.find(temp);
|
|
if(it != ptr2ref.end()) {
|
|
_END_PATCH
|
|
}
|
|
|
|
case "$1" in
|
|
version)
|
|
echo "$KERL_VERSION"
|
|
exit 0
|
|
;;
|
|
build)
|
|
if [ "$2" = "git" ]; then
|
|
if [ $# -ne 5 ]; then
|
|
echo "usage: $0 $1 $2 <git_url> <git_version> <build_name>"
|
|
exit 1
|
|
fi
|
|
do_git_build "$3" "$4" "$5"
|
|
else
|
|
if [ $# -lt 3 ]; then
|
|
echo "usage: $0 $1 <release> <build_name>"
|
|
exit 1
|
|
fi
|
|
do_normal_build "$2" "$3"
|
|
fi
|
|
;;
|
|
install)
|
|
if [ $# -lt 2 ]; then
|
|
echo "usage: $0 $1 <build_name> [directory]"
|
|
exit 1
|
|
fi
|
|
if [ $# -eq 3 ]; then
|
|
do_install "$2" "$3"
|
|
else
|
|
if [ -z "$KERL_DEFAULT_INSTALL_DIR" ]; then
|
|
do_install "$2" "$PWD"
|
|
else
|
|
do_install "$2" "$KERL_DEFAULT_INSTALL_DIR/$2"
|
|
fi
|
|
fi
|
|
;;
|
|
install-docsh)
|
|
ACTIVE_PATH="$(get_active_path)"
|
|
if [ -n "$ACTIVE_PATH" ]; then
|
|
ACTIVE_NAME="$(get_name_from_install_path "$ACTIVE_PATH")"
|
|
if [ -z "$ACTIVE_NAME" ]; then
|
|
## TODO: Are git builds installed the usual way
|
|
## or do we need this clause to provide a fallback?
|
|
#BUILDNAME="$(basename "$ACTIVE_PATH")"
|
|
echo "$ACTIVE_PATH is not a kerl installation"
|
|
exit 1
|
|
else
|
|
BUILDNAME="$ACTIVE_NAME"
|
|
fi
|
|
install_docsh "$BUILDNAME" "$ACTIVE_PATH"
|
|
echo "Please kerl_deactivate and activate again to enable docsh"
|
|
else
|
|
echo "No Erlang/OTP installation is currently active - can't install docsh"
|
|
exit 1
|
|
fi
|
|
;;
|
|
deploy)
|
|
if [ $# -lt 2 ]; then
|
|
echo "usage: $0 $1 <[user@]host> [directory] [remote_directory]"
|
|
exit 1
|
|
fi
|
|
if [ $# -eq 4 ]; then
|
|
do_deploy "$2" "$3" "$4"
|
|
else
|
|
if [ $# -eq 3 ]; then
|
|
do_deploy "$2" "$3"
|
|
else
|
|
do_deploy "$2" '.'
|
|
fi
|
|
fi
|
|
;;
|
|
update)
|
|
if [ $# -lt 2 ]; then
|
|
update_usage
|
|
exit 1
|
|
fi
|
|
case "$2" in
|
|
releases)
|
|
rm -f "${KERL_BASE_DIR:?}"/otp_releases
|
|
check_releases
|
|
echo "The available releases are:"
|
|
list_print releases spaces
|
|
;;
|
|
*)
|
|
update_usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
;;
|
|
list)
|
|
if [ $# -ne 2 ]; then
|
|
list_usage
|
|
exit 1
|
|
fi
|
|
case "$2" in
|
|
releases)
|
|
check_releases
|
|
list_print "$2" space
|
|
echo "Run '$0 update releases' to update this list from erlang.org"
|
|
;;
|
|
builds)
|
|
list_print "$2"
|
|
;;
|
|
installations)
|
|
list_print "$2"
|
|
;;
|
|
*)
|
|
echo "Cannot list $2"
|
|
list_usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
;;
|
|
path)
|
|
# Usage:
|
|
# kerl path
|
|
# # Print currently active installation path, else non-zero exit
|
|
# kerl path <install>
|
|
# Print path to installation with name <install>, else non-zero exit
|
|
if [ -z "$2" ]; then
|
|
activepath=$(get_active_path)
|
|
if [ -z "$activepath" ]; then
|
|
echo "No active kerl-managed erlang installation"
|
|
exit 1
|
|
fi
|
|
echo "$activepath"
|
|
else
|
|
# There are some possible extensions to this we could
|
|
# consider, such as:
|
|
# - if 2+ matches: prefer one in a subdir from $PWD
|
|
# - prefer $KERL_DEFAULT_INSTALL_DIR
|
|
match=
|
|
for ins in $(list_print installations | cut -d' ' -f2); do
|
|
if [ "$(basename $ins)" = "$2" ]; then
|
|
if [ -z "$match" ]; then
|
|
match="$ins"
|
|
else
|
|
echo "Error: too many matching installations" >&2
|
|
exit 2
|
|
fi
|
|
fi
|
|
done
|
|
[ -n "$match" ] && echo "$match" && exit 0
|
|
echo "Error: no matching installation found" >&2 && exit 1
|
|
fi
|
|
;;
|
|
delete)
|
|
if [ $# -ne 3 ]; then
|
|
delete_usage
|
|
exit 1
|
|
fi
|
|
case "$2" in
|
|
build)
|
|
rel="$(get_release_from_name "$3")"
|
|
if [ -d "${KERL_BUILD_DIR:?}/$3" ]; then
|
|
maybe_remove "${KERL_BUILD_DIR:?}/$3"
|
|
else
|
|
if [ -z "$rel" ]; then
|
|
echo "No build named $3"
|
|
exit 1
|
|
fi
|
|
fi
|
|
list_remove "$2"s "$rel,$3"
|
|
echo "The $3 build has been deleted"
|
|
;;
|
|
installation)
|
|
assert_valid_installation "$3"
|
|
if [ -d "$3" ]; then
|
|
maybe_remove "$3"
|
|
else
|
|
maybe_remove "$(get_install_path_from_name "$3")"
|
|
fi
|
|
escaped="$(echo "$3" | sed $SED_OPT -e 's#/$##' -e 's#\/#\\\/#g')"
|
|
list_remove "$2"s "$escaped"
|
|
echo "The installation \"$3\" has been deleted"
|
|
;;
|
|
*)
|
|
echo "Cannot delete $2"
|
|
delete_usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
;;
|
|
active)
|
|
if ! do_active; then
|
|
exit 1;
|
|
fi
|
|
;;
|
|
plt)
|
|
ACTIVE_PATH=`get_active_path`
|
|
if ! do_plt "$ACTIVE_PATH"; then
|
|
exit 1;
|
|
fi
|
|
;;
|
|
status)
|
|
echo "Available builds:"
|
|
list_print builds
|
|
echo "----------"
|
|
echo "Available installations:"
|
|
list_print installations
|
|
echo "----------"
|
|
if do_active; then
|
|
ACTIVE_PATH=`get_active_path`
|
|
if [ -n "$ACTIVE_PATH" ]; then
|
|
do_plt "$ACTIVE_PATH"
|
|
print_buildopts "$ACTIVE_PATH"
|
|
else
|
|
echo "No Erlang/OTP installation is currently active"
|
|
exit 1
|
|
fi
|
|
fi
|
|
exit 0
|
|
;;
|
|
prompt)
|
|
FMT=" (%s)"
|
|
if [ -n "$2" ]; then
|
|
FMT="$2"
|
|
fi
|
|
ACTIVE_PATH="$(get_active_path)"
|
|
if [ -n "$ACTIVE_PATH" ]; then
|
|
ACTIVE_NAME="$(get_name_from_install_path "$ACTIVE_PATH")"
|
|
if [ -z "$ACTIVE_NAME" ]; then
|
|
VALUE="$(basename "$ACTIVE_PATH")*"
|
|
else
|
|
VALUE="$ACTIVE_NAME"
|
|
fi
|
|
printf "$FMT" "$VALUE"
|
|
fi
|
|
exit 0
|
|
;;
|
|
cleanup)
|
|
if [ $# -ne 2 ]; then
|
|
cleanup_usage
|
|
exit 1
|
|
fi
|
|
case "$2" in
|
|
all)
|
|
echo "Cleaning up compilation products for ALL builds"
|
|
rm -rf "${KERL_BUILD_DIR:?}"/*
|
|
rm -rf "${KERL_DOWNLOAD_DIR:?}"/*
|
|
rm -rf "${KERL_GIT_DIR:?}"/*
|
|
echo "Cleaned up all compilation products under $KERL_BUILD_DIR"
|
|
;;
|
|
*)
|
|
echo "Cleaning up compilation products for $3"
|
|
rm -rf "${KERL_BUILD_DIR:?}/$3"
|
|
echo "Cleaned up compilation products for $3 under $KERL_BUILD_DIR"
|
|
;;
|
|
esac
|
|
;;
|
|
*)
|
|
echo "unknown command: $1"; usage; exit 1
|
|
;;
|
|
esac
|