Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

1368 lines (1205 sloc) 37.249 kb
dnl ***********************************
dnl *** include special GLib macros ***
dnl ***********************************
builtin(include, acglib.m4)dnl
# require autoconf 2.13
AC_PREREQ(2.13)
# init autoconf (and check for presence of glist.c)
AC_INIT(glist.c)
# Save this value here, since automake will set cflags later
cflags_set=${CFLAGS+set}
# we rewrite this file
rm -f glibconfig-sysdefs.h
dnl we need to AC_DIVERT_PUSH/AC_DIVERT_POP these variable definitions so they
dnl are available for $ac_help expansion (don't we all *love* autoconf?)
AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)dnl
#
# The following version number definitions apply to GLib, GModule and GThread
# as a whole, so if changes occoured in any of them, they are all
# treated with the same interface and binary age.
#
# Making releases:
# GLIB_MICRO_VERSION += 1;
# GLIB_INTERFACE_AGE += 1;
# GLIB_BINARY_AGE += 1;
# if any functions have been added, set GLIB_INTERFACE_AGE to 0.
# if backwards compatibility has been broken,
# set GLIB_BINARY_AGE _and_ GLIB_INTERFACE_AGE to 0.
#
GLIB_MAJOR_VERSION=1
GLIB_MINOR_VERSION=2
GLIB_MICRO_VERSION=10
GLIB_INTERFACE_AGE=10
GLIB_BINARY_AGE=10
GLIB_VERSION=$GLIB_MAJOR_VERSION.$GLIB_MINOR_VERSION.$GLIB_MICRO_VERSION
dnl
AC_DIVERT_POP()dnl
AC_SUBST(GLIB_MAJOR_VERSION)
AC_SUBST(GLIB_MINOR_VERSION)
AC_SUBST(GLIB_MICRO_VERSION)
AC_SUBST(GLIB_VERSION)
AC_SUBST(GLIB_INTERFACE_AGE)
AC_SUBST(GLIB_BINARY_AGE)
# libtool versioning
LT_RELEASE=$GLIB_MAJOR_VERSION.$GLIB_MINOR_VERSION
LT_CURRENT=`expr $GLIB_MICRO_VERSION - $GLIB_INTERFACE_AGE`
LT_REVISION=$GLIB_INTERFACE_AGE
LT_AGE=`expr $GLIB_BINARY_AGE - $GLIB_INTERFACE_AGE`
AC_SUBST(LT_RELEASE)
AC_SUBST(LT_CURRENT)
AC_SUBST(LT_REVISION)
AC_SUBST(LT_AGE)
VERSION=$GLIB_VERSION
PACKAGE=glib
AM_INIT_AUTOMAKE($PACKAGE, $VERSION, no-define)
# Specify a configuration file
AM_CONFIG_HEADER(config.h)
AC_DEFINE_UNQUOTED(GLIB_MAJOR_VERSION, $GLIB_MAJOR_VERSION)
AC_DEFINE_UNQUOTED(GLIB_MINOR_VERSION, $GLIB_MINOR_VERSION)
AC_DEFINE_UNQUOTED(GLIB_MICRO_VERSION, $GLIB_MICRO_VERSION)
AC_DEFINE_UNQUOTED(GLIB_INTERFACE_AGE, $GLIB_INTERFACE_AGE)
AC_DEFINE_UNQUOTED(GLIB_BINARY_AGE, $GLIB_BINARY_AGE)
dnl Initialize libtool
AM_PROG_LIBTOOL
dnl Initialize maintainer mode
AM_MAINTAINER_MODE
AC_CANONICAL_HOST
dnl figure debugging default, prior to $ac_help setup
dnl
AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)dnl
if test `expr $GLIB_MINOR_VERSION \% 2` = 1 ; then
debug_default=yes
else
debug_default=minimum
fi
AC_DIVERT_POP()dnl
dnl declare --enable-* args and collect ac_help strings
AC_ARG_ENABLE(debug, [ --enable-debug=[no/minimum/yes] turn on debugging [default=$debug_default]],,enable_debug=$debug_default)
AC_ARG_ENABLE(mem_check, [ --enable-mem-check turn on malloc/free sanity checking (not recommended) [default=no]],,enable_mem_check=no)
AC_ARG_ENABLE(mem_profile, [ --enable-mem-profile turn on malloc profiling atexit (not recommended) [default=no]],,enable_mem_profile=no)
AC_ARG_ENABLE(ansi, [ --enable-ansi turn on strict ansi [default=no]],
, enable_ansi=no)
AC_ARG_ENABLE(threads, [ --enable-threads turn on basic thread support [default=yes]
([=no] will override --with-threads)],,enable_threads=yes)
if test "x$enable_threads" != "xyes"; then
enable_threads=no
fi
mem_warn=false
AC_MSG_CHECKING(whether to enable memory checking)
if test "x$enable_mem_check" = "xyes"; then
AC_DEFINE(ENABLE_MEM_CHECK, 1)
AC_SUBST(ENABLE_MEM_CHECK)
AC_MSG_RESULT(yes)
mem_warn=true
else
AC_MSG_RESULT(no)
fi
AC_MSG_CHECKING(whether to enable memory profiling)
if test "x$enable_mem_profile" = "xyes"; then
AC_DEFINE(ENABLE_MEM_PROFILE, 1)
AC_SUBST(ENABLE_MEM_PROFILE)
AC_MSG_RESULT(yes)
mem_warn=true
else
AC_MSG_RESULT(no)
fi
if $mem_warn ; then
AC_MSG_WARN([
**********************************************************************
You have specified --enable-mem-profile or --enable-mem-check.
These options are not recommended; they have not been thoroughly
tested, and may cause unwanted side-effects. If --enable-mem-check is
specified, NO MEMORY WILL BE FREED, EVER.
References to better memory debugging tools can be found at:
http://people.redhat.com/otaylor/memprof/memtools.html
**********************************************************************])
fi
if test "x$enable_debug" = "xyes"; then
test "$cflags_set" = set || CFLAGS="$CFLAGS -g"
GLIB_DEBUG_FLAGS="-DG_ENABLE_DEBUG"
else
if test "x$enable_debug" = "xno"; then
GLIB_DEBUG_FLAGS="-DG_DISABLE_ASSERT -DG_DISABLE_CHECKS"
fi
fi
AC_DEFINE_UNQUOTED(G_COMPILED_WITH_DEBUGGING, "${enable_debug}")
# Checks for programs.
AC_PROG_CC
AM_PROG_CC_STDC
AC_PROG_INSTALL
changequote(,)dnl
if test "x$GCC" = "xyes"; then
case " $CFLAGS " in
*[\ \ ]-Wall[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wall" ;;
esac
if test "x$enable_ansi" = "xyes"; then
case " $CFLAGS " in
*[\ \ ]-ansi[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -ansi" ;;
esac
case " $CFLAGS " in
*[\ \ ]-pedantic[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -pedantic" ;;
esac
fi
fi
changequote([,])dnl
dnl DU4 native cc currently needs -std1 for ANSI mode (instead of K&R)
AC_MSG_CHECKING([for extra flags to get ANSI library prototypes])
glib_save_LIBS=$LIBS
LIBS="$LIBS -lm"
AC_TRY_RUN([#include <math.h>
int main (void) { return (log(1) != log(1.)); }],
AC_MSG_RESULT(none needed),
glib_save_CFLAGS=$CFLAGS
CFLAGS="$CFLAGS -std1"
AC_TRY_RUN([#include <math.h>
int main (void) { return (log(1) != log(1.)); }],
AC_MSG_RESULT(-std1),
AC_MSG_RESULT()
CFLAGS=$glib_save_CFLAGS
AC_MSG_WARN(
[No ANSI prototypes found in library. (-std1 didn't work.)])
)
)
LIBS=$glib_save_LIBS
dnl NeXTStep cc seems to need this
AC_MSG_CHECKING([for extra flags for POSIX compliance])
AC_TRY_COMPILE([#include <dirent.h>], [DIR *dir;],
AC_MSG_RESULT(none needed),
glib_save_CFLAGS=$CFLAGS
CFLAGS="$CFLAGS -posix"
AC_TRY_COMPILE([#include <dirent.h>], [DIR *dir;],
AC_MSG_RESULT(-posix),
AC_MSG_RESULT()
CFLAGS=$glib_save_CFLAGS
AC_MSG_WARN([Could not determine POSIX flag. (-posix didn't work.)])))
# Checks for header files.
AC_HEADER_STDC
# Checks for library functions.
AC_FUNC_VPRINTF
AC_CHECK_FUNCS(atexit on_exit)
AC_CHECK_SIZEOF(char)
AC_CHECK_SIZEOF(short)
AC_CHECK_SIZEOF(long)
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(void *)
AC_CHECK_SIZEOF(long long)
dnl long doubles were not used, and a portability problem
dnl AC_C_LONG_DOUBLE
AC_C_CONST
dnl AC_C_INLINE is useless to us since it bails out too early, we need to
dnl truely know which ones of `inline', `__inline' and `__inline__' are
dnl actually supported.
AC_MSG_CHECKING(for __inline)
AC_CACHE_VAL(glib_cv_has__inline,[
AC_TRY_RUN([
__inline int foo () { return 0; }
int main () { return foo (); }
],
glib_cv_has__inline=yes
,
glib_cv_has__inline=no
,)
])
AC_MSG_RESULT($glib_cv_has__inline)
case x$glib_cv_has__inline in
xyes) AC_DEFINE(G_HAVE___INLINE)
esac
AC_MSG_CHECKING(for __inline__)
AC_CACHE_VAL(glib_cv_has__inline__,[
AC_TRY_RUN([
__inline__ int foo () { return 0; }
int main () { return foo (); }
],
glib_cv_has__inline__=yes
,
glib_cv_has__inline__=no
,)
])
AC_MSG_RESULT($glib_cv_has__inline__)
case x$glib_cv_has__inline__ in
xyes) AC_DEFINE(G_HAVE___INLINE__)
esac
AC_MSG_CHECKING(for inline)
AC_CACHE_VAL(glib_cv_hasinline,[
AC_TRY_RUN([
inline int foo () { return 0; }
int main () { return foo (); }
],
glib_cv_hasinline=yes
,
glib_cv_hasinline=no
,)
])
AC_MSG_RESULT($glib_cv_hasinline)
case x$glib_cv_hasinline in
xyes) AC_DEFINE(G_HAVE_INLINE)
esac
dnl for bytesex stuff
AC_C_BIGENDIAN
dnl header file checks
AC_CHECK_HEADERS(float.h, AC_DEFINE(HAVE_FLOAT_H))
AC_CHECK_HEADERS(limits.h, AC_DEFINE(HAVE_LIMITS_H))
AC_CHECK_HEADERS(pwd.h, AC_DEFINE(HAVE_PWD_H))
AC_CHECK_HEADERS(sys/param.h, AC_DEFINE(HAVE_SYS_PARAM_H))
AC_CHECK_HEADERS(sys/poll.h, AC_DEFINE(HAVE_SYS_POLL_H))
AC_CHECK_HEADERS(sys/select.h, AC_DEFINE(HAVE_SYS_SELECT_H))
AC_CHECK_HEADERS(sys/time.h, AC_DEFINE(HAVE_SYS_TIME_H))
AC_CHECK_HEADERS(sys/times.h, AC_DEFINE(HAVE_SYS_TIMES_H))
AC_CHECK_HEADERS(unistd.h, AC_DEFINE(HAVE_UNISTD_H))
AC_CHECK_HEADERS(values.h, AC_DEFINE(HAVE_VALUES_H))
# Check for some functions
AC_CHECK_FUNCS(lstat strerror strsignal memmove vsnprintf strcasecmp strncasecmp poll)
# Check for sys_errlist
AC_MSG_CHECKING(for sys_errlist)
AC_TRY_LINK(, [
extern char *sys_errlist[];
extern int sys_nerr;
sys_errlist[sys_nerr-1][0] = 0;
], glib_ok=yes, glib_ok=no)
AC_MSG_RESULT($glib_ok)
if test $glib_ok = no; then
AC_DEFINE(NO_SYS_ERRLIST)
fi
# Check for sys_siglist
AC_MSG_CHECKING(for sys_siglist)
AC_TRY_LINK(, [
extern char *sys_siglist[];
exit (sys_siglist[0]);
], glib_ok=yes, glib_ok=no)
AC_MSG_RESULT($glib_ok)
if test $glib_ok = no; then
AC_DEFINE(NO_SYS_SIGLIST)
fi
# Check for sys_siglist decl (see Tue Jan 19 00:44:24 1999 in changelog)
AC_MSG_CHECKING(for sys_siglist declaration)
AC_TRY_COMPILE([#include <signal.h>], [
strlen (sys_siglist[0]);
], glib_ok=yes, glib_ok=no)
AC_MSG_RESULT($glib_ok)
if test $glib_ok = no; then
AC_DEFINE(NO_SYS_SIGLIST_DECL)
fi
# Check if <sys/select.h> needs to be included for fd_set
AC_MSG_CHECKING([for fd_set])
AC_TRY_COMPILE([#include <sys/types.h>],
[fd_set readMask, writeMask;], gtk_ok=yes, gtk_ok=no)
if test $gtk_ok = yes; then
AC_MSG_RESULT([yes, found in sys/types.h])
else
AC_HEADER_EGREP(fd_mask, sys/select.h, gtk_ok=yes)
if test $gtk_ok = yes; then
AC_DEFINE(HAVE_SYS_SELECT_H)
AC_MSG_RESULT([yes, found in sys/select.h])
else
AC_DEFINE(NO_FD_SET)
AC_MSG_RESULT(no)
fi
fi
# These are used only in GDK (gdki18n.h)
# This stuff is here only so that we can define these
# things in glibconfig.h. If gtk+ started using an installed
# gdkconfig.h file, then the definitions would belong there.
# Check for wchar.h
AC_MSG_CHECKING(for wchar.h)
AC_TRY_CPP([#include <wchar.h>], glib_wchar_h=yes, glib_wchar_h=no)
if test $glib_wchar_h = yes; then
AC_DEFINE(HAVE_WCHAR_H)
fi
AC_MSG_RESULT($glib_wchar_h)
# Check for wctype.h (for iswalnum)
AC_MSG_CHECKING(for wctype.h)
AC_TRY_CPP([#include <wctype.h>], glib_wctype_h=yes, glib_wctype_h=no)
if test $glib_wctype_h = yes; then
AC_DEFINE(HAVE_WCTYPE_H)
fi
AC_MSG_RESULT($glib_wctype_h)
oLIBS="$LIBS"
# in Solaris 2.5, `iswalnum' is in -lw
AC_CHECK_FUNC(iswalnum,,[AC_CHECK_LIB(w,iswalnum)])
# The following is necessary for Linux libc-5.4.38
AC_MSG_CHECKING(if iswalnum() and friends are properly defined)
AC_TRY_LINK([#include <stdlib.h>],[
#if (defined(HAVE_WCTYPE_H) || defined(HAVE_WCHAR_H))
# ifdef HAVE_WCTYPE_H
# include <wctype.h>
# else
# ifdef HAVE_WCHAR_H
# include <wchar.h>
# endif
# endif
#else
# define iswalnum(c) ((wchar_t)(c) <= 0xFF && isalnum(c))
#endif
iswalnum((wchar_t) 0);
], glib_working_wctype=yes, glib_working_wctype=no)
LIBS="$oLIBS"
if test $glib_working_wctype = no; then
AC_DEFINE(HAVE_BROKEN_WCTYPE)
fi
AC_MSG_RESULT($glib_working_wctype)
dnl *** check for sane realloc() ***
AC_MSG_CHECKING(whether realloc (NULL,) will work)
AC_CACHE_VAL(glib_cv_sane_realloc,[
AC_TRY_RUN([
#include <stdlib.h>
int main() {
return realloc (0, sizeof (int)) == 0;
}],
glib_cv_sane_realloc=yes
AC_DEFINE(REALLOC_0_WORKS)
,
glib_cv_sane_realloc=no
,)
])
AC_MSG_RESULT($glib_cv_sane_realloc)
dnl **********************
dnl *** va_copy checks ***
dnl **********************
dnl we currently check for all three va_copy possibilities, so we get
dnl all results in config.log for bug reports.
AC_MSG_CHECKING(for an implementation of va_copy())
AC_CACHE_VAL(glib_cv_va_copy,[
AC_TRY_RUN([
#include <stdarg.h>
void f (int i, ...) {
va_list args1, args2;
va_start (args1, i);
va_copy (args2, args1);
if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42)
exit (1);
va_end (args1); va_end (args2);
}
int main() {
f (0, 42);
return 0;
}],
glib_cv_va_copy=yes
,
glib_cv_va_copy=no
,)
])
AC_MSG_RESULT($glib_cv_va_copy)
AC_MSG_CHECKING(for an implementation of __va_copy())
AC_CACHE_VAL(glib_cv___va_copy,[
AC_TRY_RUN([
#include <stdarg.h>
void f (int i, ...) {
va_list args1, args2;
va_start (args1, i);
__va_copy (args2, args1);
if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42)
exit (1);
va_end (args1); va_end (args2);
}
int main() {
f (0, 42);
return 0;
}],
glib_cv___va_copy=yes
,
glib_cv___va_copy=no
,)
])
AC_MSG_RESULT($glib_cv___va_copy)
AC_MSG_CHECKING(whether va_lists can be copied by value)
AC_CACHE_VAL(glib_cv_va_val_copy,[
AC_TRY_RUN([
#include <stdarg.h>
void f (int i, ...) {
va_list args1, args2;
va_start (args1, i);
args2 = args1;
if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42)
exit (1);
va_end (args1); va_end (args2);
}
int main() {
f (0, 42);
return 0;
}],
glib_cv_va_val_copy=yes
,
glib_cv_va_val_copy=no
,)
])
if test "x$glib_cv_va_copy" = "xyes"; then
AC_DEFINE(G_VA_COPY, va_copy)
else if test "x$glib_cv___va_copy" = "xyes"; then
AC_DEFINE(G_VA_COPY, __va_copy)
fi
fi
if test "x$glib_cv_va_val_copy" = "xno"; then
AC_DEFINE(G_VA_COPY_AS_ARRAY)
fi
AC_MSG_RESULT($glib_cv_va_val_copy)
dnl ***********************
dnl *** g_module checks ***
dnl ***********************
G_MODULE_LIBS=
G_MODULE_LDFLAGS=
dnl G_MODULE_IMPL= don't reset, so cmd-line can override
G_MODULE_NEED_USCORE=0
G_MODULE_BROKEN_RTLD_GLOBAL=0
G_MODULE_HAVE_DLERROR=0
dnl *** dlopen() and dlsym() in system libraries
if test -z "$G_MODULE_IMPL"; then
AC_CHECK_FUNC(dlopen,
AC_CHECK_FUNC(dlsym,
G_MODULE_IMPL=G_MODULE_IMPL_DL
,)
,)
fi
dnl *** dlopen() and dlsym() in libdl
if test -z "$G_MODULE_IMPL"; then
AC_CHECK_LIB(dl, dlopen,
AC_CHECK_LIB(dl, dlsym,
G_MODULE_LIBS=-ldl
G_MODULE_IMPL=G_MODULE_IMPL_DL
,)
,)
fi
dnl *** shl_load() in libdld (HP-UX)
if test -z "$G_MODULE_IMPL"; then
AC_MSG_CHECKING(how to export all symbols)
SAVED_LDFLAGS=$LDFLAGS
LDFLAGS="$LDFLAGS -Wl,-E"
AC_TRY_LINK(,[ return 0; ],
[ G_MODULE_LDFLAGS="-Wl,-E" ],[
LDFLAGS="$SAVED_LDFLAGS -bexpall"
AC_TRY_LINK(,[ return 0; ],
G_MODULE_LDFLAGS="-bexpall",
G_MODULE_LDFLAGS="none"
)
])
LDFLAGS=$SAVED_LDFLAGS
AC_MSG_RESULT($G_MODULE_LDFLAGS)
if test "x$G_MODULE_LDFLAGS" = "xnone"; then
G_MODULE_LDFLAGS=
fi
AC_CHECK_LIB(dld, shl_load,
G_MODULE_LIBS=-ldld
G_MODULE_IMPL=G_MODULE_IMPL_DLD
,)
fi
dnl *** additional checks for G_MODULE_IMPL_DL
if test "$G_MODULE_IMPL" = "G_MODULE_IMPL_DL"; then
case "$host_os" in
linux*)
G_MODULE_LDFLAGS='-rdynamic'
;;
esac
LIBS_orig="$LIBS"
LDFLAGS_orig="$LDFLAGS"
LIBS="$LIBS $G_MODULE_LIBS"
LDFLAGS="$LDFLAGS $G_MODULE_LDFLAGS"
dnl *** check for OSF1/5.0 RTLD_GLOBAL brokenness
AC_CACHE_CHECK([for RTLD_GLOBAL brokenness],
glib_cv_rtldglobal_broken,[
AC_TRY_RUN([
#include <dlfcn.h>
#ifndef RTLD_GLOBAL
#define RTLD_GLOBAL 0
#endif
#ifndef RTLD_LAZY
#define RTLD_LAZY 0
#endif
int pthread_create;
int main () {
void *handle, *global, *local;
global = &pthread_create;
handle = dlopen ("libpthread.so", RTLD_GLOBAL | RTLD_LAZY);
if (!handle) return 0;
local = dlsym (handle, "pthread_create");
return global == local;
}],
[glib_cv_rtldglobal_broken=no],
[glib_cv_rtldglobal_broken=yes],
[])
rm -f plugin.c plugin.o plugin.lo
])
if test "x$glib_cv_rtldglobal_broken" = "xyes"; then
G_MODULE_BROKEN_RTLD_GLOBAL=1
else
G_MODULE_BROKEN_RTLD_GLOBAL=0
fi
dnl *** check whether we need preceeding underscores
AC_MSG_CHECKING(for preceeding underscore in symbols)
AC_CACHE_VAL(glib_cv_uscore,[
AC_TRY_RUN([
#include <dlfcn.h>
int glib_underscore_test (void) { return 42; }
int main() {
void *f1 = (void*)0, *f2 = (void*)0, *handle;
handle = dlopen ((void*)0, 0);
if (handle) {
f1 = dlsym (handle, "glib_underscore_test");
f2 = dlsym (handle, "_glib_underscore_test");
} return (!f2 || f1);
}],
glib_cv_uscore=yes,
glib_cv_uscore=no,
)
rm -f plugin.c plugin.o plugin.lo
])
AC_MSG_RESULT($glib_cv_uscore)
if test "x$glib_cv_uscore" = "xyes"; then
G_MODULE_NEED_USCORE=1
else
G_MODULE_NEED_USCORE=0
fi
LDFLAGS="$LDFLAGS_orig"
dnl *** check for having dlerror()
AC_CHECK_FUNC(dlerror,
G_MODULE_HAVE_DLERROR=1,
G_MODULE_HAVE_DLERROR=0)
LIBS="$LIBS_orig"
fi
dnl *** done, have e got an implementation?
if test -z "$G_MODULE_IMPL"; then
G_MODULE_IMPL=0
fi
AC_SUBST(G_MODULE_IMPL)
AC_SUBST(G_MODULE_LIBS)
AC_SUBST(G_MODULE_LDFLAGS)
AC_SUBST(G_MODULE_HAVE_DLERROR)
AC_SUBST(G_MODULE_NEED_USCORE)
AC_SUBST(G_MODULE_BROKEN_RTLD_GLOBAL)
AC_SUBST(GLIB_DEBUG_FLAGS)
dnl ***********************
dnl *** g_thread checks ***
dnl ***********************
AC_ARG_WITH(threads, [ --with-threads=[none/posix/solaris/nspr] specify a thread implementation to use],
if test "x$with_threads" = x; then
want_threads=yes
else
want_threads=$with_threads
fi,
want_threads=yes)
if test "x$enable_threads" = "xno"; then
want_threads=no
fi
if test "x$want_threads" = "xnone"; then
want_threads=no
fi
dnl error and warning message
dnl *************************
THREAD_NO_IMPLEMENTATION="You do not have any known thread system on your
computer. glib will not be thread safe on your computer."
FLAG_DOES_NOT_WORK="I can't find the MACRO, that enables thread safety on your
platform (normally it's "_REENTRANT"). I'll not use any flag on
compilation now, but then your programs might not work.
Please provide information on how it is done on your system."
LIBS_NOT_FOUND_1="I can't find the libraries for the thread implementation
"
LIBS_NOT_FOUND_2=". Please choose another thread implementation or
provide information on your thread implementation.
You can also run 'configure --disable-threads'
to compile without thread support."
FUNC_NO_GETPWUID_R="the 'g_get_(user_name|real_name|home_dir|tmp_dir)'
functions will not be MT-safe during their first call because
there is no working 'getpwuid_r' on your system."
FUNC_NO_LOCALTIME_R="the 'g_date_set_time' function will not be MT-safe
because there is no 'localtime_r' on your system."
dnl determination of thread implementation
dnl ***************************************
have_threads=none
if test "x$want_threads" = xyes || test "x$want_threads" = xsolaris; then
case $host in
*-*-solaris*)
AC_CHECK_LIB(thread, cond_init, have_threads=solaris)
;;
esac
fi
if test "x$want_threads" = xyes || test "x$want_threads" = xposix; then
if test "x$have_threads" = xnone; then
AC_CHECK_HEADER(pthread.h, have_threads=posix)
fi
fi
if test "x$want_threads" = xyes || test "x$want_threads" = xnspr; then
if test "x$have_threads" = xnone; then
AC_CHECK_LIB(nspr21, PRP_NewNakedCondVar, have_threads=nspr)
fi
fi
AC_MSG_CHECKING(for thread implementation)
if test "x$have_threads" = xnone && test "x$want_threads" != xno; then
AC_MSG_RESULT(none available)
AC_MSG_WARN($THREAD_NO_IMPLEMENTATION)
else
AC_MSG_RESULT($have_threads)
fi
dnl determination of G_THREAD_LIBS
dnl ******************************
G_THREAD_LIBS=
G_THREAD_CFLAGS=
mutex_has_default=no
case $have_threads in
posix)
G_THREAD_LIBS=error
AC_CHECK_LIB(pthread, pthread_attr_init,
G_THREAD_LIBS="-lpthread")
if test "x$G_THREAD_LIBS" = xerror; then
AC_CHECK_LIB(pthreads, pthread_attr_init,
G_THREAD_LIBS="-lpthreads")
fi
if test "x$G_THREAD_LIBS" = xerror; then
AC_CHECK_LIB(thread, pthread_attr_init,
G_THREAD_LIBS="-lthread")
fi
if test "x$G_THREAD_LIBS" = xerror; then
AC_CHECK_LIB(c_r, pthread_attr_init,
G_THREAD_LIBS="-lc_r")
fi
if test "x$G_THREAD_LIBS" = xerror; then
AC_CHECK_FUNC(pthread_attr_init, G_THREAD_LIBS="")
fi
dnl ********** DG/UX ************
if test "x$G_THREAD_LIBS" = xerror; then
AC_CHECK_LIB(thread, __d10_pthread_attr_init,
G_THREAD_LIBS="-lthread"
G_THREAD_CFLAGS="-D_POSIX4A_DRAFT10_SOURCE")
fi
dnl ********* HPUX 11 ***********
if test "x$G_THREAD_LIBS" = xerror; then
AC_CHECK_LIB(pthread, __pthread_attr_init_system,
G_THREAD_LIBS="-lpthread")
fi
mutex_has_default=yes
mutex_default_type='pthread_mutex_t'
mutex_default_init='PTHREAD_MUTEX_INITIALIZER'
mutex_header_file='pthread.h'
g_threads_impl="POSIX"
;;
solaris)
G_THREAD_LIBS=error
AC_CHECK_LIB(thread, cond_init, G_THREAD_LIBS="-lthread")
mutex_has_default=yes
mutex_default_type='mutex_t'
mutex_default_init="DEFAULTMUTEX"
mutex_header_file='thread.h'
g_threads_impl="SOLARIS"
;;
nspr)
AC_CHECK_LIB(nspr21, PRP_NewNakedCondVar,
G_THREAD_LIBS="-lnspr21")
g_threads_impl="NSPR"
;;
none)
g_threads_impl="NONE"
;;
*)
g_threads_impl="NONE"
G_THREAD_LIBS=error
;;
esac
if test "x$G_THREAD_LIBS" = xerror; then
AC_MSG_ERROR($LIBS_NOT_FOUND_1$have_threads$LIBS_NOT_FOUND_2)
fi
AC_MSG_CHECKING(necessary linker options)
AC_MSG_RESULT($G_THREAD_LIBS)
dnl determination of G_THREAD_CFLAGS
dnl ********************************
if test x"$have_threads" != xnone; then
G_THREAD_CFLAGS="$G_THREAD_CFLAGS -D_REENTRANT" # good default guess
case $host in
*-aix*)
G_THREAD_CFLAGS="$G_THREAD_CFLAGS -D_THREAD_SAFE"
if test x"$GCC" = xyes; then
G_THREAD_CFLAGS="$G_THREAD_CFLAGS -mthreads"
fi
;;
*-freebsd2.2*)
G_THREAD_CFLAGS="$G_THREAD_CFLAGS -D_THREAD_SAFE"
# FreeBSD 2.2.x shiped with gcc 2.7.2.x, which doesn't support
# -mthreads flag.
;;
esac
# if we are not finding the ctime_r function, then we probably are
# not using the proper multithread flag
# Note: Digital UNIX 4.0d #defines ctime_r to _Pctime_r for gcc.
old_CPPFLAGS=$CPPFLAGS
CPPFLAGS="$CPPFLAGS $G_THREAD_CFLAGS"
AC_EGREP_HEADER([[^a-zA-Z_](_P)?ctime_r[^a-zA-Z_]], time.h, ,
G_THREAD_CFLAGS=
AC_MSG_WARN($FLAG_DOES_NOT_WORK))
CPPFLAGS=$old_CPPFLAGS
AC_MSG_CHECKING(necessary compiler options)
AC_MSG_RESULT($G_THREAD_CFLAGS)
else
G_THREAD_CFLAGS=
fi
dnl check for mt safe function variants
dnl ***********************************
if test x"$have_threads" != xnone; then
glib_save_LIBS="$LIBS"
glib_save_CFLAGS="$CFLAGS"
# we are not doing the following for now, as this might require glib
# to always be linked with the thread libs on some platforms.
# LIBS="$LIBS $G_THREAD_LIBS"
CFLAGS="$CFLAGS $G_THREAD_CFLAGS"
AC_CHECK_FUNCS(localtime_r rand_r)
if test "$ac_cv_header_pwd_h" = "yes"; then
AC_MSG_CHECKING([for getpwuid_r])
AC_CACHE_VAL(ac_cv_func_getpwuid_r,
[AC_TRY_RUN([#include <errno.h>
int main () { char buffer[10000], *pointer;
char getpwuid_r (long, void*, void*,
int, void*);
int error;
errno = 0;
error = getpwuid_r (0, &buffer, &buffer,
sizeof (buffer), &pointer);
return errno == ENOSYS || error == ENOSYS;}],
[ac_cv_func_getpwuid_r=yes],
[ac_cv_func_getpwuid_r=no])])
if test "$ac_cv_func_getpwuid_r" = yes; then
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_GETPWUID_R)
else
AC_MSG_RESULT(no)
fi
if test "$ac_cv_func_getpwuid_r" = "yes"; then
AC_MSG_CHECKING(whether getpwuid_r is posix like)
# The signature for the POSIX version is:
# int getpwuid_r(uid_t, struct passwd *, char *, size_t, struct passwd **)
AC_TRY_COMPILE([#include <pwd.h>
#include <sys/types.h>
#include <stdlib.h>],
[getpwuid_r((uid_t)0, NULL, NULL, (size_t)0, NULL);],
[AC_DEFINE(HAVE_GETPWUID_R_POSIX)
AC_MSG_RESULT(yes)],
[AC_MSG_RESULT(no)])
fi
fi
if test x"$have_threads" = xposix; then
LIBS="$LIBS $G_THREAD_LIBS"
AC_MSG_CHECKING(whether pthread_getspecific is posix like)
# PCThreads has pthread_getspecific(pthread_key_t, void **);
AC_TRY_COMPILE([#include <pthread.h>],
[pthread_getspecific(0,NULL);],
[AC_MSG_RESULT(no)],
[AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_PTHREAD_GETSPECIFIC_POSIX)])
AC_MSG_CHECKING(whether pthread_mutex_trylock is posix like)
# DCE Threads return 1 as success, posix 0. what a mess.
AC_TRY_RUN([#include <pthread.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int main () {
return !pthread_mutex_trylock (&mutex); }],
[AC_MSG_RESULT(no)],
[AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_PTHREAD_MUTEX_TRYLOCK_POSIX)])
AC_MSG_CHECKING(whether pthread_cond_timedwait is posix like)
# DCE Threads return -1 as failure, posix ETIMEDOUT.
AC_TRY_RUN([#include <pthread.h>
int main () {
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
struct timeval tval;
struct timespec tspec;
gettimeofday (&tval, NULL);
tspec.tv_sec = tval.tv_sec;
tspec.tv_nsec = 0;
return pthread_cond_timedwait (&cond,&mutex,&tspec)
!= -1;}],
[AC_MSG_RESULT(no)],
[AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_PTHREAD_COND_TIMEDWAIT_POSIX)])
fi
LIBS="$glib_save_LIBS"
CFLAGS="$glib_save_CFLAGS"
fi
if test "x$enable_threads" = "xyes"; then
if test "$ac_cv_func_getpwuid_r" != "yes"; then
AC_MSG_WARN($FUNC_NO_GETPWUID_R)
fi
if test "$ac_cv_func_localtime_r" != "yes"; then
AC_MSG_WARN($FUNC_NO_LOCALTIME_R)
fi
fi
AC_DEFINE_UNQUOTED(G_THREAD_SOURCE,"gthread-$have_threads.c")
AC_SUBST(G_THREAD_CFLAGS)
AC_SUBST(G_THREAD_LIBS)
CFLAGS="$CFLAGS $G_THREAD_CFLAGS"
dnl **********************************************
dnl *** GDefaultMutex setup and initialization ***
dnl **********************************************
dnl
dnl if mutex_has_default = yes, we also got
dnl mutex_default_type, mutex_default_init and mutex_header_file
GLIB_IF_VAR_EQ(mutex_has_default, yes,
GLIB_SIZEOF([#include <$mutex_header_file>],
$mutex_default_type,
gmutex,
)
GLIB_BYTE_CONTENTS([#include <$mutex_header_file>],
$mutex_default_type,
gmutex,
$glib_cv_sizeof_gmutex,
$mutex_default_init)
,
)
dnl ****************************************
dnl *** GLib POLL* compatibility defines ***
dnl ****************************************
GLIB_SYSDEFS(
[#include <sys/types.h>
#include <sys/poll.h>],
POLLIN:1 POLLOUT:4 POLLPRI:2 POLLERR:8 POLLHUP:16 POLLNVAL:32,
glibconfig-sysdefs.h,
=)
dnl ******************************
dnl *** output the whole stuff ***
dnl ******************************
AC_OUTPUT_COMMANDS([
## Generate `glibconfig.h' in two cases
## 1. `config.status' is run either explicitly, or via configure.
## Esp. not when it is run in `Makefile' to generate makefiles and
## config.h
## 2. CONFIG_OTHER is set explicitly
##
## Case 1 is difficult. We know that `automake' sets one of
## CONFIG_FILES or CONFIG_HEADERS to empty. This heuristic works
## only when AM_CONFIG_HEADER is set, however.
if test -n "${CONFIG_FILES}" && test -n "${CONFIG_HEADERS}"; then
# Both CONFIG_FILES and CONFIG_HEADERS are non-empty ==> Case 1
CONFIG_OTHER=${CONFIG_OTHER:-glibconfig.h}
fi
case "$CONFIG_OTHER" in
*glibconfig.h*)
echo creating glibconfig.h
outfile=glibconfig.h-tmp
cat > $outfile <<\_______EOF
/* glibconfig.h
*
* This is a generated file. Please modify `configure.in'
*/
#ifndef GLIBCONFIG_H
#define GLIBCONFIG_H
_______EOF
if test x$glib_limits_h = xyes; then
echo '#include <limits.h>' >> $outfile
fi
if test x$glib_float_h = xyes; then
echo '#include <float.h>' >> $outfile
fi
if test x$glib_values_h = xyes; then
echo '#include <values.h>' >> $outfile
fi
if test x$g_mutex_header_file != x; then
echo '#include <'"$g_mutex_header_file"'>' >> $outfile
fi
if test x$glib_sys_poll_h = xyes; then
echo '#define GLIB_HAVE_SYS_POLL_H' >> $outfile
fi
cat >> $outfile <<_______EOF
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define G_MINFLOAT $glib_mf
#define G_MAXFLOAT $glib_Mf
#define G_MINDOUBLE $glib_md
#define G_MAXDOUBLE $glib_Md
#define G_MINSHORT $glib_ms
#define G_MAXSHORT $glib_Ms
#define G_MININT $glib_mi
#define G_MAXINT $glib_Mi
#define G_MINLONG $glib_ml
#define G_MAXLONG $glib_Ml
_______EOF
### this should always be true in a modern C/C++ compiler
cat >>$outfile <<_______EOF
typedef signed char gint8;
typedef unsigned char guint8;
_______EOF
if test -n "$gint16"; then
cat >>$outfile <<_______EOF
typedef signed $gint16 gint16;
typedef unsigned $gint16 guint16;
_______EOF
fi
if test -n "$gint32"; then
cat >>$outfile <<_______EOF
typedef signed $gint32 gint32;
typedef unsigned $gint32 guint32;
_______EOF
fi
if test -n "$gint64"; then
cat >>$outfile <<_______EOF
${glib_warning_guard}#define G_HAVE_GINT64 1
${glib_extension}typedef signed $gint64 gint64;
${glib_extension}typedef unsigned $gint64 guint64;
#define G_GINT64_CONSTANT(val) $gint64_constant
_______EOF
fi
if test -z "$glib_unknown_void_p"; then
cat >>$outfile <<_______EOF
#define GPOINTER_TO_INT(p) ((gint) ${glib_gpi_cast} (p))
#define GPOINTER_TO_UINT(p) ((guint) ${glib_gpui_cast} (p))
#define GINT_TO_POINTER(i) ((gpointer) ${glib_gpi_cast} (i))
#define GUINT_TO_POINTER(u) ((gpointer) ${glib_gpui_cast} (u))
_______EOF
else
echo '#error SIZEOF_VOID_P unknown - This should never happen' >>$outfile
fi
cat >>$outfile <<_______EOF
$glib_atexit
$glib_memmove
$glib_defines
$glib_vacopy
#ifdef __cplusplus
#define G_HAVE_INLINE 1
#else /* !__cplusplus */
$glib_inline
#endif /* !__cplusplus */
_______EOF
echo >>$outfile
if test x$g_mutex_has_default = xyes; then
cat >>$outfile <<_______EOF
$g_enable_threads_def G_THREADS_ENABLED
#define G_THREADS_IMPL_$g_threads_impl_def
typedef struct _GStaticMutex GStaticMutex;
struct _GStaticMutex
{
struct _GMutex *runtime_mutex;
union {
char pad[$g_mutex_sizeof];
double dummy_double;
void *dummy_pointer;
long dummy_long;
} aligned_pad_u;
};
#define G_STATIC_MUTEX_INIT { NULL, { { $g_mutex_contents} } }
#define g_static_mutex_get_mutex(mutex) \
(g_thread_use_default_impl ? ((GMutex*) &((mutex)->aligned_pad_u)) : \
g_static_mutex_get_mutex_impl (&((mutex)->runtime_mutex)))
_______EOF
else
cat >>$outfile <<_______EOF
$g_enable_threads_def G_THREADS_ENABLED
#define G_THREADS_IMPL_$g_threads_impl_def
typedef struct _GMutex* GStaticMutex;
#define G_STATIC_MUTEX_INIT NULL
#define g_static_mutex_get_mutex(mutex) (g_static_mutex_get_mutex_impl (mutex))
_______EOF
fi
echo >>$outfile
g_bit_sizes="16 32"
if test -n "$gint64"; then
g_bit_sizes="$g_bit_sizes 64"
fi
for bits in $g_bit_sizes; do
cat >>$outfile <<_______EOF
#define GINT${bits}_TO_${g_bs_native}(val) ((gint${bits}) (val))
#define GUINT${bits}_TO_${g_bs_native}(val) ((guint${bits}) (val))
#define GINT${bits}_TO_${g_bs_alien}(val) ((gint${bits}) GUINT${bits}_SWAP_LE_BE (val))
#define GUINT${bits}_TO_${g_bs_alien}(val) (GUINT${bits}_SWAP_LE_BE (val))
_______EOF
done
cat >>$outfile <<_______EOF
#define GLONG_TO_LE(val) ((glong) GINT${glongbits}_TO_LE (val))
#define GULONG_TO_LE(val) ((gulong) GUINT${glongbits}_TO_LE (val))
#define GLONG_TO_BE(val) ((glong) GINT${glongbits}_TO_BE (val))
#define GULONG_TO_BE(val) ((gulong) GUINT${glongbits}_TO_BE (val))
#define GINT_TO_LE(val) ((gint) GINT${gintbits}_TO_LE (val))
#define GUINT_TO_LE(val) ((guint) GUINT${gintbits}_TO_LE (val))
#define GINT_TO_BE(val) ((gint) GINT${gintbits}_TO_BE (val))
#define GUINT_TO_BE(val) ((guint) GUINT${gintbits}_TO_BE (val))
#define G_BYTE_ORDER $g_byte_order
_______EOF
if test -r glibconfig-sysdefs.h; then
cat glibconfig-sysdefs.h >>$outfile
fi
cat >>$outfile <<_______EOF
$glib_wc
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* GLIBCONFIG_H */
_______EOF
if cmp -s $outfile glibconfig.h; then
echo glibconfig.h is unchanged
rm -f $outfile
else
mv $outfile glibconfig.h
fi ;;
esac
],[
# Note that if two cases are the same, case goes with the first one.
# Note also that this is inside an AC_OUTPUT_COMMAND. We do not depend
# on variable expansion in case labels. Look at the generated config.status
# for a hint.
case xyes in
x$ac_cv_header_float_h)
glib_float_h=yes
glib_mf=FLT_MIN glib_Mf=FLT_MAX
glib_md=DBL_MIN glib_Md=DBL_MAX
;;
x$ac_cv_header_values_h)
glib_values_h=yes
glib_mf=MINFLOAT glib_Mf=MAXFLOAT
glib_md=MINDOUBLE glib_Md=MAXDOUBLE
;;
esac
case xyes in
x$ac_cv_header_limits_h)
glib_limits_h=yes
glib_ms=SHRT_MIN glib_Ms=SHRT_MAX
glib_mi=INT_MIN glib_Mi=INT_MAX
glib_ml=LONG_MIN glib_Ml=LONG_MAX
;;
x$ac_cv_header_values_h)
glib_values_h=yes
glib_ms=MINSHORT glib_Ms=MAXSHORT
glib_mi=MININT glib_Mi=MAXINT
glib_ml=MINLONG glib_Ml=MAXLONG
;;
esac
if test x$ac_cv_header_sys_poll_h = xyes ; then
glib_sys_poll_h=yes
fi
case 2 in
$ac_cv_sizeof_short) gint16=short;;
$ac_cv_sizeof_int) gint16=int;;
esac
case 4 in
$ac_cv_sizeof_short) gint32=short;;
$ac_cv_sizeof_int) gint32=int;;
$ac_cv_sizeof_long) gint32=long;;
esac
case 8 in
$ac_cv_sizeof_int)
gint64=int
glib_extension=
glib_warning_guard=
gint64_constant='(val)'
;;
$ac_cv_sizeof_long)
gint64=long
glib_extension=
glib_warning_guard=
gint64_constant='(val##L)'
;;
$ac_cv_sizeof_long_long)
gint64='long long'
glib_extension='G_GNUC_EXTENSION '
glib_warning_guard="
#if defined (__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8))
# define G_GNUC_EXTENSION __extension__
#else
# define G_GNUC_EXTENSION
#endif
"
gint64_constant='(G_GNUC_EXTENSION (val##LL))'
;;
esac
gintbits=`expr $ac_cv_sizeof_int \* 8`
glongbits=`expr $ac_cv_sizeof_long \* 8`
case $ac_cv_sizeof_void_p in
$ac_cv_sizeof_int) glib_gpi_cast='' glib_gpui_cast='' ;;
$ac_cv_sizeof_long) glib_gpi_cast='(glong)' glib_gpui_cast='(gulong)' ;;
*) glib_unknown_void_p=yes ;;
esac
case xyes in
x$ac_cv_func_atexit)
glib_atexit="
#ifdef NeXT /* @#%@! NeXTStep */
# define g_ATEXIT(proc) (!atexit (proc))
#else
# define g_ATEXIT(proc) (atexit (proc))
#endif"
;;
x$ac_cv_func_on_exit)
glib_atexit="
#define g_ATEXIT(proc) (on_exit ((void (*)(int, void*))(proc), NULL))"
;;
esac
case xyes in
x$ac_cv_func_memmove)
glib_memmove='
#define g_memmove(d,s,n) G_STMT_START { memmove ((d), (s), (n)); } G_STMT_END'
;;
*)
glib_memmove="
/* We make the assumption that if memmove isn't available, then
* bcopy will do the job. This isn't safe everywhere. (bcopy can't
* necessarily handle overlapping copies) */
#define g_memmove(d,s,n) G_STMT_START { bcopy ((s), (d), (n)); } G_STMT_END"
;;
esac
glib_defines="
#define GLIB_MAJOR_VERSION $GLIB_MAJOR_VERSION
#define GLIB_MINOR_VERSION $GLIB_MINOR_VERSION
#define GLIB_MICRO_VERSION $GLIB_MICRO_VERSION
"
case xyes in
x$glib_cv_va_copy) glib_vacopy='#define G_VA_COPY va_copy' ;;
x$glib_cv___va_copy) glib_vacopy='#define G_VA_COPY __va_copy' ;;
*) glib_vacopy=''
esac
if test x$glib_cv_va_val_copy = xno; then
glib_vacopy="\$glib_vacopy
#define G_VA_COPY_AS_ARRAY 1"
fi
if test x$glib_cv_hasinline = xyes; then
glib_inline='#define G_HAVE_INLINE 1'
fi
if test x$glib_cv_has__inline = xyes; then
glib_inline="\$glib_inline
#define G_HAVE___INLINE 1"
fi
if test x$glib_cv_has__inline__ = xyes; then
glib_inline="\$glib_inline
#define G_HAVE___INLINE__ 1"
fi
case xyes in
x$ac_cv_c_bigendian)
g_byte_order=G_BIG_ENDIAN
g_bs_native=BE
g_bs_alien=LE
;;
*)
g_byte_order=G_LITTLE_ENDIAN
g_bs_native=LE
g_bs_alien=BE
;;
esac
if test x$glib_wchar_h = xyes; then
glib_wc='
#define G_HAVE_WCHAR_H 1'
fi
if test x$glib_wctype_h = xyes; then
glib_wc="\$glib_wc
#define G_HAVE_WCTYPE_H 1"
fi
if test x$glib_working_wctype = xno; then
glib_wc="\$glib_wc
#define G_HAVE_BROKEN_WCTYPE 1"
fi
case x$enable_threads in
xyes) g_enable_threads_def="#define";;
*) g_enable_threads_def="#undef ";;
esac
g_threads_impl_def=$g_threads_impl
g_mutex_has_default="$mutex_has_default"
g_mutex_sizeof="$glib_cv_sizeof_gmutex"
g_mutex_contents="$glib_cv_byte_contents_gmutex"
])
AC_OUTPUT([
glib.spec
Makefile
glib-config
gmodule/gmoduleconf.h
gmodule/Makefile
gthread/Makefile
docs/Makefile
docs/glib-config.1
tests/Makefile
glib.pc
gmodule.pc
gthread.pc
],[case "$CONFIG_FILES" in
*glib-config*)chmod +x glib-config;;
esac])
Jump to Line
Something went wrong with that request. Please try again.