diff --git a/.gitignore b/.gitignore index a72ba1be0df..9ed279d9d74 100644 --- a/.gitignore +++ b/.gitignore @@ -65,6 +65,7 @@ config.mk /mingw-build/ src/.DS_Store /tmp/ +/dist/ /stage0/ /dl/ /stage1/ diff --git a/configure b/configure index a69069183e7..11edfbca655 100755 --- a/configure +++ b/configure @@ -22,7 +22,7 @@ err() { need_ok() { if [ $? -ne 0 ] then - err $1 + err "$1" fi } @@ -340,7 +340,7 @@ DEFAULT_BUILD="${CFG_CPUTYPE}-${CFG_OSTYPE}" CFG_SRC_DIR="$(cd $(dirname $0) && pwd)/" CFG_BUILD_DIR="$(pwd)/" -CFG_SELF=${CFG_SRC_DIR}$(basename $0) +CFG_SELF="$0" CFG_CONFIGURE_ARGS="$@" OPTIONS="" @@ -412,16 +412,15 @@ fi valopt libdir "${CFG_PREFIX}/${CFG_LIBDIR_RELATIVE}" "install libraries" valopt rustlibdir "rustlib" "subdirectory name for rustc's libraries" -# Validate Options -step_msg "validating $CFG_SELF args" -validate_opt - if [ $HELP -eq 1 ] then echo exit 0 fi +# Validate Options +step_msg "validating $CFG_SELF args" +validate_opt step_msg "looking for build programs" @@ -728,7 +727,7 @@ step_msg "making directories" for i in \ doc doc/std doc/extra \ - dl tmp + dl tmp dist do make_dir $i done diff --git a/mk/dist.mk b/mk/dist.mk index 17afeaae377..01ee7a7947b 100644 --- a/mk/dist.mk +++ b/mk/dist.mk @@ -4,16 +4,16 @@ PKG_NAME := rust PKG_DIR = $(PKG_NAME)-$(CFG_RELEASE) -PKG_TAR = $(PKG_DIR).tar.gz +PKG_TAR = dist/$(PKG_DIR).tar.gz ifdef CFG_ISCC PKG_ISS = $(wildcard $(S)src/etc/pkg/*.iss) PKG_ICO = $(S)src/etc/pkg/rust-logo.ico -PKG_EXE = $(PKG_DIR)-install.exe +PKG_EXE = dist/$(PKG_DIR)-install.exe endif ifeq ($(CFG_OSTYPE), apple-darwin) -PKG_OSX = $(PKG_DIR).pkg +PKG_OSX = dist/$(PKG_DIR).pkg endif PKG_GITMODULES := $(S)src/libuv $(S)src/llvm $(S)src/gyp $(S)src/compiler-rt @@ -71,14 +71,15 @@ dist-prepare-win: PREPARE_DIR_CMD=$(DEFAULT_PREPARE_DIR_CMD) dist-prepare-win: PREPARE_BIN_CMD=$(DEFAULT_PREPARE_BIN_CMD) dist-prepare-win: PREPARE_LIB_CMD=$(DEFAULT_PREPARE_LIB_CMD) dist-prepare-win: PREPARE_MAN_CMD=$(DEFAULT_PREPARE_MAN_CMD) +dist-prepare-win: PREPARE_CLEAN=true dist-prepare-win: prepare-base endif $(PKG_TAR): $(PKG_FILES) @$(call E, making dist dir) - $(Q)rm -Rf dist - $(Q)mkdir -p dist/$(PKG_DIR) + $(Q)rm -Rf tmp/dist/$(PKG_DIR) + $(Q)mkdir -p tmp/dist/$(PKG_DIR) $(Q)tar \ -C $(S) \ --exclude-vcs \ @@ -89,9 +90,9 @@ $(PKG_TAR): $(PKG_FILES) --exclude=*/llvm/test/*/*/*.ll \ --exclude=*/llvm/test/*/*/*.td \ --exclude=*/llvm/test/*/*/*.s \ - -c $(UNROOTED_PKG_FILES) | tar -x -C dist/$(PKG_DIR) - $(Q)tar -czf $(PKG_TAR) -C dist $(PKG_DIR) - $(Q)rm -Rf dist + -c $(UNROOTED_PKG_FILES) | tar -x -C tmp/dist/$(PKG_DIR) + $(Q)tar -czf $(PKG_TAR) -C tmp/dist $(PKG_DIR) + $(Q)rm -Rf tmp/dist/$(PKG_DIR) .PHONY: dist distcheck @@ -156,3 +157,35 @@ distcheck-osx: $(PKG_OSX) @echo ----------------------------------------------- endif + +dist-install-dir: $(foreach host,$(CFG_HOST),dist-install-dir-$(host)) + +dist-tar-bins: $(foreach host,$(CFG_HOST),dist/$(PKG_DIR)-$(host).tar.gz) + +define DEF_INSTALLER +dist-install-dir-$(1): PREPARE_HOST=$(1) +dist-install-dir-$(1): PREPARE_TARGETS=$(1) +dist-install-dir-$(1): PREPARE_STAGE=2 +dist-install-dir-$(1): PREPARE_DEST_DIR=tmp/dist/$$(PKG_DIR)-$(1) +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 + $$(Q)(cd $$(PREPARE_DEST_DIR)/ && find -type f) \ + > $$(PREPARE_DEST_DIR)/$$(CFG_LIBDIR_RELATIVE)/$$(CFG_RUSTLIBDIR)/manifest + $$(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)$$(PREPARE_BIN_CMD) $$(S)src/etc/install.sh $$(PREPARE_DEST_DIR) + +dist/$$(PKG_DIR)-$(1).tar.gz: dist-install-dir-$(1) + @$(call E, build: $$@) + $$(Q)tar -czf dist/$$(PKG_DIR)-$(1).tar.gz -C tmp/dist $$(PKG_DIR)-$(1) + +endef + +$(foreach host,$(CFG_HOST),\ + $(eval $(call DEF_INSTALLER,$(host)))) diff --git a/mk/prepare.mk b/mk/prepare.mk index 356ce2e908e..304806f12ad 100644 --- a/mk/prepare.mk +++ b/mk/prepare.mk @@ -33,7 +33,7 @@ prepare-base: PREPARE_SOURCE_LIB_DIR=$(PREPARE_SOURCE_DIR)/$(CFG_LIBDIR_RELATIVE prepare-base: PREPARE_SOURCE_MAN_DIR=$(S)/man prepare-base: PREPARE_DEST_BIN_DIR=$(PREPARE_DEST_DIR)/bin prepare-base: PREPARE_DEST_LIB_DIR=$(PREPARE_DEST_DIR)/$(CFG_LIBDIR_RELATIVE) -prepare-base: PREPARE_DEST_MAN_DIR=$(PREPARE_DEST_DIR)/man1 +prepare-base: PREPARE_DEST_MAN_DIR=$(PREPARE_DEST_DIR)/man/man1 prepare-base: prepare-host prepare-targets prepare-everything: prepare-host prepare-targets @@ -41,7 +41,7 @@ prepare-everything: prepare-host prepare-targets DEFAULT_PREPARE_DIR_CMD = umask 022 && mkdir -p DEFAULT_PREPARE_BIN_CMD = install -m755 DEFAULT_PREPARE_LIB_CMD = install -m644 -DEFAULT_PREPARE_MAN_CMD = install -m755 +DEFAULT_PREPARE_MAN_CMD = install -m644 # On windows we install from stage3, but on unix only stage2 # Because of the way these rules are organized, preparing from any @@ -55,14 +55,14 @@ endif # Create a directory # $(1) is the directory define PREPARE_DIR - @$(Q)$(call E, install: $(1)) + @$(Q)$(call E, prepare: $(1)) $(Q)$(PREPARE_DIR_CMD) $(1) endef # Copy an executable # $(1) is the filename/libname-glob define PREPARE_BIN - @$(call E, install: $(PREPARE_DEST_BIN_DIR)/$(1)) + @$(call E, prepare: $(PREPARE_DEST_BIN_DIR)/$(1)) $(Q)$(PREPARE_BIN_CMD) $(PREPARE_SOURCE_BIN_DIR)/$(1) $(PREPARE_DEST_BIN_DIR)/$(1) endef @@ -75,7 +75,7 @@ endef # problem. I'm sorry, just don't remove the $(nop), alright? define PREPARE_LIB $(nop) - @$(call E, install: $(PREPARE_WORKING_DEST_LIB_DIR)/$(1)) + @$(call E, prepare: $(PREPARE_WORKING_DEST_LIB_DIR)/$(1)) $(Q)LIB_NAME="$(notdir $(lastword $(wildcard $(PREPARE_WORKING_SOURCE_LIB_DIR)/$(1))))"; \ MATCHES="$(filter-out %$(notdir $(lastword $(wildcard $(PREPARE_WORKING_SOURCE_LIB_DIR)/$(1)))),\ $(wildcard $(PREPARE_WORKING_DEST_LIB_DIR)/$(1)))"; \ @@ -91,7 +91,7 @@ endef # Copy a man page # $(1) - source dir define PREPARE_MAN - @$(call E, install: $(PREPARE_DEST_MAN_DIR)/$(1)) + @$(call E, prepare: $(PREPARE_DEST_MAN_DIR)/$(1)) $(Q)$(PREPARE_MAN_CMD) $(PREPARE_SOURCE_MAN_DIR)/$(1) $(PREPARE_DEST_MAN_DIR)/$(1) endef @@ -106,7 +106,7 @@ prepare-host-tools: \ $(foreach host,$(CFG_HOST),\ prepare-host-tool-$(tool)-$(stage)-$(host)))) -prepare-host-dirs: +prepare-host-dirs: prepare-maybe-clean $(call PREPARE_DIR,$(PREPARE_DEST_BIN_DIR)) $(call PREPARE_DIR,$(PREPARE_DEST_LIB_DIR)) $(call PREPARE_DIR,$(PREPARE_DEST_MAN_DIR)) @@ -115,7 +115,8 @@ prepare-host-dirs: # $(2) is stage # $(3) is host define DEF_PREPARE_HOST_TOOL -prepare-host-tool-$(1)-$(2)-$(3): $$(foreach dep,$$(TOOL_DEPS_$(1)),prepare-host-lib-$$(dep)-$(2)-$(3)) \ +prepare-host-tool-$(1)-$(2)-$(3): prepare-maybe-clean \ + $$(foreach dep,$$(TOOL_DEPS_$(1)),prepare-host-lib-$$(dep)-$(2)-$(3)) \ $$(HBIN$(2)_H_$(3))/$(1)$$(X_$(3)) \ prepare-host-dirs $$(if $$(findstring $(2), $$(PREPARE_STAGE)),\ @@ -140,7 +141,8 @@ $(foreach tool,$(PREPARE_TOOLS),\ define DEF_PREPARE_HOST_LIB prepare-host-lib-$(1)-$(2)-$(3): PREPARE_WORKING_SOURCE_LIB_DIR=$$(PREPARE_SOURCE_LIB_DIR) prepare-host-lib-$(1)-$(2)-$(3): PREPARE_WORKING_DEST_LIB_DIR=$$(PREPARE_DEST_LIB_DIR) -prepare-host-lib-$(1)-$(2)-$(3): $$(foreach dep,$$(RUST_DEPS_$(1)),prepare-host-lib-$$(dep)-$(2)-$(3))\ +prepare-host-lib-$(1)-$(2)-$(3): prepare-maybe-clean \ + $$(foreach dep,$$(RUST_DEPS_$(1)),prepare-host-lib-$$(dep)-$(2)-$(3))\ $$(HLIB$(2)_H_$(3))/stamp.$(1) \ prepare-host-dirs $$(if $$(findstring $(2), $$(PREPARE_STAGE)),\ @@ -166,7 +168,7 @@ define DEF_PREPARE_TARGET_N # Rebind PREPARE_*_LIB_DIR to point to rustlib, then install the libs for the targets prepare-target-$(2)-host-$(3)-$(1): PREPARE_WORKING_SOURCE_LIB_DIR=$$(PREPARE_SOURCE_LIB_DIR)/$$(CFG_RUSTLIBDIR)/$(2)/lib prepare-target-$(2)-host-$(3)-$(1): PREPARE_WORKING_DEST_LIB_DIR=$$(PREPARE_DEST_LIB_DIR)/$$(CFG_RUSTLIBDIR)/$(2)/lib -prepare-target-$(2)-host-$(3)-$(1): \ +prepare-target-$(2)-host-$(3)-$(1): prepare-maybe-clean \ $$(foreach crate,$$(TARGET_CRATES), \ $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(crate)) \ $$(if $$(findstring $(2),$$(CFG_HOST)), \ @@ -194,3 +196,9 @@ $(foreach host,$(CFG_HOST),\ $(foreach target,$(CFG_TARGET), \ $(foreach stage,$(PREPARE_STAGES),\ $(eval $(call DEF_PREPARE_TARGET_N,$(stage),$(target),$(host)))))) + +prepare-maybe-clean: + $(if $(findstring true,$(PREPARE_CLEAN)),\ + @$(call E, cleaning destination $@),) + $(if $(findstring true,$(PREPARE_CLEAN)),\ + $(Q)rm -rf $(PREPARE_DEST_DIR),) diff --git a/src/etc/install.sh b/src/etc/install.sh new file mode 100644 index 00000000000..9e718a61d88 --- /dev/null +++ b/src/etc/install.sh @@ -0,0 +1,283 @@ +#!/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 +} + +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 + printf "%-20s := %s\n" $1 "$T" >>config.tmp +} + +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 +} + +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 + +OPTIONS="" +BOOL_OPTIONS="" +VAL_OPTIONS="" + +flag uninstall "only uninstall from the installation prefix" +valopt prefix "/usr/local" "set installation prefix" + +if [ $HELP -eq 1 ] +then + echo + exit 0 +fi + +step_msg "validating $CFG_SELF args" +validate_opt + +# Sanity check: can we can write to the destination? +touch "${CFG_PREFIX}/lib/rust-install-probe" 2> /dev/null +if [ $? -ne 0 ] +then + err "can't write to destination. try again with 'sudo'." +fi +rm -r "${CFG_PREFIX}/lib/rust-install-probe" +need_ok "failed to remove install probe" + +# Sanity check: can we run these binaries? +"${CFG_SRC_DIR}/bin/rustc" --version > /dev/null +need_ok "can't run these binaries on this platform" + +# First, uninstall from the installation prefix +# FIXME: Hardcoded 'rustlib' ignores CFG_RUSTLIBDIR +if [ -f "${CFG_PREFIX}/lib/rustlib/manifest" ] +then + while read p; do + msg "uninstall ${CFG_PREFIX}/$p" + rm "${CFG_PREFIX}/$p" + need_ok "failed to remove file" + done < "${CFG_PREFIX}/lib/rustlib/manifest" + + # Remove 'rustlib' directory + msg "uninstall ${CFG_PREFIX}/lib/rustlib" + rm -r "${CFG_PREFIX}/lib/rustlib" + need_ok "failed to remove rustlib" +fi + +# If we're only uninstalling then exit +if [ -n "${CFG_UNINSTALL}" ] +then + exit 0 +fi + +# Iterate through the new manifest and install files +while read p; do + + umask 022 && mkdir -p "${CFG_PREFIX}/$(dirname $p)" + need_ok "directory creation failed" + + msg "${CFG_PREFIX}/$p" + if echo "$p" | grep "/bin/" > /dev/null + then + install -m755 "${CFG_SRC_DIR}/$p" "${CFG_PREFIX}/$p" + else + install -m644 "${CFG_SRC_DIR}/$p" "${CFG_PREFIX}/$p" + fi + need_ok "file creation failed" + +# The manifest lists all files to install +done < "${CFG_SRC_DIR}/lib/rustlib/manifest" + +echo +echo " Rust is ready to roll." +echo + +