summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Misc/NEWS.d/next/Build/2023-09-07-19-58-05.gh-issue-109054.5r3S3l.rst6
-rwxr-xr-xconfigure85
-rw-r--r--configure.ac62
3 files changed, 151 insertions, 2 deletions
diff --git a/Misc/NEWS.d/next/Build/2023-09-07-19-58-05.gh-issue-109054.5r3S3l.rst b/Misc/NEWS.d/next/Build/2023-09-07-19-58-05.gh-issue-109054.5r3S3l.rst
new file mode 100644
index 0000000..d86a110
--- /dev/null
+++ b/Misc/NEWS.d/next/Build/2023-09-07-19-58-05.gh-issue-109054.5r3S3l.rst
@@ -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.
diff --git a/configure b/configure
index d73b4b2..c78c45d 100755
--- a/configure
+++ b/configure
@@ -27752,6 +27752,88 @@ printf "%s\n" "#define Py_NOGIL 1" >>confdefs.h
fi
+# gh-109054: Check if -latomic is needed to get <pyatomic.h> atomic functions.
+# On Linux aarch64, GCC may require programs and libraries to be linked
+# explicitly to libatomic. Call _Py_atomic_or_uint64() which may require
+# libatomic __atomic_fetch_or_8(), or not, depending on the C 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 LIBATOMIC 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.
+save_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="${BASECPPFLAGS} -I. -I${srcdir}/Include ${CPPFLAGS}"
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether libatomic is needed by <pyatomic.h>" >&5
+printf %s "checking whether libatomic is needed by <pyatomic.h>... " >&6; }
+if test ${ac_cv_libatomic_needed+y}
+then :
+ printf %s "(cached) " >&6
+else $as_nop
+ if test "$cross_compiling" = yes
+then :
+ ac_cv_libatomic_needed=yes
+else $as_nop
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+// 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 define Py_ssize_t"
+#endif
+
+#include "cpython/pyatomic.h"
+
+int main()
+{
+ 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
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"
+then :
+
+ ac_cv_libatomic_needed=no
+
+else $as_nop
+ ac_cv_libatomic_needed=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libatomic_needed" >&5
+printf "%s\n" "$ac_cv_libatomic_needed" >&6; }
+
+if test "x$ac_cv_libatomic_needed" = xyes
+then :
+ LIBATOMIC=${LIBATOMIC-"-latomic"}
+fi
+CPPFLAGS=$save_CPPFLAGS
+
+
+# stdlib
# stdlib not available
@@ -29900,7 +29982,7 @@ fi
then :
-
+ as_fn_append MODULE_BLOCK "MODULE__TESTCAPI_LDFLAGS=$LIBATOMIC$as_nl"
fi
if test "$py_cv_module__testcapi" = yes; then
@@ -30344,6 +30426,7 @@ ac_config_files="$ac_config_files Modules/Setup.bootstrap Modules/Setup.stdlib"
ac_config_files="$ac_config_files Modules/ld_so_aix"
+# Generate files like pyconfig.h
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
diff --git a/configure.ac b/configure.ac
index 612c072..f833755 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6962,6 +6962,62 @@ then
[Define if you want to disable the GIL])
fi
+# gh-109054: Check if -latomic is needed to get <pyatomic.h> atomic functions.
+# On Linux aarch64, GCC may require programs and libraries to be linked
+# explicitly to libatomic. Call _Py_atomic_or_uint64() which may require
+# libatomic __atomic_fetch_or_8(), or not, depending on the C 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 LIBATOMIC 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.
+_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 define Py_ssize_t"
+#endif
+
+#include "cpython/pyatomic.h"
+
+int main()
+{
+ 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])
+])
+
+AS_VAR_IF([ac_cv_libatomic_needed], [yes],
+ [LIBATOMIC=${LIBATOMIC-"-latomic"}])
+_RESTORE_VAR([CPPFLAGS])
+
+
+# stdlib
AC_DEFUN([PY_STDLIB_MOD_SET_NA], [
m4_foreach([mod], [$@], [
AS_VAR_SET([py_cv_module_]mod, [n/a])])
@@ -7229,7 +7285,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])
@@ -7262,6 +7321,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])