summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2017-10-29 08:05:02 +0100
committerStefan Behnel <stefan_ml@behnel.de>2017-10-29 08:05:02 +0100
commitad0a820a6294d0f54d14dac1b9868f42a594ab9d (patch)
treeb0e4cf8e12fc713d773273ebc651f1619102b736
parent77fc0ac316da08cbe2cb9c6891b6174a969422b1 (diff)
downloadcython-ad0a820a6294d0f54d14dac1b9868f42a594ab9d.tar.gz
Rewrite the docs section on embedding multiple modules into one binary.
-rw-r--r--docs/src/reference/compilation.rst59
1 files changed, 35 insertions, 24 deletions
diff --git a/docs/src/reference/compilation.rst b/docs/src/reference/compilation.rst
index 3f1334796..2b6e6de2f 100644
--- a/docs/src/reference/compilation.rst
+++ b/docs/src/reference/compilation.rst
@@ -17,6 +17,7 @@ Cython code, unlike Python, must be compiled. This happens in two stages:
The following sub-sections describe several ways to build your
extension modules, and how to pass directives to the Cython compiler.
+
Compiling from the command line
===============================
@@ -43,44 +44,54 @@ paths to libraries you need to link with]
A ``yourmod.so`` file is now in the same directory and your module,
``yourmod``, is available for you to import as you normally would.
-Compiling in a embedded interpreter
-===================================
-Sometimes you might want to use cython to compile a python module you
-made into your hand made embedded python. Here is how to do that.
+Integrating multiple modules
+============================
+
+It some scenarios, it can be useful to link multiple Cython modules
+(or other extension modules) into a single binary, e.g. when embedding
+Python in another application. This can be done through the inittab
+import mechanism of CPython.
-On the top of your C file above the main function you created
-type this without the quotes::
+Create a new C file to integrate the extension modules and add this
+macro to it::
- PyMODINIT_FUNC PyInit__test(void);
+ #if PY_MAJOR_VERSION < 3
+ # define MODINIT(name) init ## name
+ #else
+ # define MODINIT(name) PyInit_ ## name
+ #endif
-for python 3.x and::
+If you are only targeting Python 3.x, just use ``PyInit_`` as prefix.
- PyMODINIT_FUNC init_test(void);
+Then, for each or the modules, declare its module init function
+as follows, replacing ``...`` by the name of the module::
-for python 2.
+ PyMODINIT_FUNC MODINIT(...) (void);
-Where Module Name is the name of the module you cythonized. If you
-are not sure on the name of the module init function refer to your
-generated module source file.
+In C++, declare them as ``extern C``.
-You need to use ``PyImport_AppendInittab`` but right
-before you use ``Py_SetProgramName`` and ``Py_Initialize`` in your
-main as well::
+If you are not sure of the name of the module init function, refer
+to your generated module source file and look for a function name
+starting with ``PyInit_``.
- PyImport_AppendInittab("_test", PyInit__test);
+Next, before you start the Python runtime from your application code
+with ``Py_Initialize()``, you need to initialise the modules at runtime
+using the ``PyImport_AppendInittab()`` C-API function, again inserting
+the name of each of the modules::
-for python 3.x and::
+ PyImport_AppendInittab("...", MODINIT(...));
- PyImport_AppendInittab("_test", init_test)
+This enables normal imports for the embedded extension modules.
-After that is done go in and for all the sources you use define the
-following in the compiler's command line::
+In order to prevent the joined binary from exporting all of the module
+init functions as public symbols, Cython 0.28 and later can hide these
+symbols if the macro ``CYTHON_NO_PYINIT_EXPORT`` is defined while
+C-compiling the module C files.
- CYTHON_NO_PYINIT_EXPORT
+Also take a look at the `cython_freeze
+<https://github.com/cython/cython/blob/master/bin/cython_freeze>` tool.
-This macro is to ensure that your module initialization function is
-not exported.
Compiling with ``distutils``
============================