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