e889f8091a
not in hardcoded libdir path. If there was no LIBDIR provided during configuration fallback to hardcoded paths. Thanks to Jan Niklas Hasse for solution and to Alex Crichton for improvements. Closes #11671
520 lines
13 KiB
Bash
520 lines
13 KiB
Bash
#!/bin/sh
|
|
# Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
|
# file at the top-level directory of this distribution and at
|
|
# http://rust-lang.org/COPYRIGHT.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
# option. This file may not be copied, modified, or distributed
|
|
# except according to those terms.
|
|
|
|
msg() {
|
|
echo "install: $1"
|
|
}
|
|
|
|
step_msg() {
|
|
msg
|
|
msg "$1"
|
|
msg
|
|
}
|
|
|
|
warn() {
|
|
echo "install: WARNING: $1"
|
|
}
|
|
|
|
err() {
|
|
echo "install: error: $1"
|
|
exit 1
|
|
}
|
|
|
|
need_ok() {
|
|
if [ $? -ne 0 ]
|
|
then
|
|
err "$1"
|
|
fi
|
|
}
|
|
|
|
need_cmd() {
|
|
if command -v $1 >/dev/null 2>&1
|
|
then msg "found $1"
|
|
else err "need $1"
|
|
fi
|
|
}
|
|
|
|
putvar() {
|
|
local T
|
|
eval T=\$$1
|
|
eval TLEN=\${#$1}
|
|
if [ $TLEN -gt 35 ]
|
|
then
|
|
printf "install: %-20s := %.35s ...\n" $1 "$T"
|
|
else
|
|
printf "install: %-20s := %s %s\n" $1 "$T" "$2"
|
|
fi
|
|
}
|
|
|
|
valopt() {
|
|
VAL_OPTIONS="$VAL_OPTIONS $1"
|
|
|
|
local OP=$1
|
|
local DEFAULT=$2
|
|
shift
|
|
shift
|
|
local DOC="$*"
|
|
if [ $HELP -eq 0 ]
|
|
then
|
|
local UOP=$(echo $OP | tr '[:lower:]' '[:upper:]' | tr '\-' '\_')
|
|
local V="CFG_${UOP}"
|
|
eval $V="$DEFAULT"
|
|
for arg in $CFG_ARGS
|
|
do
|
|
if echo "$arg" | grep -q -- "--$OP="
|
|
then
|
|
val=$(echo "$arg" | cut -f2 -d=)
|
|
eval $V=$val
|
|
fi
|
|
done
|
|
putvar $V
|
|
else
|
|
if [ -z "$DEFAULT" ]
|
|
then
|
|
DEFAULT="<none>"
|
|
fi
|
|
OP="${OP}=[${DEFAULT}]"
|
|
printf " --%-30s %s\n" "$OP" "$DOC"
|
|
fi
|
|
}
|
|
|
|
opt() {
|
|
BOOL_OPTIONS="$BOOL_OPTIONS $1"
|
|
|
|
local OP=$1
|
|
local DEFAULT=$2
|
|
shift
|
|
shift
|
|
local DOC="$*"
|
|
local FLAG=""
|
|
|
|
if [ $DEFAULT -eq 0 ]
|
|
then
|
|
FLAG="enable"
|
|
else
|
|
FLAG="disable"
|
|
DOC="don't $DOC"
|
|
fi
|
|
|
|
if [ $HELP -eq 0 ]
|
|
then
|
|
for arg in $CFG_ARGS
|
|
do
|
|
if [ "$arg" = "--${FLAG}-${OP}" ]
|
|
then
|
|
OP=$(echo $OP | tr 'a-z-' 'A-Z_')
|
|
FLAG=$(echo $FLAG | tr 'a-z' 'A-Z')
|
|
local V="CFG_${FLAG}_${OP}"
|
|
eval $V=1
|
|
putvar $V
|
|
fi
|
|
done
|
|
else
|
|
if [ ! -z "$META" ]
|
|
then
|
|
OP="$OP=<$META>"
|
|
fi
|
|
printf " --%-30s %s\n" "$FLAG-$OP" "$DOC"
|
|
fi
|
|
}
|
|
|
|
flag() {
|
|
BOOL_OPTIONS="$BOOL_OPTIONS $1"
|
|
|
|
local OP=$1
|
|
shift
|
|
local DOC="$*"
|
|
|
|
if [ $HELP -eq 0 ]
|
|
then
|
|
for arg in $CFG_ARGS
|
|
do
|
|
if [ "$arg" = "--${OP}" ]
|
|
then
|
|
OP=$(echo $OP | tr 'a-z-' 'A-Z_')
|
|
local V="CFG_${OP}"
|
|
eval $V=1
|
|
putvar $V
|
|
fi
|
|
done
|
|
else
|
|
if [ ! -z "$META" ]
|
|
then
|
|
OP="$OP=<$META>"
|
|
fi
|
|
printf " --%-30s %s\n" "$OP" "$DOC"
|
|
fi
|
|
}
|
|
|
|
validate_opt () {
|
|
for arg in $CFG_ARGS
|
|
do
|
|
isArgValid=0
|
|
for option in $BOOL_OPTIONS
|
|
do
|
|
if test --disable-$option = $arg
|
|
then
|
|
isArgValid=1
|
|
fi
|
|
if test --enable-$option = $arg
|
|
then
|
|
isArgValid=1
|
|
fi
|
|
if test --$option = $arg
|
|
then
|
|
isArgValid=1
|
|
fi
|
|
done
|
|
for option in $VAL_OPTIONS
|
|
do
|
|
if echo "$arg" | grep -q -- "--$option="
|
|
then
|
|
isArgValid=1
|
|
fi
|
|
done
|
|
if [ "$arg" = "--help" ]
|
|
then
|
|
echo
|
|
echo "No more help available for Configure options,"
|
|
echo "check the Wiki or join our IRC channel"
|
|
break
|
|
else
|
|
if test $isArgValid -eq 0
|
|
then
|
|
err "Option '$arg' is not recognized"
|
|
fi
|
|
fi
|
|
done
|
|
}
|
|
|
|
absolutify() {
|
|
FILE_PATH="${1}"
|
|
FILE_PATH_DIRNAME="$(dirname ${FILE_PATH})"
|
|
FILE_PATH_BASENAME="$(basename ${FILE_PATH})"
|
|
FILE_ABS_PATH="$(cd ${FILE_PATH_DIRNAME} && pwd)"
|
|
FILE_PATH="${FILE_ABS_PATH}/${FILE_PATH_BASENAME}"
|
|
# This is the return value
|
|
ABSOLUTIFIED="${FILE_PATH}"
|
|
}
|
|
|
|
msg "looking for install programs"
|
|
need_cmd mkdir
|
|
need_cmd printf
|
|
need_cmd cut
|
|
need_cmd grep
|
|
need_cmd uname
|
|
need_cmd tr
|
|
need_cmd sed
|
|
|
|
CFG_SRC_DIR="$(cd $(dirname $0) && pwd)"
|
|
CFG_SELF="$0"
|
|
CFG_ARGS="$@"
|
|
|
|
HELP=0
|
|
if [ "$1" = "--help" ]
|
|
then
|
|
HELP=1
|
|
shift
|
|
echo
|
|
echo "Usage: $CFG_SELF [options]"
|
|
echo
|
|
echo "Options:"
|
|
echo
|
|
else
|
|
step_msg "processing $CFG_SELF args"
|
|
fi
|
|
|
|
# Check for mingw or cygwin in order to special case $CFG_LIBDIR_RELATIVE.
|
|
# This logic is duplicated from configure in order to get the correct libdir
|
|
# for Windows installs.
|
|
CFG_OSTYPE=$(uname -s)
|
|
|
|
case $CFG_OSTYPE in
|
|
|
|
MINGW32*)
|
|
CFG_OSTYPE=pc-mingw32
|
|
;;
|
|
|
|
MINGW64*)
|
|
# msys2, MSYSTEM=MINGW64
|
|
CFG_OSTYPE=w64-mingw32
|
|
;;
|
|
|
|
# Thad's Cygwin identifers below
|
|
|
|
# Vista 32 bit
|
|
CYGWIN_NT-6.0)
|
|
CFG_OSTYPE=pc-mingw32
|
|
;;
|
|
|
|
# Vista 64 bit
|
|
CYGWIN_NT-6.0-WOW64)
|
|
CFG_OSTYPE=w64-mingw32
|
|
;;
|
|
|
|
# Win 7 32 bit
|
|
CYGWIN_NT-6.1)
|
|
CFG_OSTYPE=pc-mingw32
|
|
;;
|
|
|
|
# Win 7 64 bit
|
|
CYGWIN_NT-6.1-WOW64)
|
|
CFG_OSTYPE=w64-mingw32
|
|
;;
|
|
esac
|
|
|
|
OPTIONS=""
|
|
BOOL_OPTIONS=""
|
|
VAL_OPTIONS=""
|
|
|
|
# On windows we just store the libraries in the bin directory because
|
|
# there's no rpath. This is where the build system itself puts libraries;
|
|
# --libdir is used to configure the installation directory.
|
|
# FIXME: Thise needs to parameterized over target triples. Do it in platform.mk
|
|
CFG_LIBDIR_RELATIVE=lib
|
|
if [ "$CFG_OSTYPE" = "pc-mingw32" ] || [ "$CFG_OSTYPE" = "w64-mingw32" ]
|
|
then
|
|
CFG_LIBDIR_RELATIVE=bin
|
|
fi
|
|
|
|
if [ "$CFG_OSTYPE" = "pc-mingw32" ] || [ "$CFG_OSTYPE" = "w64-mingw32" ]
|
|
then
|
|
CFG_LD_PATH_VAR=PATH
|
|
CFG_OLD_LD_PATH_VAR=$PATH
|
|
elif [ "$CFG_OSTYPE" = "Darwin" ]
|
|
then
|
|
CFG_LD_PATH_VAR=DYLD_LIBRARY_PATH
|
|
CFG_OLD_LD_PATH_VAR=$DYLD_LIBRARY_PATH
|
|
else
|
|
CFG_LD_PATH_VAR=LD_LIBRARY_PATH
|
|
CFG_OLD_LD_PATH_VAR=$LD_LIBRARY_PATH
|
|
fi
|
|
|
|
flag uninstall "only uninstall from the installation prefix"
|
|
opt verify 1 "verify that the installed binaries run correctly"
|
|
valopt prefix "/usr/local" "set installation prefix"
|
|
# NB This is exactly the same definition as in `configure`.
|
|
valopt libdir "${CFG_PREFIX}/${CFG_LIBDIR_RELATIVE}" "install libraries"
|
|
case "$CFG_LIBDIR" in
|
|
"$CFG_PREFIX"/*) CAT_INC=2;;
|
|
"$CFG_PREFIX"*) CAT_INC=1;;
|
|
*)
|
|
err "libdir must begin with the prefix. Use --prefix to set it accordingly.";;
|
|
esac
|
|
CFG_LIBDIR_RELATIVE=`echo ${CFG_LIBDIR} | cut -c$((${#CFG_PREFIX}+${CAT_INC}))-`
|
|
|
|
valopt mandir "${CFG_PREFIX}/share/man" "install man pages in PATH"
|
|
|
|
if [ $HELP -eq 1 ]
|
|
then
|
|
echo
|
|
exit 0
|
|
fi
|
|
|
|
step_msg "validating $CFG_SELF args"
|
|
validate_opt
|
|
|
|
|
|
# OK, let's get installing ...
|
|
|
|
# Sanity check: can we run the binaries?
|
|
if [ -z "${CFG_DISABLE_VERIFY}" ]
|
|
then
|
|
# Don't do this if uninstalling. Failure here won't help in any way.
|
|
if [ -z "${CFG_UNINSTALL}" ]
|
|
then
|
|
msg "verifying platform can run binaries"
|
|
export $CFG_LD_PATH_VAR="${CFG_SRC_DIR}/lib:$CFG_OLD_LD_PATH_VAR"
|
|
"${CFG_SRC_DIR}/bin/rustc" --version > /dev/null
|
|
if [ $? -ne 0 ]
|
|
then
|
|
err "can't execute rustc binary on this platform"
|
|
fi
|
|
export $CFG_LD_PATH_VAR=$CFG_OLD_LD_PATH_VAR
|
|
fi
|
|
fi
|
|
|
|
# Sanity check: can we can write to the destination?
|
|
msg "verifying destination is writable"
|
|
umask 022 && mkdir -p "${CFG_LIBDIR}"
|
|
need_ok "can't write to destination. consider \`sudo\`."
|
|
touch "${CFG_LIBDIR}/rust-install-probe" > /dev/null
|
|
if [ $? -ne 0 ]
|
|
then
|
|
err "can't write to destination. consider \`sudo\`."
|
|
fi
|
|
rm -f "${CFG_LIBDIR}/rust-install-probe"
|
|
need_ok "failed to remove install probe"
|
|
|
|
# Sanity check: don't install to the directory containing the installer.
|
|
# That would surely cause chaos.
|
|
msg "verifying destination is not the same as source"
|
|
INSTALLER_DIR="$(cd $(dirname $0) && pwd)"
|
|
PREFIX_DIR="$(cd ${CFG_PREFIX} && pwd)"
|
|
if [ "${INSTALLER_DIR}" = "${PREFIX_DIR}" ]
|
|
then
|
|
err "can't install to same directory as installer"
|
|
fi
|
|
|
|
# Using an absolute path to libdir in a few places so that the status
|
|
# messages are consistently using absolute paths.
|
|
absolutify "${CFG_LIBDIR}"
|
|
ABS_LIBDIR="${ABSOLUTIFIED}"
|
|
|
|
# The file name of the manifest we're going to create during install
|
|
INSTALLED_MANIFEST="${ABS_LIBDIR}/rustlib/manifest"
|
|
|
|
# First, uninstall from the installation prefix.
|
|
# Errors are warnings - try to rm everything in the manifest even if some fail.
|
|
if [ -f "${INSTALLED_MANIFEST}" ]
|
|
then
|
|
# Iterate through installed manifest and remove files
|
|
while read p; do
|
|
# The installed manifest contains absolute paths
|
|
msg "removing $p"
|
|
if [ -f "$p" ]
|
|
then
|
|
rm -f "$p"
|
|
if [ $? -ne 0 ]
|
|
then
|
|
warn "failed to remove $p"
|
|
fi
|
|
else
|
|
warn "supposedly installed file $p does not exist!"
|
|
fi
|
|
done < "${INSTALLED_MANIFEST}"
|
|
|
|
# If we fail to remove rustlib below, then the installed manifest will
|
|
# still be full; the installed manifest needs to be empty before install.
|
|
msg "removing ${INSTALLED_MANIFEST}"
|
|
rm -f "${INSTALLED_MANIFEST}"
|
|
# For the above reason, this is a hard error
|
|
need_ok "failed to remove installed manifest"
|
|
|
|
# Remove 'rustlib' directory
|
|
msg "removing ${ABS_LIBDIR}/rustlib"
|
|
rm -Rf "${ABS_LIBDIR}/rustlib"
|
|
if [ $? -ne 0 ]
|
|
then
|
|
warn "failed to remove rustlib"
|
|
fi
|
|
else
|
|
# There's no manifest. If we were asked to uninstall, then that's a problem.
|
|
if [ -n "${CFG_UNINSTALL}" ]
|
|
then
|
|
err "unable to find installation manifest at ${CFG_LIBDIR}/rustlib"
|
|
fi
|
|
fi
|
|
|
|
# If we're only uninstalling then exit
|
|
if [ -n "${CFG_UNINSTALL}" ]
|
|
then
|
|
echo
|
|
echo " Rust is uninstalled. Have a nice day."
|
|
echo
|
|
exit 0
|
|
fi
|
|
|
|
# Create the installed manifest, which we will fill in with absolute file paths
|
|
mkdir -p "${CFG_LIBDIR}/rustlib"
|
|
need_ok "failed to create rustlib"
|
|
touch "${INSTALLED_MANIFEST}"
|
|
need_ok "failed to create installed manifest"
|
|
|
|
# Now install, iterate through the new manifest and copy files
|
|
while read p; do
|
|
|
|
# Decide the destination of the file
|
|
FILE_INSTALL_PATH="${CFG_PREFIX}/$p"
|
|
|
|
if echo "$p" | grep "^${CFG_LIBDIR_RELATIVE}/" > /dev/null
|
|
then
|
|
pp=`echo $p | sed "s%^${CFG_LIBDIR_RELATIVE}/%%"`
|
|
FILE_INSTALL_PATH="${CFG_LIBDIR}/$pp"
|
|
fi
|
|
|
|
if echo "$p" | grep "^share/man/" > /dev/null
|
|
then
|
|
pp=`echo $p | sed 's/^share\/man\///'`
|
|
FILE_INSTALL_PATH="${CFG_MANDIR}/$pp"
|
|
fi
|
|
|
|
# Make sure there's a directory for it
|
|
umask 022 && mkdir -p "$(dirname ${FILE_INSTALL_PATH})"
|
|
need_ok "directory creation failed"
|
|
|
|
# Make the path absolute so we can uninstall it later without
|
|
# starting from the installation cwd
|
|
absolutify "${FILE_INSTALL_PATH}"
|
|
FILE_INSTALL_PATH="${ABSOLUTIFIED}"
|
|
|
|
# Install the file
|
|
msg "${FILE_INSTALL_PATH}"
|
|
if echo "$p" | grep "^bin/" > /dev/null
|
|
then
|
|
install -m755 "${CFG_SRC_DIR}/$p" "${FILE_INSTALL_PATH}"
|
|
else
|
|
install -m644 "${CFG_SRC_DIR}/$p" "${FILE_INSTALL_PATH}"
|
|
fi
|
|
need_ok "file creation failed"
|
|
|
|
# Update the manifest
|
|
echo "${FILE_INSTALL_PATH}" >> "${INSTALLED_MANIFEST}"
|
|
need_ok "failed to update manifest"
|
|
|
|
# The manifest lists all files to install
|
|
done < "${CFG_SRC_DIR}/${CFG_LIBDIR_RELATIVE}/rustlib/manifest.in"
|
|
|
|
# Run ldconfig to make dynamic libraries available to the linker
|
|
if [ "$CFG_OSTYPE" = "Linux" ]
|
|
then
|
|
ldconfig
|
|
if [ $? -ne 0 ]
|
|
then
|
|
warn "failed to run ldconfig."
|
|
warn "this may happen when not installing as root and may be fine"
|
|
fi
|
|
fi
|
|
|
|
# Sanity check: can we run the installed binaries?
|
|
#
|
|
# As with the verification above, make sure the right LD_LIBRARY_PATH-equivalent
|
|
# is in place. Try first without this variable, and if that fails try again with
|
|
# the variable. If the second time tries, print a hopefully helpful message to
|
|
# add something to the appropriate environment variable.
|
|
if [ -z "${CFG_DISABLE_VERIFY}" ]
|
|
then
|
|
msg "verifying installed binaries are executable"
|
|
"${CFG_PREFIX}/bin/rustc" --version 2> /dev/null 1> /dev/null
|
|
if [ $? -ne 0 ]
|
|
then
|
|
export $CFG_LD_PATH_VAR="${CFG_PREFIX}/lib:$CFG_OLD_LD_PATH_VAR"
|
|
"${CFG_PREFIX}/bin/rustc" --version > /dev/null
|
|
if [ $? -ne 0 ]
|
|
then
|
|
ERR="can't execute installed rustc binary. "
|
|
ERR="${ERR}installation may be broken. "
|
|
ERR="${ERR}if this is expected then rerun install.sh with \`--disable-verify\` "
|
|
ERR="${ERR}or \`make install\` with \`--disable-verify-install\`"
|
|
err "${ERR}"
|
|
else
|
|
echo
|
|
echo " Note: please ensure '${CFG_PREFIX}/lib' is added to ${CFG_LD_PATH_VAR}"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
echo
|
|
echo " Rust is ready to roll."
|
|
echo
|
|
|
|
|