?RCS: $Id: Extensions.U,v$
?RCS:
?RCS: Copyright (c) 1996-1998, Andy Dougherty
?RCS:
?RCS: You may distribute under the terms of either the GNU General Public
?RCS: License or the Artistic License, as specified in the README file.
?RCS:
?RCS: $Log: Extensions.U,v $
?RCS:
?MAKE:known_extensions extensions dynamic_ext static_ext nonxs_ext \
	useposix useopcode uselanginfo : \
	Myread hint usedl d_sem d_socket i_db i_dbm i_rpcsvcdbm i_gdbm \
	d_ndbm package test cat rsrc \
	d_msg d_shm osname use64bitint \
	libs d_cplusplus sed ls rm contains trnl sort
?MAKE:	-pick add $@ %<
?Y:BOTTOM
?S:known_extensions:
?S:	This variable holds a list of all extensions (both XS and non-xs)
?S:	included in the package source distribution.  This information is
?S:	only really of use during the Perl build, as the list makes no
?S:	distinction between extensions which were build and installed, and
?S:	those which where not.  See "extensions" for the list of extensions
?S:	actually built and available.
?S:.
?S:dynamic_ext:
?S:	This variable holds a list of XS extension files we want to
?S:	link dynamically into the package.  It is used by Makefile.
?S:.
?S:static_ext:
?S:	This variable holds a list of XS extension files we want to
?S:	link statically into the package.  It is used by Makefile.
?S:.
?S:nonxs_ext:
?S:	This variable holds a list of all non-xs extensions built and
?S:	installed by the package.  By default, all non-xs extensions
?S:	distributed will be built, with the exception of platform-specific
?S:	extensions (currently only one VMS specific extension).
?S:.
?S:extensions:
?S:	This variable holds a list of all extension files (both XS and
?S:	non-xs) installed with the package.  It is propagated to Config.pm
?S:	and is typically used to test whether a particular extension
?S:	is available.
?S:.
?S:useposix:
?S:	This variable holds either 'true' or 'false' to indicate
?S:	whether the POSIX extension should be used.  The sole
?S:	use for this currently is to allow an easy mechanism
?S:	for hints files to indicate that POSIX will not compile
?S:	on a particular system.
?S:.
?S:useopcode:
?S:	This variable holds either 'true' or 'false' to indicate
?S:	whether the Opcode extension should be used.  The sole
?S:	use for this currently is to allow an easy mechanism
?S:	for users to skip the Opcode extension from the Configure
?S:	command line.
?S:.
?S:uselanginfo:
?S:	This variable holds either 'true' or 'false' to indicate
?S:	whether the I18N::Langinfo extension should be used.  The sole
?S:	use for this currently is to allow an easy mechanism for users to skip
?S:	this extension from the Configure command line.
?S:.
?T:xxx avail_ext this_ext tdir xs_extensions nonxs_extensions find_extensions
?INIT:: set useposix=false in your hint file to disable the POSIX extension.
?INIT:useposix=true
?INIT:: set useopcode=false in your hint file to disable the Opcode extension.
?INIT:useopcode=true
?INIT:: set uselanginfo=false in your hint file to disable the I18N::Langinfo extension.
?INIT:uselanginfo=true
?LINT:extern noextensions
?LINT:extern onlyextensions
?T:keepextensions i
: Check extensions
echo " "
echo "Looking for extensions..." >&4
: If we are using the old config.sh, nonxs_extensions and xs_extensions may
: contain old or inaccurate or duplicate values.
nonxs_extensions=''
xs_extensions=''
: We do not use find because it might not be available.
: We do not just use MANIFEST because the user may have dropped
: some additional extensions into the source tree and expect them
: to be built.

