From 3bfc97ad29b3b602c525e18e3418398b18de6038 Mon Sep 17 00:00:00 2001 From: Chaim Halbert Date: Sun, 26 Feb 2023 08:36:51 -0700 Subject: [PATCH] bpo-36231 for v3.5.10: fix Unsupported MacOS X CPU type in ffi.h (#2633) --- ...system-libffi-patch-for-arm64-macOS-.patch | 132 ++++++++++++++++++ ...t-building-on-macOS-without-usr-incl.patch | 93 ++++++++++++ 2 files changed, 225 insertions(+) create mode 100644 plugins/python-build/share/python-build/patches/3.5.10/Python-3.5.10/0007-Port-ctypes-and-system-libffi-patch-for-arm64-macOS-.patch create mode 100644 plugins/python-build/share/python-build/patches/3.5.10/Python-3.5.10/0008-bpo-36231-Support-building-on-macOS-without-usr-incl.patch diff --git a/plugins/python-build/share/python-build/patches/3.5.10/Python-3.5.10/0007-Port-ctypes-and-system-libffi-patch-for-arm64-macOS-.patch b/plugins/python-build/share/python-build/patches/3.5.10/Python-3.5.10/0007-Port-ctypes-and-system-libffi-patch-for-arm64-macOS-.patch new file mode 100644 index 00000000..e5876b1f --- /dev/null +++ b/plugins/python-build/share/python-build/patches/3.5.10/Python-3.5.10/0007-Port-ctypes-and-system-libffi-patch-for-arm64-macOS-.patch @@ -0,0 +1,132 @@ +From 409b4ecef88643996ce00482b650c0246a977a4b Mon Sep 17 00:00:00 2001 +From: Chaim Halbert +Date: Sun, 26 Feb 2023 06:21:54 -0700 +Subject: [PATCH] Port ctypes and system libffi patch for arm64/macOS 10.15+ to + Python 3.5.10 + +This backports the following ctypes and libffi pyenv patch for Python +3.6.15 to Python 3.5.10: + +* `0004-Port-ctypes-and-system-libffi-patches-for-arm64-macO.patch` + +This patch enables use of system libffi (fixing a broken `ctypes` module +on arm64 targets) and enables calling variadic functions on arm64. +--- + setup.py | 65 +++++++++++++++++++++++++++++++++++++++++++------------- + 1 file changed, 50 insertions(+), 15 deletions(-) + +diff --git a/setup.py b/setup.py +index 2944c9dd6f..ab8065866f 100644 +--- a/setup.py ++++ b/setup.py +@@ -73,6 +73,13 @@ def macosx_sdk_root(): + sysroot = m.group(1) + return sysroot + ++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 +@@ -81,6 +88,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 +@@ -1939,7 +1953,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 = [] +@@ -1986,19 +2004,29 @@ class PyBuildExt(build_ext): + libraries=math_libs) + self.extensions.extend([ext, ext_test]) + +- if not '--with-system-ffi' in sysconfig.get_config_var("CONFIG_ARGS"): +- return ++ ffi_inc = sysconfig.get_config_var("LIBFFI_INCLUDEDIR") ++ ffi_lib = None + + if host_platform == 'darwin': +- # OS X 10.5 comes with libffi.dylib; the include files are +- # in /usr/include/ffi +- inc_dirs.append('/usr/include/ffi') +- +- 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 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 ++ ++ 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() +@@ -2009,15 +2037,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_convenience', 'ffi_pic', 'ffi'): + 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.39.2 + diff --git a/plugins/python-build/share/python-build/patches/3.5.10/Python-3.5.10/0008-bpo-36231-Support-building-on-macOS-without-usr-incl.patch b/plugins/python-build/share/python-build/patches/3.5.10/Python-3.5.10/0008-bpo-36231-Support-building-on-macOS-without-usr-incl.patch new file mode 100644 index 00000000..f95099a1 --- /dev/null +++ b/plugins/python-build/share/python-build/patches/3.5.10/Python-3.5.10/0008-bpo-36231-Support-building-on-macOS-without-usr-incl.patch @@ -0,0 +1,93 @@ +From c7302116573d853d3181133477d9d0e4d4d3abfd Mon Sep 17 00:00:00 2001 +From: Ned Deily +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 - %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) +