diff --git a/configure b/configure index b2b861a019aa6..70776849df8b5 100755 --- a/configure +++ b/configure @@ -384,6 +384,7 @@ opt pax-flags 0 "apply PaX flags to rustc binaries (required for GRSecurity/PaX- opt inject-std-version 1 "inject the current compiler version of libstd into programs" opt rpath 1 "build rpaths into rustc itself" opt nightly 0 "build nightly packages" +opt verify-install 1 "verify installed binaries work" valopt prefix "/usr/local" "set installation prefix" valopt local-rust-root "/usr/local" "set prefix for local rust binary" valopt llvm-root "" "set LLVM root" diff --git a/mk/install.mk b/mk/install.mk index b4688539ded5c..ca9497444f08d 100644 --- a/mk/install.mk +++ b/mk/install.mk @@ -8,14 +8,21 @@ # option. This file may not be copied, modified, or distributed # except according to those terms. +ifdef CFG_DISABLE_VERIFY_INSTALL +MAYBE_DISABLE_VERIFY=--disable-verify +else +MAYBE_DISABLE_VERIFY= +endif install: dist-install-dir-$(CFG_BUILD) - $(Q)sh tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --prefix="$(CFG_PREFIX)" --libdir="$(CFG_LIBDIR)" --mandir="$(CFG_MANDIR)" + $(Q)sh tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --prefix="$(DESTDIR)$(CFG_PREFIX)" --libdir="$(DESTDIR)$(CFG_LIBDIR)" --mandir="$(DESTDIR)$(CFG_MANDIR)" "$(MAYBE_DISABLE_VERIFY)" # Remove tmp files while we can because they may have been created under sudo $(Q)rm -R tmp/dist/$(PKG_NAME)-$(CFG_BUILD) uninstall: dist-install-dir-$(CFG_BUILD) - $(Q)sh tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --uninstall --prefix="$(CFG_PREFIX)" --libdir="$(CFG_LIBDIR)" --mandir="$(CFG_MANDIR)" + $(Q)sh tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --uninstall --prefix="$(DESTDIR)$(CFG_PREFIX)" --libdir="$(DESTDIR)$(CFG_LIBDIR)" --mandir="$(DESTDIR)$(CFG_MANDIR)" +# Remove tmp files while we can because they may have been created under sudo + $(Q)rm -R tmp/dist/$(PKG_NAME)-$(CFG_BUILD) ###################################################################### diff --git a/src/etc/install.sh b/src/etc/install.sh index 3a1ba91d01f23..5674b0a5045c9 100644 --- a/src/etc/install.sh +++ b/src/etc/install.sh @@ -189,6 +189,16 @@ validate_opt () { 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}" +} + CFG_SRC_DIR="$(cd $(dirname $0) && pwd)/" CFG_SELF="$0" CFG_ARGS="$@" @@ -212,6 +222,7 @@ BOOL_OPTIONS="" VAL_OPTIONS="" 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 isn't quite the same definition as in `configure`. # just using 'lib' instead of CFG_LIBDIR_RELATIVE @@ -230,19 +241,36 @@ 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" + "${CFG_SRC_DIR}/bin/rustc" --version > /dev/null + if [ $? -ne 0 ] + then + err "can't execute rustc binary on this platform" + fi + 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" 2> /dev/null +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'." + err "can't write to destination. consider \`sudo\`." fi -rm "${CFG_LIBDIR}/rust-install-probe" +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}" ] @@ -250,8 +278,13 @@ 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="${CFG_LIBDIR}/rustlib/manifest" +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. @@ -263,7 +296,7 @@ then msg "removing $p" if [ -f "$p" ] then - rm "$p" + rm -f "$p" if [ $? -ne 0 ] then warn "failed to remove $p" @@ -273,8 +306,16 @@ then 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 - rm -r "${CFG_LIBDIR}/rustlib" + msg "removing ${ABS_LIBDIR}/rustlib" + rm -Rf "${ABS_LIBDIR}/rustlib" if [ $? -ne 0 ] then warn "failed to remove rustlib" @@ -298,7 +339,9 @@ 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 @@ -324,10 +367,8 @@ while read p; do # Make the path absolute so we can uninstall it later without # starting from the installation cwd - FILE_INSTALL_PATH_DIRNAME="$(dirname ${FILE_INSTALL_PATH})" - FILE_INSTALL_PATH_BASENAME="$(basename ${FILE_INSTALL_PATH})" - FILE_INSTALL_ABS_PATH="$(cd ${FILE_INSTALL_PATH_DIRNAME} && pwd)" - FILE_INSTALL_PATH="${FILE_INSTALL_ABS_PATH}/${FILE_INSTALL_PATH_BASENAME}" + absolutify "${FILE_INSTALL_PATH}" + FILE_INSTALL_PATH="${ABSOLUTIFIED}" # Install the file msg "${FILE_INSTALL_PATH}" @@ -346,6 +387,22 @@ while read p; do # The manifest lists all files to install done < "${CFG_SRC_DIR}/lib/rustlib/manifest.in" +# Sanity check: can we run the installed binaries? +if [ -z "${CFG_DISABLE_VERIFY}" ] +then + msg "verifying installed binaries are executable" + "${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}" + fi +fi + + echo echo " Rust is ready to roll." echo