: Function to recursively find available extensions, ignoring DynaLoader
: NOTE: recursion limit of 10 to prevent runaway in case of symlink madness
: In 5.10.1 and later, extensions are stored in directories
: like File-Glob instead of the older File/Glob/.
find_extensions='
    for xxx in *; do
	case "$xxx" in
	    DynaLoader|dynaload) ;;
	    *)
	    this_ext=`echo "$xxx" | $sed -e s/-/\\\//g`;
	    case "$this_ext" in
		Scalar/List/Utils) this_ext="List/Util"	;;
		PathTools)         this_ext="Cwd"	;;
	    esac;
	    echo " $xs_extensions $nonxs_extensions" > "$tdir/$$.tmp";
	    if $contains " $this_ext " "$tdir/$$.tmp"; then
		echo >&4;
		echo "Duplicate directories detected for extension $xxx" >&4;
		echo "Configure cannot correctly recover from this - shall I abort?" >&4;
		case "$knowitall" in
		"") dflt=y;;
		*) dflt=n;;
		esac;
		. ../UU/myread;
		case "$ans" in
		n*|N*) ;;
		*) echo >&4;
		    echo "Ok.  Stopping Configure." >&4;
		    echo "Please remove the duplicate directory (e.g. using git clean) and then re-run Configure" >&4;
		    exit 1;;
		esac;
		echo "Ok.  You will need to correct config.sh before running make." >&4;
	    fi;
	    $ls -1 "$xxx" > "$tdir/$$.tmp";
	    if   $contains "\.xs$" "$tdir/$$.tmp" > /dev/null 2>&1; then
		xs_extensions="$xs_extensions $this_ext";
	    elif $contains "\.c$"  "$tdir/$$.tmp" > /dev/null 2>&1; then
		xs_extensions="$xs_extensions $this_ext";
	    elif $test -d "$xxx"; then
		nonxs_extensions="$nonxs_extensions $this_ext";
	    fi;
	    $rm -f "$tdir/$$.tmp";
	    ;;
	esac;
    done'
tdir=`pwd`
cd "$rsrc/cpan"
set X
shift
eval $find_extensions
cd "$rsrc/dist"
set X
shift
eval $find_extensions
cd "$rsrc/ext"
set X
shift
eval $find_extensions
set X $xs_extensions
shift
xs_extensions=`echo "$*" | tr ' ' $trnl | $sort | tr $trnl ' '`
set X $nonxs_extensions
shift
nonxs_extensions=`echo "$*" | tr ' ' $trnl | $sort | tr $trnl ' '`
cd "$tdir"
known_extensions=`echo $nonxs_extensions $xs_extensions  | tr ' ' $trnl | $sort | tr $trnl ' '`

: Now see which are supported on this system.
?X: avail_ext lists available XS extensions.
avail_ext=''
for xxx in $xs_extensions ; do
	case "$xxx" in
