Skip to content

Commit bacf128

Browse files
ctypes: probe libffi for ffi_closure_alloc and ffi_prep_cif_var
1 parent 36b35bc commit bacf128

File tree

2 files changed

+25
-13
lines changed

2 files changed

+25
-13
lines changed

Modules/_ctypes/callproc.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,6 @@
8686
#define DONT_USE_SEH
8787
#endif
8888

89-
#if defined(__APPLE__) && __arm64__
90-
#define HAVE_FFI_PREP_CIF_VAR 1
91-
#endif
92-
9389
#define CTYPES_CAPSULE_NAME_PYMEM "_ctypes pymem"
9490

9591
static void pymem_destructor(PyObject *ptr)

setup.py

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,13 @@ def is_macosx_sdk_path(path):
246246
or path.startswith('/Library/') )
247247

248248

249+
def grep_headers_for(function, headers):
250+
for header in headers:
251+
with open(header, 'r') as f:
252+
if function in f.read():
253+
return True
254+
return False
255+
249256
def find_file(filename, std_dirs, paths):
250257
"""Searches for the directory where a given file is located,
251258
and returns a possibly-empty list of additional directories, or None
@@ -2195,7 +2202,7 @@ def detect_ctypes(self):
21952202
sources=['_ctypes/_ctypes_test.c'],
21962203
libraries=['m']))
21972204

2198-
ffi_inc = [sysconfig.get_config_var("LIBFFI_INCLUDEDIR")]
2205+
ffi_inc = sysconfig.get_config_var("LIBFFI_INCLUDEDIR")
21992206
ffi_lib = None
22002207

22012208
ffi_inc_dirs = self.inc_dirs.copy()
@@ -2204,29 +2211,38 @@ def detect_ctypes(self):
22042211
return
22052212
ffi_in_sdk = os.path.join(macosx_sdk_root(), "usr/include/ffi")
22062213
if os.path.exists(ffi_in_sdk):
2207-
ffi_inc = [ffi_in_sdk]
2214+
ffi_inc = ffi_in_sdk
22082215
ffi_lib = 'ffi'
2209-
sources.remove('_ctypes/malloc_closure.c')
22102216
else:
22112217
# OS X 10.5 comes with libffi.dylib; the include files are
22122218
# in /usr/include/ffi
22132219
ffi_inc_dirs.append('/usr/include/ffi')
22142220

2215-
if not ffi_inc or ffi_inc[0] == '':
2216-
ffi_inc = find_file('ffi.h', [], ffi_inc_dirs)
2217-
if ffi_inc is not None:
2218-
ffi_h = ffi_inc[0] + '/ffi.h'
2221+
if not ffi_inc:
2222+
found = find_file('ffi.h', [], ffi_inc_dirs)
2223+
if found:
2224+
ffi_inc = found[0]
2225+
if ffi_inc:
2226+
ffi_h = ffi_inc + '/ffi.h'
22192227
if not os.path.exists(ffi_h):
22202228
ffi_inc = None
22212229
print('Header file {} does not exist'.format(ffi_h))
2222-
if ffi_lib is None and ffi_inc is not None:
2230+
if ffi_lib is None and ffi_inc:
22232231
for lib_name in ('ffi', 'ffi_pic'):
22242232
if (self.compiler.find_library_file(self.lib_dirs, lib_name)):
22252233
ffi_lib = lib_name
22262234
break
22272235

22282236
if ffi_inc and ffi_lib:
2229-
ext.include_dirs.extend(ffi_inc)
2237+
ffi_headers = glob(os.path.join(ffi_inc, '*.h'))
2238+
if grep_headers_for('ffi_closure_alloc', ffi_headers):
2239+
try:
2240+
sources.remove('_ctypes/malloc_closure.c')
2241+
except ValueError:
2242+
pass
2243+
if grep_headers_for('ffi_prep_cif_var', ffi_headers):
2244+
ext.extra_compile_args.append("-DHAVE_FFI_PREP_CIF_VAR=1")
2245+
ext.include_dirs.append(ffi_inc)
22302246
ext.libraries.append(ffi_lib)
22312247
self.use_system_libffi = True
22322248

0 commit comments

Comments
 (0)