Skip to content

Commit e241894

Browse files
committed
gh-109054: configure checks if libatomic is needed
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>.
1 parent 00cf626 commit e241894

File tree

4 files changed

+163
-2
lines changed

4 files changed

+163
-2
lines changed

Makefile.pre.in

+1
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ STATIC_LIBPYTHON= @STATIC_LIBPYTHON@
267267

268268
LIBS= @LIBS@
269269
LIBM= @LIBM@
270+
LIBATOMIC= @LIBATOMIC@
270271
LIBC= @LIBC@
271272
SYSLIBS= $(LIBM) $(LIBC)
272273
SHLIBS= @SHLIBS@
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Fix building the ``_testcapi`` extension on Linux AArch64 which requires
2+
linking to libatomic when ``<cpython/pyatomic.h>`` is used: the
3+
``_Py_atomic_or_uint64()`` function requires libatomic
4+
``__atomic_fetch_or_8()`` on this platform. The configure script now checks
5+
if linking to libatomic is needed and generates a new LIBATOMIC variable
6+
used to build the _testcapi extension. Patch by Victor Stinner.

configure

+89-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

configure.ac

+67-1
Original file line numberDiff line numberDiff line change
@@ -6962,6 +6962,68 @@ then
69626962
[Define if you want to disable the GIL])
69636963
fi
69646964

6965+
# gh-109054: Check if -latomic is needed to get <pyatomic.h> atomic functions.
6966+
# On aarch64, GCC may require programs to be linked explicitly to libatomic.
6967+
# Use _Py_atomic_or_uint64() which may require libatomic __atomic_fetch_or_8()
6968+
# on Linux aarch64 (or not depending on the compiler and the compiler flags).
6969+
#
6970+
# Avoid #include <Python.h> or #include <pyport.h>. The <Python.h> header
6971+
# requires <pyconfig.h> header which is only written below by AC_OUTPUT below.
6972+
# If the check is done after AC_OUTPUT, modifying LIBS has no effect anymore.
6973+
# <pyport.h> cannot be included alone, it's designed to be included by
6974+
# <Python.h>: it expects other includes and macros to be defined.
6975+
AC_SUBST([LIBATOMIC])
6976+
LIBATOMIC=""
6977+
6978+
_SAVE_VAR([CPPFLAGS])
6979+
CPPFLAGS="${BASECPPFLAGS} -I. -I${srcdir}/Include ${CPPFLAGS}"
6980+
6981+
AC_CACHE_CHECK([whether libatomic is needed by <pyatomic.h>],
6982+
[ac_cv_libatomic_needed],
6983+
[AC_RUN_IFELSE([AC_LANG_SOURCE([[
6984+
// pyatomic.h needs uint64_t and Py_ssize_t types
6985+
#include <stdint.h> // int64_t, intptr_t
6986+
#ifdef HAVE_SYS_TYPES_H
6987+
# include <sys/types.h> // ssize_t
6988+
#endif
6989+
// Code adapted from Include/pyport.h
6990+
#if HAVE_SSIZE_T
6991+
typedef ssize_t Py_ssize_t;
6992+
#elif SIZEOF_VOID_P == SIZEOF_SIZE_T
6993+
typedef intptr_t Py_ssize_t;
6994+
#else
6995+
# error "unable to find a type fitting ssize_t"
6996+
#endif
6997+
6998+
#include "cpython/pyatomic.h"
6999+
7000+
int main()
7001+
{
7002+
// use _Py_atomic_or_uint64() which requires libatomic __atomic_fetch_or_8()
7003+
// on Linux aarch64.
7004+
uint64_t byte;
7005+
_Py_atomic_store_uint64(&byte, 2);
7006+
if (_Py_atomic_or_uint64(&byte, 8) != 2) {
7007+
return 1; // error
7008+
}
7009+
if (_Py_atomic_load_uint64(&byte) != 10) {
7010+
return 1; // error
7011+
}
7012+
return 0; // all good
7013+
}
7014+
]])],[
7015+
ac_cv_libatomic_needed=no
7016+
],[ac_cv_libatomic_needed=yes],[ac_cv_libatomic_needed=yes])
7017+
])
7018+
7019+
if test $ac_cv_libatomic_needed = yes
7020+
then
7021+
LIBATOMIC="-latomic"
7022+
fi
7023+
_RESTORE_VAR([CPPFLAGS])
7024+
7025+
7026+
# stdlib
69657027
AC_DEFUN([PY_STDLIB_MOD_SET_NA], [
69667028
m4_foreach([mod], [$@], [
69677029
AS_VAR_SET([py_cv_module_]mod, [n/a])])
@@ -7229,7 +7291,10 @@ PY_STDLIB_MOD([_hashlib], [], [test "$ac_cv_working_openssl_hashlib" = yes],
72297291
[$OPENSSL_INCLUDES], [$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $LIBCRYPTO_LIBS])
72307292

72317293
dnl test modules
7232-
PY_STDLIB_MOD([_testcapi], [test "$TEST_MODULES" = yes])
7294+
PY_STDLIB_MOD([_testcapi],
7295+
[test "$TEST_MODULES" = yes], []
7296+
dnl Modules/_testcapi/pyatomic.c uses <cpython/pyatomic.h> header
7297+
[], [], [$LIBATOMIC])
72337298
PY_STDLIB_MOD([_testclinic], [test "$TEST_MODULES" = yes])
72347299
PY_STDLIB_MOD([_testclinic_limited], [test "$TEST_MODULES" = yes])
72357300
PY_STDLIB_MOD([_testinternalcapi], [test "$TEST_MODULES" = yes])
@@ -7262,6 +7327,7 @@ AC_CONFIG_FILES(m4_normalize([
72627327
Modules/Setup.stdlib
72637328
]))
72647329
AC_CONFIG_FILES([Modules/ld_so_aix], [chmod +x Modules/ld_so_aix])
7330+
# Generate files like pyconfig.h
72657331
AC_OUTPUT
72667332

72677333
AC_MSG_NOTICE([creating Modules/Setup.local])

0 commit comments

Comments
 (0)