@@ -229,6 +229,13 @@ def macosx_sdk_specified():
229229 macosx_sdk_root ()
230230 return MACOS_SDK_SPECIFIED
231231
232+ def is_macosx_at_least (vers ):
233+ if MACOS :
234+ dep_target = sysconfig .get_config_var ('MACOSX_DEPLOYMENT_TARGET' )
235+ if dep_target :
236+ return tuple (map (int , dep_target .split ('.' ))) >= vers
237+ return False
238+
232239
233240def is_macosx_sdk_path (path ):
234241 """
@@ -239,6 +246,13 @@ def is_macosx_sdk_path(path):
239246 or path .startswith ('/Library/' ) )
240247
241248
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+
242256def find_file (filename , std_dirs , paths ):
243257 """Searches for the directory where a given file is located,
244258 and returns a possibly-empty list of additional directories, or None
@@ -2100,43 +2114,18 @@ def detect_tkinter(self):
21002114 library_dirs = added_lib_dirs ))
21012115 return True
21022116
2103- def configure_ctypes_darwin (self , ext ):
2104- # Darwin (OS X) uses preconfigured files, in
2105- # the Modules/_ctypes/libffi_osx directory.
2106- ffi_srcdir = os .path .abspath (os .path .join (self .srcdir , 'Modules' ,
2107- '_ctypes' , 'libffi_osx' ))
2108- sources = [os .path .join (ffi_srcdir , p )
2109- for p in ['ffi.c' ,
2110- 'x86/darwin64.S' ,
2111- 'x86/x86-darwin.S' ,
2112- 'x86/x86-ffi_darwin.c' ,
2113- 'x86/x86-ffi64.c' ,
2114- 'powerpc/ppc-darwin.S' ,
2115- 'powerpc/ppc-darwin_closure.S' ,
2116- 'powerpc/ppc-ffi_darwin.c' ,
2117- 'powerpc/ppc64-darwin_closure.S' ,
2118- ]]
2119-
2120- # Add .S (preprocessed assembly) to C compiler source extensions.
2121- self .compiler .src_extensions .append ('.S' )
2122-
2123- include_dirs = [os .path .join (ffi_srcdir , 'include' ),
2124- os .path .join (ffi_srcdir , 'powerpc' )]
2125- ext .include_dirs .extend (include_dirs )
2126- ext .sources .extend (sources )
2127- return True
2128-
21292117 def configure_ctypes (self , ext ):
2130- if not self .use_system_libffi :
2131- if MACOS :
2132- return self .configure_ctypes_darwin (ext )
2133- print ('INFO: Could not locate ffi libs and/or headers' )
2134- return False
21352118 return True
21362119
21372120 def detect_ctypes (self ):
21382121 # Thomas Heller's _ctypes module
2139- self .use_system_libffi = False
2122+
2123+ if (not sysconfig .get_config_var ("LIBFFI_INCLUDEDIR" ) and MACOS and
2124+ (is_macosx_at_least ((10 ,15 )) or '-arch arm64' in sysconfig .get_config_var ("CFLAGS" ))):
2125+ self .use_system_libffi = True
2126+ else :
2127+ self .use_system_libffi = '--with-system-ffi' in sysconfig .get_config_var ("CONFIG_ARGS" )
2128+
21402129 include_dirs = []
21412130 extra_compile_args = ['-DPy_BUILD_CORE_MODULE' ]
21422131 extra_link_args = []
@@ -2149,11 +2138,10 @@ def detect_ctypes(self):
21492138
21502139 if MACOS :
21512140 sources .append ('_ctypes/malloc_closure.c' )
2152- sources .append ('_ctypes/darwin/dlfcn_simple.c' )
2141+ extra_compile_args .append ('-DUSING_MALLOC_CLOSURE_DOT_C=1' )
2142+ #sources.append('_ctypes/darwin/dlfcn_simple.c')
21532143 extra_compile_args .append ('-DMACOSX' )
21542144 include_dirs .append ('_ctypes/darwin' )
2155- # XXX Is this still needed?
2156- # extra_link_args.extend(['-read_only_relocs', 'warning'])
21572145
21582146 elif HOST_PLATFORM == 'sunos5' :
21592147 # XXX This shouldn't be necessary; it appears that some
@@ -2183,31 +2171,47 @@ def detect_ctypes(self):
21832171 sources = ['_ctypes/_ctypes_test.c' ],
21842172 libraries = ['m' ]))
21852173
2174+ ffi_inc = sysconfig .get_config_var ("LIBFFI_INCLUDEDIR" )
2175+ ffi_lib = None
2176+
21862177 ffi_inc_dirs = self .inc_dirs .copy ()
21872178 if MACOS :
2188- if '--with-system-ffi' not in sysconfig .get_config_var ("CONFIG_ARGS" ):
2189- return
2190- # OS X 10.5 comes with libffi.dylib; the include files are
2191- # in /usr/include/ffi
2192- ffi_inc_dirs .append ('/usr/include/ffi' )
2193-
2194- ffi_inc = [sysconfig .get_config_var ("LIBFFI_INCLUDEDIR" )]
2195- if not ffi_inc or ffi_inc [0 ] == '' :
2196- ffi_inc = find_file ('ffi.h' , [], ffi_inc_dirs )
2197- if ffi_inc is not None :
2198- ffi_h = ffi_inc [0 ] + '/ffi.h'
2179+ # XXX: The define should only be added when actually using the system
2180+ # version (and not a locally compiled one)
2181+ ext .extra_compile_args .append ("-DUSING_APPLE_OS_LIBFFI=1" )
2182+ ffi_in_sdk = os .path .join (macosx_sdk_root (), "usr/include/ffi" )
2183+ if os .path .exists (ffi_in_sdk ):
2184+ ffi_inc = ffi_in_sdk
2185+ ffi_lib = 'ffi'
2186+ else :
2187+ # OS X 10.5 comes with libffi.dylib; the include files are
2188+ # in /usr/include/ffi
2189+ ffi_inc_dirs .append ('/usr/include/ffi' )
2190+
2191+ if not ffi_inc :
2192+ found = find_file ('ffi.h' , [], ffi_inc_dirs )
2193+ if found :
2194+ ffi_inc = found [0 ]
2195+ if ffi_inc :
2196+ ffi_h = ffi_inc + '/ffi.h'
21992197 if not os .path .exists (ffi_h ):
22002198 ffi_inc = None
22012199 print ('Header file {} does not exist' .format (ffi_h ))
2202- ffi_lib = None
2203- if ffi_inc is not None :
2200+ if ffi_lib is None and ffi_inc :
22042201 for lib_name in ('ffi' , 'ffi_pic' ):
22052202 if (self .compiler .find_library_file (self .lib_dirs , lib_name )):
22062203 ffi_lib = lib_name
22072204 break
22082205
22092206 if ffi_inc and ffi_lib :
2210- ext .include_dirs .extend (ffi_inc )
2207+ ffi_headers = glob (os .path .join (ffi_inc , '*.h' ))
2208+ if grep_headers_for ('ffi_prep_cif_var' , ffi_headers ):
2209+ ext .extra_compile_args .append ("-DHAVE_FFI_PREP_CIF_VAR=1" )
2210+ if grep_headers_for ('ffi_prep_closure_loc' , ffi_headers ):
2211+ ext .extra_compile_args .append ("-DHAVE_FFI_PREP_CLOSURE_LOC=1" )
2212+ if grep_headers_for ('ffi_closure_alloc' , ffi_headers ):
2213+ ext .extra_compile_args .append ("-DHAVE_FFI_CLOSURE_ALLOC=1" )
2214+ ext .include_dirs .append (ffi_inc )
22112215 ext .libraries .append (ffi_lib )
22122216 self .use_system_libffi = True
22132217
0 commit comments