Blame m4/acx_pthread.m4

Packit 18d29c
# This was retrieved from
Packit 18d29c
#    http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?revision=1277&root=avahi
Packit 18d29c
# See also (perhaps for new versions?)
Packit 18d29c
#    http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?root=avahi
Packit 18d29c
#
Packit 18d29c
# We've rewritten the inconsistency check code (from avahi), to work
Packit 18d29c
# more broadly.  In particular, it no longer assumes ld accepts -zdefs.
Packit 18d29c
# This caused a restructing of the code, but the functionality has only
Packit 18d29c
# changed a little.
Packit 18d29c
Packit 18d29c
dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
Packit 18d29c
dnl
Packit 18d29c
dnl @summary figure out how to build C programs using POSIX threads
Packit 18d29c
dnl
Packit 18d29c
dnl This macro figures out how to build C programs using POSIX threads.
Packit 18d29c
dnl It sets the PTHREAD_LIBS output variable to the threads library and
Packit 18d29c
dnl linker flags, and the PTHREAD_CFLAGS output variable to any special
Packit 18d29c
dnl C compiler flags that are needed. (The user can also force certain
Packit 18d29c
dnl compiler flags/libs to be tested by setting these environment
Packit 18d29c
dnl variables.)
Packit 18d29c
dnl
Packit 18d29c
dnl Also sets PTHREAD_CC to any special C compiler that is needed for
Packit 18d29c
dnl multi-threaded programs (defaults to the value of CC otherwise).
Packit 18d29c
dnl (This is necessary on AIX to use the special cc_r compiler alias.)
Packit 18d29c
dnl
Packit 18d29c
dnl NOTE: You are assumed to not only compile your program with these
Packit 18d29c
dnl flags, but also link it with them as well. e.g. you should link
Packit 18d29c
dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS
Packit 18d29c
dnl $LIBS
Packit 18d29c
dnl
Packit 18d29c
dnl If you are only building threads programs, you may wish to use
Packit 18d29c
dnl these variables in your default LIBS, CFLAGS, and CC:
Packit 18d29c
dnl
Packit 18d29c
dnl        LIBS="$PTHREAD_LIBS $LIBS"
Packit 18d29c
dnl        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
Packit 18d29c
dnl        CC="$PTHREAD_CC"
Packit 18d29c
dnl
Packit 18d29c
dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute
Packit 18d29c
dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to
Packit 18d29c
dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
Packit 18d29c
dnl
Packit 18d29c
dnl ACTION-IF-FOUND is a list of shell commands to run if a threads
Packit 18d29c
dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to
Packit 18d29c
dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the
Packit 18d29c
dnl default action will define HAVE_PTHREAD.
Packit 18d29c
dnl
Packit 18d29c
dnl Please let the authors know if this macro fails on any platform, or
Packit 18d29c
dnl if you have any other suggestions or comments. This macro was based
Packit 18d29c
dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with
Packit 18d29c
dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros
Packit 18d29c
dnl posted by Alejandro Forero Cuervo to the autoconf macro repository.
Packit 18d29c
dnl We are also grateful for the helpful feedback of numerous users.
Packit 18d29c
dnl
Packit 18d29c
dnl @category InstalledPackages
Packit 18d29c
dnl @author Steven G. Johnson <stevenj@alum.mit.edu>
Packit 18d29c
dnl @version 2006-05-29
Packit 18d29c
dnl @license GPLWithACException
Packit 18d29c
dnl 
Packit 18d29c
dnl Checks for GCC shared/pthread inconsistency based on work by
Packit 18d29c
dnl Marcin Owsiany <marcin@owsiany.pl>
Packit 18d29c
Packit 18d29c
Packit 18d29c
AC_DEFUN([ACX_PTHREAD], [
Packit 18d29c
AC_REQUIRE([AC_CANONICAL_HOST])
Packit 18d29c
AC_LANG_SAVE
Packit 18d29c
AC_LANG_C
Packit 18d29c
acx_pthread_ok=no
Packit 18d29c
Packit 18d29c
# We used to check for pthread.h first, but this fails if pthread.h
Packit 18d29c
# requires special compiler flags (e.g. on True64 or Sequent).
Packit 18d29c
# It gets checked for in the link test anyway.
Packit 18d29c
Packit 18d29c
# First of all, check if the user has set any of the PTHREAD_LIBS,
Packit 18d29c
# etcetera environment variables, and if threads linking works using
Packit 18d29c
# them:
Packit 18d29c
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
Packit 18d29c
        save_CFLAGS="$CFLAGS"
Packit 18d29c
        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
Packit 18d29c
        save_LIBS="$LIBS"
Packit 18d29c
        LIBS="$PTHREAD_LIBS $LIBS"
Packit 18d29c
        AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
Packit 18d29c
        AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
Packit 18d29c
        AC_MSG_RESULT($acx_pthread_ok)
Packit 18d29c
        if test x"$acx_pthread_ok" = xno; then
Packit 18d29c
                PTHREAD_LIBS=""
Packit 18d29c
                PTHREAD_CFLAGS=""
Packit 18d29c
        fi
Packit 18d29c
        LIBS="$save_LIBS"
Packit 18d29c
        CFLAGS="$save_CFLAGS"
Packit 18d29c
fi
Packit 18d29c
Packit 18d29c
# We must check for the threads library under a number of different
Packit 18d29c
# names; the ordering is very important because some systems
Packit 18d29c
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
Packit 18d29c
# libraries is broken (non-POSIX).
Packit 18d29c
Packit 18d29c
# Create a list of thread flags to try.  Items starting with a "-" are
Packit 18d29c
# C compiler flags, and other items are library names, except for "none"
Packit 18d29c
# which indicates that we try without any flags at all, and "pthread-config"
Packit 18d29c
# which is a program returning the flags for the Pth emulation library.
Packit 18d29c
Packit 18d29c
acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
Packit 18d29c
Packit 18d29c
# The ordering *is* (sometimes) important.  Some notes on the
Packit 18d29c
# individual items follow:
Packit 18d29c
Packit 18d29c
# pthreads: AIX (must check this before -lpthread)
Packit 18d29c
# none: in case threads are in libc; should be tried before -Kthread and
Packit 18d29c
#       other compiler flags to prevent continual compiler warnings
Packit 18d29c
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
Packit 18d29c
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
Packit 18d29c
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
Packit 18d29c
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
Packit 18d29c
# -pthreads: Solaris/gcc
Packit 18d29c
# -mthreads: Mingw32/gcc, Lynx/gcc
Packit 18d29c
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
Packit 18d29c
#      doesn't hurt to check since this sometimes defines pthreads too;
Packit 18d29c
#      also defines -D_REENTRANT)
Packit 18d29c
#      ... -mt is also the pthreads flag for HP/aCC
Packit 18d29c
# pthread: Linux, etcetera
Packit 18d29c
# --thread-safe: KAI C++
Packit 18d29c
# pthread-config: use pthread-config program (for GNU Pth library)
Packit 18d29c
Packit 18d29c
case "${host_cpu}-${host_os}" in
Packit 18d29c
        *solaris*)
Packit 18d29c
Packit 18d29c
        # On Solaris (at least, for some versions), libc contains stubbed
Packit 18d29c
        # (non-functional) versions of the pthreads routines, so link-based
Packit 18d29c
        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/
Packit 18d29c
        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
Packit 18d29c
        # a function called by this macro, so we could check for that, but
Packit 18d29c
        # who knows whether they'll stub that too in a future libc.)  So,
Packit 18d29c
        # we'll just look for -pthreads and -lpthread first:
Packit 18d29c
Packit 18d29c
        acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
Packit 18d29c
        ;;
Packit 18d29c
esac
Packit 18d29c
Packit 18d29c
if test x"$acx_pthread_ok" = xno; then
Packit 18d29c
for flag in $acx_pthread_flags; do
Packit 18d29c
Packit 18d29c
        case $flag in
Packit 18d29c
                none)
