cargo 0.6.1

Cargo, a package manager for Rust.
#!/bin/sh

msg() {
    echo "configure: $1"
}

step_msg() {
    msg
    msg "$1"
    msg
}

warn() {
    echo "configure: WARNING: $1"
}

err() {
    echo "configure: 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
}

make_dir() {
    if [ ! -d $1 ]
    then
        msg "mkdir -p $1"
        mkdir -p $1
    fi
}

copy_if_changed() {
    if cmp -s $1 $2
    then
        msg "leaving $2 unchanged"
    else
        msg "cp $1 $2"
        cp -f $1 $2
        chmod u-w $2 # make copied artifact read-only
    fi
}

move_if_changed() {
    if cmp -s $1 $2
    then
        msg "leaving $2 unchanged"
    else
        msg "mv $1 $2"
        mv -f $1 $2
        chmod u-w $2 # make moved artifact read-only
    fi
}

putvar() {
    local T
    eval T=\$$1
    eval TLEN=\${#$1}
    if [ $TLEN -gt 35 ]
    then
        printf "configure: %-20s := %.35s ...\n" $1 "$T"
    else
        printf "configure: %-20s := %s %s\n" $1 "$T" "$2"
    fi
    printf "%-20s := %s\n" $1 "$T" >>config.tmp
}

probe() {
    local V=$1
    shift
    local P
    local T
    for P
    do
        T=$(command -v $P 2>&1)
        if [ $? -eq 0 ]
        then
            VER0=$($P --version 2>/dev/null | head -1 \
                |  sed -e 's/[^0-9]*\([vV]\?[0-9.]\+[^ ]*\).*/\1/' )
            if [ $? -eq 0 -a "x${VER0}" != "x" ]
            then
              VER="($VER0)"
            else
              VER=""
            fi
            break
        else
            VER=""
            T=""
        fi
    done
    eval $V=\$T
    putvar $V "$VER"
}

probe_need() {
    local V=$1
    probe $*
    eval VV=\$$V
    if [ -z "$VV" ]
    then
        err "needed, but unable to find any of: $*"
    fi
}

validate_opt () {
    for arg in $CFG_CONFIGURE_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
        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
}

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_CONFIGURE_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_CONFIGURE_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
}

envopt() {
    local NAME=$1
    local V="CFG_${NAME}"
    eval VV=\$$V

    # If configure didn't set a value already, then check environment.
    #
    # (It is recommended that the configure script always check the
    # environment before setting any values to envopt variables; see
    # e.g.  how CFG_CC is handled, where it first checks `-z "$CC"`,
    # and issues msg if it ends up employing that provided value.)
    if [ -z "$VV" ]
    then
        eval $V=\$$NAME
        eval VV=\$$V
    fi

    # If script or environment provided a value, save it.
    if [ ! -z "$VV" ]
    then
        putvar $V
    fi
}

msg "looking for configure programs"
need_cmd cmp
need_cmd mkdir
need_cmd printf
need_cmd cut
need_cmd head
need_cmd grep
need_cmd xargs
need_cmd cp
need_cmd find
need_cmd uname
need_cmd date
need_cmd tr
need_cmd sed
need_cmd cmake
if [ "${OS}" != "Windows_NT" ]; then
    need_cmd curl
fi

CFG_SRC_DIR="$(cd $(dirname $0) && pwd)/"
CFG_BUILD_DIR="$(pwd)/"
CFG_SELF="$0"
CFG_CONFIGURE_ARGS="$@"

OPTIONS=""
HELP=0
if [ "$1" = "--help" ]
then
    HELP=1
    shift
    echo
    echo "Usage: $CFG_SELF [options]"
    echo
    echo "Options:"
    echo
else
    msg "recreating config.tmp"
    echo '' >config.tmp

    step_msg "processing $CFG_SELF args"
fi

BOOL_OPTIONS=""
VAL_OPTIONS=""

opt debug 1 "build with extra debug fun"
opt optimize 1 "build with optimizations"
opt nightly 0 "build nightly packages"
opt verify-install 1 "verify installed binaries work"
opt cross-tests 1 "run cross-compilation tests"
valopt prefix "/usr/local" "set installation prefix"
valopt local-rust-root "" "set prefix for local rust binary"

