Fix Python 3.6.15 compilation on macOS arm64/M1. (#2189)

This change ports several established patches to the Python 3.6.15
build, enabling compilation on arm64/Apple M1 architectures:

1. `0001-Detect-arm64-in-configure.patch` -
   Updates configure to detect arm64 architectures (port of an existing
   pyenv patch for 2.7.18).

2. `0002-bpo-36231-Support-building-on-macOS-without-usr-incl.patch` -
   Adds macOS SDK root computation logic for determining include paths
   (port of existing Python patches introduced in 2.7.17 and 3.7.4).

3. `0003-Fix-macOS-_tkinter-use-of-Tck-Tk-in-Library-Framewor.patch` -
   Fixes Tcl/Tk support on macOS (port of an existing pyenv patch
   for 2.7.18).

4. `0004-Port-ctypes-and-system-libffi-patches-for-arm64-macO.patch` -
   Fixes system `ffi.h`/`libffi` path determination and usage and
   enables calling of variadic functions, fixing ctypes support
   (consolidated port of existing pyenv patches for 2.7.18 that iterate
   on this logic).

5. `0005-BPO-41100-Support-macOS-11-when-building-GH-21113.patch` -
   Updates Darwin version checks to handle macOS 11's major version
   bump (port of Python patches introduced in 3.7.0 and 3.9.0).

6. `0006-bpo-41100-fix-_decimal-for-arm64-Mac-OS-GH-21228.patch` -
   Adds arm64 to the list of allowable architectures for the
   `decimal` module (port of Python patch introduced in 3.8.10).
This commit is contained in:
Christian Hammond 2021-12-19 20:09:38 -08:00 committed by GitHub
parent 86ca164a11
commit 152457a428
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 774 additions and 0 deletions

View file

@ -0,0 +1,41 @@
From 002501946bad91a308f37a09204393c172f03c3e Mon Sep 17 00:00:00 2001
From: Takumi Sueda <puhitaku@gmail.com>
Date: Sat, 11 Sep 2021 16:50:14 +0900
Subject: [PATCH 2/6] Detect arm64 in configure
---
configure | 3 +++
configure.ac | 3 +++
2 files changed, 6 insertions(+)
diff --git a/configure b/configure
index e39c16eee2..8dc1fc7595 100755
--- a/configure
+++ b/configure
@@ -9230,6 +9230,9 @@ fi
ppc)
MACOSX_DEFAULT_ARCH="ppc64"
;;
+ arm64)
+ MACOSX_DEFAULT_ARCH="arm64"
+ ;;
*)
as_fn_error $? "Unexpected output of 'arch' on OSX" "$LINENO" 5
;;
diff --git a/configure.ac b/configure.ac
index cf280506bd..34846a7df3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2435,6 +2435,9 @@ case $ac_sys_system/$ac_sys_release in
ppc)
MACOSX_DEFAULT_ARCH="ppc64"
;;
+ arm64)
+ MACOSX_DEFAULT_ARCH="arm64"
+ ;;
*)
AC_MSG_ERROR([Unexpected output of 'arch' on OSX])
;;
--
2.30.1 (Apple Git-130)

View file