Packit 18d29c
                AC_MSG_CHECKING([whether pthreads work without any flags])
Packit 18d29c
                ;;
Packit 18d29c
Packit 18d29c
                -*)
Packit 18d29c
                AC_MSG_CHECKING([whether pthreads work with $flag])
Packit 18d29c
                PTHREAD_CFLAGS="$flag"
Packit 18d29c
                ;;
Packit 18d29c
Packit 18d29c
		pthread-config)
Packit 18d29c
		AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
Packit 18d29c
		if test x"$acx_pthread_config" = xno; then continue; fi
Packit 18d29c
		PTHREAD_CFLAGS="`pthread-config --cflags`"
Packit 18d29c
		PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
Packit 18d29c
		;;
Packit 18d29c
Packit 18d29c
                *)
Packit 18d29c
                AC_MSG_CHECKING([for the pthreads library -l$flag])
Packit 18d29c
                PTHREAD_LIBS="-l$flag"
Packit 18d29c
                ;;
Packit 18d29c
        esac
Packit 18d29c
Packit 18d29c
        save_LIBS="$LIBS"
Packit 18d29c
        save_CFLAGS="$CFLAGS"
Packit 18d29c
        LIBS="$PTHREAD_LIBS $LIBS"
Packit 18d29c
        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
Packit 18d29c
Packit 18d29c
        # Check for various functions.  We must include pthread.h,
