rust/configure
Brian Anderson 2573fe7026 The Big Test Suite Overhaul
This replaces the make-based test runner with a set of Rust-based test
runners. I believe that all existing functionality has been
preserved. The primary objective is to dogfood the Rust test
framework.

A few main things happen here:

1) The run-pass/lib-* tests are all moved into src/test/stdtest. This
is a standalone test crate intended for all standard library tests. It
compiles to build/test/stdtest.stageN.

2) rustc now compiles into yet another build artifact, this one a test
runner that runs any tests contained directly in the rustc crate. This
allows much more fine-grained unit testing of the compiler. It
compiles to build/test/rustctest.stageN.

3) There is a new custom test runner crate at src/test/compiletest
that reproduces all the functionality for running the compile-fail,
run-fail, run-pass and bench tests while integrating with Rust's test
framework. It compiles to build/test/compiletest.stageN.

4) The build rules have been completely changed to use the new test
runners, while also being less redundant, following the example of the
recent stageN.mk rewrite.

It adds two new features to the cfail/rfail/rpass/bench tests:

1) Tests can specify multiple 'error-pattern' directives which must be
satisfied in order.

2) Tests can specify a 'compile-flags' directive which will make the
test runner provide additional command line arguments to rustc.

There are some downsides, the primary being that Rust has to be
functioning pretty well just to run _any_ tests, which I imagine will
be the source of some frustration when the entire test suite
breaks. Will also cause some headaches during porting.

Not having individual make rules, each rpass, etc test no longer
remembers between runs whether it completed successfully. As a result,
it's not possible to incrementally fix multiple tests by just running
'make check', fixing a test, and repeating without re-running all the
tests contained in the test runner. Instead you can filter just the
tests you want to run by using the TESTNAME environment variable.

This also dispenses with the ability to run stage0 tests, but they
tended to be broken more often than not anyway.
2011-07-24 15:34:34 -07:00

314 lines
6.6 KiB
Bash
Executable File

