#!/bin/sh # # Copyright 2009-2014 # Kaz Kylheku <kaz@kylheku.com> # Vancouver, Canada # All rights reserved. # # BSD License: # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # 3. The name of the author may not be used to endorse or promote # products derived from this software without specific prior # written permission. # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR # IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. # # Save command line in a way that can be re-run. # This takes care of spaces, but if there are shell-meta characters # in the arguments, oops. # if test x$txr_shell = x ; then for shell in /usr/xpg4/bin/sh /bin/bash /usr/bin/bash ; do if test -x $shell ; then txr_shell=$shell break fi done if test x$txr_shell = x ; then echo "No known POSIX shell found: falling back on /bin/sh, which may not work" txr_shell=/bin/sh fi export txr_shell exec $txr_shell $0 ${@+"$@"} fi set -u cmdline= for arg in "$0" ${@+"$@"} ; do [ -n "$cmdline" ] && cmdline="$cmdline " case $arg in *" "* | " "* | *" " ) cmdline=$cmdline$(printf "\"%s\"" "$arg") ;; * ) cmdline=$cmdline$arg ;; esac done # # Establish default values for any variables that are not specified # on the command line. The default derivations from prefix are in # Make syntax. They go verbatim into the generated config.make. # This way they can be overridden more flexibly at make time. # # # non-config # help= # # config # prefix='/usr/local' install_prefix= bindir='bin' datadir='share/txr' mandir='share/man' make= cross= compiler_prefix= ccname=gcc cc='$(cross)$(compiler_prefix)$(ccname)' intptr= exe= tool_prefix= lex='$(cross)$(tool_prefix)flex' lexlib=-lfl yaccname_given= yaccname= yacc='$(cross)$(tool_prefix)$(yaccname)' yacc_given= nm='$(cross)$(tool_prefix)nm' opt_flags=-O2 lang_flags='-ansi -D_XOPEN_SOURCE=600' diag_flags='-Wall -Werror=implicit-function-declaration -Werror=missing-prototypes -Werror=strict-prototypes' debug_flags=-g inline= platform_flags= remove_flags= lex_dbg_flags= txr_dbg_opts=--gc-debug valgrind= lit_align= extra_debugging= debug_support=y gen_gc=y mpi_version=1.8.6 have_quilt= have_patch= have_unistd= have_timegm= have_syslog= have_windows_h= have_posix_sigs= need_darwin_c_source= # # Parse configuration variables # while [ $# -gt 0 ] ; do case $1 in --no-* | --no_* ) var=${1#--no?} val= ;; --*=* ) var=${1%%=*} var=${var#--} val=${1#*=} ;; --*= ) var=${1%%=*} var=${var#--} val= ;; --* ) var=${1#--} val=y ;; *=* ) var=${1%%=*} val=${1#*=} ;; *= ) var=${1%%=*} val= ;; * ) printf "$0: '$1' doesn't look like a configuration variable assignment\n" printf "$0: use --help to get help\n" exit 1 esac var=$(echo "$var" | tr - _) if ! echo $var | grep -q -E '^[A-Za-z_][A-Za-z0-9_]*$' ; then printf "$0: '$var' isn't a proper configuration variable name\n" exit 1 fi eval "var_exists=\${$var+y}" if [ "$var_exists" != y ] ; then printf "$0: nonexistent option: '%s'\n" "$1" exit 1 fi eval "$var='$val'" eval "var_given_exists=\${${var}_given+y}" if [ "$var_given_exists" = y ] ; then eval "${var}_given=y" fi shift done # # If --help was given (or --help=<nonempty> or help=<nonempty>) then # print help and exit. The termination status is failed, to indicate # that configuration was not done. # if [ -n "$help" ] ; then cat <<! usage: $0 { variable=value }* The configure script prepares txr program for compilation and installation. To configure a program means to establish the values of make variables which influence how the software is built, where it is installed. These variables can also influence what features are present in the software, and can determine various defaults for those behaviors which are dynamically configurable when the software is run. Configuration variables are recorded in a file called config.make. This is a GNU makefile, and consequently uses the GNU make syntax. It is included in the main Makefile by an include statement. The configure script is flexible. It allows variables to be entered in any of these forms: Canonical: variable=value Defines the given variable as having the given value. variable= Defines the variable as having an empty value. An empty value serves as boolean false. Long-option style: --variable=value Same as 'variable=value', but resembles a GNU-style long option. --variable Same as 'variable=y'. --no-variable Same as 'variable='. No variables are required. The configure script establishes default values for any variables which are needed by the build, but which are not specified on the command line. After running $0, check that the config.make contents are sane. The following variables are supported. Note that make variable syntax may be used in paths. Default values are shown in [square brackets]. Variables are case-sensitive, but underscores and dashes are interchangeable. prefix [$prefix] Specifies root directory where the software will ultimately be installed and run from. install-prefix [$install_prefix] Specifies an extra path prefix that will be prepended to all paths during installation, which allows the software to be installed in a temporary directory for packaging. This variable becomes the \$(DESTDIR) variable in the config.make makefile. bindir [$bindir] Specifies where the program executable will be installed, as a relative path from the prefix. datadir [$datadir] Specifies where read-only program data is to be stored, as a relative path from the prefix. mandir [$mandir] Specifies the directory where to install man pages, as a relative path from the prefix. cross [$cross] Specifies the root of a cross-compiling toolchain. This becomes the \$(cross) variable in the config.make makefile, and by default will be added as a prefix to all of the toolchain commands. It should include the trailing slash, unless the \$compiler_prefix and \$tool_prefix variables take care of this by providing a leading slash. compiler-prefix [$compiler_prefix] Specifies a prefix to be added to the compiler command. This is added to the \$(cross) prefix. This can include some path name components, and a name fragment. For instance, if \$cross is "/cross/toolchain/" and \$compiler_prefix is "bin/mips-linux-" then the compiler command, unless otherwise specified, will be "/cross/toolchain/bin/mips-linux-gcc". ccname [$ccname] Specifies just the name of the compiler front-end program, without the path. The following variable, cc, specifies the full name. cc [$cc] Specifies the name of the toolchain front-end driver command to use for compiling C sources to object files, and for linking object files to executables. This becomes the CC variable in config.make. intptr [$intptr] Specifies the name of the C integer type wide enough such that a pointer value can be converted to it. If this is blank, the configure script will try to auto detect it. lit-align [$lit_align] Specifies alignment for wide string literals. This is guessed from the size of the wchar_t type. If your wchar_t type is two byte wide, but wide literals are aligned to four bytes, then you should specify this. This will eliminate some kludges in the program. There is no easy way to check for this withut generating and running a C program, which is unfriendly for cross-compiling! inline [$inline] Specifies the syntax for defining an inline function, in such a way that the function definition can be included into multiple translation units without clashes. If blank, an attempt is made to auto-detect this which falls back on "static". tool-prefix [$tool_prefix] Specifies a prefix to be added to tool commands other than the compiler, like lex and yacc, in addition to \$cross. lex [$lex] Specifies the program to use for compiling lex scanners to C. This must be compatible with GNU flex, since flex extensions are used. lexlib [$lexlib] Specifies the linker flag to use for linking the lex library. yaccname [$yaccname] Specifies just the name of the yacc program without the path. The following variable, yacc, specifies the full name. If blank, the choice yacc program will be auto-detected. yacc [$yacc] Specifies the program to use for compiling yacc scanners to C. nm [$nm] Specifies the nm program for dumping symbols from an object file. opt-flags [$opt_flags] Specifies optimization flags to use for compiling and linking C sources. lang-flags [$lang_flags] Specifies compiler flags which control the C language dialect and standard conformance in the language and header files. The txr program is written in C90, and requires POSIX and possibly other extensions. diag-flags [$diag_flags] Specifies compiler flags for obtaining extra diagnostics. debug-flags [$debug_flags] Specifies flags for requesting that debugging information be retained in the compile and link. platform-flags [$platform_flags] Specify additional compiler flags for anything else, such as CPU tuning, target ABI selection, code generation options, et cetera. remove-flags [$remove_flags] This is a negative otpion. Any flags mentioned in this variable will be removed from any of the other compiler flags options above. The flags may contain GNU Make patterns. lex-dbg-flags [$lex_dbg_flags] Specifies debug flags to be passed to lex, perhaps to generate a debugging scanner. txr-dbg-opts [$txr_dbg_opts] Specifies debug flags to pass to the txr program during the execution of "make tests". valgrind [$valgrind] Use --valgrind to to build txr with valgrind integration. Valgrind integration means that when the program is running under valgrind, it advises valgrind about stack memory locations accessed by the garbage collector, to suppress diagnostics about uninitialized accesses. extra-debugging [$extra_debugging] Use --extra_debugging to configure some additional debugging features, which incur a run-time penalty. gen-gc [$gen_gc] Use --no-gen-gc to disable the generational garbage collector which is now enabled by default. When disabled, the garbage collector performs a full object traversal and sweep on each garbage collection. ! exit 1 fi # # Variables are read, --help wasn't given, so let's configure! # txr_ver=93 # # The all important banner. # if [ $txr_ver ] ; then banner_text=$(printf " Configuring txr %s " "$txr_ver") else banner_text=" Configuring txr (unknown version) " fi banner_box=$(printf "%.${#banner_text}s\n" \ "-------------------------------------------") printf "+%s+\n|%s|\n+%s+\n" $banner_box "$banner_text" $banner_box # # From here on in, we bail if any command fails. # set -e printf "We are using this shell: %s\n" $txr_shell # # Check for GNU make # printf "Checking for GNU Make ... " if [ -z "$make" ] ; then for make in make gmake ; do output=$($make --version 2> /dev/null) || true set -- $output if [ $# -lt 2 ] || [ $1 != "GNU" -o $2 != "Make" ] ; then continue fi break done fi if [ -z "$make" ] ; then printf "missing\n" exit 1 fi make_version=$3 save_ifs=$IFS ; IFS=. ; set -- $make_version ; IFS=$save_ifs if [ $1 -lt 3 -o \( $1 -eq 3 -a $2 -lt 80 \) ] ; then printf "too old (%s found, 3.80 or newer needed)\n" $make_version exit 1 else printf "yes (%s found)\n" $make_version fi # # Verify sanity of --prefix and other directories. # printf "Checking installation paths:\n" for name in bindir datadir mandir; do eval path="\$install_prefix\$prefix/\${$name}" printf "\$(install_prefix)\$(prefix)/\$%s=%s ... " $name "$path" test_access=y case "$path" in " "* | *" "* | *" " ) printf "incorrect (contains spaces)\n" exit 1 ;; -* ) printf "incorrect (resembles a command option)\n" exit 1 ;; *'$('* ) # It's a make expression; can't test it test_access= ;; /* ) ;; * ) printf "incorrect (must be absolute path)\n" exit 1 ;; esac if [ $test_access ] ; then test_prefix=$path while true ; do if [ -e $test_prefix ] ; then if [ ! -d $test_prefix ] ; then printf "incorrect ('%s' is not a directory)!\n" $test_prefix exit 1 fi if [ ! -w $test_prefix ] ; then printf "okay\n (but no write access to '%s'\n" $test_prefix printf " so '$make install' will require root privileges)\n" else printf "okay\n" fi break fi test_prefix=$(dirname $test_prefix) done else printf "okay\n (make variable derivation)\n" fi done # # First, we have to figure out whether we are configured straight # in the source directory, or whether we are in a separate build directory. # In the latter case, we set up a symbolic link to the Makefile. # source_dir="$(dirname $0)" # # Compute an absolute path to the source directory. # top_srcdir="$(cd "$source_dir" ; pwd -P)" printf "Checking source directory %s ..." "$top_srcdir" case "$top_srcdir" in " "* | *" "* | *" " ) printf " bad (contains spaces)\n" exit 1 ;; * ) printf " okay\n" ;; esac if [ "$source_dir" != "." ] ; then printf "Symlinking Makefile -> $source_dir/Makefile\n" ln -sf "$source_dir/Makefile" . else printf "Warning: its recommended to build in a separate directory\n" fi gen_config_make() { cat > config.make <<! # # Make include file automatically generated by $0. # Changes to this file are lost when the above is re-run. # # Shell used by make for running recipes; this # is the as the shell we chose for the configure script, # derived from the txr_shell variable. SHELL := $txr_shell txr_ver := $txr_ver # absolute path to source code directory top_srcdir := $top_srcdir # ultimate installation prefix, where the # application will be run. prefix := $prefix # packaging installation prefix, where the # application may be temporarily installed # for creating pre-compiled packages, # e.g. for an operating system distro. DESTDIR := $install_prefix # relative path from prefix to datadir bindir_rel := $bindir # executable directory bindir = \$(prefix)/\$(bindir_rel) # read-only data directory datadir = \$(prefix)/$datadir # man page directory mandir = \$(prefix)/$mandir # cross compiler toolchain root directory cross := $cross # compiler name ccname = $ccname # name of yacc program yaccname = $yaccname # prefix for compiler command compiler_prefix := $compiler_prefix # prefix for non-compiler toolchain commands tool_prefix := $tool_prefix # do we compile in syslog support? have_syslog := $have_syslog # do we modern posix signal handling? have_posix_sigs := $have_posix_sigs # do we compile in debug support? debug_support := $debug_support # MPI version mpi_version := $mpi_version # EXE suffix EXE := $exe CC := $cc LEX := $lex LEXLIB := $lexlib YACC := $yacc NM := $nm OPT_FLAGS := $opt_flags LANG_FLAGS := $lang_flags DIAG_FLAGS := $diag_flags DBG_FLAGS := $debug_flags PLATFORM_FLAGS := $platform_flags REMOVE_FLAGS := $remove_flags LEX_DBG_FLAGS := $lex_dbg_flags TXR_DBG_OPTS := $txr_dbg_opts ! } # # Before doing some other tests, we need a config.make # printf "Generating config.make ... " gen_config_make printf "\n" # # Start config.h header # cat <<! > config.h /* * Header file automatically generated by $0. * Tweaking this file may seem like a good temporary workaround * to some problem but you probably should fix the script * to do the job. In any case, be aware that you will lose your * changes if you re-run $0. */ ! # # Perform a configure test. # Arguments are passed through to make # conftest() { rm -f ${exe-"conftest conftest.exe"} ${exe+"conftest$exe"} $make conftest ${@+"$@"} > conftest.err 2>&1 && [ -x conftest ] } # # Like conftest but make only .o # conftest_o() { rm -f conftest.o $make conftest.o ${@+"$@"} > conftest.err 2>&1 } # # Like conftest but make conftest.syms # conftest_syms() { rm -f conftest.o conftest.syms $make conftest.syms ${@+"$@"} > conftest.err 2>&1 } # # Check C compiler sanity # printf "Checking whether your C compiler can make a simple executable ... " cat > conftest.c <<! #include <stdio.h> int main(void) { printf("Hello, world!\n"); return 0; } ! if ! conftest ; then printf "failed\n" printf "Checking whether the failure is due to a requirement to use C99 ... " if conftest EXTRA_FLAGS=-std=c99 ; then printf "yes\n" lang_flags="$(echo "$lang_flags" | sed -e 's/-ansi/-std=c99/')" else printf "no\n\n" conftest && true printf "Errors from compilation: \n\n" cat conftest.err exit 1 fi else printf "okay\n" fi printf "Checking whether executables have that idiotic .exe suffix ... " if ls conftest.exe > /dev/null 2>&1 ; then echo "yes" exe=.exe else echo "no" fi rm -f conftest$exe # # Check for annoying clashes from non-conforming BSD-derived systems that don't # honor Unix/POSIX feature selection macros! # printf "Checking for name clashes caused by nonconforming toolchains ... " for ident in trunc floorf random longlong_t ; do cat > conftest.c <<! #include <assert.h> #include <ctype.h> #include <dirent.h> #include <errno.h> #include <float.h> #include <limits.h> #include <math.h> #include <setjmp.h> #include <stdarg.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/wait.h> #include <time.h> #include <unistd.h> #include <wchar.h> #include <wctype.h> struct txr_foo { int txr; } $ident; int $ident(void); int main(void) { return 0; } ! if ! conftest ; then printf "#define %s txr_%s\n" $ident $ident >> config.h have_unistd=y fi done printf "done\n" # # Check for idiotic behavior: extensions in C header files controlled # by __STRICT_ANSI__ rather than things like __POSIX_SOURCE. # printf "Checking for proper support for feature-test macros ... " cat > conftest.c <<! #include <stdio.h> int main(void) { return fileno(stdin); } ! if conftest EXTRA_FLAGS=-Werror ; then printf "yes\n" else printf "no\n" lang_flags="$lang_flags -U__STRICT_ANSI__" printf "Regenerating config.make ..." gen_config_make printf "done\n" fi # # Detect Apple environment. We need _DARWIN_C_SOURCE. # case "$ccname" in *gcc ) printf "Checking for Apple environment ... " if echo | gcc -dM -E - | grep -s __APPLE__ > /dev/null 2>&1 ; then printf "yes\n" need_darwin_c_source=y lang_flags="$lang_flags -D_DARWIN_C_SOURCE" printf "Regenerating config.make ..." gen_config_make printf "done\n" else printf "no\n" fi ;; esac # # Detect stupid FreeBSD problem: no defined way to reveal # traditional BSD functions if Unix compliance is selected with # _XOPEN_SOURCE. Heaven help these troglodytes. # printf "Detecting what symbol reveals BSD functions ... " cat > conftest.c <<! #include <unistd.h> #include <stdlib.h> int main(int argc, char **argv) { int (*pdaemon)(int, int) = &daemon; } ! if conftest ; then printf "none needed\n" else for flag in _BSD_SOURCE __BSD_VISIBLE _GNU_SOURCE _X_OOPS; do if [ $flag = _X_OOPS ] ; then printf "failed\n" break fi if conftest EXTRA_FLAGS=-D$flag ; then printf "%s\n" $flag lang_flags="$lang_flags -D$flag" gen_config_make break fi done fi # # Check for annoying warnings from ctype.h macros # printf "Checking for annoying warnings from <ctype.h> macros ... " cat > conftest.c <<! #include <ctype.h> int main(void) { char x = '3'; return isdigit(x); } ! if conftest EXTRA_FLAGS=-Werror ; then printf "absent\n" else printf "present\n" cat >> config.h <<! $(for x in isalpha isupper islower isdigit isxdigit isalnum isspace \ ispunct isprint isgraph iscntrl isblank ; do \ printf "#undef %s\n" $x ; done) ! fi # # Check what kind of C type we have for integers wider than long, # if any. # printf "Checking what C type we have for integers wider than \"long\" ... " longlong= for try_type in int64 __int64 "long long" ; do cat > conftest.c <<! $try_type value; ! if conftest_o ; then longlong=$try_type break fi done if [ -n "$longlong" ] ; then printf '"%s"\n' "$longlong" printf "#define HAVE_LONGLONG_T 1\n" >> config.h printf "typedef $longlong longlong_t;\n" >> config.h else printf "none\n" fi printf "Checking what C type we have for unsigned integers wider than \"long\" ... " ulonglong= for try_type in uint64 __uint64 "unsigned long long" ; do cat > conftest.c <<! $try_type value; ! if conftest_o; then ulonglong=$try_type break fi done if [ -n "$ulonglong" ] ; then printf '"%s"\n' "$ulonglong" printf "#define HAVE_ULONGLONG_T 1\n" >> config.h printf "typedef $ulonglong ulonglong_t;\n" >> config.h else printf "none\n" fi printf "Checking what C type we have for integers wider than \"long long\" ... " broken128= output=$($make conftest.ccver) set -- $output if [ "$1" = "gcc" ] ; then gcc_version=$3 save_ifs=$IFS ; IFS=. ; set -- $gcc_version ; IFS=$save_ifs if [ $1 -lt 4 ] || [ $1 -eq 4 -a $2 -le 3 ] ; then broken128=y fi fi superlong= if [ -z "$broken128" ] ; then for try_type in int128 int128_t __int128 __int128_t ; do cat > conftest.c <<! #include "config.h" int main(void) { extern longlong_t a, b; $try_type value = ($try_type) a * ($try_type) b; return 0; } longlong_t a, b; ! if conftest_o ; then superlong=$try_type break fi done fi if [ -n "$superlong" ] ; then printf '"%s"\n' "$superlong" printf "#define HAVE_SUPERLONG_T 1\n" >> config.h printf "typedef $superlong superlong_t;\n" >> config.h else printf "none\n" fi printf "Checking what C type we have for u. integers wider than \"long long\" ... " usuperlong= if [ -z "$broken128" ] ; then for try_type in uint128 uint128_t __uint128 __uint128_t ; do cat > conftest.c <<! #include "config.h" int main(void) { extern longlong_t a, b; $try_type value = ($try_type) a * ($try_type) b; return 0; } longlong_t a, b; ! if conftest_o ; then usuperlong=$try_type break fi done fi if [ -n "$usuperlong" ] ; then printf '"%s"\n' "$usuperlong" printf "#define HAVE_USUPERLONG_T 1\n" >> config.h printf "typedef $usuperlong usuperlong_t;\n" >> config.h else printf "none\n" fi printf "Checking what C integer type can hold a pointer ... " read_syms() { print_into_config=${1-} deferred_offset= while read symbol type offset size ; do size=$(( 0$size + 0 )) offset=$(( 0$offset + 0 )) symbol=${symbol#_} case "$type" in C ) size=$(( offset + 0 )) ;; S ) if [ -n "$deferred_offset" ] ; then size=$(( offset - deferred_offset )) case "$deferred_sym" in SIZEOF* ) eval $(printf "%s=%d\n" "$deferred_sym" "$size") if [ -n "$print_into_config" ] ; then printf "#define %s %s\n" "$deferred_sym" "$size" >> config.h fi ;; esac fi deferred_sym=$symbol deferred_offset=$offset continue ;; esac case "$symbol" in SIZEOF* ) eval $(printf "%s=%d\n" "$symbol" "$size") if [ -n "$print_into_config" ] ; then printf "#define %s %s\n" "$symbol" "$size" >> config.h fi ;; esac done < conftest.syms } if [ -z "$intptr" ] ; then cat > conftest.c <<! #include "config.h" #ifdef HAVE_SUPERLONG_T char SIZEOF_SUPERLONG_T[sizeof (superlong_t)]; #endif #ifdef HAVE_LONGLONG_T char SIZEOF_LONGLONG_T[sizeof (longlong_t)]; #endif char SIZEOF_PTR[sizeof (char *)]; char SIZEOF_LONG[sizeof (long)]; char SIZEOF_INT[sizeof (int)]; char SIZEOF_SHORT[sizeof (short)]; char DUMMY; ! if ! conftest_syms ; then printf "failed\n\n" printf "Errors from compilation: \n\n" cat conftest.err exit 1 fi SIZEOF_PTR=0 SIZEOF_SHORT=0 SIZEOF_INT=0 SIZEOF_LONG=0 SIZEOF_LONGLONG_T=0 SIZEOF_SUPERLONG_T=0 read_syms y if [ $SIZEOF_PTR -eq 0 ] ; then printf "failed\n" exit 1 fi if [ $SIZEOF_PTR -eq $SIZEOF_SHORT ] ; then intptr="short" uintptr=y elif [ $SIZEOF_PTR -eq $SIZEOF_INT ] ; then intptr="int" uintptr=y elif [ $SIZEOF_PTR -eq $SIZEOF_LONG ] ; then intptr="long" uintptr=y elif [ $SIZEOF_PTR -eq $SIZEOF_LONG_LONG_T ] ; then intptr="longlong_t" uintptr=$ulonglong fi if [ -z "$intptr" ] ; then printf "failed\n" exit 1 fi fi printf '"%s"\n' "$intptr" printf "typedef $intptr int_ptr_t;\n" >> config.h if [ -n "$uintptr" ] ; then printf "#define HAVE_UINTPTR_T 1\n" >> config.h printf "typedef unsigned $intptr uint_ptr_t;\n" >> config.h fi intptr_max_expr="((((($intptr) 1 << $((SIZEOF_PTR * 8 - 2))) - 1) << 1) + 1)" printf "#define INT_PTR_MAX %s\n" "$intptr_max_expr" >> config.h printf "#define INT_PTR_MIN (-INT_PTR_MAX)\n" >> config.h if [ -n "$longlong" ] && [ $SIZEOF_LONGLONG_T -eq $(( 2 * $SIZEOF_PTR )) ] then printf "#define HAVE_DOUBLE_INTPTR_T 1\n" >> config.h printf "typedef longlong_t double_intptr_t;\n" >> config.h elif [ -n "$superlong" ] && [ $SIZEOF_SUPERLONG_T -eq $(( 2 * $SIZEOF_PTR )) ] then printf "#define HAVE_DOUBLE_INTPTR_T 1\n" >> config.h printf "typedef superlong_t double_intptr_t;\n" >> config.h fi #if HAVE_LONGLONG_T && # # Alignment of wchar_t # # What we really want to know is the alignment of wide string literals # like L"wide literal". # # We make pessimistic assumption that the size of the wchar_t type is this # alignment. # # There is no easy way to get the information without running a compiled # program. # printf "Conservatively guessing the alignment of wide literals ... " if [ -z "$lit_align" ] ; then cat > conftest.c <<! #include <wchar.h> char SIZEOF_WCHAR_T[sizeof (wchar_t)]; char DUMMY; ! if ! conftest_syms ; then printf "failed\n\n" printf "Errors from compilation: \n\n" cat conftest.err exit 1 fi SIZEOF_WCHAR_T=0 deferred_offset= read_syms if [ $SIZEOF_WCHAR_T -eq 0 ] ; then printf "failed\n" exit 1 fi lit_align=$SIZEOF_WCHAR_T fi printf "%d\n" "$lit_align" printf "#define LIT_ALIGN %d\n" "$lit_align" >> config.h # # Inline functions # printf "Checking how to declare inline functions ... " if [ -z "$inline" ] ; then for inline in \ "inline" "static inline" "extern inline" \ "__inline__" "static __inline__" "extern __inline__" \ "static" do cat > conftest1.c <<! $inline int func(void) { return 0; } int main(void) { return func(); } ! cat > conftest2.c <<! $inline int func(void) { return 0; } ! rm -f conftest2$exe if ! $make conftest2 > conftest.err 2>&1 || ! [ -x conftest2 ] ; then continue fi break done fi printf '"%s"\n' "$inline" printf "#define INLINE $inline\n" >> config.h # # Valgrind # if [ -n "$valgrind" ] ; then printf "Checking valgrind API availability ... " cat > conftest.c <<! #include <valgrind/memcheck.h> #ifdef VALGRIND_DO_CLIENT_REQUEST int main(void) { return 0; } #else syntax error #endif ! if ! conftest ; then printf "failed\n\n" printf "Errors from compilation: \n\n" cat conftest.err exit 1 fi printf "okay\n" printf "#define HAVE_VALGRIND 1\n" >> config.h fi # # Yacc tests # printf "Checking for yacc program ... " if [ -z "$yacc_given" -a -z "$yaccname_given" ] ; then rm -f conftest.yacc for yaccname in "yacc" "byacc" "bison -y" "" ; do yaccpath=$($make yaccname="$yaccname" conftest.yacc) if command -v $yaccpath > /dev/null ; then break; fi done if [ -z "$yaccname" ] ; then printf "not found\n" exit 1 fi printf '"%s"\n' "$yaccpath" else yaccpath=$($make conftest.yacc) case $yaccpath in *bison ) printf "error\n\n" printf "GNU Bison needs -y to behave like yacc\n\n" printf "This needs to be specified in the --yaccname or --yacc option\n\n" exit 1 ;; * ) if ! command -v $yaccpath > /dev/null ; then printf "not found\n\n" exit 1 fi printf "given\n" ;; esac fi # # sys/wait.h # printf "Checking whether we have <sys/wait.h> ... " cat > conftest.c <<! #include <sys/wait.h> int main(void) { return 0; } ! if conftest ; then printf "yes\n" printf "#define HAVE_SYS_WAIT 1\n" >> config.h else printf "no\n" fi # # sys/stat.h # printf "Checking whether we have <sys/stat.h> ... " cat > conftest.c <<! #include <sys/stat.h> struct stat s; int main(void) { return 0; } ! if conftest ; then printf "yes\n" printf "#define HAVE_SYS_STAT 1\n" >> config.h else printf "no\n" fi # # environ # printf "Checking whether we have environ ... " cat > conftest.c <<! #include <stdio.h> int main(void) { extern char **environ; puts(environ[0]); return 0; } ! if conftest ; then printf "yes\n" printf "#define HAVE_ENVIRON 1\n" >> config.h else printf "no\n" fi # # GetEnvironmentStrings # printf "Checking whether we have GetEnvironmentStrings ... " cat > conftest.c <<! #include <windows.h> int main(void) { WCHAR *ptr = GetEnvironmentStringsW(); return 0; } ! if conftest ; then printf "yes\n" printf "#define HAVE_GETENVIRONMENTSTRINGS 1\n" >> config.h have_windows_h=y else printf "no\n" fi # # fork, pipe, exec, waitpid. # printf "Checking for POSIX fork/pipe/exec/waitpid ... " cat > conftest.c <<! #include "config.h" #ifdef HAVE_SYS_WAIT #include <sys/wait.h> #endif #include <sys/types.h> #include <unistd.h> int main(int argc, char **argv) { int status, fd[2]; pid_t p = fork(); int res = pipe(fd); (void) execvp(argv[0], argv); (void) waitpid(p, &status, 0); (void) res; return 0; } ! if conftest ; then printf "yes\n" printf "#define HAVE_FORK_STUFF 1\n" >> config.h have_unistd=y else printf "no\n" fi # # fcntl # printf "Checking for POSIX fcntl ... " cat > conftest.c <<! #include "config.h" #include <fcntl.h> int main(int argc, char **argv) { int err = fcntl(0, F_SETFD, FD_CLOEXEC); return 0; } ! if conftest ; then printf "yes\n" printf "#define HAVE_FCNTL_H 1\n" >> config.h else printf "no\n" fi # # Check for fields inside struct tm # printf "Printf detecting timezone fields in struct tm ... " tm_gmtoff= tm_tmzone= for try_field in tm_gmtoff __tm_gmtoff ; do cat > conftest.c <<! #include <time.h> int x = sizeof ((struct tm *) 0)->$try_field; ! if conftest_o ; then printf "#define HAVE_TM_GMTOFF 1\n" >> config.h printf "#define TM_GMTOFF %s\n" $try_field >> config.h break fi done for try_field in tm_zone __tm_zone ; do cat > conftest.c <<! #include <time.h> int x = sizeof ((struct tm *) 0)->$try_field; ! if conftest_o ; then printf "#define HAVE_TM_ZONE 1\n" >> config.h printf "#define TM_ZONE %s\n" $try_field >> config.h break fi done printf "done\n" printf "Checking for timegm function ... " cat > conftest.c <<! #include <time.h> int main(void) { time_t (*ptgm)(struct tm *) = &timegm; return 0; } ! if conftest ; then printf "yes\n" printf "#define HAVE_TIMEGM 1\n" >> config.h have_timegm=y else printf "no\n" fi printf "Checking for setenv and unsetenv functions ... " cat > conftest.c <<! #include <stdlib.h> int main(void) { setenv("TERM", "foo", 1); unsetenv("TERM"); return 0; } ! if conftest ; then printf "yes\n" printf "#define HAVE_SETENV 1\n" >> config.h else printf "no\n" fi printf "Checking for tzset function ... " cat > conftest.c <<! #include <time.h> int main(void) { tzset(); return 0; } ! if conftest ; then printf "yes\n" printf "#define HAVE_TZSET 1\n" >> config.h else printf "no\n" fi printf "Checking for localtime_r and gmtime_r functions ... " cat > conftest.c <<! #include <time.h> int main(int argc, char **argv) { struct tm stm; time_t t; localtime_r(&t, &stm); gmtime_r(&t, &stm); return 0; } ! if conftest ; then printf "yes\n" printf "#define HAVE_GMTIME_R 1\n" >> config.h have_unistd=y else printf "no\n" fi printf "Checking for POSIX sleep function ... " cat > conftest.c <<! #include <unistd.h> int main(int argc, char **argv) { sleep(42); return 0; } ! if conftest ; then printf "yes\n" printf "#define HAVE_POSIX_SLEEP 1\n" >> config.h have_unistd=y else printf "no\n" fi printf "Checking for POSIX usleep function ... " cat > conftest.c <<! #include <unistd.h> int main(int argc, char **argv) { usleep(42); return 0; } ! if conftest ; then printf "yes\n" printf "#define HAVE_POSIX_USLEEP 1\n" >> config.h have_unistd=y else printf "no\n" fi printf "Checking for POSIX nanosleep function ... " cat > conftest.c <<! #include <time.h> int main(int argc, char **argv) { struct timespec ts; nanosleep(&ts, &ts); return 0; } ! if conftest ; then printf "yes\n" printf "#define HAVE_POSIX_NANOSLEEP 1\n" >> config.h have_unistd=y else printf "no\n" fi printf "Checking for BSD daemon function ... " cat > conftest.c <<! #include <stdlib.h> #include <unistd.h> int main(int argc, char **argv) { int (*pdaemon)(int, int) = &daemon; } ! if conftest ; then printf "yes\n" printf "#define HAVE_DAEMON 1\n" >> config.h have_unistd=y else printf "no\n" fi printf "Checking for isatty function ... " cat > conftest.c <<! #include <unistd.h> int main(void) { isatty(0); return 0; } ! if conftest ; then printf "yes\n" printf "#define HAVE_ISATTY 1\n" >> config.h have_unistd=y else printf "no\n" fi printf "Checking for syslog ... " cat > conftest.c <<! #include <syslog.h> int main(void) { openlog("foo", LOG_CONS, LOG_DAEMON); syslog(LOG_EMERG, "bar %d\n", 3); setlogmask(0); closelog(); return 0; } ! if conftest ; then printf "yes\n" printf "#define HAVE_SYSLOG 1\n" >> config.h have_syslog=y else printf "no\n" fi printf "Checking for reasonably modern POSIX signal handling ... " cat > conftest.c <<! #include <signal.h> #include <setjmp.h> int main(void) { sigjmp_buf jb; static struct sigaction olda, newa; static sigset_t olds, news; sigaction(0, &newa, &olda); sigprocmask(SIG_BLOCK, &news, &olds); if (!sigsetjmp(jb, 1)) siglongjmp(jb, 1); return 0; } ! if conftest ; then printf "yes\n" printf "#define HAVE_POSIX_SIGS 1\n" >> config.h have_posix_sigs=y else printf "no\n" fi printf "Checking for sigaltstack ... " cat > conftest.c <<! #include <signal.h> #include <stdlib.h> int main(void) { stack_t ss; ss.ss_sp = malloc(SIGSTKSZ); ss.ss_size = SIGSTKSZ; ss.ss_flags = 0; return sigaltstack(&ss, 0); } ! if conftest ; then printf "yes\n" printf "#define HAVE_SIGALTSTACK 1\n" >> config.h else printf "no\n" fi printf "Checking for makedev ... " cat > conftest.c <<! #include <sys/types.h> int main(void) { int d = makedev(1, 2); int j = major(d); int n = minor(d); return 0; } ! if conftest ; then printf "yes\n" printf "#define HAVE_MAKEDEV 1\n" >> config.h else printf "no\n" fi printf "Checking for link, symlink and readlink ... " cat > conftest.c <<! #include <unistd.h> int main(void) { int e1 = symlink("a", "b"); int e2 = link("c", "d"); char buf[256]; ssize_t foo = readlink("e", buf, sizeof buf); return 0; } ! if conftest ; then printf "yes\n" printf "#define HAVE_SYMLINK 1\n" >> config.h have_unistd=y else printf "no\n" fi printf "Checking for POSIX mkdir ... " cat > conftest.c <<! #include "config.h" #include <sys/stat.h> #if HAVE_WINDOWS_H #include <windows.h> #endif int main(void) { int e = mkdir("a", 0); return 0; } ! if conftest ; then printf "yes\n" printf "#define HAVE_MKDIR 1\n" >> config.h else printf "no\n" fi printf "Checking for mknod ... " cat > conftest.c <<! #include "config.h" #include <unistd.h> #if HAVE_SYS_STAT #include <sys/stat.h> #endif int main(void) { int e = mknod("a", 0, 0); return 0; } ! if conftest ; then printf "yes\n" printf "#define HAVE_MKNOD 1\n" >> config.h have_unistd=y else printf "no\n" fi printf "Checking for _wspawnlp ... " cat > conftest.c <<! #include "config.h" #include <process.h> #include <wchar.h> int main(int argc, char **argv) { wchar_t *wargv[] = { L"foo", L"bar", 0 }; int r = _wspawnlp(_P_WAIT, L"foo", wargv); return 0; } ! if conftest ; then printf "yes\n" printf "#define HAVE_WSPAWN 1\n" >> config.h else printf "no\n" fi printf "Checking for log2 ... " cat > conftest.c <<! #include <math.h> int main(void) { double x = log2(42.0); return 0; } ! if conftest ; then printf "yes\n" printf "#define HAVE_LOG2 1\n" >> config.h else printf "no\n" fi # # Dependent variables # if [ -n "$have_unistd" ] ; then printf "#define HAVE_UNISTD_H 1\n" >> config.h fi if [ -n "$have_windows_h" ] ; then printf "#define HAVE_WINDOWS_H 1\n" >> config.h fi # # Extra debugging. # if [ -n "$extra_debugging" ] ; then printf "Configuring extra debugging, as requested ...\n" printf "#define EXTRA_DEBUGGING 1\n" >> config.h fi # # Clean up # $make conftest.clean # # What do we have for patch management. # printf "Checking for quilt ... " if ! quilt --version > /dev/null 2>&1 ; then printf "not found\n" else printf "found\n" have_quilt=y fi printf "Checking for patch ... " if ! patch --version > /dev/null 2>&1 ; then printf "not found\n" printf "\npatch tool required!\n\n" exit 1 else printf "found\n" have_patch=y fi # # Function to apply patches. # apply_patches() { if ! [ -e patches/series ] ; then echo "no patches" return 0 fi while read patch patchlevel ; do case patch in '#' ) continue ;; * ) patch ${patchlevel:--p1} < patches/$patch ;; esac done < patches/series } # # Try to extract MPI if not already. # printf "Extracting MPI ... " if [ -e mpi-${mpi_version} ] ; then printf "already extracted\n" else tar -xzf $top_srcdir/mpi-${mpi_version}.tar.gz printf "\n" printf "Symlinking MPI patches ...\n" ln -sf $top_srcdir/mpi-patches mpi-${mpi_version}/patches printf "Applying MPI patches ...\n" if [ -n "$have_quilt" ] ; then ( cd mpi-${mpi_version}/patches ; if [ -e series ] ; then quilt push -a ; else echo "no patches" ; fi ) else ( cd mpi-${mpi_version} ; apply_patches ) fi fi # # Some final blurbs into config.h # [ -n "$debug_support" ] && printf "#define CONFIG_DEBUG_SUPPORT 1\n" >> config.h [ -n "$gen_gc" ] && printf "#define CONFIG_GEN_GC 1\n" >> config.h # # Regenerate config.make # printf "Regenerating config.make ... " gen_config_make printf "done\n" # # Save configuration in config.log # cat > config.log <<! Configured on $(date) using $cmdline ! # # Parting message # cat <<! The configuration seems to have been successful. That doesn't mean it's correct! Please check the above output for any problems, and verify that the contents of the generated files config.make and config.h are sane for the target platform. The next step is to build the program with $make. If that is successful, please follow the INSTALL guide. Usually, most users just need to "$make tests" and "$make install", possibly switching to superuser for "$make install" if the prefix points to a privileged location like /usr/local/. !