Packit 18d29c
        # since some functions may be macros.  (On the Sequent, we
Packit 18d29c
        # need a special flag -Kthread to make this header compile.)
Packit 18d29c
        # We check for pthread_join because it is in -lpthread on IRIX
Packit 18d29c
        # while pthread_create is in libc.  We check for pthread_attr_init
Packit 18d29c
        # due to DEC craziness with -lpthreads.  We check for
Packit 18d29c
        # pthread_cleanup_push because it is one of the few pthread
Packit 18d29c
        # functions on Solaris that doesn't have a non-functional libc stub.
Packit 18d29c
        # We try pthread_create on general principles.
Packit 18d29c
        AC_TRY_LINK([#include <pthread.h>],
Packit 18d29c
                    [pthread_t th; pthread_join(th, 0);
Packit 18d29c
                     pthread_attr_init(0); pthread_cleanup_push(0, 0);
Packit 18d29c
                     pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
Packit 18d29c
                    [acx_pthread_ok=yes])
Packit 18d29c
Packit 18d29c
        LIBS="$save_LIBS"
Packit 18d29c
        CFLAGS="$save_CFLAGS"
Packit 18d29c
Packit 18d29c
        AC_MSG_RESULT($acx_pthread_ok)
Packit 18d29c
        if test "x$acx_pthread_ok" = xyes; then
Packit 18d29c
                break;
Packit 18d29c
        fi
Packit 18d29c
Packit 18d29c
        PTHREAD_LIBS=""
Packit 18d29c
        PTHREAD_CFLAGS=""
Packit 18d29c
done
Packit 18d29c
fi
Packit 18d29c
Packit 18d29c
# Various other checks:
Packit 18d29c
if test "x$acx_pthread_ok" = xyes; then
Packit 18d29c
        save_LIBS="$LIBS"
Packit 18d29c
        LIBS="$PTHREAD_LIBS $LIBS"
Packit 18d29c
        save_CFLAGS="$CFLAGS"
Packit 18d29c
        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
Packit 18d29c
Packit 18d29c
        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
Packit 18d29c
	AC_MSG_CHECKING([for joinable pthread attribute])
Packit 18d29c
	attr_name=unknown
Packit 18d29c
	for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
Packit 18d29c
	    AC_TRY_LINK([#include <pthread.h>], [int attr=$attr; return attr;],
Packit 18d29c
                        [attr_name=$attr; break])
Packit 18d29c
	done
Packit 18d29c
        AC_MSG_RESULT($attr_name)
Packit 18d29c
        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
Packit 18d29c
            AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
Packit 18d29c
                               [Define to necessary symbol if this constant
Packit 18d29c
                                uses a non-standard name on your system.])
Packit 18d29c
        fi
Packit 18d29c
Packit 18d29c
        AC_MSG_CHECKING([if more special flags are required for pthreads])
Packit 18d29c
        flag=no
Packit 18d29c
        case "${host_cpu}-${host_os}" in
Packit 18d29c
            *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
Packit 18d29c
            *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
Packit 18d29c
        esac
Packit 18d29c
        AC_MSG_RESULT(${flag})
Packit 18d29c
        if test "x$flag" != xno; then
Packit 18d29c
            PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
Packit 18d29c
        fi
Packit 18d29c
Packit 18d29c
        LIBS="$save_LIBS"
Packit 18d29c
        CFLAGS="$save_CFLAGS"
Packit 18d29c
        # More AIX lossage: must compile with xlc_r or cc_r
Packit 18d29c
	if test x"$GCC" != xyes; then
Packit 18d29c
          AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
Packit 18d29c
        else
Packit 18d29c
          PTHREAD_CC=$CC
Packit 18d29c
	fi
Packit 18d29c
Packit 18d29c
	# The next part tries to detect GCC inconsistency with -shared on some
Packit 18d29c
	# architectures and systems. The problem is that in certain
Packit 18d29c
	# configurations, when -shared is specified, GCC "forgets" to
Packit 18d29c
	# internally use various flags which are still necessary.
Packit 18d29c
	
Packit 18d29c
	#
Packit 18d29c
	# Prepare the flags
Packit 18d29c
	#
Packit 18d29c
	save_CFLAGS="$CFLAGS"
Packit 18d29c
	save_LIBS="$LIBS"
Packit 18d29c
	save_CC="$CC"
Packit 18d29c
	
Packit 18d29c
	# Try with the flags determined by the earlier checks.
Packit 18d29c
	#
Packit 18d29c
	# -Wl,-z,defs forces link-time symbol resolution, so that the
Packit 18d29c
	# linking checks with -shared actually have any value
Packit 18d29c
	#
Packit 18d29c
	# FIXME: -fPIC is required for -shared on many architectures,
Packit 18d29c
	# so we specify it here, but the right way would probably be to
Packit 18d29c
	# properly detect whether it is actually required.
Packit 18d29c
	CFLAGS="-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS"
Packit 18d29c
	LIBS="$PTHREAD_LIBS $LIBS"
Packit 18d29c
	CC="$PTHREAD_CC"
Packit 18d29c
	
Packit 18d29c
	# In order not to create several levels of indentation, we test
Packit 18d29c
	# the value of "$done" until we find the cure or run out of ideas.
Packit 18d29c
	done="no"
Packit 18d29c
	
Packit 18d29c
	# First, make sure the CFLAGS we added are actually accepted by our
Packit 18d29c
	# compiler.  If not (and OS X's ld, for instance, does not accept -z),
Packit 18d29c
	# then we can't do this test.
Packit 18d29c
	if test x"$done" = xno; then
Packit 18d29c
	   AC_MSG_CHECKING([whether to check for GCC pthread/shared inconsistencies])
Packit 18d29c
	   AC_TRY_LINK(,, , [done=yes])
Packit 18d29c
	
Packit 18d29c
	   if test "x$done" = xyes ; then
Packit 18d29c
	      AC_MSG_RESULT([no])
Packit 18d29c
	   else
Packit 18d29c
	      AC_MSG_RESULT([yes])
Packit 18d29c
	   fi
Packit 18d29c
	fi
Packit 18d29c
	
Packit 18d29c
	if test x"$done" = xno; then
Packit 18d29c
	   AC_MSG_CHECKING([whether -pthread is sufficient with -shared])
Packit 18d29c
	   AC_TRY_LINK([#include <pthread.h>],
Packit 18d29c
	      [pthread_t th; pthread_join(th, 0);
Packit 18d29c
	      pthread_attr_init(0); pthread_cleanup_push(0, 0);
Packit 18d29c
	      pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
Packit 18d29c
	      [done=yes])
Packit 18d29c
	   
Packit 18d29c
	   if test "x$done" = xyes; then
Packit 18d29c
	      AC_MSG_RESULT([yes])
Packit 18d29c
	   else
Packit 18d29c
	      AC_MSG_RESULT([no])
Packit 18d29c
	   fi
Packit 18d29c
	fi
Packit 18d29c
	
Packit 18d29c
	#
Packit 18d29c
	# Linux gcc on some architectures such as mips/mipsel forgets
Packit 18d29c
	# about -lpthread
Packit 18d29c
	#
Packit 18d29c
	if test x"$done" = xno; then
Packit 18d29c
	   AC_MSG_CHECKING([whether -lpthread fixes that])
Packit 18d29c
	   LIBS="-lpthread $PTHREAD_LIBS $save_LIBS"
Packit 18d29c
	   AC_TRY_LINK([#include <pthread.h>],
Packit 18d29c
	      [pthread_t th; pthread_join(th, 0);
Packit 18d29c
	      pthread_attr_init(0); pthread_cleanup_push(0, 0);
Packit 18d29c
	      pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
Packit 18d29c
	      [done=yes])
Packit 18d29c
	
Packit 18d29c
	   if test "x$done" = xyes; then
Packit 18d29c
	      AC_MSG_RESULT([yes])
Packit 18d29c
	      PTHREAD_LIBS="-lpthread $PTHREAD_LIBS"
Packit 18d29c
	   else
Packit 18d29c
	      AC_MSG_RESULT([no])
Packit 18d29c
	   fi
Packit 18d29c
	fi
Packit 18d29c
	#
Packit 18d29c
	# FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc
Packit 18d29c
	#
Packit 18d29c
	if test x"$done" = xno; then
Packit 18d29c
	   AC_MSG_CHECKING([whether -lc_r fixes that])
Packit 18d29c
	   LIBS="-lc_r $PTHREAD_LIBS $save_LIBS"
Packit 18d29c
	   AC_TRY_LINK([#include <pthread.h>],
Packit 18d29c
	       [pthread_t th; pthread_join(th, 0);
Packit 18d29c
	        pthread_attr_init(0); pthread_cleanup_push(0, 0);
Packit 18d29c
	        pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
Packit 18d29c
	       [done=yes])
Packit 18d29c
	
Packit 18d29c
	   if test "x$done" = xyes; then
Packit 18d29c
	      AC_MSG_RESULT([yes])
Packit 18d29c
	      PTHREAD_LIBS="-lc_r $PTHREAD_LIBS"
Packit 18d29c
	   else
Packit 18d29c
	      AC_MSG_RESULT([no])
Packit 18d29c
	   fi
Packit 18d29c
	fi
Packit 18d29c
	if test x"$done" = xno; then
Packit 18d29c
	   # OK, we have run out of ideas
Packit 18d29c
	   AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries])
Packit 18d29c
	
Packit 18d29c
	   # so it's not safe to assume that we may use pthreads
Packit 18d29c
	   acx_pthread_ok=no
Packit 18d29c
	fi
Packit 18d29c
	
Packit 18d29c
	CFLAGS="$save_CFLAGS"
Packit 18d29c
	LIBS="$save_LIBS"
Packit 18d29c
	CC="$save_CC"
Packit 18d29c
else
Packit 18d29c
        PTHREAD_CC="$CC"
Packit 18d29c
fi
Packit 18d29c
Packit 18d29c
AC_SUBST(PTHREAD_LIBS)
Packit 18d29c
AC_SUBST(PTHREAD_CFLAGS)
Packit 18d29c
AC_SUBST(PTHREAD_CC)
Packit 18d29c
Packit 18d29c
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
Packit 18d29c
if test x"$acx_pthread_ok" = xyes; then
Packit 18d29c
        ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
Packit 18d29c
        :
Packit 18d29c
else
Packit 18d29c
        acx_pthread_ok=no
Packit 18d29c
        $2
Packit 18d29c
fi
Packit 18d29c
AC_LANG_RESTORE
Packit 18d29c
])dnl ACX_PTHREAD