?RCS: $Id$
?RCS:
?RCS: Copyright (c) 2000, Jarkko Hietaniemi
?RCS:
?RCS: You may redistribute only under the terms of the Artistic License,
?RCS: as specified in the README file that comes with the distribution.
?RCS: You may reuse parts of this distribution only within the terms of
?RCS: that same Artistic License; a copy of which may be found at the root
?RCS: of the source tree for dist 3.0.
?RCS:
?MAKE:gccversion gccosandvers gccansipedantic: cat cpp rm +cc \
	Myread Guess Options Oldconfig Loc osname osvers run
?MAKE:	-pick add $@ %<
?S:gccversion:
?S:	If GNU cc (gcc) is used, this variable holds '1' or '2' to
?S:	indicate whether the compiler is version 1 or 2.  This is used in
?S:	setting some of the default cflags.  It is set to '' if not gcc.
?S:.
?S:gccosandvers:
?S:	If GNU cc (gcc) is used, this variable holds the operating system
?S:	and version used to compile gcc.  It is set to '' if not gcc,
?S:	or if nothing useful can be parsed as the os version.
?S:.
?S:gccansipedantic:
?S:	If GNU cc (gcc) is used, this variable will enable (if set) the
?S:	-ansi and -pedantic ccflags for building core files (through
?S:	cflags script). (See Porting/pumpkin.pod for full description).
?S:.
?D:gccversion=''
?D:gccansipedantic=''
?T:c99_for
?T:flag
?T:gccshortvers
?T:incdir
?T:warn
?F:!try
?LINT:change cpp
?LINT:extern ccflags
?LINT:extern ldflags
?LINT:extern locincpth
?LINT:extern ccname
?LINT:change ccname
?LINT:change locincpth
?LINT:change ccflags
?LINT:set gccansipedantic
?X: Check if they have gcc in any guise.
: Check if we are using GNU gcc and what its version is
echo " "
echo "Checking for GNU cc in disguise and/or its version number..." >&4
$cat >try.c <<EOM
#include <stdio.h>
int main() {
#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
#ifdef __VERSION__
	printf("%s\n", __VERSION__);
#else
	printf("%s\n", "1");
#endif
#endif
	return(0);
}
EOM
if $cc -o try $ccflags $ldflags try.c; then
	gccversion=`$run ./try`
	case "$gccversion" in
	'') echo "You are not using GNU cc." ;;
	*)  echo "You are using GNU cc $gccversion."
	    ccname=gcc
	    ;;
	esac
else
	echo " "
	echo "*** WHOA THERE!!! ***" >&4
	echo "    Your C compiler \"$cc\" doesn't seem to be working!" >&4
?X: using -K will prevent aborting--maybe they're cross compiling?
	case "$knowitall" in
	'')
	echo "    You'd better start hunting for one and let me know about it." >&4
		exit 1
		;;
	esac
fi
$rm -f try try.*
case "$gccversion" in
1.*) cpp=`./loc gcc-cpp $cpp $pth` ;;
esac
case "$gccversion" in
'') gccosandvers='' ;;
*) gccshortvers=`echo "$gccversion"|sed 's/ .*//'`
   gccosandvers=`$cc -v 2>&1|grep '/specs$'|sed "s!.*/[^-/]*-[^-/]*-\([^-/]*\)/$gccshortvers/specs!\1!"`
   gccshortvers=''
   case "$gccosandvers" in
   $osname) gccosandvers='' ;; # linux gccs seem to have no linux osvers, grr
   $osname$osvers) ;; # looking good
   $osname*) cat <<EOM >&4

*** WHOA THERE!!! ***

    Your gcc has not been compiled for the exact release of
    your operating system ($gccosandvers versus $osname$osvers).

    In general it is a good idea to keep gcc synchronized with
    the operating system because otherwise serious problems
    may ensue when trying to compile software, like Perl.

    I'm trying to be optimistic here, though, and will continue.
    If later during the configuration and build icky compilation
    problems appear (headerfile conflicts being the most common
    manifestation), I suggest reinstalling the gcc to match
    your operating system release.