@ -0,0 +1,93 @@
From c7302116573d853d3181133477d9d0e4d4d3abfd Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Tue, 18 Jun 2019 16:28:13 -0400
Subject: [PATCH] bpo-36231: Support building on macOS without /usr/include
(GH-13773) (GH-14208)
---
.../2019-06-03-05-49-49.bpo-36231.RfmW_p.rst | 3 ++
setup.py | 53 ++++++++++++++++---
2 files changed, 49 insertions(+), 7 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2019-06-03-05-49-49.bpo-36231.RfmW_p.rst
diff --git a/Misc/NEWS.d/next/macOS/2019-06-03-05-49-49.bpo-36231.RfmW_p.rst b/Misc/NEWS.d/next/macOS/2019-06-03-05-49-49.bpo-36231.RfmW_p.rst
new file mode 100644
index 0000000000..c82e54c12c
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2019-06-03-05-49-49.bpo-36231.RfmW_p.rst
@@ -0,0 +1,3 @@
+Support building Python on macOS without /usr/include installed. As of macOS
+10.14, system header files are only available within an SDK provided by
+either the Command Line Tools or the Xcode app.
diff --git a/setup.py b/setup.py
index bcc4bfa89d..5e0cd02430 100644
--- a/setup.py
+++ b/setup.py
@@ -90,18 +90,57 @@ def sysroot_paths(make_vars, subdirs):
break
return dirs
+MACOS_SDK_ROOT = None
+
def macosx_sdk_root():
+ """Return the directory of the current macOS SDK.
+
+ If no SDK was explicitly configured, call the compiler to find which
+ include files paths are being searched by default. Use '/' if the
+ compiler is searching /usr/include (meaning system header files are
+ installed) or use the root of an SDK if that is being searched.
+ (The SDK may be supplied via Xcode or via the Command Line Tools).
+ The SDK paths used by Apple-supplied tool chains depend on the
+ setting of various variables; see the xcrun man page for more info.
"""
- Return the directory of the current OSX SDK,
- or '/' if no SDK was specified.
- """
+ global MACOS_SDK_ROOT
+
+ # If already called, return cached result.
+ if MACOS_SDK_ROOT:
+ return MACOS_SDK_ROOT
+
cflags = sysconfig.get_config_var('CFLAGS')
m = re.search(r'-isysroot\s+(\S+)', cflags)
- if m is None:
- sysroot = '/'
+ if m is not None:
+ MACOS_SDK_ROOT = m.group(1)
else:
- sysroot = m.group(1)
- return sysroot
+ MACOS_SDK_ROOT = '/'
+ cc = sysconfig.get_config_var('CC')
+ tmpfile = '/tmp/setup_sdk_root.%d' % os.getpid()
+ try:
+ os.unlink(tmpfile)
+ except:
+ pass
+ ret = os.system('%s -E -v - </dev/null 2>%s 1>/dev/null' % (cc, tmpfile))
+ in_incdirs = False
+ try:
+ if ret >> 8 == 0:
+ with open(tmpfile) as fp:
+ for line in fp.readlines():
+ if line.startswith("#include <...>"):
+ in_incdirs = True
+ elif line.startswith("End of search list"):
+ in_incdirs = False
+ elif in_incdirs:
+ line = line.strip()
+ if line == '/usr/include':
+ MACOS_SDK_ROOT = '/'
+ elif line.endswith(".sdk/usr/include"):
+ MACOS_SDK_ROOT = line[:-12]
+ finally:
+ os.unlink(tmpfile)
+
+ return MACOS_SDK_ROOT
def is_macosx_sdk_path(path):
"""
--
2.30.1 (Apple Git-130)

View file