#!/bin/sh
msg() {
echo "configure: $1"
}
step_msg() {
msg
msg "$1"
msg
}
err() {
echo "configure: error: $1"
exit 1
}
need_cmd() {
if which $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() {
msg "cp $1 $2"
cp $1 $2
}
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\n" $1 "$T"
fi
printf "%-20s := %s\n" $1 "$T" >>config.mk
}
probe() {
local V=$1
local P=$2
local T
T=$(which $P 2>&1)
if [ $? -ne 0 ]
then
T=""
fi
eval $V=\$T
putvar $V
}
probe_need() {
local V=$1
local P=$2
probe $V $P
eval VV=\$$V
if [ -z "$VV" ]
then
err "required program '$P' not found"
fi
}
opt() {
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
}
msg "looking for configure programs"
need_cmd mkdir
need_cmd printf
need_cmd cut
need_cmd grep
need_cmd xargs
need_cmd cp
need_cmd find
need_cmd uname
need_cmd date
need_cmd tr
need_cmd sed
msg "inspecting environment"
CFG_OSTYPE=$(uname -s)
CFG_CPUTYPE=$(uname -m)
if [ $CFG_OSTYPE = Darwin -a $CFG_CPUTYPE = i386 ]
then
# Darwin's `uname -s` lies and always returns i386. We have to use sysctl
# instead.
if sysctl hw.optional.x86_64 | grep ': 1'
then
CFG_CPUTYPE=x86_64
fi
fi
CFG_SELF=$(echo $0 | tr '\\' '/')
CFG_SRC_DIR=${CFG_SELF%${CFG_SELF##*/}}
CFG_BUILD_DIR=$(echo $PWD | tr '\\' '/')
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.mk"
echo '' >config.mk
step_msg "processing $CFG_SELF args"
fi
opt sharedstd 1 "build libstd as a shared library"
opt valgrind 1 "run tests with valgrind"
opt docs 1 "build documentation"
opt optimize 1 "build optimized rust code"
opt mingw-cross 0 "cross-compile for win32 using mingw"
if [ $HELP -eq 1 ]
then
echo ""
exit 0
fi
step_msg "making directories"
for i in \
doc \
rt rt/isaac rt/bigint rt/sync rt/test rt/arch/i386 \
rustllvm \
dl stage0 stage1 stage2 stage3 \
stage0/lib stage1/lib stage2/lib stage3/lib \
test/run-pass test/run-fail test/compile-fail test/bench
do
make_dir $i
done
step_msg "writing out basic parameters"
putvar CFG_SRC_DIR
putvar CFG_BUILD_DIR
putvar CFG_OSTYPE
putvar CFG_CPUTYPE
putvar CFG_CONFIGURE_ARGS
step_msg "looking for build programs"
probe_need CFG_PERL perl
probe_need CFG_PYTHON python
probe_need CFG_CURL curl
probe CFG_GIT git
probe CFG_CLANG clang++
probe CFG_GCC gcc
probe CFG_LLVM_CONFIG llvm-config
probe CFG_VALGRIND valgrind
probe CFG_MAKEINFO makeinfo
probe CFG_TEXI2PDF texi2pdf
probe CFG_TEX tex
probe CFG_MAKENSIS makensis
if [ -z "$CFG_CLANG" -a -z "$CFG_GCC" ]
then
err "either clang or gcc is required"
fi
if head -n 1 ${CFG_SRC_DIR}src/snapshots.txt | grep -q '^T'
then
CFG_IN_TRANSITION=1
putvar CFG_IN_TRANSITION
fi
# Valgrind is only reliable on Linux. On Windows it doesn't work at all, and
# on the Mac the dynamic linker causes Valgrind to emit a huge stream of
# errors.
if [ $CFG_OSTYPE != Linux ] && [ $CFG_OSTYPE != Darwin ]
then
CFG_BAD_VALGRIND=1
putvar CFG_BAD_VALGRIND
fi
if [ ! -z "$CFG_LLVM_ROOT" -a -e "$CFG_LLVM_ROOT/bin/llvm-config" ]
then
CFG_LLVM_CONFIG="$CFG_LLVM_ROOT/bin/llvm-config"
fi
if [ ! -z "$CFG_LLVM_ROOT" -a -z "$CFG_LLVM_CONFIG" ]
then
CFG_LLVM_INCDIR="$CFG_LLVM_ROOT/include"
CFG_LLVM_BINDIR="$CFG_LLVM_ROOT/bin"
CFG_LLVM_LIBDIR="$CFG_LLVM_ROOT/lib"
CFG_LLVM_CXXFLAGS="-I$CFG_LLVM_INCDIR"
CFG_LLVM_LDFLAGS=""
CFG_LLVM_LIBS=$(find "$CFG_LLVM_LIBDIR" \
-name '*.lib' \
-exec echo '\"{}\"' ';' \
| xargs echo)
CFG_LLVM_VERSION=$("$CFG_LLVM_BINDIR/llc" \
--version \
| grep version \
| cut -d ' ' -f 5-)
CFG_LLVM_TRIPLE=$("$CFG_LLVM_BINDIR/llc" \
--version \
| grep Host: \
| cut -d ' ' -f 4-)
elif [ ! -z "$CFG_LLVM_CONFIG" ]
then
CFG_LLVM_VERSION=$($CFG_LLVM_CONFIG --version)
CFG_LLVM_INCDIR=$($CFG_LLVM_CONFIG --includedir)
CFG_LLVM_BINDIR=$($CFG_LLVM_CONFIG --bindir)
CFG_LLVM_LIBDIR=$($CFG_LLVM_CONFIG --libdir)
CFG_LLVM_CXXFLAGS=$($CFG_LLVM_CONFIG --cxxflags)
CFG_LLVM_LDFLAGS=$($CFG_LLVM_CONFIG --ldflags)
CFG_LLVM_LIBS=$($CFG_LLVM_CONFIG --libs)
CFG_LLVM_TRIPLE=$($CFG_LLVM_CONFIG --host-target)
else
err "either the \"CFG_LLVM_ROOT\" environment variable must be set, or a \
\"llvm-config\" script must be present"
fi
case $CFG_LLVM_VERSION in
(3.0svn | 3.0)
step_msg "found ok version of LLVM: $CFG_LLVM_VERSION"
;;
(*)
err "bad LLVM version: $CFG_LLVM_VERSION, need >=3.0svn"
;;
esac
if [ ! -z "$CFG_CLANG" ]
then
CFG_CLANG_VERSION=$("$CFG_CLANG" \
--version \
| grep version \
| cut -d ' ' -f 3)
case $CFG_CLANG_VERSION in
(3.0svn | 3.0)
step_msg "found ok version of CLANG: $CFG_CLANG_VERSION"
;;
(*)
err "bad CLANG version: $CFG_CLANG_VERSION, need >=3.0svn"
;;
esac
fi
putvar CFG_LLVM_ROOT
putvar CFG_LLVM_INCDIR
putvar CFG_LLVM_BINDIR
putvar CFG_LLVM_LIBDIR
putvar CFG_LLVM_CXXFLAGS
putvar CFG_LLVM_LDFLAGS
putvar CFG_LLVM_LIBS
putvar CFG_LLVM_TRIPLE
# Munge any paths that appear in config.mk back to posix-y
perl -i.bak -p -e 's@ ([a-zA-Z]):[/\\]@ /\1/@go;' \
-e 's@\\@/@go;' config.mk
rm -f config.mk.bak
copy ${CFG_SRC_DIR}Makefile.in ./Makefile
step_msg "complete"