# Initalization # prefixes="prefix exec-prefix" dirs="bin sbin libexec data sysconf sharedstate localstatedir \ lib include info man" with_options="" feature_options="" # saved shell / Makefile config save_make="" # saved to a config.h save_h="" # Append to a variable. # var_append var seperator content # var_append() { eval "[ \"\$$1\" ] && $1=\"\${$1}$2\"" || true eval "$1=\"\${$1}\$3\"" } # Prepend to a variable. # var_insert var seperator content # var_insert() { eval "[ \"\$$1\" ] && $1=\"$2\$$1\"" || true eval "$1=\"\$3\$$1\"" } # Remove from a variable. # var_remove var seperator content # var_remove() { local a=${2//\/\\/} local b=${3//\/\\/} eval '[ "$'$1'" = "$3" ] && '$1'="" || true' eval $1'="${'$1'//$a$b$a/$2}"' eval $1'="${'$1'%$a$b}"' eval $1'="${'$1'#$b$a}"' } # Test for a key in a give "array". # in_list key values # in_list () { search=$1 ; shift while [ "$1" ] ; do [ "$1" = "$search" ] && return 0 shift done return 1 } # Uppercase given argument. # uppercase text # uppercase () { echo $1 | tr '\-a-z' _A-Z } # Remove dashes ('-') from a given argument. # undash text # undash () { echo $1 | tr '\-' _ } # Compare version with a given comperator. # check_version [ atleast, equals ] expected-version current-version # check_version () { m="$1" shouldbe="`echo "$2" | sed 's/[._-]/ /g'`" is="`echo "$3" | sed 's/[. -]/ /g'`" # better ideas welcome -ReneR set -- $shouldbe case $m in atleast) for x in $is ; do if [ "$1" -a "$x" ]; then [ $x -lt $1 ] && return 1 [ $x -gt $1 ] && return 0 fi shift done ;; equals) for x in $is ; do [ "$1" = "$x" ] || return 1 shift done ;; *) status "mode $m invalid" return 1 esac return 0 } # Generate and print a generic usage text. # usage () { cat <<- EOT 'configure' configures checks the system and adapts the package to many kinds of systems. This is a rewritten 'configure' system created by ExactCODE. It differs significantly from the typical GNU/Autoconf!g (C) 2004 - 2006 Rene Rebe - License: GPL Usage: ./configure [OPTION]... Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit -V, --version display version information and exit Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data [PREFIX/share] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --infodir=DIR info documentation [PREFIX/info] --mandir=DIR man documentation [PREFIX/man] Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] EOT for x in $feature_options ; do echo " --enable-$x" done cat <<- EOT Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) EOT for x in $with_options ; do echo " --with-$x" done if [ "$feature_options" -o "$with_options" ] ; then if [ -f ./README -o -f ./INSTALL ] ; then cat <<- EOT Please refer to a supplied README or INSTALL file for a detailed explanation of the various custom options. EOT else cat <<- EOT Please refer to the package documentation for a detailed exmplanation of the various custom options. EOT fi fi } # Initialize some internal stage. # init () { [ "$VERSION" ] || VERSION="$VERSION_MAJOR.$VERSION_MINOR.$VERSION_MICRO" [ "$DATE" ] || DATE="`date "+%a, %d %b %Y"`" prefix="/usr/local" exec_prefix="\${prefix}" bindir="\${exec_prefix}/bin" sbindir="\${exec_prefix}/sbin" libdir="\${exec_prefix}/lib" libexecdir="\${exec_prefix}/lib" datadir="\${prefix}/share" sysconfdir="\${prefix}/etc" sharedstatedir="\${prefix}/com" localstatedirdir="\${prefix}/var" includedir="\${prefix}/include" infodir="\${prefix}/info" mandir="\${prefix}/man" save_make="prefix exec_prefix PACKAGE VERSION VERSION_MAJOR VERSION_MINOR \ VERSION_MICRO DATE" save_h="PACKAGE VERSION VERSION_MAJOR VERSION_MINOR \ VERSION_MICRO DATE" # set to be saved options and features for x in $dirs ; do var_append save_make " " "${x}dir" done for x in $with_options ; do var_append save_make " " "WITH$(uppercase $x)" var_append save_h " " "WITH$(uppercase $x)" done for x in $feature_options ; do var_append save_make " " "$(uppercase $x)" var_append save_h " " "$(uppercase $x)" done } # Save the state to a config.make and/or config.h. # save () { # initilize the config files echo -n "" > config.log echo -n "" > config.make echo -n "" > config.h for x in $save_make ; do eval echo "$x = \$$x | sed -e 's/{/(/g' -e 's/}/)/g' " >> config.make done for x in $save_h ; do # decide whether to quote the value if [ "`eval echo \\$$x | sed s/[0-9]*//g`" = "" ] ; then eval echo "\#define $x \$$x" >> config.h else eval echo "\#define $x \\\"\$$x\\\"" >> config.h fi done } # Parse the the specified command line switches. # parse_options () { errors=0 while [ "$1" ] ; do case "$1" in --without-*) pkg=${1/--without-} if in_list $pkg $with_options ; then eval WITH$(uppercase $pkg)=0 else echo "'$pkg' is not available!" : $(( ++errors )) fi ;; --with-*) pkg=${1/--with-} [[ $pkg = *=* ]] && value=${pkg/*=/} || value=1 pkg=${pkg/=*/} if in_list $pkg $with_options ; then [ "$value" = "no" ] && value=0 eval WITH$(uppercase $pkg)=$value else echo "'$pkg' is not available!" : $(( ++errors )) fi ;; --enable-*) feature=${1/--enable-} if in_list $feature $feature_options ; then eval $(uppercase $feature)=1 else echo "'$feature' is not available!" : $(( ++errors )) fi ;; --disable-*) feature=${1/--disable-} if in_list $feature $feature_options ; then eval $(uppercase $feature)=0 else echo "'$feature' is not available!" : $(( ++errors )) fi ;; --*prefix=*) prefix=${1/--} value=${prefix/*=/} prefix=${prefix/=*/} if in_list $prefix $prefixes ; then eval $(undash $prefix)="$value" else echo "'$prefix' is not a valid prefix specification!" : $(( ++errors )) fi ;; --*dir=*) dir=${1/--} value=${dir/*=/} xdir=${dir/dir=*/} dir=${dir/=*/} if in_list ${xdir} $dirs ; then eval $(undash $dir)="$value" else echo "'$dir' is not a valid directory specification!" : $(( ++errors )) fi ;; --help) usage exit 0 ;; *) echo "Unable to parse $1 ..." : $(( ++errors )) ;; esac shift done if [ $errors -gt 0 ] ; then echo "Errors while parsing arguements, exitting now!" usage exit $errors fi } # Print a status (to screen and log). # status () { echo -n "$*" | tee -a config.log } # Print a final status result (to screen and log). # status_result () { echo "$*" | tee -a config.log } # Print a fatal error (to screen and log) and exit. # status_error () { status_result "$*" exit 1 } # Run a predefined test stored in config/test-$test. # runtest () { local file="./config/test-$1" if [ ! -f $file ] ; then status_result "test $1 not found!" else desc="`grep -a DESC= $file | sed 's/.*DESC="\(.*\)".*/\1/'`" status "$desc ... " if sh -e $file >/dev/null 2>> config.log ; then status_result "yes" eval $2=1 else status_result "no" eval $2=0 fi fi } # Compile a test stored in config/$prog-$test. # compile program test # compile () { local errors=0 local PROG="$1" ; shift while [ "$1" ] ; do local file="config/$PROG-$1" if [ ! -f $file ] ; then status_result "test $1 not found!" : $(( ++errors )) else desc="`grep -a DESC= $file | sed 's/.*DESC="\(.*\)".*/\1/'`" cflags="`grep -a CFLAGS= $file | sed 's/.* CFLAGS="\(.*\)".*/\1/'`" libs="`grep -a LIBS= $file | sed 's/.* LIBS="\(.*\)".*/\1/'`" status "$desc ... " if $PROG -c $cflags $libs $file -o config.tmp \ >/dev/null 2>> config.log ; then status_result "yes" else status_result "no" : $(( ++errors )) fi fi shift done return $errors } # Check for a given system header. # headercheck program header # headercheck () { local errors=0 local PROG="$1" ; shift while [ "$1" ] ; do echo "#include <$1>" > conftest.c status "checking for header "$1" ... " if $PROG -E conftest.c >/dev/null 2>> config.log ; then status_result "found" else status_result "not found" : $(( ++errors )) fi shift done return $errors } # Check whether the specifid package is installed. # pkgcheck pkg pkg 'mode' PKG-WITH-VAR [ 'mode' flags ] [ atleast, ... ] [ version ] # e.g: pkgcheck pkg -config PKG atleast 0.9.9 # pkgcheck () { local pkg="$1" ; shift local mode="$1" ; shift local FLAGSVAR="$1" ; shift if [ $mode = lib -o $mode = header ]; then local prg="$1"; shift local args="$*"; shift $# elif [ $mode = shell ]; then local script="$1"; shift fi [ "$1" ] && local vermode="$1" ; shift [ "$1" ] && local version="$1" ; shift local found=0 local ver="" local incs="" local libs="" status "checking for package $pkg " [ "$version" ] && status "($vermode $version)" status " ... " withvar="WITH$FLAGSVAR" if [ "`eval echo \\$$withvar`" = "0" ] ; then status_result "disabled" return 1 fi case "$mode" in compile) local file="config/pkgcheck-$pkg.c" if [ ! -e $file ] ; then status_result "test not found!" else cc="`grep -a CC= $file | sed 's/.*CC="\(.*\)".*/\1/'`" incs="`grep -a CFLAGS= $file | sed 's/.* CFLAGS="\(.*\)".*/\1/'`" libs="`grep -a LIBS= $file | sed 's/.* LIBS="\(.*\)".*/\1/'`" if $cc $incs $libs $file -o conftest.o \ >>config.log 2>> config.log ; then found=1 ver="`./conftest.o 2>>config.log`" fi fi ;; -config) ver="`$pkg-config --version 2>/dev/null`" if [ $? = 0 -a "$ver" != "" ] ; then incs="`$pkg-config --cflags`" libs="`$pkg-config --libs`" found=1 fi ;; pkg-config) ver="`pkg-config $pkg --modversion 2>/dev/null`" if [ $? = 0 -a "$ver" != "" ] ; then incs="`pkg-config $pkg --cflags`" libs="`pkg-config $pkg --libs`" found=1 fi ;; lib) echo "int main () { return 0; }" > conftest.c if $prg $args conftest.c -o conftest.o 2> /dev/null ; then found=1 libs="$arg" # TODO: is this perfect? fi ;; header) echo "" > conftest.c for h in $args; do echo "#include <$h>" >> conftest.c ; done echo "int main () { return 0; }" >> conftest.c if $prg conftest.c -o conftest.o 2> /dev/null ; then found=1 fi ;; shell) ver="`eval $script`" if [ "$ver" ]; then found=1 fi ;; *) status_error "mode $mode unknown!" esac # version check if [ $found = 1 ]; then if [ "$version" ] ; then if check_version "$vermode" "$version" "$ver" ; then status_result "yes ($ver)" else status_result "no ($ver)" found=0 fi else status_result "yes" fi else status_result "no" fi # set WITH var (if it was not set -> optional package) [ "`eval echo \\$$withvar`" = "" ] && eval $withvar=$found [ $found = 0 ] && return 1 # fill variables var_append ${FLAGSVAR}INCS " " "$incs" var_append ${FLAGSVAR}LIBS " " "$libs" var_append save_make " " "${FLAGSVAR}INCS ${FLAGSVAR}LIBS" return 0 }