@ -0,0 +1,240 @@
From 942db3e6b96225ef8330f5329c702d62483c6ef8 Mon Sep 17 00:00:00 2001
From: Takumi Sueda <puhitaku@gmail.com>
Date: Sat, 11 Sep 2021 17:14:34 +0900
Subject: [PATCH 3/6] Fix macOS _tkinter use of Tck/Tk in /Library/Framework
Modified and imported from https://github.com/Homebrew/formula-patches/blob/master/python/3.8.7.patch
---
setup.py | 147 ++++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 107 insertions(+), 40 deletions(-)
diff --git a/setup.py b/setup.py
index e2c1898253..8e03c77997 100644
--- a/setup.py
+++ b/setup.py
@@ -91,6 +91,7 @@ def sysroot_paths(make_vars, subdirs):
return dirs
MACOS_SDK_ROOT = None
+MACOS_SDK_SPECIFIED = None
def macosx_sdk_root():
"""Return the directory of the current macOS SDK.
@@ -102,8 +103,9 @@ def macosx_sdk_root():
(The SDK may be supplied via Xcode or via the Command Line Tools).
The SDK paths used by Apple-supplied tool chains depend on the
setting of various variables; see the xcrun man page for more info.
+ Also sets MACOS_SDK_SPECIFIED for use by macosx_sdk_specified().
"""
- global MACOS_SDK_ROOT
+ global MACOS_SDK_ROOT, MACOS_SDK_SPECIFIED
# If already called, return cached result.
if MACOS_SDK_ROOT:
@@ -113,8 +115,10 @@ def macosx_sdk_root():
m = re.search(r'-isysroot\s+(\S+)', cflags)
if m is not None:
MACOS_SDK_ROOT = m.group(1)
+ MACOS_SDK_SPECIFIED = MACOS_SDK_ROOT != '/'
else:
MACOS_SDK_ROOT = '/'
+ MACOS_SDK_SPECIFIED = False
cc = sysconfig.get_config_var('CC')
tmpfile = '/tmp/setup_sdk_root.%d' % os.getpid()
try:
@@ -142,6 +146,27 @@ def macosx_sdk_root():
return MACOS_SDK_ROOT
+def macosx_sdk_specified():
+ """Returns true if an SDK was explicitly configured.
+
+ True if an SDK was selected at configure time, either by specifying
+ --enable-universalsdk=(something other than no or /) or by adding a
+ -isysroot option to CFLAGS. In some cases, like when making
+ decisions about macOS Tk framework paths, we need to be able to
+ know whether the user explicitly asked to build with an SDK versus
+ the implicit use of an SDK when header files are no longer
+ installed on a running system by the Command Line Tools.
+ """
+ global MACOS_SDK_SPECIFIED
+
+ # If already called, return cached result.
+ if MACOS_SDK_SPECIFIED:
+ return MACOS_SDK_SPECIFIED
+
+ # Find the sdk root and set MACOS_SDK_SPECIFIED
+ macosx_sdk_root()
+ return MACOS_SDK_SPECIFIED
+
def is_macosx_sdk_path(path):
"""
Returns True if 'path' can be located in an OSX SDK
@@ -1758,31 +1783,72 @@ class PyBuildExt(build_ext):
return 1
def detect_tkinter_darwin(self, inc_dirs, lib_dirs):
- # The _tkinter module, using frameworks. Since frameworks are quite
- # different the UNIX search logic is not sharable.
- from os.path import join, exists
- framework_dirs = [
- '/Library/Frameworks',
- '/System/Library/Frameworks/',
- join(os.getenv('HOME'), '/Library/Frameworks')
- ]
+ # Build default _tkinter on macOS using Tcl and Tk frameworks.
+ #
+ # The macOS native Tk (AKA Aqua Tk) and Tcl are most commonly
+ # built and installed as macOS framework bundles. However,
+ # for several reasons, we cannot take full advantage of the
+ # Apple-supplied compiler chain's -framework options here.
+ # Instead, we need to find and pass to the compiler the
+ # absolute paths of the Tcl and Tk headers files we want to use
+ # and the absolute path to the directory containing the Tcl
+ # and Tk frameworks for linking.
+ #
+ # We want to handle here two common use cases on macOS:
+ # 1. Build and link with system-wide third-party or user-built
+ # Tcl and Tk frameworks installed in /Library/Frameworks.
+ # 2. Build and link using a user-specified macOS SDK so that the
+ # built Python can be exported to other systems. In this case,
+ # search only the SDK's /Library/Frameworks (normally empty)
+ # and /System/Library/Frameworks.
+ #
+ # Any other use case should be able to be handled explicitly by
+ # using the options described above in detect_tkinter_explicitly().
+ # In particular it would be good to handle here the case where
+ # you want to build and link with a framework build of Tcl and Tk
+ # that is not in /Library/Frameworks, say, in your private
+ # $HOME/Library/Frameworks directory or elsewhere. It turns
+ # out to be difficult to make that work automtically here
+ # without bringing into play more tools and magic. That case
+ # can be hamdled using a recipe with the right arguments
+ # to detect_tkinter_explicitly().
+ #
+ # Note also that the fallback case here is to try to use the
+ # Apple-supplied Tcl and Tk frameworks in /System/Library but
+ # be forewarned that they are deprecated by Apple and typically
+ # out-of-date and buggy; their use should be avoided if at
+ # all possible by installing a newer version of Tcl and Tk in
+ # /Library/Frameworks before bwfore building Python without
+ # an explicit SDK or by configuring build arguments explicitly.
- sysroot = macosx_sdk_root()
+ from os.path import join, exists
+ sysroot = macosx_sdk_root() # path to the SDK or '/'
+
+ if macosx_sdk_specified():
+ # Use case #2: an SDK other than '/' was specified.
+ # Only search there.
+ framework_dirs = [
+ join(sysroot, 'Library', 'Frameworks'),
+ join(sysroot, 'System', 'Library', 'Frameworks'),
+ ]
+ else:
+ # Use case #1: no explicit SDK selected.
+ # Search the local system-wide /Library/Frameworks,
+ # not the one in the default SDK, othewise fall back to
+ # /System/Library/Frameworks whose header files may be in
+ # the default SDK or, on older systems, actually installed.
+ framework_dirs = [
+ join('/', 'Library', 'Frameworks'),
+ join(sysroot, 'System', 'Library', 'Frameworks'),
+ ]
- # Find the directory that contains the Tcl.framework and Tk.framework
- # bundles.
- # XXX distutils should support -F!
+ # Find the directory that contains the Tcl.framework and
+ # Tk.framework bundles.
for F in framework_dirs:
# both Tcl.framework and Tk.framework should be present
-
-
for fw in 'Tcl', 'Tk':
- if is_macosx_sdk_path(F):
- if not exists(join(sysroot, F[1:], fw + '.framework')):
- break
- else:
- if not exists(join(F, fw + '.framework')):
- break
+ if not exists(join(F, fw + '.framework')):
+ break
else:
# ok, F is now directory with both frameworks. Continure
# building
@@ -1792,24 +1858,16 @@ class PyBuildExt(build_ext):
# will now resume.
return 0
- # For 8.4a2, we must add -I options that point inside the Tcl and Tk
- # frameworks. In later release we should hopefully be able to pass
- # the -F option to gcc, which specifies a framework lookup path.
- #
include_dirs = [
join(F, fw + '.framework', H)
for fw in ('Tcl', 'Tk')
- for H in ('Headers', 'Versions/Current/PrivateHeaders')
+ for H in ('Headers',)
]
- # For 8.4a2, the X11 headers are not included. Rather than include a
- # complicated search, this is a hard-coded path. It could bail out
- # if X11 libs are not found...
- include_dirs.append('/usr/X11R6/include')
- frameworks = ['-framework', 'Tcl', '-framework', 'Tk']
+ # Add the base framework directory as well
+ compile_args = ['-F', F]
- # All existing framework builds of Tcl/Tk don't support 64-bit
- # architectures.
+ # Do not build tkinter for archs that this Tk was not built with.
cflags = sysconfig.get_config_vars('CFLAGS')[0]
archs = re.findall(r'-arch\s+(\w+)', cflags)
@@ -1819,10 +1877,7 @@ class PyBuildExt(build_ext):
# Note: cannot use os.popen or subprocess here, that
# requires extensions that are not available here.
- if is_macosx_sdk_path(F):
- os.system("file %s/Tk.framework/Tk | grep 'for architecture' > %s"%(os.path.join(sysroot, F[1:]), tmpfile))
- else:
- os.system("file %s/Tk.framework/Tk | grep 'for architecture' > %s"%(F, tmpfile))
+ os.system("file %s/Tk.framework/Tk | grep 'for architecture' > %s"%(F, tmpfile))
with open(tmpfile) as fp:
detected_archs = []
@@ -1832,16 +1887,26 @@ class PyBuildExt(build_ext):
detected_archs.append(ln.split()[-1])
os.unlink(tmpfile)
+ arch_args = []
for a in detected_archs:
- frameworks.append('-arch')
- frameworks.append(a)
+ arch_args.append('-arch')
+ arch_args.append(a)
+
+ compile_args += arch_args
+ link_args = [','.join(['-Wl', '-F', F, '-framework', 'Tcl', '-framework', 'Tk'])] + arch_args
+
+ # The X11/xlib.h file bundled in the Tk sources can cause function
+ # prototype warnings from the compiler. Since we cannot easily fix
+ # that, suppress the warnings here instead.
+ if '-Wstrict-prototypes' in cflags.split():
+ compile_args.append('-Wno-strict-prototypes')
ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'],
define_macros=[('WITH_APPINIT', 1)],
include_dirs = include_dirs,
libraries = [],
- extra_compile_args = frameworks[2:],
- extra_link_args = frameworks,
+ extra_compile_args = compile_args,
+ extra_link_args = link_args,
)
self.extensions.append(ext)
return 1
--
2.30.1 (Apple Git-130)

View file

@ -0,0 +1,315 @@
From: Christian Hammond <christian@beanbaginc.com>
Date: Wed, 15 Dec 2021 23:12:36 -0800
Subject: Port ctypes and system libffi patches for arm64/macOS 10.15+ to Python 3.6.15
This ports the following ctypes and libffi pyenv patches for Python
2.7.18 to Python 3.6.15:
* `0004-Use-system-libffi-for-Mac-OS-10.15-and-up.patch`
* `0005-ctypes-use-the-correct-ABI-for-variadic-functions.patch`
* `0006-ctypes-probe-libffi-for-ffi_closure_alloc-and-ffi_pr.patch`
These patches enable use of system libffi (fixing a broken `ctypes`
module on arm64 targets) and enable calling variadic functions on arm64.
They've been combined from patches port from Homebrew to pyenv by Takumi
Sueda, updated to work on the Python 3.6.15 codebase.
The Homebrew patches are themselves backports of changes in Python 3.9
and 3.10. That patch can be found at:
https://github.com/Homebrew/formula-patches/blob/master/python/3.8.7.patch
diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst
index a7cc0c84df..f25f3c78d9 100644
--- a/Doc/library/ctypes.rst
+++ b/Doc/library/ctypes.rst
@@ -1551,6 +1551,13 @@ They are instances of a private class:
value usable as argument (integer, string, ctypes instance). This allows
defining adapters that can adapt custom objects as function parameters.
+ .. attribute:: variadic
+
+ Assign a boolean to specify that the function takes a variable number of
+ arguments. This does not matter on most platforms, but for Apple arm64
+ platforms variadic functions have a different calling convention than
+ normal functions.
+
.. attribute:: errcheck
Assign a Python function or another callable to this attribute. The
diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py
index 56ab0ad732..013b1e9ce7 100644
--- a/Lib/test/test_unicode.py
+++ b/Lib/test/test_unicode.py
@@ -2443,11 +2443,14 @@ class CAPITest(unittest.TestCase):
def test_from_format(self):
support.import_module('ctypes')
from ctypes import (
+ c_char_p,
pythonapi, py_object, sizeof,
c_int, c_long, c_longlong, c_ssize_t,
c_uint, c_ulong, c_ulonglong, c_size_t, c_void_p)
name = "PyUnicode_FromFormat"
_PyUnicode_FromFormat = getattr(pythonapi, name)
+ _PyUnicode_FromFormat.argtypes = (c_char_p,)
+ _PyUnicode_FromFormat.variadic = True
_PyUnicode_FromFormat.restype = py_object
def PyUnicode_FromFormat(format, *args):
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
index 24d64858ed..351f274ad3 100644
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -3120,6 +3120,34 @@ PyCFuncPtr_get_restype(PyCFuncPtrObject *self, void *Py_UNUSED(ignored))
}
}
+static int
+PyCFuncPtr_set_variadic(PyCFuncPtrObject *self, PyObject *ob)
+{
+ StgDictObject *dict = PyObject_stgdict((PyObject *)self);
+ assert(dict);
+ int r = PyObject_IsTrue(ob);
+ if (r == 1) {
+ dict->flags |= FUNCFLAG_VARIADIC;
+ return 0;
+ } else if (r == 0) {
+ dict->flags &= ~FUNCFLAG_VARIADIC;
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+static PyObject *
+PyCFuncPtr_get_variadic(PyCFuncPtrObject *self)
+{
+ StgDictObject *dict = PyObject_stgdict((PyObject *)self);
+ assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
+ if (dict->flags & FUNCFLAG_VARIADIC)
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+}
+
static int
PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored))
{
@@ -3166,6 +3194,8 @@ static PyGetSetDef PyCFuncPtr_getsets[] = {
{ "argtypes", (getter)PyCFuncPtr_get_argtypes,
(setter)PyCFuncPtr_set_argtypes,
"specify the argument types", NULL },
+ { "variadic", (getter)PyCFuncPtr_get_variadic, (setter)PyCFuncPtr_set_variadic,
+ "specify if function takes variable number of arguments", NULL },
{ NULL, NULL }
};
@@ -5576,6 +5606,7 @@ PyInit__ctypes(void)
PyModule_AddObject(m, "FUNCFLAG_USE_ERRNO", PyLong_FromLong(FUNCFLAG_USE_ERRNO));
PyModule_AddObject(m, "FUNCFLAG_USE_LASTERROR", PyLong_FromLong(FUNCFLAG_USE_LASTERROR));
PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyLong_FromLong(FUNCFLAG_PYTHONAPI));
+ PyModule_AddObject(m, "FUNCFLAG_VARIADIC", PyLong_FromLong(FUNCFLAG_VARIADIC));
PyModule_AddStringConstant(m, "__version__", "1.1.0");
PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c
index 2bb289bce0..12951eadbf 100644
--- a/Modules/_ctypes/callproc.c
+++ b/Modules/_ctypes/callproc.c
@@ -752,7 +754,8 @@ static int _call_function_pointer(int flags,
ffi_type **atypes,
ffi_type *restype,
void *resmem,
- int argcount)
+ int argcount,
+ int argtypecount)
{
#ifdef WITH_THREAD
PyThreadState *_save = NULL; /* For Py_BLOCK_THREADS and Py_UNBLOCK_THREADS */
@@ -780,15 +783,39 @@ static int _call_function_pointer(int flags,
if ((flags & FUNCFLAG_CDECL) == 0)
cc = FFI_STDCALL;
#endif
- if (FFI_OK != ffi_prep_cif(&cif,
- cc,
- argcount,
- restype,
- atypes)) {
- PyErr_SetString(PyExc_RuntimeError,
- "ffi_prep_cif failed");
- return -1;
+
+#if HAVE_FFI_PREP_CIF_VAR
+ /* Everyone SHOULD set f.variadic=True on variadic function pointers, but
+ * lots of existing code will not. If there's at least one arg and more
+ * args are passed than are defined in the prototype, then it must be a
+ * variadic function. */
+ if ((flags & FUNCFLAG_VARIADIC) ||
+ (argtypecount != 0 && argcount > argtypecount))
+ {
+ if (FFI_OK != ffi_prep_cif_var(&cif,
+ cc,
+ argtypecount,
+ argcount,
+ restype,
+ atypes)) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "ffi_prep_cif_var failed");
+ return -1;
+ }
+ } else {
+#endif
+ if (FFI_OK != ffi_prep_cif(&cif,
+ cc,
+ argcount,
+ restype,
+ atypes)) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "ffi_prep_cif failed");
+ return -1;
+ }
+#if HAVE_FFI_PREP_CIF_VAR
}
+#endif
if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) {
error_object = _ctypes_get_errobj(&space);
@@ -1181,9 +1208,8 @@ PyObject *_ctypes_callproc(PPROC pProc,
if (-1 == _call_function_pointer(flags, pProc, avalues, atypes,
rtype, resbuf,
- Py_SAFE_DOWNCAST(argcount,
- Py_ssize_t,
- int)))
+ Py_SAFE_DOWNCAST(argcount, Py_ssize_t, int),
+ Py_SAFE_DOWNCAST(argtype_count, Py_ssize_t, int)))
goto cleanup;
#ifdef WORDS_BIGENDIAN
diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h
index 5d3b966338..1299ec25aa 100644
--- a/Modules/_ctypes/ctypes.h
+++ b/Modules/_ctypes/ctypes.h
@@ -285,6 +285,7 @@ PyObject *_ctypes_callproc(PPROC pProc,
#define FUNCFLAG_PYTHONAPI 0x4
#define FUNCFLAG_USE_ERRNO 0x8
#define FUNCFLAG_USE_LASTERROR 0x10
+#define FUNCFLAG_VARIADIC 0x20
#define TYPEFLAG_ISPOINTER 0x100
#define TYPEFLAG_HASPOINTER 0x200
diff --git a/setup.py b/setup.py
index 8e03c77997..3b124c4b7b 100644
--- a/setup.py
+++ b/setup.py
@@ -167,6 +167,13 @@ def macosx_sdk_specified():
macosx_sdk_root()
return MACOS_SDK_SPECIFIED
+def is_macosx_at_least(vers):
+ if host_platform == 'darwin':
+ dep_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
+ if dep_target:
+ return tuple(map(int, str(dep_target).split('.'))) >= vers
+ return False
+
def is_macosx_sdk_path(path):
"""
Returns True if 'path' can be located in an OSX SDK
@@ -175,6 +182,13 @@ def is_macosx_sdk_path(path):
or path.startswith('/System/')
or path.startswith('/Library/') )
+def grep_headers_for(function, headers):
+ for header in headers:
+ with open(header, 'r') as f:
+ if function in f.read():
+ return True
+ return False
+
def find_file(filename, std_dirs, paths):
"""Searches for the directory where a given file is located,
and returns a possibly-empty list of additional directories, or None
@@ -2115,7 +2129,11 @@ class PyBuildExt(build_ext):
return True
def detect_ctypes(self, inc_dirs, lib_dirs):
- self.use_system_libffi = False
+ if not sysconfig.get_config_var("LIBFFI_INCLUDEDIR") and is_macosx_at_least((10,15)):
+ self.use_system_libffi = True
+ else:
+ self.use_system_libffi = '--with-system-ffi' in sysconfig.get_config_var("CONFIG_ARGS")
+
include_dirs = []
extra_compile_args = []
extra_link_args = []
@@ -2162,20 +2180,30 @@ class PyBuildExt(build_ext):
libraries=math_libs)
self.extensions.extend([ext, ext_test])
+ ffi_inc = sysconfig.get_config_var("LIBFFI_INCLUDEDIR")
+ ffi_lib = None
+ inc_dirs = self.compiler.include_dirs[:]
+
if host_platform == 'darwin':
- if '--with-system-ffi' not in sysconfig.get_config_var("CONFIG_ARGS"):
- return
- # OS X 10.5 comes with libffi.dylib; the include files are
- # in /usr/include/ffi
- inc_dirs.append('/usr/include/ffi')
+ if not self.use_system_libffi:
+ return
+ ffi_in_sdk = os.path.join(macosx_sdk_root(), "usr/include/ffi")
+ if os.path.exists(ffi_in_sdk):
+ ffi_inc = ffi_in_sdk
+ ffi_lib = 'ffi'
+ else:
+ # OS X 10.5 comes with libffi.dylib; the include files are
+ # in /usr/include/ffi
+ inc_dirs.append('/usr/include/ffi')
elif '--without-system-ffi' in sysconfig.get_config_var("CONFIG_ARGS"):
return
- ffi_inc = [sysconfig.get_config_var("LIBFFI_INCLUDEDIR")]
- if not ffi_inc or ffi_inc[0] == '':
- ffi_inc = find_file('ffi.h', [], inc_dirs)
- if ffi_inc is not None:
- ffi_h = ffi_inc[0] + '/ffi.h'
+ if not ffi_inc:
+ found = find_file('ffi.h', [], inc_dirs)
+ if found:
+ ffi_inc = found[0]
+ if ffi_inc:
+ ffi_h = ffi_inc + '/ffi.h'
with open(ffi_h) as f:
for line in f:
line = line.strip()
@@ -2186,15 +2214,22 @@ class PyBuildExt(build_ext):
ffi_inc = None
print('Header file {} does not define LIBFFI_H or '
'ffi_wrapper_h'.format(ffi_h))
- ffi_lib = None
- if ffi_inc is not None:
+ if ffi_lib is None and ffi_inc is not None:
for lib_name in ('ffi', 'ffi_pic'):
if (self.compiler.find_library_file(lib_dirs, lib_name)):
ffi_lib = lib_name
break
if ffi_inc and ffi_lib:
- ext.include_dirs.extend(ffi_inc)
+ ffi_headers = glob(os.path.join(ffi_inc, '*.h'))
+ if grep_headers_for('ffi_closure_alloc', ffi_headers):
+ try:
+ sources.remove('_ctypes/malloc_closure.c')
+ except ValueError:
+ pass
+ if grep_headers_for('ffi_prep_cif_var', ffi_headers):
+ ext.extra_compile_args.append("-DHAVE_FFI_PREP_CIF_VAR=1")
+ ext.include_dirs.append(ffi_inc)
ext.libraries.append(ffi_lib)
self.use_system_libffi = True
--
2.30.1 (Apple Git-130)

View file

@ -0,0 +1,48 @@
From 8ea6353f60625c96ce96588c70ff24a77f8c71f9 Mon Sep 17 00:00:00 2001
From: Ronald Oussoren <ronaldoussoren@mac.com>
Date: Thu, 25 Jun 2020 16:55:48 +0200
Subject: [PATCH] BPO-41100: Support macOS 11 when building (GH-21113)
---
Misc/NEWS.d/next/macOS/2020-06-24-13-51-57.bpo-41100.mcHdc5.rst | 1 +
configure | 2 +-
configure.ac | 2 +-
3 files changed, 3 insertions(+), 2 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2020-06-24-13-51-57.bpo-41100.mcHdc5.rst
diff --git a/Misc/NEWS.d/next/macOS/2020-06-24-13-51-57.bpo-41100.mcHdc5.rst b/Misc/NEWS.d/next/macOS/2020-06-24-13-51-57.bpo-41100.mcHdc5.rst
new file mode 100644
index 0000000000..ded66b567a
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2020-06-24-13-51-57.bpo-41100.mcHdc5.rst
@@ -0,0 +1 @@
+Support macOS 11 when building.
diff --git a/configure b/configure
index c51f396824..5024860ca4 100755
--- a/configure
+++ b/configure
@@ -3375,7 +3375,7 @@ $as_echo "#define _BSD_SOURCE 1" >>confdefs.h
# has no effect, don't bother defining them
Darwin/[6789].*)
define_xopen_source=no;;
- Darwin/1[0-9].*)
+ Darwin/[12][0-9].*)
define_xopen_source=no;;
# On AIX 4 and 5.1, mbstate_t is defined only when _XOPEN_SOURCE == 500 but
# used in wcsnrtombs() and mbsnrtowcs() even if _XOPEN_SOURCE is not defined
diff --git a/configure.ac b/configure.ac
index 70deefb6b9..5a3e340aa3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -495,7 +495,7 @@ case $ac_sys_system/$ac_sys_release in
# has no effect, don't bother defining them
Darwin/@<:@6789@:>@.*)
define_xopen_source=no;;
- Darwin/1@<:@0-9@:>@.*)
+ Darwin/@<:@[12]@:>@@<:@0-9@:>@.*)
define_xopen_source=no;;
# On AIX 4 and 5.1, mbstate_t is defined only when _XOPEN_SOURCE == 500 but
# used in wcsnrtombs() and mbsnrtowcs() even if _XOPEN_SOURCE is not defined
--
2.30.1 (Apple Git-130)

View file

@ -0,0 +1,37 @@
From 604d95e235d86465b8c17f02095edcaf18464d4c Mon Sep 17 00:00:00 2001
From: Lawrence D'Anna <64555057+lawrence-danna-apple@users.noreply.github.com>
Date: Tue, 30 Jun 2020 02:15:46 -0700
Subject: [PATCH] bpo-41100: fix _decimal for arm64 Mac OS (GH-21228)
Patch by Lawrence Danna.
---
.../Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst | 1 +
Modules/_decimal/libmpdec/mpdecimal.h | 3 +++
2 files changed, 4 insertions(+)
create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst
diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst
new file mode 100644
index 0000000000..d6176d69f0
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst
@@ -0,0 +1 @@
+add arm64 to the allowable Mac OS arches in mpdecimal.h
\ No newline at end of file
diff --git a/Modules/_decimal/libmpdec/mpdecimal.h b/Modules/_decimal/libmpdec/mpdecimal.h
index 108b76efa8..35ce429f60 100644
--- a/Modules/_decimal/libmpdec/mpdecimal.h
+++ b/Modules/_decimal/libmpdec/mpdecimal.h
@@ -135,6 +135,9 @@ const char *mpd_version(void);
#elif defined(__x86_64__)
#define CONFIG_64
#define ASM
+ #elif defined(__arm64__)
+ #define CONFIG_64
+ #define ANSI
#else
#error "unknown architecture for universal build."
#endif
--
2.30.1 (Apple Git-130)