#!/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="" 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 file need_cmd cmake need_cmd pkg-config need_cmd curl 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 0 "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