Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r2599:c3c29cfd035a
Date: 2016-01-16 16:35 +0100
http://bitbucket.org/cffi/cffi/changeset/c3c29cfd035a/

Log:    OS/X: in-progress, one test now passes

diff --git a/cffi/api.py b/cffi/api.py
--- a/cffi/api.py
+++ b/cffi/api.py
@@ -633,7 +633,7 @@
         compiled DLL.  Use '*' to force distutils' choice, suitable for
         regular CPython C API modules.  Use a file name ending in '.*'
         to ask for the system's default extension for dynamic libraries
-        (.so/.dll).
+        (.so/.dll/.dylib).
 
         The default is '*' when building a non-embedded C API extension,
         and (module_name + '.*') when building an embedded library.
diff --git a/cffi/recompiler.py b/cffi/recompiler.py
--- a/cffi/recompiler.py
+++ b/cffi/recompiler.py
@@ -1363,18 +1363,34 @@
 # around that, in the _patch_for_*() functions...
 
 def _patch_meth(patchlist, cls, name, new_meth):
-    patchlist.append((cls, name, getattr(cls, name)))
+    old = getattr(cls, name)
+    patchlist.append((cls, name, old))
     setattr(cls, name, new_meth)
+    return old
 
 def _unpatch_meths(patchlist):
     for cls, name, old_meth in reversed(patchlist):
         setattr(cls, name, old_meth)
 
-def _patch_for_embedding_win32(patchlist):
-    from distutils.msvc9compiler import MSVCCompiler
-    # we must not remove the manifest when building for embedding!
-    _patch_meth(patchlist, MSVCCompiler, '_remove_visual_c_ref',
-                lambda self, manifest_file: manifest_file)
+def _patch_for_embedding(patchlist):
+    if sys.platform == 'win32':
+        # we must not remove the manifest when building for embedding!
+        from distutils.msvc9compiler import MSVCCompiler
+        _patch_meth(patchlist, MSVCCompiler, '_remove_visual_c_ref',
+                    lambda self, manifest_file: manifest_file)
+
+    if sys.platform == 'darwin':
+        # we must not make a '-bundle', but a '-dynamiclib' instead
+        from distutils.ccompiler import CCompiler
+        def my_link_shared_object(self, *args, **kwds):
+            if '-bundle' in self.linker_so:
+                self.linker_so = list(self.linker_so)
+                i = self.linker_so.index('-bundle')
+                self.linker_so[i] = '-dynamiclib'
+            return old_link_shared_object(self, *args, **kwds)
+        old_link_shared_object = _patch_meth(patchlist, CCompiler,
+                                             'link_shared_object',
+                                             my_link_shared_object)
 
 def _patch_for_target(patchlist, target):
     from distutils.command.build_ext import build_ext
@@ -1385,6 +1401,8 @@
         target = target[:-2]
         if sys.platform == 'win32':
             target += '.dll'
+        elif sys.platform == 'darwin':
+            target += '.dylib'
         else:
             target += '.so'
     _patch_meth(patchlist, build_ext, 'get_ext_filename',
@@ -1423,8 +1441,8 @@
             patchlist = []
             cwd = os.getcwd()
             try:
-                if embedding and sys.platform == 'win32':
-                    _patch_for_embedding_win32(patchlist)
+                if embedding:
+                    _patch_for_embedding(patchlist)
                 if target != '*':
                     _patch_for_target(patchlist, target)
                 os.chdir(tmpdir)
diff --git a/doc/source/embedding.rst b/doc/source/embedding.rst
--- a/doc/source/embedding.rst
+++ b/doc/source/embedding.rst
@@ -4,18 +4,18 @@
 
 .. contents::
 
-You can use CFFI to generate a ``.so/.dll`` which exports the API of
-your choice to any C application that wants to link with this
-``.so/.dll``.
+You can use CFFI to generate a ``.so/.dll/.dylib`` which exports the
+API of your choice to any C application that wants to link with this
+``.so/.dll/.dylib``.
 
 The general idea is as follows:
 
-* You write and execute a Python script, which produces a ``.so/.dll``
-  file with the API of your choice.  The script also gives some Python
-  code to be "frozen" inside the ``.so``.
+* You write and execute a Python script, which produces a
+  ``.so/.dll/.dylib`` file with the API of your choice.  The script
+  also gives some Python code to be "frozen" inside the ``.so``.
 
-* At runtime, the C application loads this ``.so/.dll`` without having
-  to know that it was produced by Python and CFFI.
+* At runtime, the C application loads this ``.so/.dll/.dylib`` without
+  having to know that it was produced by Python and CFFI.
 
 * The first time a C function is called, Python is initialized and
   the frozen Python code is executed.
@@ -73,10 +73,10 @@
     ffi.compile(target="plugin-1.5.*", verbose=True)
 
 Running the code above produces a *DLL*, i,e, a dynamically-loadable
-library.  It is a file with the extension ``.dll`` on Windows or
-``.so`` on other platforms.  As usual, it is produced by generating
-some intermediate ``.c`` code and then calling the regular
-platform-specific C compiler.
+library.  It is a file with the extension ``.dll`` on Windows,
+``.dylib`` on Mac OS/X, or ``.so`` on other platforms.  As usual, it
+is produced by generating some intermediate ``.c`` code and then
+calling the regular platform-specific C compiler.
 
 Here are some details about the methods used above:
 
@@ -143,12 +143,14 @@
 
 * **ffi.compile([target=...] [, verbose=True]):** make the C code and
   compile it.  By default, it produces a file called
-  ``c_module_name.dll`` or ``c_module_name.so``, but the default can
-  be changed with the optional ``target`` keyword argument.  You can
-  use ``target="foo.*"`` with a literal ``*`` to ask for a file called
-  ``foo.dll`` on Windows or ``foo.so`` elsewhere.  One reason for
-  specifying an alternate ``target`` is to include characters not
-  usually allowed in Python module names, like "``plugin-1.5.*``".
+  ``c_module_name.dll``, ``c_module_name.dylib`` or
+  ``c_module_name.so``, but the default can be changed with the
+  optional ``target`` keyword argument.  You can use
+  ``target="foo.*"`` with a literal ``*`` to ask for a file called
+  ``foo.dll`` on Windows, ``foo.dylib`` on OS/X and ``foo.so``
+  elsewhere.  One reason for specifying an alternate ``target`` is to
+  include characters not usually allowed in Python module names, like
+  "``plugin-1.5.*``".
 
   For more complicated cases, you can call instead
   ``ffi.emit_c_code("foo.c")`` and compile the resulting ``foo.c``
diff --git a/testing/embedding/test_basic.py b/testing/embedding/test_basic.py
--- a/testing/embedding/test_basic.py
+++ b/testing/embedding/test_basic.py
@@ -78,6 +78,8 @@
             dynamic_lib_name = match.group(1)
             if sys.platform == 'win32':
                 assert dynamic_lib_name.endswith('_cffi.dll')
+            elif sys.platform == 'darwin':
+                assert dynamic_lib_name.endswith('_cffi.dylib')
             else:
                 assert dynamic_lib_name.endswith('_cffi.so')
             self._compiled_modules[name] = dynamic_lib_name
@@ -124,6 +126,8 @@
         executable_name = name
         if sys.platform == 'win32':
             executable_name = os.path.join(path, executable_name + '.exe')
+        else:
+            executable_name = os.path.join('.', executable_name)
         popen = self._run_base([executable_name], env_extra, cwd=path,
                                stdout=subprocess.PIPE,
                                universal_newlines=True)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to