diff --git a/.gitmodules b/.gitmodules index 987791ac9db5f..6cd704b370376 100644 --- a/.gitmodules +++ b/.gitmodules @@ -11,3 +11,6 @@ [submodule "src/jemalloc"] path = src/jemalloc url = https://github.com/rust-lang/jemalloc.git +[submodule "src/rust-installer"] + path = src/rust-installer + url = https://github.com/rust-lang/rust-installer diff --git a/mk/dist.mk b/mk/dist.mk index 00f6e8617391d..2db26f819dfdf 100644 --- a/mk/dist.mk +++ b/mk/dist.mk @@ -58,6 +58,7 @@ PKG_FILES := \ rt \ rustllvm \ snapshots.txt \ + rust-installer \ test) \ $(PKG_GITMODULES) \ $(filter-out config.stamp, \ @@ -209,33 +210,40 @@ distcheck-osx: dist-osx # Unix binary installer tarballs ###################################################################### +NON_INSTALLED_PREFIXES=COPYRIGHT,LICENSE-APACHE,LICENSE-MIT,README.md,doc + define DEF_INSTALLER $$(eval $$(call DEF_PREPARE,dir-$(1))) dist-install-dir-$(1): PREPARE_HOST=$(1) dist-install-dir-$(1): PREPARE_TARGETS=$(2) -dist-install-dir-$(1): PREPARE_DEST_DIR=tmp/dist/$$(PKG_NAME)-$(1) +dist-install-dir-$(1): PREPARE_DEST_DIR=tmp/dist/$$(PKG_NAME)-$(1)-image dist-install-dir-$(1): PREPARE_DIR_CMD=$(DEFAULT_PREPARE_DIR_CMD) dist-install-dir-$(1): PREPARE_BIN_CMD=$(DEFAULT_PREPARE_BIN_CMD) dist-install-dir-$(1): PREPARE_LIB_CMD=$(DEFAULT_PREPARE_LIB_CMD) dist-install-dir-$(1): PREPARE_MAN_CMD=$(DEFAULT_PREPARE_MAN_CMD) dist-install-dir-$(1): PREPARE_CLEAN=true dist-install-dir-$(1): prepare-base-dir-$(1) docs compiler-docs - $$(Q)(cd $$(PREPARE_DEST_DIR)/ && find . -type f | sed 's/^\.\///') \ - > tmp/dist/manifest-$(1).in - $$(Q)mv tmp/dist/manifest-$(1).in $$(PREPARE_DEST_DIR)/$$(CFG_LIBDIR_RELATIVE)/rustlib/manifest.in -# Add remaining non-installed files $$(Q)$$(PREPARE_MAN_CMD) $$(S)COPYRIGHT $$(PREPARE_DEST_DIR) $$(Q)$$(PREPARE_MAN_CMD) $$(S)LICENSE-APACHE $$(PREPARE_DEST_DIR) $$(Q)$$(PREPARE_MAN_CMD) $$(S)LICENSE-MIT $$(PREPARE_DEST_DIR) $$(Q)$$(PREPARE_MAN_CMD) $$(S)README.md $$(PREPARE_DEST_DIR) $$(Q)cp -r doc $$(PREPARE_DEST_DIR) - $$(Q)$$(PREPARE_BIN_CMD) $$(S)src/etc/install.sh $$(PREPARE_DEST_DIR) dist/$$(PKG_NAME)-$(1).tar.gz: dist-install-dir-$(1) @$(call E, build: $$@) - $$(Q)tar -czf dist/$$(PKG_NAME)-$(1).tar.gz -C tmp/dist $$(PKG_NAME)-$(1) + $$(Q)$$(S)src/rust-installer/gen-installer.sh \ + --product-name=Rust \ + --verify-bin=rustc \ + --rel-manifest-dir=rustlib \ + --success-message=Rust-is-ready-to-roll. \ + --image-dir=tmp/dist/$$(PKG_NAME)-$(1)-image \ + --work-dir=tmp/dist \ + --output-dir=dist \ + --non-installed-prefixes=$$(NON_INSTALLED_PREFIXES) \ + --package-name=$$(PKG_NAME)-$(1) + $$(Q)rm -R tmp/dist/$$(PKG_NAME)-$(1)-image endef diff --git a/mk/install.mk b/mk/install.mk index 88b451f661af2..632df3c754b8d 100644 --- a/mk/install.mk +++ b/mk/install.mk @@ -25,7 +25,7 @@ endif # Remove tmp files because it's a decent amount of disk space $(Q)rm -R tmp/dist -prepare_install: dist-install-dir-$(CFG_BUILD) | tmp/empty_dir +prepare_install: dist/$(PKG_NAME)-$(CFG_BUILD).tar.gz | tmp/empty_dir uninstall: ifeq (root user, $(USER) $(patsubst %,user,$(SUDO_USER))) @@ -38,7 +38,7 @@ endif # Remove tmp files because it's a decent amount of disk space $(Q)rm -R tmp/dist -prepare_uninstall: dist-install-dir-$(CFG_BUILD) | tmp/empty_dir +prepare_uninstall: dist/$(PKG_NAME)-$(CFG_BUILD).tar.gz | tmp/empty_dir .PHONY: install prepare_install uninstall prepare_uninstall diff --git a/src/etc/install.sh b/src/etc/install.sh deleted file mode 100644 index 8bc48fc7934e2..0000000000000 --- a/src/etc/install.sh +++ /dev/null @@ -1,519 +0,0 @@ -#!/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 or the MIT license -# , 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="" - 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 - - diff --git a/src/rust-installer b/src/rust-installer new file mode 160000 index 0000000000000..aed7347241606 --- /dev/null +++ b/src/rust-installer @@ -0,0 +1 @@ +Subproject commit aed73472416064642911af790b25d57c9390b6c7