?X: Handle possible DOS 8.3 filename and case alterations
	Amiga*)
		case "$osname" in
		amigaos) avail_ext="$avail_ext $xxx" ;;
		esac
		;;
	DB_File|db_file)
		case "$i_db" in
		$define) avail_ext="$avail_ext $xxx" ;;
		esac
		;;
	GDBM_File|gdbm_fil)
		case "$i_gdbm" in
		$define) avail_ext="$avail_ext $xxx" ;;
		esac
		;;
	IPC/SysV|ipc/sysv)
		: XXX Do we need a useipcsysv variable here
		case "${d_msg}${d_sem}${d_shm}" in
		*"${define}"*) avail_ext="$avail_ext $xxx" ;;
		esac
		;;
	NDBM_File|ndbm_fil)
		case "$d_ndbm" in
		$define)
		    case "$osname-$use64bitint" in
		    hpux-define)
			case "$libs" in
			*-lndbm*) avail_ext="$avail_ext $xxx" ;;
			esac
			;;
		    *) avail_ext="$avail_ext $xxx" ;;
		    esac
		    ;;
		esac
		;;
	ODBM_File|odbm_fil)
		case "${i_dbm}${i_rpcsvcdbm}" in
		*"${define}"*)
		    case "$d_cplusplus" in
		    define) ;; # delete as a function name will not work
		    *)  case "$osname-$use64bitint" in
			hpux-define)
			    case "$libs" in
			    *-ldbm*) avail_ext="$avail_ext $xxx" ;;
			    esac
			    ;;
			*) avail_ext="$avail_ext $xxx" ;;
			esac
			;;
		    esac
		    ;;
		esac
		;;
	Opcode|opcode)
		case "$useopcode" in
		true|define|y) avail_ext="$avail_ext $xxx" ;;
		esac
		;;
	POSIX|posix)
		case "$useposix" in
		true|define|y) avail_ext="$avail_ext $xxx" ;;
		esac
		;;
	Socket|socket)
		case "$d_socket" in
		true|$define|y) avail_ext="$avail_ext $xxx" ;;
		esac
		;;
	I18N/Langinfo|langinfo)
		case "$uselanginfo" in
		true|define|y) avail_ext="$avail_ext $xxx" ;;
		esac
		;;
	Sys/Syslog|sys/syslog)
		case $osname in
			amigaos) ;; # not really very useful on AmigaOS
			*)
			: XXX syslog requires socket
			case "$d_socket" in
			true|$define|y) avail_ext="$avail_ext $xxx" ;;
			esac
			;;
		esac
		;;
	threads|threads/shared)
		# threads and threads::shared are special cases.
		# To stop people from asking "Perl 5.8.0 was supposed
		# to have this new fancy threads implementation but my
		# perl doesn't have it" and from people trying to
		# (re)install the threads module using CPAN.pm and
		# CPAN.pm then offering to reinstall Perl 5.8.0,
		# the threads.pm and threads/shared.pm will always be
		# there, croaking informatively ("you need to rebuild
		# all of Perl with threads, sorry") when threads haven't
		# been compiled in.
		# --jhi
		avail_ext="$avail_ext $xxx"
		;;
	VMS*)
		;;
	Win32*)
		case "$osname" in
		cygwin) avail_ext="$avail_ext $xxx" ;;
		esac
		;;
	XS/APItest|xs/apitest)
		# This is just for testing.  Skip it unless we have dynamic loading.

		case "$usedl" in
		$define) avail_ext="$avail_ext $xxx" ;;
		esac
		;;
	XS/Typemap|xs/typemap)
		# This is just for testing.  Skip it unless we have dynamic loading.
		case "$usedl" in
		$define) avail_ext="$avail_ext $xxx" ;;
		esac
		;;
	*)	avail_ext="$avail_ext $xxx"
		;;
	esac
done

set X $avail_ext
shift
avail_ext="$*"

case "$onlyextensions" in
'') ;;
*)  keepextensions=''
    echo "You have requested that only certain extensions be included..." >&4
    for i in $onlyextensions; do
        case " $avail_ext " in
        *" $i "*)
            echo "Keeping extension $i."
            keepextensions="$keepextensions $i"
            ;;
        *) echo "Ignoring extension $i." ;;
        esac
    done
    avail_ext="$keepextensions"
    ;;
esac

case "$noextensions" in
'') ;;
*)  keepextensions=''
    echo "You have requested that certain extensions be ignored..." >&4
    for i in $avail_ext; do
        case " $noextensions " in
        *" $i "*) echo "Ignoring extension $i." ;;
        *) echo "Keeping extension $i.";
           keepextensions="$keepextensions $i"
           ;;
        esac
    done
    avail_ext="$keepextensions"
    ;;
esac

: Now see which nonxs extensions are supported on this system.
: For now assume all are.
nonxs_ext=''
for xxx in $nonxs_extensions ; do
	case "$xxx" in
	VMS*)
		;;
	*)	nonxs_ext="$nonxs_ext $xxx"
		;;
	esac
done

set X $nonxs_ext
shift
nonxs_ext="$*"

case $usedl in
$define)
	$cat <<EOM
A number of extensions are supplied with $package.  You may choose to
compile these extensions for dynamic loading (the default), compile
them into the $package executable (static loading), or not include
them at all.  Answer "none" to include no extensions.
Note that DynaLoader is always built and need not be mentioned here.

EOM
	case "$dynamic_ext" in
	'')
		: Exclude those listed in static_ext
		dflt=''
		for xxx in $avail_ext; do
			case " $static_ext " in
			*" $xxx "*) ;;
			*) dflt="$dflt $xxx" ;;
			esac
		done
		set X $dflt
		shift
		dflt="$*"
		;;
	*)	dflt="$dynamic_ext"
		# Perhaps we are reusing an old out-of-date config.sh.
		case "$hint" in
		previous)
			if test X"$dynamic_ext" != X"$avail_ext"; then
				$cat <<EOM
