Skip to content

Commit

Permalink
pythongh-109054: configure checks if libatomic is needed
Browse files Browse the repository at this point in the history
Fix building the _testcapi extension on Linux AArch64 which requires
linking to libatomic when <cpython/pyatomic.h> is used: the
_Py_atomic_or_uint64() function requires libatomic
__atomic_fetch_or_8() on this platform.

The configure script now checks if linking to libatomic is needed and
generates a new LIBATOMIC variable used to build the _testcapi
extension.

Building the _testcapi extension now uses the LIBATOMIC variable in
its LDFLAGS, since Modules/_testcapi/pyatomic.c uses
<cpython/pyatomic.h>.
  • Loading branch information
vstinner committed Sep 8, 2023
1 parent 00cf626 commit e241894
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 2 deletions.
1 change: 1 addition & 0 deletions Makefile.pre.in
Expand Up @@ -267,6 +267,7 @@ STATIC_LIBPYTHON= @STATIC_LIBPYTHON@

LIBS= @LIBS@
LIBM= @LIBM@
LIBATOMIC= @LIBATOMIC@
LIBC= @LIBC@
SYSLIBS= $(LIBM) $(LIBC)
SHLIBS= @SHLIBS@
Expand Down
@@ -0,0 +1,6 @@
Fix building the ``_testcapi`` extension on Linux AArch64 which requires
linking to libatomic when ``<cpython/pyatomic.h>`` is used: the
``_Py_atomic_or_uint64()`` function requires libatomic
``__atomic_fetch_or_8()`` on this platform. The configure script now checks
if linking to libatomic is needed and generates a new LIBATOMIC variable
used to build the _testcapi extension. Patch by Victor Stinner.
90 changes: 89 additions & 1 deletion configure

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

68 changes: 67 additions & 1 deletion configure.ac
Expand Up @@ -6962,6 +6962,68 @@ then
[Define if you want to disable the GIL])
fi

# gh-109054: Check if -latomic is needed to get <pyatomic.h> atomic functions.
# On aarch64, GCC may require programs to be linked explicitly to libatomic.
# Use _Py_atomic_or_uint64() which may require libatomic __atomic_fetch_or_8()
# on Linux aarch64 (or not depending on the compiler and the compiler flags).
#
# Avoid #include <Python.h> or #include <pyport.h>. The <Python.h> header
# requires <pyconfig.h> header which is only written below by AC_OUTPUT below.
# If the check is done after AC_OUTPUT, modifying LIBS has no effect anymore.
# <pyport.h> cannot be included alone, it's designed to be included by
# <Python.h>: it expects other includes and macros to be defined.
AC_SUBST([LIBATOMIC])
LIBATOMIC=""

_SAVE_VAR([CPPFLAGS])
CPPFLAGS="${BASECPPFLAGS} -I. -I${srcdir}/Include ${CPPFLAGS}"

AC_CACHE_CHECK([whether libatomic is needed by <pyatomic.h>],
[ac_cv_libatomic_needed],
[AC_RUN_IFELSE([AC_LANG_SOURCE([[
// pyatomic.h needs uint64_t and Py_ssize_t types
#include <stdint.h> // int64_t, intptr_t
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h> // ssize_t
#endif
// Code adapted from Include/pyport.h
#if HAVE_SSIZE_T
typedef ssize_t Py_ssize_t;
#elif SIZEOF_VOID_P == SIZEOF_SIZE_T
typedef intptr_t Py_ssize_t;
#else
# error "unable to find a type fitting ssize_t"
#endif
#include "cpython/pyatomic.h"
int main()
{
// use _Py_atomic_or_uint64() which requires libatomic __atomic_fetch_or_8()
// on Linux aarch64.
uint64_t byte;
_Py_atomic_store_uint64(&byte, 2);
if (_Py_atomic_or_uint64(&byte, 8) != 2) {
return 1; // error
}
if (_Py_atomic_load_uint64(&byte) != 10) {
return 1; // error
}
return 0; // all good
}
]])],[
ac_cv_libatomic_needed=no
],[ac_cv_libatomic_needed=yes],[ac_cv_libatomic_needed=yes])
])

if test $ac_cv_libatomic_needed = yes
then
LIBATOMIC="-latomic"
fi
_RESTORE_VAR([CPPFLAGS])


# stdlib
AC_DEFUN([PY_STDLIB_MOD_SET_NA], [
m4_foreach([mod], [$@], [
AS_VAR_SET([py_cv_module_]mod, [n/a])])
Expand Down Expand Up @@ -7229,7 +7291,10 @@ PY_STDLIB_MOD([_hashlib], [], [test "$ac_cv_working_openssl_hashlib" = yes],
[$OPENSSL_INCLUDES], [$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $LIBCRYPTO_LIBS])

dnl test modules
PY_STDLIB_MOD([_testcapi], [test "$TEST_MODULES" = yes])
PY_STDLIB_MOD([_testcapi],
[test "$TEST_MODULES" = yes], []
dnl Modules/_testcapi/pyatomic.c uses <cpython/pyatomic.h> header
[], [], [$LIBATOMIC])
PY_STDLIB_MOD([_testclinic], [test "$TEST_MODULES" = yes])
PY_STDLIB_MOD([_testclinic_limited], [test "$TEST_MODULES" = yes])
PY_STDLIB_MOD([_testinternalcapi], [test "$TEST_MODULES" = yes])
Expand Down Expand Up @@ -7262,6 +7327,7 @@ AC_CONFIG_FILES(m4_normalize([
Modules/Setup.stdlib
]))
AC_CONFIG_FILES([Modules/ld_so_aix], [chmod +x Modules/ld_so_aix])
# Generate files like pyconfig.h
AC_OUTPUT

AC_MSG_NOTICE([creating Modules/Setup.local])
Expand Down

0 comments on commit e241894

Please sign in to comment.