if [ $HELP -eq 0 ]; then
    if [ ! -z "${CFG_LOCAL_RUST_ROOT}" ]; then
        export LD_LIBRARY_PATH="${CFG_LOCAL_RUST_ROOT}/lib:$LD_LIBRARY_PATH"
        export DYLD_LIBRARY_PATH="${CFG_LOCAL_RUST_ROOT}/lib:$DYLD_LIBRARY_PATH"
        LRV=`${CFG_LOCAL_RUST_ROOT}/bin/rustc --version`
        if [ $? -eq 0 ]; then
            step_msg "using rustc at: ${CFG_LOCAL_RUST_ROOT} with version: $LRV"
        else
            err "failed to run rustc at: ${CFG_LOCAL_RUST_ROOT}"
        fi
        CFG_RUSTC="${CFG_LOCAL_RUST_ROOT}/bin/rustc"
    else
        probe_need CFG_RUSTC        rustc
    fi
    DEFAULT_BUILD=$("${CFG_RUSTC}" -vV | grep 'host: ' | sed 's/host: //')
fi

valopt build "${DEFAULT_BUILD}" "GNUs ./configure syntax LLVM build triple"
valopt host "${CFG_BUILD}" "GNUs ./configure syntax LLVM host triples"
valopt target "${CFG_HOST}" "GNUs ./configure syntax LLVM target triples"

valopt localstatedir "/var/lib" "local state directory"
valopt sysconfdir "/etc" "install system configuration files"
valopt datadir "${CFG_PREFIX}/share" "install data"
valopt infodir "${CFG_PREFIX}/share/info" "install additional info"
valopt mandir "${CFG_PREFIX}/share/man" "install man pages in PATH"
valopt libdir "${CFG_PREFIX}/lib" "install libraries"
valopt local-cargo "" "local cargo to bootstrap from"

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"

probe_need CFG_CURLORWGET  curl wget
probe_need CFG_PYTHON      python
probe_need CFG_CC          cc gcc clang

if [ ! -z "${CFG_LOCAL_RUST_ROOT}" ]; then
    CFG_RUSTDOC="${CFG_LOCAL_RUST_ROOT}/bin/rustdoc"
else
    probe_need CFG_RUSTDOC        rustdoc
fi

# a little post-processing of various config values
CFG_PREFIX=${CFG_PREFIX%/}
CFG_MANDIR=${CFG_MANDIR%/}
CFG_HOST="$(echo $CFG_HOST | tr ',' ' ')"
CFG_TARGET="$(echo $CFG_TARGET | tr ',' ' ')"

# copy host-triples to target-triples so that hosts are a subset of targets
V_TEMP=""
for i in $CFG_HOST $CFG_TARGET;
do
   echo "$V_TEMP" | grep -qF $i || V_TEMP="$V_TEMP${V_TEMP:+ }$i"
done
CFG_TARGET=$V_TEMP

if [ "$CFG_SRC_DIR" != "$CFG_BUILD_DIR" ]; then
    err "cargo does not currently support an out-of-tree build dir"
fi

if [ ! -z "$CFG_ENABLE_NIGHTLY" ]; then
    if [ ! -f .cargo/config ]; then
        mkdir -p .cargo
        cat > .cargo/config <<-EOF
[target.x86_64-unknown-linux-gnu.openssl]
rustc-flags = "-l static=ssl -l static=crypto -l dl -L /home/rustbuild/root64/lib"
root = "/home/rustbuild/root64"
include = "/home/rustbuild/root64/include"

[target.i686-unknown-linux-gnu.openssl]
rustc-flags = "-l static=ssl -l static=crypto -l dl -L /home/rustbuild/root32/lib"
root = "/home/rustbuild/root32"
include = "/home/rustbuild/root32/include"
EOF
    fi
fi

step_msg "writing configuration"

putvar CFG_SRC_DIR
putvar CFG_BUILD_DIR
putvar CFG_CONFIGURE_ARGS
putvar CFG_PREFIX
putvar CFG_BUILD
putvar CFG_HOST
putvar CFG_TARGET
putvar CFG_LIBDIR
putvar CFG_MANDIR
putvar CFG_RUSTC
putvar CFG_RUSTDOC

msg
copy_if_changed ${CFG_SRC_DIR}Makefile.in ./Makefile
move_if_changed config.tmp config.mk
rm -f config.tmp
touch config.stamp

step_msg "complete"
msg