EOM
      ;;
   *) gccosandvers='' ;; # failed to parse, better be silent
   esac
   ;;
esac
case "$ccname" in
'') ccname="$cc" ;;
esac

# gcc 3.* complain about adding -Idirectories that they already know about,
# so we will take those off from locincpth.
case "$gccversion" in
3.*)
    echo "int main(){}">try.c
    for incdir in $locincpth; do
       warn=`$cc $ccflags -I$incdir -c try.c 2>&1 | \
	     grep '^c[cp]p*[01]: warning: changing search order '`
       if test "X$warn" != X; then
	   locincpth=`echo " $locincpth " | sed "s! $incdir ! !"`
       fi
    done
    $rm -f try try.*
esac

# gcc 4.9 by default does some optimizations that break perl.
# see ticket 121505.
#
# The -fwrapv disables those optimizations (and probably others,) so
# for gcc 4.9 (and later, since the optimizations probably won't go
# away), add -fwrapv unless the user requests -fno-wrapv, which
# disables -fwrapv, or if the user requests -fsanitize=undefined,
# which turns the overflows -fwrapv ignores into runtime errors.
case "$gccversion" in
4.[3-9].*|4.[1-9][0-9]*|[5-9].*|[1-9][0-9]*)
    case "$ccflags" in
    *-fno-wrapv*|*-fsanitize=undefined*|*-fwrapv*) ;;
    *) ccflags="$ccflags -fwrapv" ;;
    esac
esac

# Really old versions of gcc default to C89 and will error for this code.
# See if the compiler (gcc or otherwise) needs a flag to compile C99 code
# Initialisations in for loops seem to be the particular problem
# (Does this syntax conflict with something else that was valid C89?)
# We also add a declaration after a statement to detect whether the compiler
# (or the user supplied -Accflags) consider such declarations to be errors.
# This causes 'Configure with -Accflags="-Werror=declaration-after-statement"'
# to fail hard and early.
#
# Annoyingly -std=c99 will cause gcc to tell glibc not to define prototypes for
# syscall, drand48 etc when including <unistd.h>, which messes up our build.
# I guess we *could* loop round trying -std=c99 first with checks both for the
# prototype found and the code compiling (because -std=gnu99 might do other
# things we don't want, particularly on non-GCC compilers) but
# 1) We would need to check for the prototype first (without any flags)
# 2) We would still end up with most Linux systems either being -std=gnu99
#    or "" (no flag), and so both common options would not rigorously check our
#    portability to other platforms.
# So it doesn't seem worth the complexity and chance of different failure.
$cat >try.c <<'EOCP'
int main(int argc, char **argv) {
    argc = argc + 1;
    /* This is deliberately a declaration after a statement. */
    unsigned long long count = 0;
    for (char **p = argv; *p; ++p) {
        ++count;
    }
    return count == 1 ? 0 : argc;
}
EOCP
c99_for=no
for flag in '' '-std=gnu99' '-std=c99'; do
    if $cc -o try $flag $ccflags $ldflags try.c 2>/dev/null && ./try; then
        c99_for="$flag"
        break;
    fi
done
case "$c99_for" in
'') echo "Your C compiler doesn't need any special flags to compile C99 code"
    ;;
no) echo >&4 "Your C compiler doesn't seem to be able to compile C99 code"
    rp='Do you really want to continue?'
    dflt='n'
    . ./myread
    case "$ans" in
	[yY])	echo >&4 "Okay, continuing."	;;
	*)	exit 1				;;
    esac
    ;;
*)  echo "Your C compiler needs $c99_for to compile C99 code"
    ccflags="$c99_for $ccflags"
    ;;
esac
$rm -f try try.*