NOTICE:  Your previous config.sh list may be incorrect.
The extensions now available to you are
	${avail_ext}
but the default list from your previous config.sh is
	${dynamic_ext}

EOM
			fi
			;;
		esac
		;;
	esac
	case "$dflt" in
	'')	dflt=none;;
	esac
	rp="What extensions do you wish to load dynamically?"
	. ./myread
	case "$ans" in
?X: Use ' ' so a subsequent Configure will preserve that value.
	none) dynamic_ext=' ' ;;
	*) dynamic_ext="$ans" ;;
	esac

	case "$static_ext" in
	'')
		: Exclude those already listed in dynamic linking
		dflt=''
		for xxx in $avail_ext; do
			case " $dynamic_ext " in
			*" $xxx "*) ;;
			*) dflt="$dflt $xxx" ;;
			esac
		done
		set X $dflt
		shift
		dflt="$*"
		;;
	*)  dflt="$static_ext"
		;;
	esac

	case "$dflt" in
	'')	dflt=none;;
	esac
	rp="What extensions do you wish to load statically?"
	. ./myread
	case "$ans" in
?X: Use ' ' so a subsequent Configure will preserve that value.
	none) static_ext=' ' ;;
	*) static_ext="$ans" ;;
	esac
	;;
*)
	$cat <<EOM
A number of extensions are supplied with $package.  Answer "none"
to include no extensions.
Note that DynaLoader is always built and need not be mentioned here.

EOM
	case "$static_ext" in
	'') dflt="$avail_ext" ;;
	*)	dflt="$static_ext"
		# Perhaps we are reusing an old out-of-date config.sh.
		case "$hint" in
		previous)
			if test X"$static_ext" != X"$avail_ext"; then
				$cat <<EOM
NOTICE:  Your previous config.sh list may be incorrect.
The extensions now available to you are
	${avail_ext}
but the default list from your previous config.sh is
	${static_ext}

EOM
			fi
			;;
		esac
		;;
	esac
	: Exclude those that are not xs extensions
	case "$dflt" in
	'')	dflt=none;;
	esac
	rp="What extensions do you wish to include?"
	. ./myread
	case "$ans" in
?X: Use ' ' so a subsequent Configure will preserve that value.
	none) static_ext=' ' ;;
	*) static_ext="$ans" ;;
	esac
	;;
esac
#
# Encode is a special case.  If we are building Encode as a static
# extension, we need to explicitly list its subextensions as well.
# For other nested extensions, this is handled automatically by
# the appropriate Makefile.PL.
case " $static_ext " in
	*" Encode "*) # Add the subextensions of Encode
	cd "$rsrc/cpan"
	for xxx in `ls Encode/*/Makefile.PL|awk -F/ '{print $2}'`; do
		static_ext="$static_ext Encode/$xxx"
		known_extensions="$known_extensions Encode/$xxx"
	done
	cd "$tdir"
	;;
esac

set X $dynamic_ext $static_ext $nonxs_ext
shift
extensions="$*"

# Sanity check:  We require an extension suitable for use with
# AnyDBM_File, as well as Fcntl and IO.  (Failure to have these
# should show up as failures in the test suite, but it's helpful to
# catch them now.) The 'extensions' list is normally sorted
# alphabetically, so we need to accept either
#    DB_File ... Fcntl ... IO  ....
# or something like
#    Fcntl ... NDBM_File ... IO  ....
case " $extensions"  in
*"_File "*" Fcntl "*" IO "*) ;; # DB_File
*" Fcntl "*"_File "*" IO "*) ;; # GDBM_File
*" Fcntl "*" IO "*"_File "*) ;; # NDBM_File
*) echo "WARNING: Extensions DB_File or *DBM_File, Fcntl, and IO not configured." >&4
   echo "WARNING: The Perl you are building will be quite crippled." >&4
   ;;
esac

